rpool: improve the order while resolving dependencies.

See the NEWS file for more information. After that change you don't have
to set a virtual pkg in conf file, if required virtual pkg is in rpool.
This commit is contained in:
Juan RP 2012-05-30 10:22:53 +02:00
parent fa7bee1164
commit da4b8b7427
5 changed files with 152 additions and 91 deletions

11
NEWS
View File

@ -1,5 +1,16 @@
xbps-0.16 (???): xbps-0.16 (???):
* libxbps: extended rpool with a new function:
xbps_repository_pool_find_virtualpkg_conf. This function will match
a virtual package as was specified in configuration file. That means
that the find_xxx functions now do exactly what the API documents.
While resolving packages, the order to look for them is the following:
find_virtualpkg_conf -> find_pkg -> find_virtualpkg
If no virtual pkg from conf matched, look for a real pkg, otherwise
use the first virtual package from rpool that matches our pattern.
* libxbps: introduce the concept of "soft replace". When a package * libxbps: introduce the concept of "soft replace". When a package
contains that boolean object set in pkg's metadata props.plist, contains that boolean object set in pkg's metadata props.plist,
some steps will be skipped at remove time for the package being some steps will be skipped at remove time for the package being

View File

@ -56,7 +56,7 @@
*/ */
#define XBPS_PKGINDEX_VERSION "1.4" #define XBPS_PKGINDEX_VERSION "1.4"
#define XBPS_API_VERSION "20120525-3" #define XBPS_API_VERSION "20120530"
#define XBPS_VERSION "0.16" #define XBPS_VERSION "0.16"
/** /**
@ -1537,13 +1537,13 @@ int xbps_repository_pool_foreach(
/** /**
* Finds a package dictionary in the repository pool by specifying a * Finds a package dictionary in the repository pool by specifying a
* package pattern or a package name. This function does not take into * package pattern or a package name. This function does not take into
* account virtual packages set in configuration file. * account virtual packages, just matches real packages.
* *
* @param[in] pkg Package pattern or name. * @param[in] pkg Package pattern or name.
* @param[in] bypattern Set it to true if \a pkg is a pkgpattern (foo>=0), * @param[in] bypattern Set it to true if \a pkg is a pkgpattern (foo>=0),
* false if it is a pkgname. * false if it is a pkgname.
* @param[in] best True to find the best version available in repo, false to * @param[in] best True to find the best version available in repo, false to
* fetch the first package found matching its pkgname. * fetch the first package found matching \a pkg.
* *
* @return The package dictionary if found, NULL otherwise. * @return The package dictionary if found, NULL otherwise.
* @note When returned dictionary is no longer needed, you must release it * @note When returned dictionary is no longer needed, you must release it
@ -1564,6 +1564,21 @@ prop_dictionary_t
*/ */
prop_dictionary_t xbps_repository_pool_find_pkg_exact(const char *pkgver); prop_dictionary_t xbps_repository_pool_find_pkg_exact(const char *pkgver);
/**
* Finds a package dictionary in repository pool by specifying a
* virtual package pattern or a package name.
*
* @param[in] pkg Virtual package pattern or name to match.
* @param[in] bypattern Set it to true if \a pkg is a pkgpattern (foo>=0),
* false if it is a pkgname.
*
* @return The package dictionary if found, NULL otherwise.
* @note When returned dictionary is no longer needed, you must release it
* with prop_object_release(3).
*/
prop_dictionary_t
xbps_repository_pool_find_virtualpkg(const char *pkg, bool bypattern);
/** /**
* Finds a package dictionary in repository pool by specifying a * Finds a package dictionary in repository pool by specifying a
* package pattern or a package name. Only virtual packages set in * package pattern or a package name. Only virtual packages set in
@ -1578,7 +1593,7 @@ prop_dictionary_t xbps_repository_pool_find_pkg_exact(const char *pkgver);
* with prop_object_release(3). * with prop_object_release(3).
*/ */
prop_dictionary_t prop_dictionary_t
xbps_repository_pool_find_virtualpkg(const char *pkg, bool bypattern); xbps_repository_pool_find_virtualpkg_conf(const char *pkg, bool bypattern);
/** /**
* Iterate over the the repository pool and search for a metadata plist * Iterate over the the repository pool and search for a metadata plist

View File

@ -386,11 +386,9 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
* If dependency does not match add pkg into the missing * If dependency does not match add pkg into the missing
* deps array and pass to next one. * deps array and pass to next one.
*/ */
curpkgd = xbps_repository_pool_find_virtualpkg(reqpkg, true); if (((curpkgd = xbps_repository_pool_find_virtualpkg_conf(reqpkg, true)) == NULL) &&
if (curpkgd == NULL) { ((curpkgd = xbps_repository_pool_find_pkg(reqpkg, true, true)) == NULL) &&
curpkgd = xbps_repository_pool_find_pkg(reqpkg, true, ((curpkgd = xbps_repository_pool_find_virtualpkg(reqpkg, true)) == NULL)) {
true);
if (curpkgd == NULL) {
/* pkg not found, there was some error */ /* pkg not found, there was some error */
if (errno && errno != ENOENT) { if (errno && errno != ENOENT) {
xbps_dbg_printf("failed to find pkg " xbps_dbg_printf("failed to find pkg "
@ -399,7 +397,6 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
rv = errno; rv = errno;
break; break;
} }
rv = add_missing_reqdep(trans_mdeps, reqpkg); rv = add_missing_reqdep(trans_mdeps, reqpkg);
if (rv != 0 && rv != EEXIST) { if (rv != 0 && rv != EEXIST) {
xbps_dbg_printf_append("`%s': " xbps_dbg_printf_append("`%s': "
@ -418,7 +415,6 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */
continue; continue;
} }
} }
}
prop_dictionary_set_cstring_nocopy(curpkgd, "transaction", reason); prop_dictionary_set_cstring_nocopy(curpkgd, "transaction", reason);
prop_dictionary_get_cstring_nocopy(curpkgd, "pkgver", &pkgver_q); prop_dictionary_get_cstring_nocopy(curpkgd, "pkgver", &pkgver_q);
/* /*

View File

@ -51,6 +51,33 @@ repo_find_virtualpkg_cb(struct repository_pool_index *rpi, void *arg, bool *done
assert(rpi != NULL); assert(rpi != NULL);
if (rpf->bypattern) {
rpf->pkgd =
xbps_find_virtualpkg_in_array_by_pattern(rpi->rpi_repo,
rpf->pattern);
} else {
rpf->pkgd =
xbps_find_virtualpkg_in_array_by_name(rpi->rpi_repo,
rpf->pattern);
}
if (rpf->pkgd) {
prop_dictionary_set_cstring(rpf->pkgd, "repository",
rpi->rpi_uri);
*done = true;
return 0;
}
/* not found */
return 0;
}
static int
repo_find_virtualpkg_conf_cb(struct repository_pool_index *rpi,
void *arg, bool *done)
{
struct repo_pool_fpkg *rpf = arg;
assert(rpi != NULL);
if (rpf->bypattern) { if (rpf->bypattern) {
rpf->pkgd = rpf->pkgd =
xbps_find_virtualpkg_conf_in_array_by_pattern(rpi->rpi_repo, xbps_find_virtualpkg_conf_in_array_by_pattern(rpi->rpi_repo,
@ -61,10 +88,6 @@ repo_find_virtualpkg_cb(struct repository_pool_index *rpi, void *arg, bool *done
rpf->pattern); rpf->pattern);
} }
if (rpf->pkgd) { if (rpf->pkgd) {
#ifdef DEBUG
xbps_dbg_printf("%s: found pkg in repository\n", __func__);
xbps_dbg_printf_append("%s", prop_dictionary_externalize(rpf->pkgd));
#endif
prop_dictionary_set_cstring(rpf->pkgd, "repository", prop_dictionary_set_cstring(rpf->pkgd, "repository",
rpi->rpi_uri); rpi->rpi_uri);
*done = true; *done = true;
@ -89,20 +112,10 @@ repo_find_pkg_cb(struct repository_pool_index *rpi, void *arg, bool *done)
/* match by pkgpattern in pkgver*/ /* match by pkgpattern in pkgver*/
rpf->pkgd = xbps_find_pkg_in_array_by_pattern(rpi->rpi_repo, rpf->pkgd = xbps_find_pkg_in_array_by_pattern(rpi->rpi_repo,
rpf->pattern); rpf->pattern);
/* If no pkg exists matching pattern, look for virtual packages */
if (rpf->pkgd == NULL) {
rpf->pkgd = xbps_find_virtualpkg_in_array_by_pattern(
rpi->rpi_repo, rpf->pattern);
}
} else { } else {
/* match by pkgname */ /* match by pkgname */
rpf->pkgd = xbps_find_pkg_in_array_by_name(rpi->rpi_repo, rpf->pkgd = xbps_find_pkg_in_array_by_name(rpi->rpi_repo,
rpf->pattern); rpf->pattern);
/* If no pkg exists matching pattern, look for virtual packages */
if (rpf->pkgd == NULL) {
rpf->pkgd = xbps_find_virtualpkg_in_array_by_name(
rpi->rpi_repo, rpf->pattern);
}
} }
if (rpf->pkgd) { if (rpf->pkgd) {
/* /*
@ -170,9 +183,16 @@ repo_find_best_pkg_cb(struct repository_pool_index *rpi,
return 0; return 0;
} }
typedef enum {
BEST_PKG = 1,
EXACT_PKG,
VIRTUAL_PKG,
VIRTUAL_CONF_PKG,
REAL_PKG
} pkg_repo_type_t;
static struct repo_pool_fpkg * static struct repo_pool_fpkg *
repo_find_pkg(const char *pkg, bool bypattern, bool best, bool exact, repo_find_pkg(const char *pkg, bool bypattern, pkg_repo_type_t type)
bool virtual)
{ {
struct repo_pool_fpkg *rpf; struct repo_pool_fpkg *rpf;
int rv = 0; int rv = 0;
@ -185,43 +205,45 @@ repo_find_pkg(const char *pkg, bool bypattern, bool best, bool exact,
rpf->pattern = pkg; rpf->pattern = pkg;
rpf->bypattern = bypattern; rpf->bypattern = bypattern;
rpf->exact = exact; rpf->exact = false;
rpf->pkgd = NULL; rpf->pkgd = NULL;
rpf->bestpkgver = NULL; rpf->bestpkgver = NULL;
if (exact) { switch (type) {
case EXACT_PKG:
/* /*
* Look for exact package match with pkgver in all repos. * Find exact pkg version.
*/ */
rpf->exact = true;
rv = xbps_repository_pool_foreach(repo_find_pkg_cb, rpf); rv = xbps_repository_pool_foreach(repo_find_pkg_cb, rpf);
if (rv != 0) break;
errno = rv; case BEST_PKG:
} else if (best) {
/* /*
* Look for the best package version of a package name or * Find best pkg version.
* pattern in all repositories.
*/ */
rv = xbps_repository_pool_foreach(repo_find_best_pkg_cb, rpf); rv = xbps_repository_pool_foreach(repo_find_best_pkg_cb, rpf);
if (rv != 0) break;
errno = rv; case VIRTUAL_PKG:
} else {
if (virtual) {
/* /*
* No package found. Look for virtual package * Find virtual pkg.
* set by the user or any virtual pkg available.
*/ */
rv = xbps_repository_pool_foreach(repo_find_virtualpkg_cb, rpf); rv = xbps_repository_pool_foreach(repo_find_virtualpkg_cb, rpf);
if (rv != 0) break;
errno = rv; case VIRTUAL_CONF_PKG:
} else {
/* /*
* Look for a package (non virtual) in repositories. * Find virtual pkg as specified in configuration file.
*/
rv = xbps_repository_pool_foreach(repo_find_virtualpkg_conf_cb, rpf);
break;
case REAL_PKG:
/*
* Find real pkg.
*/ */
rv = xbps_repository_pool_foreach(repo_find_pkg_cb, rpf); rv = xbps_repository_pool_foreach(repo_find_pkg_cb, rpf);
break;
}
if (rv != 0) if (rv != 0)
errno = rv; errno = rv;
}
}
return rpf; return rpf;
} }
@ -234,7 +256,23 @@ xbps_repository_pool_find_virtualpkg(const char *pkg, bool bypattern)
assert(pkg != NULL); assert(pkg != NULL);
rpf = repo_find_pkg(pkg, bypattern, false, false, true); rpf = repo_find_pkg(pkg, bypattern, VIRTUAL_PKG);
if (prop_object_type(rpf->pkgd) == PROP_TYPE_DICTIONARY)
pkgd = prop_dictionary_copy(rpf->pkgd);
free(rpf);
return pkgd;
}
prop_dictionary_t
xbps_repository_pool_find_virtualpkg_conf(const char *pkg, bool bypattern)
{
struct repo_pool_fpkg *rpf;
prop_dictionary_t pkgd = NULL;
assert(pkg != NULL);
rpf = repo_find_pkg(pkg, bypattern, VIRTUAL_CONF_PKG);
if (prop_object_type(rpf->pkgd) == PROP_TYPE_DICTIONARY) if (prop_object_type(rpf->pkgd) == PROP_TYPE_DICTIONARY)
pkgd = prop_dictionary_copy(rpf->pkgd); pkgd = prop_dictionary_copy(rpf->pkgd);
free(rpf); free(rpf);
@ -250,7 +288,11 @@ xbps_repository_pool_find_pkg(const char *pkg, bool bypattern, bool best)
assert(pkg != NULL); assert(pkg != NULL);
rpf = repo_find_pkg(pkg, bypattern, best, false, false); if (best)
rpf = repo_find_pkg(pkg, bypattern, BEST_PKG);
else
rpf = repo_find_pkg(pkg, bypattern, REAL_PKG);
if (prop_object_type(rpf->pkgd) == PROP_TYPE_DICTIONARY) if (prop_object_type(rpf->pkgd) == PROP_TYPE_DICTIONARY)
pkgd = prop_dictionary_copy(rpf->pkgd); pkgd = prop_dictionary_copy(rpf->pkgd);
free(rpf); free(rpf);
@ -266,7 +308,7 @@ xbps_repository_pool_find_pkg_exact(const char *pkgver)
assert(pkgver != NULL); assert(pkgver != NULL);
rpf = repo_find_pkg(pkgver, false, false, true, false); rpf = repo_find_pkg(pkgver, false, EXACT_PKG);
if (prop_object_type(rpf->pkgd) == PROP_TYPE_DICTIONARY) if (prop_object_type(rpf->pkgd) == PROP_TYPE_DICTIONARY)
pkgd = prop_dictionary_copy(rpf->pkgd); pkgd = prop_dictionary_copy(rpf->pkgd);
free(rpf); free(rpf);

View File

@ -84,17 +84,14 @@ transaction_find_pkg(const char *pkg, bool bypattern, bool bestpkg, int action)
/* /*
* 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(pkg, bypattern, bestpkg); if (((pkg_repod = xbps_repository_pool_find_virtualpkg_conf(pkg, bypattern)) == NULL) &&
if (pkg_repod == NULL) { ((pkg_repod = xbps_repository_pool_find_pkg(pkg, bypattern, bestpkg)) == NULL) &&
pkg_repod = ((pkg_repod = xbps_repository_pool_find_virtualpkg(pkg, bypattern)) == NULL)) {
xbps_repository_pool_find_virtualpkg(pkg, bypattern);
if (pkg_repod == NULL) {
/* not found */ /* not found */
rv = errno; rv = errno;
errno = 0; errno = 0;
goto out; goto out;
} }
}
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &pkgver);
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);