App: Remove duplicate from dependency graph #77

Merged
Jan Lindemann merged 2 commits from jan/fix/20260822-app-remove-duplicate-from-dependency-graph into master 2026-08-22 16:11:34 +02:00 AGit

View file

@ -232,7 +232,6 @@ class App(Base):
for project in projects:
if project in graph:
continue
for section in sections:
deps = self.get_project_refs(
[project],
['pkg.requires.jw'],
@ -259,45 +258,43 @@ class App(Base):
project: str,
graph: Graph,
unvisited: list[str],
temp: set[str],
path: list[str],
) -> str | None:
if project in temp:
stack: list[str],
) -> list[str] | None:
if project in stack:
log(DEBUG, 'found circular dependency at project', project)
return project
idx = stack.index(project)
return stack[idx:] + [project]
if project not in unvisited:
return None
temp.add(project)
stack.append(project)
if project in graph:
for dep in graph[project]:
last = self.__find_circular_deps_recursive(
dep, graph, unvisited, temp, path
cycle = self.__find_circular_deps_recursive(
dep, graph, unvisited, stack
)
if last is not None:
path.insert(0, dep)
return last
if cycle is not None:
return cycle
unvisited.remove(project)
temp.remove(project)
stack.pop()
return None
def __find_circular_deps(self, projects: list[str],
flavours: list[str]) -> list[str]:
graph: Graph = {}
ret: list[str] = []
self.__read_dep_graph(projects, flavours, graph)
unvisited = list(graph.keys())
temp: set[str] = set()
flipped = self.__flip_dep_graph(graph)
while unvisited:
project = unvisited[0]
log(DEBUG, 'Checking circular dependency of', project)
last = self.__find_circular_deps_recursive(
project, flipped, unvisited, temp, ret
)
if last is not None:
log(DEBUG, f'Found circular dependency below {project}, last is {last}')
ret.append(last)
return ret
cycle = self.__find_circular_deps_recursive(project, flipped, unvisited, [])
if cycle is not None:
# An edge a -> b in the flipped graph means that b
# depends on a, so reverse to report the cycle in the
# original direction
cycle = list(reversed(cycle))
log(DEBUG, f'Found circular dependency: {" -> ".join(cycle)}')
return cycle
return []
def __init__(self, distro: Distro | None = None) -> None: