From abb0d260b940d38a6f3716922a8ab2726856b6a7 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Wed, 25 Jan 2012 02:14:04 +0100 Subject: [PATCH] xbps-bin: the install target gains suppor for installing best pkg available. --- NEWS | 7 +++++ bin/xbps-bin/transaction.c | 55 +++++--------------------------------- include/xbps_api.h | 20 +++++++++----- lib/repository_finddeps.c | 16 +++++------ lib/transaction_ops.c | 49 ++++++++++++++++++++++----------- 5 files changed, 70 insertions(+), 77 deletions(-) diff --git a/NEWS b/NEWS index 4c701989..ad32afeb 100644 --- a/NEWS +++ b/NEWS @@ -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 diff --git a/bin/xbps-bin/transaction.c b/bin/xbps-bin/transaction.c index 47b9c937..c931b873 100644 --- a/bin/xbps-bin/transaction.c +++ b/bin/xbps-bin/transaction.c @@ -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) diff --git a/include/xbps_api.h b/include/xbps_api.h index 3f32c1a6..e3bdfb38 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -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. diff --git a/lib/repository_finddeps.c b/lib/repository_finddeps.c index 431fb8ce..0f9018db 100644 --- a/lib/repository_finddeps.c +++ b/lib/repository_finddeps.c @@ -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); } diff --git a/lib/transaction_ops.c b/lib/transaction_ops.c index 5686c0d9..863a3398 100644 --- a/lib/transaction_ops.c +++ b/lib/transaction_ops.c @@ -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