cmds.projects.CmdBuild: Add --pkg-relations

The relations the build closure of projects build follows are hard-coded in
read_deps(): [pkg.requires.jw] only. A workspace that also wants to build
the projects its seeds recommend in [pkg.recommends.jw] has no way to say
so.

Add a --pkg-relations option that lists the relations between jw packages
to take into consideration for the build, comma or space separated,
defaulting to requires.

Signed-off-by: Jan Lindemann <jan@janware.com>
Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.86.1
This commit is contained in:
Jan Lindemann 2026-09-21 05:34:47 +02:00
commit 5f98de8f5a
Signed by: Jan Lindemann
GPG key ID: 3750640C9E25DD61
2 changed files with 26 additions and 7 deletions

View file

@ -62,6 +62,14 @@ class CmdBuild(Cmd): # export
'comma or space separated'
)
)
parser.add_argument(
'--pkg-relations',
default = 'requires',
help = (
'Relations between packages to take into consideration for build, '
'comma or space separated'
)
)
parser.add_argument(
'--env-reinit',
action = 'store_true',
@ -103,7 +111,11 @@ class CmdBuild(Cmd): # export
)
@lru_cache(maxsize = None)
def read_deps(cur: str, dep_flavour: str) -> list[str]:
def read_deps(
cur: str,
dep_flavour: str,
relations: tuple[str, ...],
) -> Iterable[str]:
# dep cache doesn't make a difference at all
if dep_flavour in dep_cache:
if cur in dep_cache[dep_flavour]:
@ -113,13 +125,13 @@ class CmdBuild(Cmd): # export
ret = self.app.get_project_refs(
[cur],
['pkg.requires.jw'],
[f'pkg.{rel}.jw' for rel in relations],
dep_flavour,
scope = Scope.Subtree,
add_self = False,
names_only = True,
)
log(DEBUG, f'Prerequisites: {" ".join(ret)}')
log(DEBUG, f'Prerequisites ({"/".join(relations)}): {" ".join(ret)}')
if cur in ret:
ret.remove(cur)
@ -134,6 +146,7 @@ class CmdBuild(Cmd): # export
def add_dep_tree(
cur: str,
dep_flavours: Iterable[str],
relations: tuple[str, ...],
tree: DepNode,
all_deps: set[str],
) -> int:
@ -145,9 +158,9 @@ class CmdBuild(Cmd): # export
all_deps.add(cur)
for t in dep_flavours:
log(DEBUG, f'Checking deps of type "{t}"')
deps.update(read_deps(cur, t))
deps.update(read_deps(cur, t, relations))
for d in deps:
add_dep_tree(d, dep_flavours, tree, all_deps)
add_dep_tree(d, dep_flavours, relations, tree, all_deps)
tree[cur] = deps
return len(deps)
@ -158,9 +171,10 @@ class CmdBuild(Cmd): # export
) -> int:
all_deps: set[str] = set()
dep_tree: DepNode = {}
relations = tuple(re.split(r'[,\s]+', args.pkg_relations))
for m in modules:
log(DEBUG, f'--- Adding dependency tree of module "{m}"')
add_dep_tree(m, dep_flavours, dep_tree, all_deps)
add_dep_tree(m, dep_flavours, relations, dep_tree, all_deps)
while len(all_deps):
# Find any leaf, deterministically: sorted, so that the
# order is reproducible across runs