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-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 * Massive pkgdb API rototill. The xbps-uhelper command gained support
for the 'updatepkgdb' target which will migrate old pkgdb for the 'updatepkgdb' target which will migrate old pkgdb
format to the new 0.12 format. ALERT: make sure to execute 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 int
autoremove_pkgs(bool yes) autoremove_pkgs(bool yes)
{ {
int rv = 0; int rv;
if ((rv = xbps_transaction_autoremove_pkgs()) != 0) { if ((rv = xbps_transaction_autoremove_pkgs()) != 0) {
if (rv == ENOENT) { if (rv == ENOENT) {
@ -242,48 +242,12 @@ autoremove_pkgs(bool yes)
int int
install_new_pkg(const char *pkg, bool reinstall) install_new_pkg(const char *pkg, bool reinstall)
{ {
prop_dictionary_t pkgd; int rv;
char *pkgname = NULL, *pkgpatt = NULL;
int rv = 0;
bool pkgmatch = false;
pkg_state_t state;
if (xbps_pkgpattern_version(pkg)) { if ((rv = xbps_transaction_install_pkg(pkg, reinstall)) != 0) {
pkgpatt = __UNCONST(pkg); if (rv == ENODEV) {
} else { printf("Package `%s' already installed.\n", pkg);
/* } else if (rv == ENOENT) {
* 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) {
xbps_error_printf("xbps-bin: unable to locate '%s' in " xbps_error_printf("xbps-bin: unable to locate '%s' in "
"repository pool.\n", pkg); "repository pool.\n", pkg);
} else if (rv == ENOTSUP) { } else if (rv == ENOTSUP) {
@ -295,18 +259,13 @@ install_new_pkg(const char *pkg, bool reinstall)
rv = -1; rv = -1;
} }
} }
out:
if (pkgmatch)
free(pkgpatt);
free(pkgname);
return rv; return rv;
} }
int int
update_pkg(const char *pkgname) update_pkg(const char *pkgname)
{ {
int rv = 0; int rv;
rv = xbps_transaction_update_pkg(pkgname); rv = xbps_transaction_update_pkg(pkgname);
if (rv == EEXIST) if (rv == EEXIST)

View File

@ -56,7 +56,7 @@
*/ */
#define XBPS_PKGINDEX_VERSION "1.4" #define XBPS_PKGINDEX_VERSION "1.4"
#define XBPS_API_VERSION "20120124" #define XBPS_API_VERSION "20120125"
#define XBPS_VERSION "0.12" #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 * Finds a package by name or by pattern and enqueues it into
* the transaction dictionary for future use. The first repository in * the transaction dictionary for future use. If pkg is a pkgname, the best
* the pool that matched the pattern wins. * 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. * @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. * 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(""); xbps_dbg_printf("");
for (x = 0; x < *depth; x++) for (x = 0; x < *depth; x++)
xbps_dbg_printf_append(" "); xbps_dbg_printf_append(" ");
xbps_dbg_printf_append("%s requires dependency '%s': ", xbps_dbg_printf_append("%s: requires dependency '%s': ",
curpkg ? curpkg : " ", reqpkg); curpkg ? curpkg : " ", reqpkg);
} }
/* /*
@ -258,7 +258,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
break; break;
} }
/* Required pkgdep not installed */ /* Required pkgdep not installed */
xbps_dbg_printf_append("not installed"); xbps_dbg_printf_append("not installed. ");
reason = "install"; reason = "install";
state = XBPS_PKG_STATE_NOT_INSTALLED; state = XBPS_PKG_STATE_NOT_INSTALLED;
} else { } else {
@ -403,8 +403,8 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
if (tmpd == NULL) { if (tmpd == NULL) {
/* dependency not installed */ /* dependency not installed */
reason = "install"; reason = "install";
xbps_dbg_printf_append("satisfied by `%s', " xbps_dbg_printf_append("(found `%s')\n",
"installing...\n", pkgver_q); pkgver_q);
} else { } else {
/* dependency installed, check its state */ /* dependency installed, check its state */
state = 0; state = 0;
@ -416,12 +416,12 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
} }
if (state == XBPS_PKG_STATE_INSTALLED) { if (state == XBPS_PKG_STATE_INSTALLED) {
reason = "update"; reason = "update";
xbps_dbg_printf_append("satisfied by `%s', " xbps_dbg_printf_append("(found `%s')\n",
"updating...\n", pkgver_q); pkgver_q);
} else if (state == XBPS_PKG_STATE_UNPACKED) { } else if (state == XBPS_PKG_STATE_UNPACKED) {
reason = "install"; reason = "install";
xbps_dbg_printf_append("satisfied by `%s', " xbps_dbg_printf_append("(found `%s')\n",
"installing...\n", pkgver_q); pkgver_q);
} }
prop_object_release(tmpd); prop_object_release(tmpd);
} }

View File

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