diff --git a/lib/package_alternatives.c b/lib/package_alternatives.c index 61f19f26..12e69566 100644 --- a/lib/package_alternatives.c +++ b/lib/package_alternatives.c @@ -345,8 +345,9 @@ xbps_alternatives_unregister(struct xbps_handle *xhp, xbps_dictionary_t pkgd) continue; xbps_array_get_cstring_nocopy(array, 0, &first); - if ((current = (strcmp(pkgname, first) == 0))) { + if (strcmp(pkgname, first) == 0) { /* this pkg is the current alternative for this group */ + current = true; rv = remove_symlinks(xhp, xbps_dictionary_get(pkg_alternatives, keyname), keyname); @@ -354,9 +355,9 @@ xbps_alternatives_unregister(struct xbps_handle *xhp, xbps_dictionary_t pkgd) break; } - xbps_set_cb_state(xhp, XBPS_STATE_ALTGROUP_REMOVED, 0, NULL, - "%s: unregistered '%s' alternatives group", pkgver, keyname); if (!update) { + xbps_set_cb_state(xhp, XBPS_STATE_ALTGROUP_REMOVED, 0, NULL, + "%s: unregistered '%s' alternatives group", pkgver, keyname); xbps_remove_string_from_array(array, pkgname); xbps_array_get_cstring_nocopy(array, 0, &first); } @@ -366,24 +367,20 @@ xbps_alternatives_unregister(struct xbps_handle *xhp, xbps_dictionary_t pkgd) continue; } - if (!update && !current) + if (update || !current) continue; - if (current) { - /* get the new alternative group package */ - curpkgd = xbps_pkgdb_get_pkg(xhp, first); - assert(curpkgd); - } - + /* get the new alternative group package */ + curpkgd = xbps_pkgdb_get_pkg(xhp, first); + assert(curpkgd); xbps_set_cb_state(xhp, XBPS_STATE_ALTGROUP_SWITCHED, 0, NULL, - "Switched '%s' alternatives group to '%s'", keyname, first); + "Switched '%s' alternatives group to '%s'", keyname, first); pkg_alternatives = xbps_dictionary_get(curpkgd, "alternatives"); rv = create_symlinks(xhp, xbps_dictionary_get(pkg_alternatives, keyname), keyname); if (rv != 0) break; - } xbps_object_release(allkeys); free(pkgname); @@ -462,7 +459,7 @@ xbps_alternatives_register(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod) for (unsigned int i = 0; i < xbps_array_count(allkeys); i++) { xbps_array_t array; xbps_object_t keysym; - const char *keyname; + const char *keyname, *first; keysym = xbps_array_get(allkeys, i); keyname = xbps_dictionary_keysym_cstring_nocopy(keysym); @@ -472,6 +469,11 @@ xbps_alternatives_register(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod) array = xbps_array_create(); } else { if (xbps_match_string_in_array(array, pkgname)) { + xbps_array_get_cstring_nocopy(array, 0, &first); + if (strcmp(pkgname, first)) { + /* current alternative does not match */ + continue; + } /* already registered, update symlinks */ rv = create_symlinks(xhp, xbps_dictionary_get(pkg_alternatives, keyname), diff --git a/tests/xbps/xbps-alternatives/main.sh b/tests/xbps/xbps-alternatives/main.sh index 3c67dab8..fd66bcbf 100644 --- a/tests/xbps/xbps-alternatives/main.sh +++ b/tests/xbps/xbps-alternatives/main.sh @@ -617,6 +617,63 @@ remove_current_provider_body() { atf_check_equal $rv 0 } +atf_test_case respect_current_provider + +respect_current_provider_head() { + atf_set "descr" "xbps-alternatives: respecting current provider" +} +respect_current_provider_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 B + atf_check_equal $? 0 + + out=$(xbps-query -r root -p pkgver B) + atf_check_equal $out B-1.1_1 + + out=$(xbps-query -r root -p pkgver A) + atf_check_equal $out A-1.1_1 + + # B is now the current provider + xbps-alternatives -r root -s B + atf_check_equal $? 0 + + cd repo + xbps-create -A noarch -n A-1.2_1 -s "A pkg" --alternatives "file:/usr/bin/file:/usr/bin/fileA" ../pkg_A + atf_check_equal $? 0 + xbps-rindex -d -a $PWD/*.xbps + atf_check_equal $? 0 + cd .. + + # A is updated and is assigned to be the current provider incorrectly! + xbps-install -r root --repository=repo -yud + atf_check_equal $? 0 + + out=$(xbps-query -r root -p pkgver B) + atf_check_equal $out B-1.1_1 + + out=$(xbps-query -r root -p pkgver A) + atf_check_equal $out A-1.2_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 @@ -634,4 +691,5 @@ atf_init_test_cases() { atf_add_test_case more_entries_update atf_add_test_case useless_switch atf_add_test_case remove_current_provider + atf_add_test_case respect_current_provider }