xbps-install(8): implemented single pkg updates without -u, --update.

The -u, --update is now only necessary to perform full system updates.

Close #35 (https://github.com/voidlinux/xbps/issues/35)
This commit is contained in:
Juan RP 2014-05-27 11:33:45 +02:00
parent e1e5310428
commit 61a1d33995
4 changed files with 122 additions and 40 deletions

10
NEWS
View File

@ -1,5 +1,15 @@
xbps-0.37 (???):
* xbps-install(8): it's possible now to update a single package (if it's already
installed) without using the -u, --update option. This implements
GH #35 (https://github.com/voidlinux/xbps/issues/35).
$ xbps-install [-f] -y foo
- if foo is installed, update it.
- if foo not installed, install it.
- if -f is set, reinstall or downgrade it.
* xbps-query(8): new option (-S, --show) which shows info of a package
installed locally or in a repository with -R. This is the default mode
if no other mode is set; to preserve compatibility with previous versions.

View File

@ -1,9 +1,9 @@
.Dd April 21, 2014
.Dd May 27, 2014
.Os Void Linux
.Dt xbps-install 8
.Sh NAME
.Nm xbps-install
.Nd XBPS utility to install and update packages
.Nd XBPS utility to (re)install and update packages
.Sh SYNOPSYS
.Nm xbps-install
.Op OPTIONS
@ -11,12 +11,17 @@
.Sh DESCRIPTION
The
.Nm
utility installs and updates packages in the target root directory.
utility installs, reinstalls, downgrades and updates packages in the target root directory.
The argument
.Ar PKG
is a package expression, which is explained in the
.Em PACKAGE EXPRESSION
section.
section. If package is installed, it will be updated to the version available in repositories
matching the
.Em PACKAGE EXPRESSION .
Otherwise it will be installed, or reinstalled/downgraded if
.Fl f , Fl -force
option is set.
.Sh PACKAGE EXPRESSION
A package expression is a form to match a pattern; currently xbps
supports 3 ways to specify them:
@ -61,8 +66,10 @@ Specifies a full path to the cache directory, where binary packages are stored.
.It Fl d, Fl -debug
Enables extra debugging shown to stderr.
.It Fl f, Fl -force
Forcefully install target package even if another version is already installed,
overwritting regular package files and symlinks (if they have been modified) but
Force downgrade installation (if package version in repos is less than installed version),
or reinstallation (if package version in repos is the same) to the target
.Ar PKG ,
overwriting regular package files and symlinks (if they have been modified) but
.Em preserving configuration files .
If
.Fl f
@ -79,9 +86,8 @@ Specifies a full path for the target root directory.
.It Fl S, Fl -sync
Synchronize remote repository index files.
.It Fl u, Fl -update
Update target package(s) rather than install. If
.Op PKG
not set, all installed packages will be updated.
Performs a full system upgrade: all installed packages will be updated to the greatest
versions that were found in repositories.
.It Fl v, Fl -verbose
Enables verbose messages.
.It Fl y, Fl -yes

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2009-2013 Juan Romero Pardines.
* Copyright (c) 2009-2014 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -54,17 +54,18 @@
*/
enum {
TRANS_INSTALL = 1,
TRANS_UPDATE
TRANS_UPDATE,
TRANS_REINSTALL
};
static int
trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action)
trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall)
{
xbps_dictionary_t pkg_pkgdb = NULL, pkg_repod;
xbps_dictionary_t pkg_pkgdb = NULL, pkg_repod = NULL;
xbps_array_t unsorted;
const char *repoloc, *repopkgver, *instpkgver, *reason;
char *pkgname;
int rv = 0;
int action = 0, rv = 0;
pkg_state_t state = 0;
bool autoinst = false;
@ -77,7 +78,9 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action)
/*
* Find out if the pkg has been found in repository pool.
*/
if (action == TRANS_INSTALL) {
if (pkg_pkgdb == NULL) {
/* pkg not installed, perform installation */
action = TRANS_INSTALL;
reason = "install";
if (((pkg_repod = xbps_rpool_get_pkg(xhp, pkg)) == NULL) &&
((pkg_repod = xbps_rpool_get_virtualpkg(xhp, pkg)) == NULL)) {
@ -85,21 +88,27 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action)
return ENOENT;
}
} else {
if (pkg_pkgdb == NULL)
return ENODEV;
/* pkg installed, update or reinstall */
if (!reinstall) {
action = TRANS_UPDATE;
reason = "update";
} else {
action = TRANS_REINSTALL;
reason = "install";
}
if ((pkg_repod = xbps_rpool_get_pkg(xhp, pkg)) == NULL) {
/* not found */
return ENOENT;
}
}
xbps_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &repopkgver);
xbps_dictionary_get_cstring_nocopy(pkg_repod, "repository", &repoloc);
if (action == TRANS_UPDATE) {
/*
* Compare installed version vs best pkg available in repos.
* Compare installed version vs best pkg available in repos
* for pkg updates.
*/
xbps_dictionary_get_cstring_nocopy(pkg_pkgdb,
"pkgver", &instpkgver);
@ -109,16 +118,26 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action)
repopkgver, instpkgver, repoloc);
return EEXIST;
}
} else if (action == TRANS_REINSTALL) {
/*
* For reinstallation check if installed version is less than
* or equal to the pkg in repos, if true, continue with reinstallation;
* otherwise perform an update.
*/
xbps_dictionary_get_cstring_nocopy(pkg_pkgdb, "pkgver", &instpkgver);
if (xbps_cmpver(repopkgver, instpkgver) == 1) {
action = TRANS_UPDATE;
reason = "update";
}
}
if (pkg_pkgdb) {
/*
* If pkg is already installed, respect its automatic-install
* property.
*/
xbps_dictionary_get_bool(pkg_pkgdb, "automatic-install",
&autoinst);
xbps_dictionary_set_bool(pkg_repod, "automatic-install",
autoinst);
xbps_dictionary_get_bool(pkg_pkgdb, "automatic-install", &autoinst);
xbps_dictionary_set_bool(pkg_repod, "automatic-install", autoinst);
}
/*
* Prepare transaction dictionary.
@ -216,7 +235,7 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
}
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
rv = trans_find_pkg(xhp, pkgname, TRANS_UPDATE);
rv = trans_find_pkg(xhp, pkgname, false);
if (rv == 0)
newpkg_found = true;
else if (rv == ENOENT || rv == EEXIST || rv == ENODEV) {
@ -236,27 +255,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, TRANS_UPDATE);
return trans_find_pkg(xhp, pkg, false);
}
int
xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg,
bool reinstall)
{
xbps_dictionary_t pkgd = NULL;
pkg_state_t state;
if ((pkgd = xbps_pkgdb_get_pkg(xhp, pkg)) ||
(pkgd = xbps_pkgdb_get_virtualpkg(xhp, pkg))) {
if (xbps_pkg_state_dictionary(pkgd, &state) != 0)
return EINVAL;
if ((state == XBPS_PKG_STATE_INSTALLED) && !reinstall) {
/* error out if pkg installed and no reinstall */
return EEXIST;
}
}
return trans_find_pkg(xhp, pkg, TRANS_INSTALL);
return trans_find_pkg(xhp, pkg, reinstall);
}
int

View File

@ -66,7 +66,67 @@ install_with_vpkg_deps_body() {
atf_check_equal $? 0
}
atf_test_case update_if_installed
update_if_installed_head() {
atf_set "descr" "Tests for pkg installations: update if installed (issue #35)"
}
update_if_installed_body() {
mkdir some_repo
mkdir -p pkg_A/usr/bin
cd some_repo
xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A
atf_check_equal $? 0
xbps-rindex -a *.xbps
atf_check_equal $? 0
cd ..
xbps-install -C empty.conf -r root --repository=$PWD/some_repo -y A
atf_check_equal $? 0
cd some_repo
xbps-create -A noarch -n A-1.1_1 -s "A pkg" ../pkg_A
atf_check_equal $? 0
xbps-rindex -a *.xbps
atf_check_equal $? 0
cd ..
xbps-install -C empty.conf -r root --repository=$PWD/some_repo -y A
atf_check_equal $? 0
pkgver=$(xbps-query -r root -ppkgver A)
atf_check_equal $pkgver A-1.1_1
}
atf_test_case install_if_not_installed_on_update
install_if_not_installed_on_update_head() {
atf_set "descr" "Tests for pkg installations: install if not installed on update (issue #35)"
}
install_if_not_installed_on_update_body() {
mkdir some_repo
mkdir -p pkg_A/usr/bin
cd some_repo
xbps-create -A noarch -n A-1.0_1 -s "A pkg" ../pkg_A
atf_check_equal $? 0
xbps-rindex -a *.xbps
atf_check_equal $? 0
cd ..
xbps-install -C empty.conf -r root --repository=$PWD/some_repo -yu A
atf_check_equal $? 0
pkgver=$(xbps-query -r root -ppkgver A)
atf_check_equal $pkgver A-1.0_1
}
atf_init_test_cases() {
atf_add_test_case install_with_deps
atf_add_test_case install_with_vpkg_deps
atf_add_test_case install_if_not_installed_on_update
atf_add_test_case update_if_installed
}