lib/package_alternatives.c: prune obsolete alternatives groups

In the edge case when an updated package has different (or no)
alternatives groups, make sure to prune those that are in pkgdb
but not in the newly installed package.

A potentially common case of this is when a package that formerly
had alternatives gets removed and a transitional metapackage
takes its place (which has no alternatives).

When the new package has no dependencies, oldest next possible
alternatives group will be used. This is because that indicates
a removed package. When there are dependencies, the newest one
will be used; as this indicates a transitional package.
This commit is contained in:
q66
2019-11-14 17:40:54 +01:00
committed by Juan RP
parent 5c9be1eefd
commit 85b8b3bbb7
2 changed files with 218 additions and 30 deletions

View File

@@ -674,6 +674,98 @@ respect_current_provider_body() {
atf_check_equal $rv 0
}
atf_test_case prune_leftover_groups
prune_leftover_groups_head() {
atf_set "descr" "xbps-alternatives: prune leftover groups on upgrades"
}
prune_leftover_groups_body() {
mkdir -p repo pkg_A/usr/bin pkg_B/usr/bin
touch pkg_A/usr/bin/fileA pkg_B/usr/bin/fileB
cd repo
xbps-create -A noarch -n A-1.1_1 -s "A pkg" --alternatives "file:/usr/bin/file:/usr/bin/fileA" ../pkg_A
atf_check_equal $? 0
xbps-create -A noarch -n B-1.1_1 -s "B pkg" --alternatives "file:/usr/bin/file:/usr/bin/fileB" ../pkg_B
atf_check_equal $? 0
xbps-rindex -d -a $PWD/*.xbps
atf_check_equal $? 0
cd ..
# A is the current provider now
xbps-install -r root --repository=repo -ydv A
atf_check_equal $? 0
out=$(xbps-query -r root -p pkgver A)
atf_check_equal $out A-1.1_1
# C will replace it via a transitional package
mkdir -p pkg_C/usr/bin
touch pkg_C/usr/bin/fileC
rm pkg_A/usr/bin/fileA
cd repo
xbps-create -A noarch -n C-1.2_1 -s "C pkg" --alternatives "file:/usr/bin/file:/usr/bin/fileC" ../pkg_C
atf_check_equal $? 0
xbps-create -A noarch -n A-1.2_1 -s "A pkg" --dependencies "C>=1.2_1" ../pkg_A
atf_check_equal $? 0
xbps-rindex -d -a $PWD/*.xbps
atf_check_equal $? 0
cd ..
# C is now the current provider, via upgraded A
# also install B, to make sure it doesn't get that first
xbps-install -r root --repository=repo -ydv B A
out=$(xbps-query -r root -p pkgver A)
atf_check_equal $out A-1.2_1
out=$(xbps-query -r root -p pkgver B)
atf_check_equal $out B-1.1_1
out=$(xbps-query -r root -p pkgver C)
atf_check_equal $out C-1.2_1
lnk=$(readlink -f root/usr/bin/file)
rv=1
if [ "$lnk" = "$PWD/root/usr/bin/fileC" ]; then
rv=0
fi
echo "lnk: $lnk"
atf_check_equal $rv 0
# Create a new provider, D; then make C a removed package
mkdir -p pkg_D/usr/bin
touch pkg_D/usr/bin/fileD
rm pkg_C/usr/bin/fileC
cd repo
xbps-create -A noarch -n D-1.4_1 -s "D pkg" --alternatives "file:/usr/bin/file:/usr/bin/fileD" ../pkg_D
atf_check_equal $? 0
xbps-create -A noarch -n C-1.3_1 -s "C pkg" ../pkg_C
atf_check_equal $? 0
xbps-rindex -d -a $PWD/*.xbps
atf_check_equal $? 0
cd ..
# B is now the current provider, as it's the first group available after
# pruning C; the system special cases packages without dependencies as
# removed packages, so it will not assume a renamed replacement
xbps-install -r root --repository=repo -ydv C D
out=$(xbps-query -r root -p pkgver A)
atf_check_equal $out A-1.2_1
out=$(xbps-query -r root -p pkgver B)
atf_check_equal $out B-1.1_1
out=$(xbps-query -r root -p pkgver C)
atf_check_equal $out C-1.3_1
out=$(xbps-query -r root -p pkgver D)
atf_check_equal $out D-1.4_1
lnk=$(readlink -f root/usr/bin/file)
rv=1
if [ "$lnk" = "$PWD/root/usr/bin/fileB" ]; then
rv=0
fi
echo "lnk: $lnk"
atf_check_equal $rv 0
}
atf_init_test_cases() {
atf_add_test_case register_one
atf_add_test_case register_one_dangling
@@ -692,4 +784,5 @@ atf_init_test_cases() {
atf_add_test_case useless_switch
atf_add_test_case remove_current_provider
atf_add_test_case respect_current_provider
atf_add_test_case prune_leftover_groups
}