diff --git a/NEWS b/NEWS index 50b006b2..e1ea7664 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,10 @@ xbps-0.44 (???): + * libxbps: add packages on hold mode to the transaction, but just ignore them. + This way those are shown in the xbps-install(8) output and the user really + knows that there's a pending update that is not being applied. + Idea by @chneukirchen. + * libxbps: make sure to remove the pkg metadata file if a pkg upgrade does not own any file and a dependency replaces it due to moving files between them. Added two new test cases to verify its correctness. diff --git a/lib/transaction_commit.c b/lib/transaction_commit.c index 5a2cf783..da0a9ae5 100644 --- a/lib/transaction_commit.c +++ b/lib/transaction_commit.c @@ -67,6 +67,7 @@ check_binpkgs(struct xbps_handle *xhp, xbps_object_iterator_t iter) while ((obj = xbps_object_iterator_next(iter)) != NULL) { xbps_dictionary_get_cstring_nocopy(obj, "transaction", &trans); if ((strcmp(trans, "remove") == 0) || + (strcmp(trans, "hold") == 0) || (strcmp(trans, "configure") == 0)) continue; @@ -132,6 +133,7 @@ download_binpkgs(struct xbps_handle *xhp, xbps_object_iterator_t iter) while ((obj = xbps_object_iterator_next(iter)) != NULL) { xbps_dictionary_get_cstring_nocopy(obj, "transaction", &trans); if ((strcmp(trans, "remove") == 0) || + (strcmp(trans, "hold") == 0) || (strcmp(trans, "configure") == 0)) continue; @@ -315,6 +317,11 @@ xbps_transaction_commit(struct xbps_handle *xhp) strerror(rv)); goto out; } + } else if (strcmp(tract, "hold") == 0) { + /* + * Package is on hold mode, ignore it. + */ + continue; } else { /* Install a package */ xbps_set_cb_state(xhp, XBPS_STATE_INSTALL, 0, @@ -359,6 +366,7 @@ xbps_transaction_commit(struct xbps_handle *xhp) xbps_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); xbps_dictionary_get_cstring_nocopy(obj, "transaction", &tract); if ((strcmp(tract, "remove") == 0) || + (strcmp(tract, "hold") == 0) || (strcmp(tract, "configure") == 0)) { xbps_dbg_printf(xhp, "%s: skipping configuration for " "%s: %s\n", __func__, pkgver, tract); diff --git a/lib/transaction_dictionary.c b/lib/transaction_dictionary.c index fa05fb86..2be598b2 100644 --- a/lib/transaction_dictionary.c +++ b/lib/transaction_dictionary.c @@ -277,7 +277,7 @@ xbps_transaction_prepare(struct xbps_handle *xhp) pkgd = xbps_array_get(pkgs, i); str = xbps_dictionary_get(pkgd, "pkgver"); xbps_dictionary_get_cstring_nocopy(pkgd, "transaction", &tract); - if (strcmp(tract, "remove") == 0) + if ((strcmp(tract, "remove") == 0) || strcmp(tract, "hold") == 0) continue; assert(xbps_object_type(str) == XBPS_TYPE_STRING); diff --git a/lib/transaction_ops.c b/lib/transaction_ops.c index b1496041..60a802ea 100644 --- a/lib/transaction_ops.c +++ b/lib/transaction_ops.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2014 Juan Romero Pardines. + * Copyright (c) 2009-2015 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -59,7 +59,8 @@ enum { }; static int -trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall) +trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall, + bool hold) { xbps_dictionary_t pkg_pkgdb = NULL, pkg_repod = NULL; xbps_array_t pkgs; @@ -187,10 +188,11 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall) reason = "configure"; else if (state == XBPS_PKG_STATE_NOT_INSTALLED) reason = "install"; + else if ((action == TRANS_UPDATE) && hold) + reason = "hold"; /* - * Set transaction obj in pkg dictionary to "install", "configure" - * or "update". + * Set transaction obj reason. */ if (!xbps_dictionary_set_cstring_nocopy(pkg_repod, "transaction", reason)) { @@ -208,12 +210,9 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall) int xbps_transaction_update_packages(struct xbps_handle *xhp) { - xbps_dictionary_t pkgd; xbps_object_t obj; xbps_object_iterator_t iter; - const char *pkgver; - char *pkgname = NULL; - bool hold, newpkg_found = false; + bool newpkg_found = false; int rv = 0; if ((rv = xbps_pkgdb_init(xhp)) != 0) @@ -223,21 +222,24 @@ xbps_transaction_update_packages(struct xbps_handle *xhp) assert(iter); while ((obj = xbps_object_iterator_next(iter))) { + xbps_dictionary_t pkgd; + const char *pkgver; + char *pkgname; + bool hold = false; + pkgd = xbps_dictionary_get_keysym(xhp->pkgdb, obj); xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver); - hold = false; xbps_dictionary_get_bool(pkgd, "hold", &hold); if (hold) { xbps_dbg_printf(xhp, "[rpool] package `%s' " "on hold, ignoring updates.\n", pkgver); - continue; } pkgname = xbps_pkg_name(pkgver); assert(pkgname); - rv = trans_find_pkg(xhp, pkgname, false); - if (rv == 0) + rv = trans_find_pkg(xhp, pkgname, false, hold); + if (rv == 0) { newpkg_found = true; - else if (rv == ENOENT || rv == EEXIST || rv == ENODEV) { + } else if (rv == ENOENT || rv == EEXIST || rv == ENODEV) { /* * missing pkg or installed version is greater than or * equal than pkg in repositories. @@ -254,14 +256,14 @@ xbps_transaction_update_packages(struct xbps_handle *xhp) int xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg) { - return trans_find_pkg(xhp, pkg, false); + return trans_find_pkg(xhp, pkg, false, false); } int xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall) { - return trans_find_pkg(xhp, pkg, reinstall); + return trans_find_pkg(xhp, pkg, reinstall, false); } int diff --git a/tests/xbps/libxbps/shell/Kyuafile b/tests/xbps/libxbps/shell/Kyuafile index 5bc1f1de..9b48c916 100644 --- a/tests/xbps/libxbps/shell/Kyuafile +++ b/tests/xbps/libxbps/shell/Kyuafile @@ -17,3 +17,4 @@ atf_test_program{name="vpkg_test"} atf_test_program{name="install_test"} atf_test_program{name="preserve_files_test"} atf_test_program{name="update_shlibs"} +atf_test_program{name="update_hold"} diff --git a/tests/xbps/libxbps/shell/Makefile b/tests/xbps/libxbps/shell/Makefile index 060a4502..46586503 100644 --- a/tests/xbps/libxbps/shell/Makefile +++ b/tests/xbps/libxbps/shell/Makefile @@ -6,7 +6,7 @@ TESTSHELL = conf_files_test issue6_test issue18_test issue20_test remove_test TESTSHELL+= replace_test installmode_test obsoletefiles_test TESTSHELL+= issue31_test scripts_test incorrect_deps_test TESTSHELL+= vpkg_test install_test preserve_files_test -TESTSHELL+= update_shlibs +TESTSHELL+= update_shlibs update_hold EXTRA_FILES = Kyuafile include $(TOPDIR)/mk/test.mk diff --git a/tests/xbps/libxbps/shell/update_hold.sh b/tests/xbps/libxbps/shell/update_hold.sh new file mode 100644 index 00000000..8521e144 --- /dev/null +++ b/tests/xbps/libxbps/shell/update_hold.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env atf-sh + +atf_test_case update_hold + +update_hold_head() { + atf_set "descr" "Tests for pkg update: pkg is on hold mode" +} + +update_hold_body() { + mkdir -p repo pkg_A + cd repo + xbps-create -A noarch -n A-1.0_1 -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=$PWD/repo -yd A + atf_check_equal $? 0 + xbps-pkgdb -r root -m hold A + atf_check_equal $? 0 + out=$(xbps-query -r root -H) + atf_check_equal $out A-1.0_1 + cd repo + xbps-create -A noarch -n A-1.1_1 -s "A pkg" ../pkg_A + atf_check_equal $? 0 + xbps-rindex -d -a $PWD/*.xbps + atf_check_equal $? 0 + cd .. + out=$(xbps-install -r root --repository=$PWD/repo -un) + atf_check_equal "$out" "A-1.1_1 hold noarch $PWD/repo" + xbps-install -r root --repository=$PWD/repo -yuvd + atf_check_equal $? 0 + out=$(xbps-query -r root -p pkgver A) + atf_check_equal $out A-1.0_1 + +} + +atf_init_test_cases() { + atf_add_test_case update_hold +}