From c52453dc685cbefa11f3aaf6904991094044c8af Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Wed, 9 Sep 2026 21:15:39 +0200 Subject: [PATCH] App.__get_project_refs(): Fix recursion stop conditions App.__get_project_refs() recurses into the package dependency graph, but the recursion end conditions only work well if all required packages are present. Whether a required package is installed or not is decided upon a wrong condition, however - existence of the project's project directory, which may or may not be misleading for both the -devel and the -run requirements. This can lead to various unwanted outcomes: Missing packages happily inserted into the recursion buffer, process termination instead of recursion stop, path lookup errors instead of a clearer "unmet dependency" message (No project path found for module xyz, Failed to find directory of project foo). This commit cleanly detects if -run or -devel are installed and makes the walk stop or raise under the appropriate conditions: 1. -run missing but required, raises unmet dependency 2. -devel missing but required, raises unmet dependency 3. -run present, no -devel required, stop recursing Signed-off-by: Jan Lindemann Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.85.1 --- src/python/jw/pkg/App.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/python/jw/pkg/App.py b/src/python/jw/pkg/App.py index 5af315ea..d437742f 100644 --- a/src/python/jw/pkg/App.py +++ b/src/python/jw/pkg/App.py @@ -206,6 +206,7 @@ class App(Base): names_only: bool, ) -> None: name = self.strip_module_from_spec(spec) + mod = re.split('([=><]+)', spec)[0].strip() if names_only: spec = name if spec in buf: @@ -215,6 +216,15 @@ class App(Base): buf.append(spec) return visited.add(spec) + needed_subpackage = 'devel' if mod.endswith(('-dev', '-devel')) else 'run' + if not self.is_installed(name, devel = True): + if not mod.endswith(('-dev', '-devel')): + if self.is_installed(name, devel = False): + return + raise Exception( + f'Unmet dependency on {mod}: the -{needed_subpackage} package ' + f'of project {name} is not installed' + ) vals = self.get_value(name, section, key) log( DEBUG,