From 108a165534b64bf0392cc31fe37a2f730cda23b0 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Tue, 14 May 2019 08:54:24 +0200 Subject: [PATCH] libxbps: try to update revdeps when installing or updating pkgs. This fixes the cases where a pkg installation or update could break its revdeps due to not satisfying dependencies. When performing an install or update, xbps now always checks if there are updates for its revdeps and get added to the transaction. See the two new test cases for more information. --- lib/transaction_ops.c | 34 +++++++++- tests/xbps/libxbps/shell/install_test.sh | 79 ++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/lib/transaction_ops.c b/lib/transaction_ops.c index f47b5bea..565c1049 100644 --- a/lib/transaction_ops.c +++ b/lib/transaction_ops.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2015 Juan Romero Pardines. + * Copyright (c) 2009-2019 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -314,6 +314,22 @@ xbps_transaction_update_packages(struct xbps_handle *xhp) int xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg) { + xbps_array_t rdeps; + + rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, pkg); + for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) { + const char *curpkgver; + char *curpkgn; + int rv; + + xbps_array_get_cstring_nocopy(rdeps, i, &curpkgver); + curpkgn = xbps_pkg_name(curpkgver); + assert(curpkgn); + rv = trans_find_pkg(xhp, curpkgn, false, false); + free(curpkgn); + if (rv != 0 && rv != EEXIST) + return rv; + } return trans_find_pkg(xhp, pkg, false, false); } @@ -321,6 +337,22 @@ int xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall) { + xbps_array_t rdeps; + + rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, pkg); + for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) { + const char *curpkgver; + char *curpkgn; + int rv; + + xbps_array_get_cstring_nocopy(rdeps, i, &curpkgver); + curpkgn = xbps_pkg_name(curpkgver); + assert(curpkgn); + rv = trans_find_pkg(xhp, curpkgn, false, false); + free(curpkgn); + if (rv != 0 && rv != EEXIST) + return rv; + } return trans_find_pkg(xhp, pkg, reinstall, false); } diff --git a/tests/xbps/libxbps/shell/install_test.sh b/tests/xbps/libxbps/shell/install_test.sh index a65f3bf5..0d70cce1 100644 --- a/tests/xbps/libxbps/shell/install_test.sh +++ b/tests/xbps/libxbps/shell/install_test.sh @@ -290,6 +290,38 @@ install_bestmatch_disabled_body() { atf_check_equal $out A-1.0_1 } +atf_test_case install_and_update_revdeps + +install_and_update_revdeps_head() { + atf_set "descr" "Tests for pkg install: install pkg and update its revdeps" +} + +install_and_update_revdeps_body() { + mkdir -p repo pkg_A/usr/bin pkg_B/usr/bin + cd repo + xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A + atf_check_equal $? 0 + xbps-create -A noarch -n B-1.0_2 -s "B pkg" --dependencies "A-1.0_2" ../pkg_B + xbps-rindex -d -a $PWD/*.xbps + atf_check_equal $? 0 + + cd .. + xbps-install -r root --repository=repo -yvd A + atf_check_equal $? 0 + atf_check_equal $(xbps-query -r root -p pkgver A) A-1.0_1 + + cd repo + xbps-create -A noarch -n A-1.0_2 -s "A pkg" ../pkg_A + atf_check_equal $? 0 + xbps-rindex -d -a $PWD/*.xbps + atf_check_equal $? 0 + cd .. + xbps-install -r root --repository=repo -yvd B + atf_check_equal $? 0 + atf_check_equal $(xbps-query -r root -p pkgver A) A-1.0_2 + atf_check_equal $(xbps-query -r root -p pkgver B) B-1.0_2 +} + atf_test_case update_file_timestamps update_file_timestamps_head() { @@ -481,6 +513,51 @@ update_xbps_virtual_body() { atf_check_equal "$exp" "xbps-git-1.1_1 update noarch $(readlink -f repo)" } +atf_test_case update_with_revdeps + +update_with_revdeps_head() { + atf_set "descr" "Tests for pkg install: update pkg and its revdeps" +} + +update_with_revdeps_body() { + mkdir -p repo pkg_A/usr/bin pkg_B/usr/bin + cd repo + xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A + atf_check_equal $? 0 + xbps-create -A noarch -n B-1.0_2 -s "B pkg" --dependencies "A-1.0_2" ../pkg_B + xbps-rindex -d -a $PWD/*.xbps + atf_check_equal $? 0 + + cd .. + xbps-install -r root --repository=repo -yvd A + atf_check_equal $? 0 + atf_check_equal $(xbps-query -r root -p pkgver A) A-1.0_1 + + cd repo + xbps-create -A noarch -n A-1.0_2 -s "A pkg" ../pkg_A + atf_check_equal $? 0 + xbps-rindex -d -a $PWD/*.xbps + atf_check_equal $? 0 + cd .. + xbps-install -r root --repository=repo -yvd B + atf_check_equal $? 0 + atf_check_equal $(xbps-query -r root -p pkgver A) A-1.0_2 + atf_check_equal $(xbps-query -r root -p pkgver B) B-1.0_2 + + cd repo + xbps-create -A noarch -n A-1.1_1 -s "A pkg" ../pkg_A + atf_check_equal $? 0 + xbps-create -A noarch -n B-1.1_1 -s "B pkg" --dependencies "A-1.1_1" ../pkg_B + xbps-rindex -d -a $PWD/*.xbps + atf_check_equal $? 0 + + cd .. + xbps-install -r root --repository=repo -yvdu A + atf_check_equal $? 0 + atf_check_equal $(xbps-query -r root -p pkgver A) A-1.1_1 + atf_check_equal $(xbps-query -r root -p pkgver B) B-1.1_1 +} + atf_init_test_cases() { atf_add_test_case install_empty atf_add_test_case install_with_deps @@ -490,6 +567,7 @@ atf_init_test_cases() { atf_add_test_case install_bestmatch atf_add_test_case install_bestmatch_deps atf_add_test_case install_bestmatch_disabled + atf_add_test_case install_and_update_revdeps atf_add_test_case update_if_installed atf_add_test_case update_to_empty_pkg atf_add_test_case update_file_timestamps @@ -497,4 +575,5 @@ atf_init_test_cases() { atf_add_test_case update_move_unmodified_file atf_add_test_case update_xbps atf_add_test_case update_xbps_virtual + atf_add_test_case update_with_revdeps }