Do not silently update xbps on any install/update transaction.

When there's a new xbps update, xbps-install(1) will now return
EBUSY (16) and a message (if dry-run disabled) explaining
how to proceed.

If there's an update and transaction does not contain xbps, it will
error out unless the 'xbps' pkg is the only target pkg, i.e:

	# xbps-install -Su
	# echo $?
	16

To update xbps, the only way to proceed is to explicitly declare
it as an update, i.e:

	# xbps-install -u xbps

The dry-run mode will still show there's an xbps update.

Modified the existing test cases to satisfy the new behaviour.

Closes #166
Closes #142
This commit is contained in:
Juan RP 2019-12-27 14:33:53 +01:00
parent c81a2806ff
commit 166caab986
5 changed files with 90 additions and 118 deletions

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2015 Juan Romero Pardines. * Copyright (c) 2009-2019 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -229,7 +229,8 @@ out:
} }
static bool static bool
all_pkgs_on_hold(struct transaction *trans) { all_pkgs_on_hold(struct transaction *trans)
{
xbps_object_t obj; xbps_object_t obj;
const char *action = NULL; const char *action = NULL;
bool all_on_hold = true; bool all_on_hold = true;
@ -252,21 +253,25 @@ dist_upgrade(struct xbps_handle *xhp, int cols, bool yes, bool drun)
{ {
int rv = 0; int rv = 0;
if ((rv = xbps_transaction_update_packages(xhp)) != 0) { rv = xbps_transaction_update_packages(xhp);
if (rv == ENOENT) { if (rv == ENOENT) {
printf("No packages currently registered.\n"); printf("No packages currently registered.\n");
return 0; return 0;
} else if (rv == EBUSY) {
if (drun) {
rv = 0;
} else {
printf("The 'xbps' package must be updated, please run `xbps-install -u xbps`\n");
return rv;
}
} else if (rv == EEXIST) { } else if (rv == EEXIST) {
return 0; return 0;
} else if (rv == ENOTSUP) { } else if (rv == ENOTSUP) {
fprintf(stderr, "No repositories currently " fprintf(stderr, "No repositories currently registered!\n");
"registered!\n"); return rv;
} else if (rv != 0) {
fprintf(stderr, "Unexpected error %s\n", strerror(rv));
return -1; return -1;
} else {
fprintf(stderr, "Unexpected error %s\n",
strerror(rv));
return -1;
}
} }
return exec_transaction(xhp, cols, yes, drun); return exec_transaction(xhp, cols, yes, drun);
@ -277,42 +282,42 @@ install_new_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall)
{ {
int rv; int rv;
if ((rv = xbps_transaction_install_pkg(xhp, pkg, reinstall)) != 0) { rv = xbps_transaction_install_pkg(xhp, pkg, reinstall);
if (rv == EEXIST) { if (rv == EEXIST)
printf("Package `%s' already installed.\n", pkg); printf("Package `%s' already installed.\n", pkg);
} else if (rv == ENOENT) { else if (rv == ENOENT)
fprintf(stderr, "Unable to locate '%s' in " fprintf(stderr, "Package '%s' not found in repository pool.\n", pkg);
"repository pool.\n", pkg); else if (rv == ENOTSUP)
} else if (rv == ENOTSUP) { fprintf(stderr, "No repositories currently registered!\n");
fprintf(stderr, "No repositories " else if (rv == ENXIO)
"currently registered!\n");
} else if (rv == ENXIO) {
fprintf(stderr, "Package `%s' contains invalid dependencies, exiting.\n", pkg); fprintf(stderr, "Package `%s' contains invalid dependencies, exiting.\n", pkg);
} else { else if (rv == EBUSY)
fprintf(stderr, "Unexpected error: %s\n", fprintf(stderr, "The 'xbps' package must be updated, please run `xbps-install -u xbps`\n");
strerror(rv)); else if (rv != 0) {
fprintf(stderr, "Unexpected error: %s\n", strerror(rv));
rv = -1; rv = -1;
} }
}
return rv; return rv;
} }
int int
update_pkg(struct xbps_handle *xhp, const char *pkgname) update_pkg(struct xbps_handle *xhp, const char *pkg)
{ {
int rv; int rv;
rv = xbps_transaction_update_pkg(xhp, pkgname); rv = xbps_transaction_update_pkg(xhp, pkg);
if (rv == EEXIST) { if (rv == EEXIST)
printf("Package '%s' is up to date.\n", pkgname); printf("Package '%s' is up to date.\n", pkg);
return EEXIST; else if (rv == ENOENT)
} else if (rv == ENOENT) fprintf(stderr, "Package '%s' not found in repository pool.\n", pkg);
fprintf(stderr, "Package '%s' not found in "
"repository pool.\n", pkgname);
else if (rv == ENODEV) else if (rv == ENODEV)
printf("Package '%s' not installed.\n", pkgname); fprintf(stderr, "Package '%s' not installed.\n", pkg);
else if (rv == ENOTSUP) else if (rv == ENOTSUP)
fprintf(stderr, "No repositories currently registered!\n"); fprintf(stderr, "No repositories currently registered!\n");
else if (rv == ENXIO)
fprintf(stderr, "Package `%s' contains invalid dependencies, exiting.\n", pkg);
else if (rv == EBUSY)
fprintf(stderr, "The 'xbps' package must be updated, please run `xbps-install -u xbps`\n");
else if (rv != 0) { else if (rv != 0) {
fprintf(stderr, "Unexpected error: %s\n", strerror(rv)); fprintf(stderr, "Unexpected error: %s\n", strerror(rv));
return -1; return -1;

View File

@ -50,7 +50,7 @@
* *
* This header documents the full API for the XBPS Library. * This header documents the full API for the XBPS Library.
*/ */
#define XBPS_API_VERSION "20190707" #define XBPS_API_VERSION "20191227"
#ifndef XBPS_VERSION #ifndef XBPS_VERSION
#define XBPS_VERSION "UNSET" #define XBPS_VERSION "UNSET"

View File

@ -297,8 +297,8 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
rv = xbps_autoupdate(xhp); rv = xbps_autoupdate(xhp);
switch (rv) { switch (rv) {
case 1: case 1:
/* xbps needs to be updated, don't add any other package */ /* xbps needs to be updated, don't allow any other update */
return 0; return EBUSY;
case -1: case -1:
/* error */ /* error */
return EINVAL; return EINVAL;
@ -349,7 +349,9 @@ xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg)
xbps_dbg_printf(xhp, "%s: xbps_autoupdate %d\n", __func__, rv); xbps_dbg_printf(xhp, "%s: xbps_autoupdate %d\n", __func__, rv);
switch (rv) { switch (rv) {
case 1: case 1:
/* xbps needs to be updated, don't add any other package */ /* xbps needs to be updated, only allow xbps to be updated */
if (strcmp(pkg, "xbps"))
return EBUSY;
return 0; return 0;
case -1: case -1:
/* error */ /* error */
@ -388,7 +390,9 @@ xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg,
rv = xbps_autoupdate(xhp); rv = xbps_autoupdate(xhp);
switch (rv) { switch (rv) {
case 1: case 1:
/* xbps needs to be updated, don't add any other package */ /* xbps needs to be updated, only allow xbps to be updated */
if (strcmp(pkg, "xbps"))
return EBUSY;
return 0; return 0;
case -1: case -1:
/* error */ /* error */

View File

@ -488,6 +488,20 @@ update_xbps_body() {
set -- $out set -- $out
exp="$1 $2 $3 $4" exp="$1 $2 $3 $4"
atf_check_equal "$exp" "xbps-1.1_1 update noarch $(readlink -f repo)" atf_check_equal "$exp" "xbps-1.1_1 update noarch $(readlink -f repo)"
xbps-install -r root --repository=repo -yu xbps
atf_check_equal $? 0
out=$(xbps-query -r root -p pkgver xbps)
atf_check_equal "$out" "xbps-1.1_1"
xbps-install -r root --repository=repo -yu
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 C)
atf_check_equal "$out" "C-1.1_1"
} }
atf_test_case update_xbps_virtual atf_test_case update_xbps_virtual
@ -527,6 +541,12 @@ update_xbps_virtual_body() {
set -- $out set -- $out
exp="$1 $2 $3 $4" exp="$1 $2 $3 $4"
atf_check_equal "$exp" "xbps-git-1.1_1 update noarch $(readlink -f repo)" atf_check_equal "$exp" "xbps-git-1.1_1 update noarch $(readlink -f repo)"
xbps-install -r root --repository=repo -yu xbps
atf_check_equal $? 0
out=$(xbps-query -r root -p pkgver xbps-git)
atf_check_equal "$out" "xbps-git-1.1_1"
} }
atf_test_case update_with_revdeps atf_test_case update_with_revdeps

View File

@ -30,7 +30,14 @@ update_xbps_body() {
atf_check_equal $? 0 atf_check_equal $? 0
cd .. cd ..
# EBUSY
xbps-install -r root --repository=$PWD/repo -yud xbps-install -r root --repository=$PWD/repo -yud
atf_check_equal $? 16
out=$(xbps-query -r root -p pkgver xbps)
atf_check_equal $out xbps-1.0_1
xbps-install -r root --repository=$PWD/repo -yu xbps
atf_check_equal $? 0 atf_check_equal $? 0
out=$(xbps-query -r root -p pkgver xbps) out=$(xbps-query -r root -p pkgver xbps)
@ -40,7 +47,7 @@ update_xbps_body() {
atf_test_case update_xbps_with_revdeps atf_test_case update_xbps_with_revdeps
update_xbps_with_revdeps_head() { update_xbps_with_revdeps_head() {
atf_set "descr" "Tests for pkg updates: xbps autoupdates itself with revdeps" atf_set "descr" "Tests for pkg updates: xbps updates itself with revdeps"
} }
update_xbps_with_revdeps_body() { update_xbps_with_revdeps_body() {
@ -80,8 +87,11 @@ update_xbps_with_revdeps_body() {
atf_check_equal $? 0 atf_check_equal $? 0
cd .. cd ..
# first time, xbps autoupdates # first time, xbps must be updated (returns EBUSY)
xbps-install -r root --repository=$PWD/repo -yud xbps-install -r root --repository=$PWD/repo -yud
atf_check_equal $? 16
xbps-install -r root --repository=$PWD/repo -yu xbps
atf_check_equal $? 0 atf_check_equal $? 0
out=$(xbps-query -r root -p pkgver xbps) out=$(xbps-query -r root -p pkgver xbps)
@ -110,7 +120,7 @@ update_xbps_with_revdeps_body() {
atf_test_case update_xbps_with_uptodate_revdeps atf_test_case update_xbps_with_uptodate_revdeps
update_xbps_with_uptodate_revdeps_head() { update_xbps_with_uptodate_revdeps_head() {
atf_set "descr" "Tests for pkg updates: xbps autoupdates itself with already up-to-date revdeps" atf_set "descr" "Tests for pkg updates: xbps updates itself with already up-to-date revdeps"
} }
update_xbps_with_uptodate_revdeps_body() { update_xbps_with_uptodate_revdeps_body() {
@ -143,6 +153,9 @@ update_xbps_with_uptodate_revdeps_body() {
cd .. cd ..
xbps-install -r root --repository=$PWD/repo -yud xbps-install -r root --repository=$PWD/repo -yud
atf_check_equal $? 16
xbps-install -r root --repository=$PWD/repo -yu xbps
atf_check_equal $? 0 atf_check_equal $? 0
out=$(xbps-query -r root -p pkgver xbps) out=$(xbps-query -r root -p pkgver xbps)
@ -154,78 +167,8 @@ update_xbps_with_uptodate_revdeps_body() {
atf_test_case update_xbps_on_any_op 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 bar
touch xbps/foo foo/blah bar/baz
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-create -A noarch -n bar-1.0_1 -s "bar pkg" ../bar
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 ..
# install an unrelated pkg, xbps autoupdates
xbps-install -r root --repository=$PWD/repo -yd bar
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
# ENOENT
xbps-query -r root -p pkgver bar
atf_check_equal $? 2
# xbps has been updated, 2nd time
xbps-install -r root --repository=$PWD/repo -yd bar
atf_check_equal $? 0
out=$(xbps-query -r root -p pkgver bar)
atf_check_equal $out bar-1.0_1
# perform a globl update
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_init_test_cases() {
atf_add_test_case update_xbps atf_add_test_case update_xbps
atf_add_test_case update_xbps_with_revdeps atf_add_test_case update_xbps_with_revdeps
atf_add_test_case update_xbps_with_uptodate_revdeps atf_add_test_case update_xbps_with_uptodate_revdeps
atf_add_test_case update_xbps_on_any_op
} }