xbps-bin: the install target gains suppor for installing best pkg available.

This commit is contained in:
Juan RP 2012-01-25 02:14:04 +01:00
parent 11f94a4f46
commit abb0d260b9
5 changed files with 70 additions and 77 deletions

7
NEWS
View File

@ -1,5 +1,12 @@
xbps-0.12.0 (???):
* xbps-bin: the install target will now install the best package
version available in repository pool if just package name has
been specified, otherwise the first repository matching the
specified pattern wins, i.e:
$ xbps-bin install foo 'blah>=1.2<2.0'
* Massive pkgdb API rototill. The xbps-uhelper command gained support
for the 'updatepkgdb' target which will migrate old pkgdb
format to the new 0.12 format. ALERT: make sure to execute

View File

@ -224,7 +224,7 @@ autoupdate_pkgs(bool yes, bool show_download_pkglist_url)
int
autoremove_pkgs(bool yes)
{
int rv = 0;
int rv;
if ((rv = xbps_transaction_autoremove_pkgs()) != 0) {
if (rv == ENOENT) {
@ -242,48 +242,12 @@ autoremove_pkgs(bool yes)
int
install_new_pkg(const char *pkg, bool reinstall)
{
prop_dictionary_t pkgd;
char *pkgname = NULL, *pkgpatt = NULL;
int rv = 0;
bool pkgmatch = false;
pkg_state_t state;
int rv;
if (xbps_pkgpattern_version(pkg)) {
pkgpatt = __UNCONST(pkg);
} else {
/*
* If only pkgname has been specified, always make it
* use a package pattern, i.e 'foo>=0'.
*/
pkgmatch = true;
pkgpatt = xbps_xasprintf("%s%s", pkg, ">=0");
if (pkgpatt == NULL)
return -1;
}
pkgname = xbps_pkgpattern_name(pkgpatt);
if (pkgname == NULL)
return -1;
/*
* Find a package in a repository and prepare for installation.
*/
if ((pkgd = xbps_find_pkg_dict_installed(pkgname, false))) {
if ((rv = xbps_pkg_state_dictionary(pkgd, &state)) != 0) {
prop_object_release(pkgd);
goto out;
}
prop_object_release(pkgd);
if (state == XBPS_PKG_STATE_INSTALLED) {
if (!reinstall) {
printf("Package '%s' is already installed.\n",
pkgname);
goto out;
}
} else {
printf("Package `%s' needs to be configured.\n", pkgname);
}
}
if ((rv = xbps_transaction_install_pkg(pkgpatt)) != 0) {
if (rv == ENOENT) {
if ((rv = xbps_transaction_install_pkg(pkg, reinstall)) != 0) {
if (rv == ENODEV) {
printf("Package `%s' already installed.\n", pkg);
} else if (rv == ENOENT) {
xbps_error_printf("xbps-bin: unable to locate '%s' in "
"repository pool.\n", pkg);
} else if (rv == ENOTSUP) {
@ -295,18 +259,13 @@ install_new_pkg(const char *pkg, bool reinstall)
rv = -1;
}
}
out:
if (pkgmatch)
free(pkgpatt);
free(pkgname);
return rv;
}
int
update_pkg(const char *pkgname)
{
int rv = 0;
int rv;
rv = xbps_transaction_update_pkg(pkgname);
if (rv == EEXIST)

View File

@ -56,7 +56,7 @@
*/
#define XBPS_PKGINDEX_VERSION "1.4"
#define XBPS_API_VERSION "20120124"
#define XBPS_API_VERSION "20120125"
#define XBPS_VERSION "0.12"
/**
@ -1304,15 +1304,23 @@ int xbps_remove_pkg_files(prop_dictionary_t dict,
/*@{*/
/**
* Finds a package by a pattern and enqueues it into
* the transaction dictionary for future use. The first repository in
* the pool that matched the pattern wins.
* Finds a package by name or by pattern and enqueues it into
* the transaction dictionary for future use. If pkg is a pkgname, the best
* package version in repository pool will be queued, otherwise the first
* repository matching the package pattern wins.
*
* @param pkgpattern Package pattern, i.e `foo>=0' or 'foo<2.0'.
* @param str Package name or package pattern to match, i.e
* `foo>=0' or 'foo<1'.
* @param reinstall If true, package will be queued (if \a str matches)
* even if package is already installed.
*
* @return 0 on success, otherwise an errno value.
* @retval ENODEV Package is already installed (reinstall wasn't enabled).
* @retval ENOENT Package not matched in repository pool.
* @retval ENOTSUP No repositories are available.
* @retval EINVAL Any other error ocurred in the process.
*/
int xbps_transaction_install_pkg(const char *pkgpattern);
int xbps_transaction_install_pkg(const char *pkg, bool reinstall);
/**
* Marks a package as "going to be updated" in the transaction dictionary.

View File

@ -214,7 +214,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
xbps_dbg_printf("");
for (x = 0; x < *depth; x++)
xbps_dbg_printf_append(" ");
xbps_dbg_printf_append("%s requires dependency '%s': ",
xbps_dbg_printf_append("%s: requires dependency '%s': ",
curpkg ? curpkg : " ", reqpkg);
}
/*
@ -258,7 +258,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
break;
}
/* Required pkgdep not installed */
xbps_dbg_printf_append("not installed");
xbps_dbg_printf_append("not installed. ");
reason = "install";
state = XBPS_PKG_STATE_NOT_INSTALLED;
} else {
@ -403,8 +403,8 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
if (tmpd == NULL) {
/* dependency not installed */
reason = "install";
xbps_dbg_printf_append("satisfied by `%s', "
"installing...\n", pkgver_q);
xbps_dbg_printf_append("(found `%s')\n",
pkgver_q);
} else {
/* dependency installed, check its state */
state = 0;
@ -416,12 +416,12 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
}
if (state == XBPS_PKG_STATE_INSTALLED) {
reason = "update";
xbps_dbg_printf_append("satisfied by `%s', "
"updating...\n", pkgver_q);
xbps_dbg_printf_append("(found `%s')\n",
pkgver_q);
} else if (state == XBPS_PKG_STATE_UNPACKED) {
reason = "install";
xbps_dbg_printf_append("satisfied by `%s', "
"installing...\n", pkgver_q);
xbps_dbg_printf_append("(found `%s')\n",
pkgver_q);
}
prop_object_release(tmpd);
}

View File

@ -57,43 +57,37 @@ enum {
};
static int
transaction_find_pkg(const char *pattern, int action)
transaction_find_pkg(const char *pkg, bool bypattern, bool bestpkg, int action)
{
prop_dictionary_t pkg_pkgdb, pkg_repod = NULL;
prop_array_t unsorted;
struct xbps_handle *xhp = xbps_handle_get();
const char *pkgname, *pkgver, *repoloc, *repover, *instver, *reason;
int rv = 0;
bool bypattern, bestpkg;
pkg_state_t state = 0;
assert(pattern != NULL);
assert(pkg != NULL);
if (action == TRANS_INSTALL) {
/* install */
bypattern = true;
bestpkg = false;
reason = "install";
} else {
/* update */
pkg_pkgdb = xbps_find_pkg_dict_installed(pattern, false);
pkg_pkgdb = xbps_find_pkg_dict_installed(pkg, false);
if (pkg_pkgdb == NULL) {
rv = ENODEV;
goto out;
}
bypattern = false;
bestpkg = true;
reason = "update";
}
/*
* Find out if the pkg has been found in repository pool.
*/
pkg_repod = xbps_repository_pool_find_pkg(pattern,
bypattern, bestpkg);
pkg_repod = xbps_repository_pool_find_pkg(pkg, bypattern, bestpkg);
if (pkg_repod == NULL) {
pkg_repod =
xbps_repository_pool_find_virtualpkg(pattern, bypattern);
xbps_repository_pool_find_virtualpkg(pkg, bypattern);
if (pkg_repod == NULL) {
/* not found */
rv = errno;
@ -105,7 +99,7 @@ transaction_find_pkg(const char *pattern, int action)
prop_dictionary_get_cstring_nocopy(pkg_repod, "repository", &repoloc);
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname);
if (bestpkg) {
if (bestpkg && (action == TRANS_UPDATE)) {
/*
* Compare installed version vs best pkg available in repos.
*/
@ -231,13 +225,38 @@ xbps_transaction_update_packages(void)
int
xbps_transaction_update_pkg(const char *pkgname)
{
return transaction_find_pkg(pkgname, TRANS_UPDATE);
return transaction_find_pkg(pkgname, false, true, TRANS_UPDATE);
}
int
xbps_transaction_install_pkg(const char *pkgpattern)
xbps_transaction_install_pkg(const char *pkg, bool reinstall)
{
return transaction_find_pkg(pkgpattern, TRANS_INSTALL);
prop_dictionary_t pkgd;
pkg_state_t state;
bool bypattern, bestpkg;
if (xbps_pkgpattern_version(pkg)) {
bypattern = true;
bestpkg = false;
} else {
bypattern = false;
bestpkg = true;
}
pkgd = xbps_pkgdb_get_pkgd(pkg, bypattern);
if (pkgd != NULL) {
if (xbps_pkg_state_dictionary(pkgd, &state) != 0) {
prop_object_release(pkgd);
return EINVAL;
}
prop_object_release(pkgd);
if ((state == XBPS_PKG_STATE_INSTALLED) && !reinstall) {
/* error out if pkg installed and no reinstall */
return ENODEV;
}
}
return transaction_find_pkg(pkg, bypattern, bestpkg, TRANS_INSTALL);
}
int