Improved "xbps auto-updating itself" behaviour.
Always check if there's a new xbps package version available while *installing* or *updating* in any form. This fixes the following scenario: - xbps-0.53_10 is currently installed - xbps-0.54_1 is available in repo - xbps-install --update netbsd-wtf || xbps-install new-pkg || xbps-install --update As expected any of the following scenarios in last cmd will use *this* transaction to autoupdate xbps and its reverse dependencies. Another transaction will be necessary to install or update the other unrelated packages. Added a new test case to verify this case and improve the other test cases with more extensive checks.
This commit is contained in:
parent
f5f7f6b5a3
commit
b672e1a7f2
@ -224,6 +224,67 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if there's an update, 0 if none or -1 on error.
|
||||
*/
|
||||
static int
|
||||
xbps_autoupdate(struct xbps_handle *xhp)
|
||||
{
|
||||
xbps_array_t rdeps;
|
||||
xbps_dictionary_t pkgd;
|
||||
const char *pkgver;
|
||||
char *pkgname;
|
||||
int rv;
|
||||
|
||||
/*
|
||||
* Check if there's a new update for XBPS before starting
|
||||
* another transaction.
|
||||
*/
|
||||
if (((pkgd = xbps_pkgdb_get_pkg(xhp, "xbps")) == NULL) &&
|
||||
((pkgd = xbps_pkgdb_get_virtualpkg(xhp, "xbps")) == NULL))
|
||||
return 0;
|
||||
|
||||
xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
|
||||
pkgname = xbps_pkg_name(pkgver);
|
||||
assert(pkgname);
|
||||
|
||||
rv = trans_find_pkg(xhp, pkgname, false, false);
|
||||
free(pkgname);
|
||||
|
||||
xbps_dbg_printf(xhp, "%s: trans_find_pkg xbps: %d\n", __func__, rv);
|
||||
|
||||
if (rv == 0) {
|
||||
/* a new xbps version is available, check its revdeps */
|
||||
rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, "xbps");
|
||||
for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) {
|
||||
const char *curpkgver;
|
||||
char *curpkgn;
|
||||
|
||||
xbps_array_get_cstring_nocopy(rdeps, i, &curpkgver);
|
||||
xbps_dbg_printf(xhp, "%s: processing revdep %s\n", __func__, curpkgver);
|
||||
|
||||
curpkgn = xbps_pkg_name(curpkgver);
|
||||
assert(curpkgn);
|
||||
rv = trans_find_pkg(xhp, curpkgn, false, false);
|
||||
free(curpkgn);
|
||||
xbps_dbg_printf(xhp, "%s: trans_find_pkg revdep %s: %d\n", __func__, curpkgver, rv);
|
||||
if (rv && rv != ENOENT && rv != EEXIST && rv != ENODEV)
|
||||
return -1;
|
||||
|
||||
rv = 0;
|
||||
}
|
||||
return 1;
|
||||
} else if (rv == ENOENT || rv == EEXIST || rv == ENODEV) {
|
||||
/* no update */
|
||||
return 0;
|
||||
} else {
|
||||
/* error */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xbps_transaction_update_packages(struct xbps_handle *xhp)
|
||||
{
|
||||
@ -235,52 +296,16 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
|
||||
bool hold, newpkg_found = false;
|
||||
int rv = 0;
|
||||
|
||||
if ((rv = xbps_pkgdb_init(xhp)) != 0)
|
||||
return rv;
|
||||
|
||||
/*
|
||||
* Check if there's a new update for XBPS before starting
|
||||
* a full system upgrade.
|
||||
*/
|
||||
if ((pkgd = xbps_pkgdb_get_pkg(xhp, "xbps")) ||
|
||||
(pkgd = xbps_pkgdb_get_virtualpkg(xhp, "xbps"))) {
|
||||
xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
|
||||
pkgname = xbps_pkg_name(pkgver);
|
||||
assert(pkgname);
|
||||
|
||||
rv = trans_find_pkg(xhp, pkgname, false, false);
|
||||
free(pkgname);
|
||||
|
||||
xbps_dbg_printf(xhp, "%s: trans_find_pkg xbps: %d\n", __func__, rv);
|
||||
|
||||
if (rv == 0) {
|
||||
/* new version found, take into account its revdeps */
|
||||
xbps_array_t rdeps;
|
||||
|
||||
rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, "xbps");
|
||||
for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) {
|
||||
const char *curpkgver;
|
||||
char *curpkgn;
|
||||
|
||||
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 && rv != ENOENT && rv != EEXIST && rv != ENODEV)
|
||||
return rv;
|
||||
|
||||
rv = 0;
|
||||
}
|
||||
|
||||
return rv;
|
||||
} else if (rv == ENOENT || rv == EEXIST || rv == ENODEV) {
|
||||
/* no update */
|
||||
;
|
||||
} else {
|
||||
rv = xbps_autoupdate(xhp);
|
||||
switch (rv) {
|
||||
case 1:
|
||||
/* xbps needs to be updated, don't add any other package */
|
||||
return 0;
|
||||
case -1:
|
||||
/* error */
|
||||
return rv;
|
||||
}
|
||||
return EINVAL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
iter = xbps_dictionary_iterator(xhp->pkgdb);
|
||||
@ -319,12 +344,26 @@ int
|
||||
xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg)
|
||||
{
|
||||
xbps_array_t rdeps;
|
||||
int rv;
|
||||
|
||||
rv = xbps_autoupdate(xhp);
|
||||
xbps_dbg_printf(xhp, "%s: xbps_autoupdate %d\n", __func__, rv);
|
||||
switch (rv) {
|
||||
case 1:
|
||||
/* xbps needs to be updated, don't add any other package */
|
||||
return 0;
|
||||
case -1:
|
||||
/* error */
|
||||
return EINVAL;
|
||||
default:
|
||||
/* no update */
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
@ -342,12 +381,25 @@ xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg,
|
||||
bool reinstall)
|
||||
{
|
||||
xbps_array_t rdeps;
|
||||
int rv;
|
||||
|
||||
rv = xbps_autoupdate(xhp);
|
||||
switch (rv) {
|
||||
case 1:
|
||||
/* xbps needs to be updated, don't add any other package */
|
||||
return 0;
|
||||
case -1:
|
||||
/* error */
|
||||
return EINVAL;
|
||||
default:
|
||||
/* no update */
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -21,7 +21,7 @@ update_xbps_body() {
|
||||
atf_check_equal $? 0
|
||||
|
||||
out=$(xbps-query -r root -p pkgver xbps)
|
||||
atf_check_equal "$out" "xbps-1.0_1"
|
||||
atf_check_equal $out xbps-1.0_1
|
||||
|
||||
cd repo
|
||||
xbps-create -A noarch -n xbps-1.1_1 -s "xbps pkg" ../xbps
|
||||
@ -34,7 +34,7 @@ update_xbps_body() {
|
||||
atf_check_equal $? 0
|
||||
|
||||
out=$(xbps-query -r root -p pkgver xbps)
|
||||
atf_check_equal "$out" "xbps-1.1_1"
|
||||
atf_check_equal $out xbps-1.1_1
|
||||
}
|
||||
|
||||
atf_test_case update_xbps_with_revdeps
|
||||
@ -44,8 +44,8 @@ update_xbps_with_revdeps_head() {
|
||||
}
|
||||
|
||||
update_xbps_with_revdeps_body() {
|
||||
mkdir -p repo xbps xbps-dbg
|
||||
touch xbps/foo xbps-dbg/foo
|
||||
mkdir -p repo xbps xbps-dbg baz
|
||||
touch xbps/foo xbps-dbg/foo baz/blah
|
||||
|
||||
cd repo
|
||||
xbps-create -A noarch -n xbps-1.0_1 -s "xbps pkg" ../xbps
|
||||
@ -58,35 +58,53 @@ update_xbps_with_revdeps_body() {
|
||||
atf_check_equal $? 0
|
||||
|
||||
cd repo
|
||||
xbps-create -A noarch -n xbps-1.1_1 -s "xbps pkg" ../xbps
|
||||
xbps-create -A noarch -n baz-1.0_1 -s "baz pkg" ../baz
|
||||
atf_check_equal $? 0
|
||||
xbps-rindex -d -a $PWD/*.xbps
|
||||
atf_check_equal $? 0
|
||||
|
||||
xbps-create -A noarch -n xbps-dbg-1.0_1 -s "xbps-dbg pkg" --dependencies "xbps-1.0_1" ../xbps-dbg
|
||||
atf_check_equal $? 0
|
||||
xbps-rindex -d -a $PWD/*.xbps
|
||||
atf_check_equal $? 0
|
||||
cd ..
|
||||
|
||||
xbps-install -r root --repository=$PWD/repo -yd xbps-dbg-1.0_1
|
||||
xbps-install -r root --repository=$PWD/repo -yd xbps-dbg baz
|
||||
atf_check_equal $? 0
|
||||
|
||||
cd repo
|
||||
xbps-create -A noarch -n xbps-1.1_1 -s "xbps pkg" ../xbps
|
||||
atf_check_equal $? 0
|
||||
xbps-create -A noarch -n baz-1.1_1 -s "baz pkg" ../baz
|
||||
atf_check_equal $? 0
|
||||
xbps-create -A noarch -n xbps-dbg-1.1_1 -s "xbps-dbg pkg" --dependencies "xbps-1.1_1" ../xbps-dbg
|
||||
atf_check_equal $? 0
|
||||
xbps-rindex -d -a $PWD/*.xbps
|
||||
atf_check_equal $? 0
|
||||
cd ..
|
||||
|
||||
# first time, xbps autoupdates
|
||||
xbps-install -r root --repository=$PWD/repo -yud
|
||||
atf_check_equal $? 0
|
||||
|
||||
out=$(xbps-query -r root -p pkgver xbps)
|
||||
atf_check_equal $out "xbps-1.1_1"
|
||||
atf_check_equal $out xbps-1.1_1
|
||||
|
||||
out=$(xbps-query -r root -p pkgver xbps-dbg)
|
||||
atf_check_equal $out "xbps-dbg-1.1_1"
|
||||
atf_check_equal $out xbps-dbg-1.1_1
|
||||
|
||||
out=$(xbps-query -r root -p pkgver baz)
|
||||
atf_check_equal $out baz-1.0_1
|
||||
|
||||
# second time, updates everything
|
||||
xbps-install -r root --repository=$PWD/repo -yud
|
||||
atf_check_equal $? 0
|
||||
|
||||
out=$(xbps-query -r root -p pkgver xbps)
|
||||
atf_check_equal $out xbps-1.1_1
|
||||
|
||||
out=$(xbps-query -r root -p pkgver xbps-dbg)
|
||||
atf_check_equal $out xbps-dbg-1.1_1
|
||||
|
||||
out=$(xbps-query -r root -p pkgver baz)
|
||||
atf_check_equal $out baz-1.1_1
|
||||
}
|
||||
|
||||
atf_test_case update_xbps_with_uptodate_revdeps
|
||||
@ -128,14 +146,71 @@ update_xbps_with_uptodate_revdeps_body() {
|
||||
atf_check_equal $? 0
|
||||
|
||||
out=$(xbps-query -r root -p pkgver xbps)
|
||||
atf_check_equal $out "xbps-1.1_1"
|
||||
atf_check_equal $out xbps-1.1_1
|
||||
|
||||
out=$(xbps-query -r root -p pkgver base-system)
|
||||
atf_check_equal $out "base-system-1.0_1"
|
||||
atf_check_equal $out base-system-1.0_1
|
||||
}
|
||||
|
||||
atf_test_case update_xbps_on_any_op
|
||||
|
||||
update_xbps_on_any_op_head() {
|
||||
atf_set "descr" "Tests for pkg updates: xbps autoupdates itself on any operation"
|
||||
}
|
||||
|
||||
update_xbps_on_any_op_body() {
|
||||
mkdir -p repo xbps foo
|
||||
touch xbps/foo foo/blah
|
||||
|
||||
cd repo
|
||||
xbps-create -A noarch -n xbps-1.0_1 -s "xbps pkg" ../xbps
|
||||
atf_check_equal $? 0
|
||||
xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" ../foo
|
||||
atf_check_equal $? 0
|
||||
xbps-rindex -d -a $PWD/*.xbps
|
||||
atf_check_equal $? 0
|
||||
cd ..
|
||||
|
||||
xbps-install -r root --repository=$PWD/repo -yd xbps foo
|
||||
atf_check_equal $? 0
|
||||
|
||||
out=$(xbps-query -r root -p pkgver xbps)
|
||||
atf_check_equal $out xbps-1.0_1
|
||||
|
||||
out=$(xbps-query -r root -p pkgver foo)
|
||||
atf_check_equal $out foo-1.0_1
|
||||
|
||||
cd repo
|
||||
xbps-create -A noarch -n xbps-1.1_1 -s "xbps pkg" ../xbps
|
||||
atf_check_equal $? 0
|
||||
xbps-create -A noarch -n foo-1.1_1 -s "foo pkg" ../foo
|
||||
atf_check_equal $? 0
|
||||
xbps-rindex -d -a $PWD/*.xbps
|
||||
atf_check_equal $? 0
|
||||
cd ..
|
||||
|
||||
xbps-install -r root --repository=$PWD/repo -yud foo
|
||||
atf_check_equal $? 0
|
||||
|
||||
out=$(xbps-query -r root -p pkgver xbps)
|
||||
atf_check_equal $out xbps-1.1_1
|
||||
|
||||
out=$(xbps-query -r root -p pkgver foo)
|
||||
atf_check_equal $out foo-1.0_1
|
||||
|
||||
xbps-install -r root --repository=$PWD/repo -yud
|
||||
atf_check_equal $? 0
|
||||
|
||||
out=$(xbps-query -r root -p pkgver xbps)
|
||||
atf_check_equal $out xbps-1.1_1
|
||||
|
||||
out=$(xbps-query -r root -p pkgver foo)
|
||||
atf_check_equal $out foo-1.1_1
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case update_xbps
|
||||
atf_add_test_case update_xbps_with_revdeps
|
||||
atf_add_test_case update_xbps_with_uptodate_revdeps
|
||||
atf_add_test_case update_xbps_on_any_op
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user