pkg_relations(): Fix --skip-excluded, add integration test #125

Merged
Jan Lindemann merged 2 commits from jan/fix/20260923-fix-skip-excluded into master 2026-09-23 17:50:01 +02:00 AGit
10 changed files with 145 additions and 10 deletions

View file

@ -30,16 +30,11 @@ def pkg_relations(
if syntax == Syntax.DEBIAN:
expand_semver_revision_range = True
if skip_excluded:
excluded = app.get_project_refs(
seed_pkgs,
['build'],
'exclude',
scope = Scope.One,
add_self = False,
names_only = True,
)
ignore |= set(excluded)
def __is_excluded(module: str) -> bool:
# True if the module is excluded from the build on the current
# distro, i.e. if its [build] exclude list matches the distro's
# os cascade
return app.is_excluded_from_build(module) is not None
log(
DEBUG,
@ -55,6 +50,9 @@ def pkg_relations(
closure: list[str] = []
visited: set[str] = set()
for seed in seed_pkgs:
if skip_excluded and __is_excluded(seed):
# Excluded seeds are neither considered nor output
continue
app.walk_project_deps(
closure,
visited,
@ -69,6 +67,9 @@ def pkg_relations(
recurse = recursive,
)
for cur_pkg in closure:
if skip_excluded and __is_excluded(cur_pkg):
# Excluded modules contribute no dependencies
continue
for subsec in subsections:
section = 'pkg.' + rel_type + '.' + subsec
for deps_spec in app.read_dep_edges(cur_pkg, [section], flavour):
@ -81,6 +82,8 @@ def pkg_relations(
if dep_name in ignore or dep.full_name in ignore:
continue
if subsec == 'jw':
if skip_excluded and __is_excluded(dep_name):
continue
if hide_jw_pkg and dep_name == 'jw-pkg':
continue
expand_version_macros = subsec == 'jw'

View file

@ -0,0 +1,28 @@
TOPDIR = ../../../../..
OUTPUT = test-out.txt
REFERENCE = test-expected.txt
# Relative topdir keeps the rendered project paths relocatable; dropping the
# log position keeps the error output free of volatile line numbers. The
# fixture tree under ./proj provides the topdir and the projects root; the
# last -t wins over the global one.
TEST_CMD_ARGS = --topdir-format relative --log-flags prio,stderr \
-t ./proj/excl-never -p ./proj
include $(TOPDIR)/make/proj.mk
include $(TOPDIR)/make/test-jw-pkg.mk
all:
$(OUTPUT): Makefile test.sh \
$(wildcard proj/*) $(wildcard proj/*/make/project.conf) \
$(wildcard proj/*/VERSION)
bash ./test.sh $(TEST_CMD_LINE) > $(OUTPUT).tmp 2>&1
diff $(REFERENCE) $(OUTPUT).tmp
mv $(OUTPUT).tmp $(OUTPUT)
test: $(OUTPUT)
clean: test.integration.in-tree.clean
test.integration.in-tree.clean:
rm -f $(OUTPUT) $(OUTPUT).tmp

View file

@ -0,0 +1 @@
1.0.0-1

View file

@ -0,0 +1,10 @@
[summary]
Test fixture: plain dependency target
[description]
Fixture for pkg-requires --skip-excluded: a project without [build]
exclude.
[global]
group = "Testing"
subpackages = run

View file

@ -0,0 +1 @@
1.0.0-1

View file

@ -0,0 +1,18 @@
[summary]
Test fixture: excluded from the build on all platforms
[description]
Fixture for pkg-requires --skip-excluded: [build] exclude = all.
[global]
group = "Testing"
subpackages = run
[build]
exclude = all
[pkg.requires.os]
run = bar-foo-qux
[pkg.requires.jw]
run = dep-target-run

View file

@ -0,0 +1 @@
1.0.0-1

View file

@ -0,0 +1,19 @@
[summary]
Test fixture: [build] exclude lists a platform name
[description]
Fixture for pkg-requires --skip-excluded: [build] exclude contains a
platform name (centos), not a project name.
[global]
group = "Testing"
subpackages = run
[build]
exclude = centos
[pkg.requires.os]
run = foo-bar-baz
[pkg.requires.jw]
run = excl-all-run, dep-target-run

View file

@ -0,0 +1,8 @@
============= Running: jw-pkg.py -t ../../../../.. --log-level info --topdir-format relative --log-flags prio,stderr -t ./proj/excl-never -p ./proj projects pkg-requires --quote --skip-excluded --hide-self --syntax names-only --delimiter run excl-never
"foo-bar-baz" "dep-target-run"
============= Running: jw-pkg.py -t ../../../../.. --log-level info --topdir-format relative --log-flags prio,stderr -t ./proj/excl-never -p ./proj projects pkg-requires --quote --hide-self --syntax names-only --delimiter run excl-never
"foo-bar-baz" "excl-all-run" "dep-target-run"
============= Running: jw-pkg.py -t ../../../../.. --log-level info --topdir-format relative --log-flags prio,stderr -t ./proj/excl-never -p ./proj projects pkg-requires --quote --skip-excluded --hide-self --syntax names-only --delimiter run excl-all
============= Running: jw-pkg.py -t ../../../../.. --log-level info --topdir-format relative --log-flags prio,stderr -t ./proj/excl-never -p ./proj projects pkg-requires --quote --hide-self --syntax names-only --delimiter run excl-all
"bar-foo-qux" "dep-target-run"

View file

@ -0,0 +1,46 @@
#!/bin/bash
# shellcheck disable=SC2048,SC2086
# Unquoted $* is intentional — the jw-pkg command line
export LC_ALL="C"
set -euo pipefail
jw_pkg_py="$*"
# Print a header and run a command whose output is part of the expected
# result. Under `set -e` a non-zero exit aborts the test.
run()
{
local log_cmd
# shellcheck disable=SC2001
log_cmd=$(echo "$*" | sed 's|.*python3[0-9.]*\s\+\(\.\.\/\)*scripts/||')
printf '============= Running: %s\n' "$log_cmd"
"$@"
}
# The topdir (-t ./proj/excl-never) and the projects root (-p ./proj) are
# part of the test command line (see the Makefile); the last -t wins over
# the global one. excl-never lists the platform name "centos" in [build]
# exclude and is therefore not excluded from the build here; excl-all is
# excluded on every platform.
# -- the platform name in [build] exclude must not be treated as a project;
# -- the excluded jw dependency is not reported
run $jw_pkg_py projects pkg-requires \
--quote --skip-excluded --hide-self --syntax names-only --delimiter " " \
run excl-never
# -- without --skip-excluded, the excluded jw dependency is reported
run $jw_pkg_py projects pkg-requires \
--quote --hide-self --syntax names-only --delimiter " " \
run excl-never
# -- an excluded seed is neither considered nor output
run $jw_pkg_py projects pkg-requires \
--quote --skip-excluded --hide-self --syntax names-only --delimiter " " \
run excl-all
# -- without --skip-excluded, the excluded seed's dependencies are reported
run $jw_pkg_py projects pkg-requires \
--quote --hide-self --syntax names-only --delimiter " " \
run excl-all