From 24d67a5ec0ecb32c37358034b836e79659b69b88 Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Tue, 30 Jun 2026 11:26:52 +0200 Subject: [PATCH] App: Return cycle path from find_circular_deps() The __find_circular_deps() and find_circular_deps() methods now return list[str] instead of bool. On a cycle, the path builds up the dependency chain in __find_circular_deps_recursive(), and __find_circular_deps() appends the closing project to complete the cycle. An empty list means no cycle found. CmdDep prints the cycle as 'a -> b -> c -> a' instead of a generic message. Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev Signed-off-by: Jan Lindemann --- src/python/jw/pkg/App.py | 10 ++++++---- src/python/jw/pkg/cmds/projects/check/CmdDep.py | 12 +++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/python/jw/pkg/App.py b/src/python/jw/pkg/App.py index a3583459..1cd974c8 100644 --- a/src/python/jw/pkg/App.py +++ b/src/python/jw/pkg/App.py @@ -315,7 +315,8 @@ class App(Base): temp.remove(project) return None - def __find_circular_deps(self, projects: list[str], flavours: list[str]) -> bool: + 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) @@ -330,8 +331,9 @@ class App(Base): ) if last is not None: log(DEBUG, f'Found circular dependency below {project}, last is {last}') - return True - return False + ret.append(last) + return ret + return [] def __init__(self, distro: Distro | None = None) -> None: @@ -627,5 +629,5 @@ class App(Base): return ', '.join(intersection) return None - def find_circular_deps(self, projects: list[str], flavours: list[str]) -> bool: + def find_circular_deps(self, projects: list[str], flavours: list[str]) -> list[str]: return self.__find_circular_deps(projects, flavours) diff --git a/src/python/jw/pkg/cmds/projects/check/CmdDep.py b/src/python/jw/pkg/cmds/projects/check/CmdDep.py index e6469b90..478b26ae 100644 --- a/src/python/jw/pkg/cmds/projects/check/CmdDep.py +++ b/src/python/jw/pkg/cmds/projects/check/CmdDep.py @@ -1,8 +1,9 @@ from __future__ import annotations +from typing import TYPE_CHECKING + from ....lib.log import NOTICE, log from .Cmd import Cmd, Parent -from typing import TYPE_CHECKING if TYPE_CHECKING: from argparse import ArgumentParser, Namespace @@ -22,8 +23,13 @@ class CmdDep(Cmd): # export parser.add_argument('-f', '--flavour', nargs = '?', default = 'build') async def _run(self, args: Namespace) -> None: - if self.app.find_circular_deps(args.module, args.flavour): - log(NOTICE, f'Found circular dependency in flavour {args.flavour}') + cycle = self.app.find_circular_deps(args.module, args.flavour) + if cycle: + log( + NOTICE, + f'Found circular dependency in flavour {args.flavour}: ' + ' -> '.join(cycle) + ) exit(1) log( NOTICE,