From 3956d1473c66083485487201a71ed4f811c8dbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20G=C3=B6zen?= Date: Mon, 7 Sep 2026 21:51:57 +0300 Subject: [PATCH] lib: filter overridden repository reverse dependencies xbps-query -RX concatenates reverse dependencies from all repositories, including packages overridden by an earlier repository. This can report multiple versions or dependencies removed by a local package override. Look up each reverse dependency by name in the repository pool and retain it only if its selected repository matches the current repository. Keep collecting unrelated reverse dependencies from later repositories. Add tests for cross-repository results, version and same-version overrides, virtual dependencies, and overrides in repositories without the target. Fixes #696. --- lib/rpool.c | 13 +++++ tests/xbps/xbps-query/query_test.sh | 86 +++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/lib/rpool.c b/lib/rpool.c index aa58849de..f6c1a789e 100644 --- a/lib/rpool.c +++ b/lib/rpool.c @@ -215,7 +215,20 @@ find_pkg_revdeps_cb(struct xbps_repo *repo, void *arg, bool *done UNUSED) if (rpf->revdeps == NULL) rpf->revdeps = xbps_array_create(); for (unsigned int i = 0; i < xbps_array_count(revdeps); i++) { + xbps_dictionary_t pkgd; + const char *repouri; + char pkgname[XBPS_NAME_SIZE]; + xbps_array_get_cstring_nocopy(revdeps, i, &pkgver); + if (!xbps_pkg_name(pkgname, sizeof(pkgname), pkgver)) + abort(); + /* Ignore reverse dependencies overridden by another repository. */ + pkgd = xbps_rpool_get_pkg(repo->xhp, pkgname); + if (pkgd == NULL || + !xbps_dictionary_get_cstring_nocopy(pkgd, "repository", &repouri) || + strcmp(repouri, repo->uri) != 0) + continue; + xbps_array_add_cstring_nocopy(rpf->revdeps, pkgver); } xbps_object_release(revdeps); diff --git a/tests/xbps/xbps-query/query_test.sh b/tests/xbps/xbps-query/query_test.sh index 6bfaf9743..982fb2a7a 100644 --- a/tests/xbps/xbps-query/query_test.sh +++ b/tests/xbps/xbps-query/query_test.sh @@ -175,10 +175,96 @@ show_prop_body() { xbps-query -r root --property pkgver bar-1.0_1 } +atf_test_case repo_revdeps + +repo_revdeps_head() { + atf_set "descr" "xbps-query(1) -RX includes reverse dependencies from multiple repositories" +} + +repo_revdeps_body() { + mkdir -p root repo1 repo2 pkg_foo1 pkg_foo2 pkg_consumer1 pkg_consumer2 + + cd repo1 + atf_check -o ignore -- xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" ../pkg_foo1 + atf_check -o ignore -- xbps-create -A noarch -n consumer-first-1.0_1 -s "consumer first" -D "foo>=0" ../pkg_consumer1 + atf_check -o ignore -- xbps-rindex -a $PWD/*.xbps + cd .. + + cd repo2 + atf_check -o ignore -- xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" ../pkg_foo2 + atf_check -o ignore -- xbps-create -A noarch -n consumer-second-1.0_1 -s "consumer second" -D "foo>=0" ../pkg_consumer2 + atf_check -o ignore -- xbps-rindex -a $PWD/*.xbps + cd .. + + atf_check -o inline:"consumer-first-1.0_1\nconsumer-second-1.0_1\n" -- \ + xbps-query -r root -C empty.conf --repository=repo1 --repository=repo2 -RX foo +} + +atf_test_case repo_revdeps_override + +repo_revdeps_override_head() { + atf_set "descr" "xbps-query(1) -RX ignores overridden reverse dependencies" +} + +repo_revdeps_override_body() { + mkdir -p root repo1 repo2 pkg + + cd repo1 + atf_check -o ignore -- xbps-create -A noarch -n foo-1.0_1 \ + -s "foo pkg" -P "virtual-1.0_1" ../pkg + atf_check -o ignore -- xbps-create -A noarch -n bar-1.0_1 \ + -s "bar pkg" -D "foo>=0" ../pkg + atf_check -o ignore -- xbps-create -A noarch -n baz-1.0_1 -s "baz pkg" ../pkg + atf_check -o ignore -- xbps-rindex -a $PWD/*.xbps + cd ../repo2 + atf_check -o ignore -- xbps-create -A noarch -n foo-1.0_1 \ + -s "foo pkg" -P "virtual-1.0_1" ../pkg + atf_check -o ignore -- xbps-create -A noarch -n bar-2.0_1 \ + -s "bar pkg" -D "foo>=0" ../pkg + atf_check -o ignore -- xbps-create -A noarch -n baz-1.0_1 \ + -s "baz pkg" -D "virtual>=0" ../pkg + atf_check -o ignore -- xbps-create -A noarch -n other-1.0_1 \ + -s "other pkg" -D "virtual>=0" ../pkg + atf_check -o ignore -- xbps-rindex -a $PWD/*.xbps + cd .. + + # The older bar takes precedence; baz has the same version but no dependency. + atf_check -o inline:"bar-1.0_1\nother-1.0_1\n" -- \ + xbps-query -r root -C empty.conf --repository=repo1 --repository=repo2 -RX foo + atf_check -o inline:"other-1.0_1\n" -- \ + xbps-query -r root -C empty.conf --repository=repo1 --repository=repo2 -RX virtual +} + +atf_test_case repo_revdeps_override_no_target + +repo_revdeps_override_no_target_head() { + atf_set "descr" "xbps-query(1) -RX honors overrides in repositories without the queried package" +} + +repo_revdeps_override_no_target_body() { + mkdir -p root repo1 repo2 pkg + + cd repo1 + atf_check -o ignore -- xbps-create -A noarch -n bar-1.0_1 -s "bar pkg" ../pkg + atf_check -o ignore -- xbps-rindex -a $PWD/*.xbps + cd ../repo2 + atf_check -o ignore -- xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" ../pkg + atf_check -o ignore -- xbps-create -A noarch -n bar-1.0_1 \ + -s "bar pkg" -D "foo>=0" ../pkg + atf_check -o ignore -- xbps-rindex -a $PWD/*.xbps + cd .. + + atf_check -o empty -- \ + xbps-query -r root -C empty.conf --repository=repo1 --repository=repo2 -RX foo +} + atf_init_test_cases() { atf_add_test_case cat_file atf_add_test_case repo_cat_file atf_add_test_case search atf_add_test_case search_prop atf_add_test_case show_prop + atf_add_test_case repo_revdeps + atf_add_test_case repo_revdeps_override + atf_add_test_case repo_revdeps_override_no_target }