diff --git a/include/xbps_api.h b/include/xbps_api.h index 781fe9c1..9c9c86d1 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -1229,7 +1229,8 @@ int xbps_repository_pool_foreach( /** * Finds a package dictionary in the repository pool by specifying a - * package pattern or a package name. + * package pattern or a package name. This function does not take into + * account virtual packages set in configuration file. * * @param[in] pkg Package pattern or name. * @param[in] bypattern True if \a pkg is a pattern, false if it is a pkgname. @@ -1241,6 +1242,22 @@ int xbps_repository_pool_foreach( prop_dictionary_t xbps_repository_pool_find_pkg(const char *pkg, bool bypattern, bool best); +/** + * Finds a package dictionary in repository pool by specifying a + * package pattern or a package name. Only virtual packages set in + * configuration file will be matched. + * + * @param[in] pkg Virtual package pattern or name. + * @param[in] bypattern True if \a pkg is a pattern, false if it is a pkgname. + * @param[in] best True to find the best version available in repo, false to + * fetch the first package found matching its pkgname. + * + * @return The package dictionary if found, NULL otherwise. + */ +prop_dictionary_t + xbps_repository_pool_find_virtualpkg(const char *pkg, + bool bypattern, bool best); + /** * Iterate over the the repository pool and search for a metadata plist * file in a binary package named 'pkgname'. If a package is matched by diff --git a/lib/repository_finddeps.c b/lib/repository_finddeps.c index 8f665b82..f845eca0 100644 --- a/lib/repository_finddeps.c +++ b/lib/repository_finddeps.c @@ -242,10 +242,20 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */ /* * Check if package is already added in the * array of unsorted deps, and check if current required - * dependency pattern is matched. + * dependency pattern is matched. First checking if required + * dependency is supplied by a virtual pkg set in + * the configuration file. */ - curpkgd = xbps_find_pkg_in_dict_by_pattern(transd, + curpkgd = xbps_find_virtualpkg_conf_in_dict_by_pattern(transd, "unsorted_deps", reqpkg); + if (curpkgd == NULL) { + /* + * Look for a real package matching pattern + * if no match. + */ + curpkgd = xbps_find_pkg_in_dict_by_pattern(transd, + "unsorted_deps", reqpkg); + } if (curpkgd != NULL) { prop_dictionary_get_cstring_nocopy(curpkgd, "pkgver", &pkgver_q); @@ -260,30 +270,35 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */ } } /* - * If required pkgdep is not in repo, add it into the - * missing deps array and pass to the next one. + * If required pkgdep (first virtual pkg in conf, otherwise + * real pkg) is not in repo, add it into the missing deps + * array and pass to the next one. */ - curpkgd = xbps_repository_pool_find_pkg(reqpkg, true, false); + curpkgd = xbps_repository_pool_find_virtualpkg(reqpkg, true, false); if (curpkgd == NULL) { - if (errno && errno != ENOENT) { - rv = errno; - break; - } + curpkgd = xbps_repository_pool_find_pkg(reqpkg, true, false); + if (curpkgd == NULL) { + /* pkg not found, there was some error */ + if (errno && errno != ENOENT) { + rv = errno; + break; + } - rv = add_missing_reqdep(mrdeps, reqpkg); - if (rv != 0 && rv != EEXIST) { - xbps_dbg_printf_append("`%s': " - "add_missing_reqdep failed %s\n", reqpkg); - break; - } else if (rv == EEXIST) { - xbps_dbg_printf_append("`%s' missing dep " - "already added.\n", reqpkg); - rv = 0; - continue; - } else { - xbps_dbg_printf_append("`%s' added " - "into the missing deps array.\n", reqpkg); - continue; + rv = add_missing_reqdep(mrdeps, reqpkg); + if (rv != 0 && rv != EEXIST) { + xbps_dbg_printf_append("`%s': " + "add_missing_reqdep failed %s\n", reqpkg); + break; + } else if (rv == EEXIST) { + xbps_dbg_printf_append("`%s' missing dep " + "already added.\n", reqpkg); + rv = 0; + continue; + } else { + xbps_dbg_printf_append("`%s' added " + "into the missing deps array.\n", reqpkg); + continue; + } } } pkgname = xbps_pkgpattern_name(reqpkg); diff --git a/lib/repository_findpkg.c b/lib/repository_findpkg.c index ce79070e..4fd9f02c 100644 --- a/lib/repository_findpkg.c +++ b/lib/repository_findpkg.c @@ -87,10 +87,14 @@ repository_find_pkg(const char *pattern, const char *reason) pkg_repod = xbps_repository_pool_find_pkg(pattern, bypattern, bestpkg); if (pkg_repod == NULL) { - /* not found */ - rv = errno; - errno = 0; - goto out; + pkg_repod = xbps_repository_pool_find_virtualpkg(pattern, + bypattern, bestpkg); + if (pkg_repod == NULL) { + /* not found */ + rv = errno; + errno = 0; + goto out; + } } /* * Prepare transaction dictionary and missing deps array. diff --git a/lib/repository_pool.c b/lib/repository_pool.c index 5c2baf94..789780ab 100644 --- a/lib/repository_pool.c +++ b/lib/repository_pool.c @@ -387,11 +387,10 @@ repo_find_best_pkg_cb(struct repository_pool_index *rpi, return 0; } -prop_dictionary_t -xbps_repository_pool_find_pkg(const char *pkg, bool bypattern, bool best) +static struct repo_pool_fpkg * +repo_find_pkg(const char *pkg, bool bypattern, bool best, bool virtual) { struct repo_pool_fpkg *rpf; - prop_dictionary_t pkgd = NULL; int rv = 0; assert(pkg != NULL); @@ -411,37 +410,57 @@ xbps_repository_pool_find_pkg(const char *pkg, bool bypattern, bool best) * pattern in all repositories. */ rv = xbps_repository_pool_foreach(repo_find_best_pkg_cb, rpf); - if (rv != 0) { + if (rv != 0) errno = rv; - goto out; - } else if (rpf->pkgfound == false) { - goto out; - } } else { - /* - * Look for any virtual package set by the user matching - * the package name or pattern. - */ - rv = xbps_repository_pool_foreach(repo_find_virtualpkg_cb, rpf); - if (rv != 0) { - errno = rv; - goto out; - } else if (rpf->pkgfound == false) { + if (virtual) { /* - * No virtual package found. Look for real package - * names or patterns instead. + * No package found. Look for virtual package + * set by the user or any virtual pkg available. + */ + rv = xbps_repository_pool_foreach(repo_find_virtualpkg_cb, rpf); + if (rv != 0) + errno = rv; + } else { + /* + * Look for a package (non virtual) in repositories. */ rv = xbps_repository_pool_foreach(repo_find_pkg_cb, rpf); - if (rv != 0) { + if (rv != 0) errno = rv; - goto out; - } else if (rpf->pkgfound == false) { - goto out; - } } } - pkgd = prop_dictionary_copy(rpf->pkgd); -out: + + return rpf; +} + +prop_dictionary_t +xbps_repository_pool_find_virtualpkg(const char *pkg, bool bypattern, bool best) +{ + struct repo_pool_fpkg *rpf; + prop_dictionary_t pkgd = NULL; + + assert(pkg != NULL); + + rpf = repo_find_pkg(pkg, bypattern, best, true); + if (rpf->pkgfound && rpf->pkgd != NULL) + pkgd = prop_dictionary_copy(rpf->pkgd); + free(rpf); + + return pkgd; +} + +prop_dictionary_t +xbps_repository_pool_find_pkg(const char *pkg, bool bypattern, bool best) +{ + struct repo_pool_fpkg *rpf; + prop_dictionary_t pkgd = NULL; + + assert(pkg != NULL); + + rpf = repo_find_pkg(pkg, bypattern, best, false); + if (rpf->pkgfound && rpf->pkgd != NULL) + pkgd = prop_dictionary_copy(rpf->pkgd); free(rpf); return pkgd; diff --git a/lib/transaction_sortdeps.c b/lib/transaction_sortdeps.c index 3e667587..b0c81940 100644 --- a/lib/transaction_sortdeps.c +++ b/lib/transaction_sortdeps.c @@ -71,7 +71,8 @@ pkgdep_find(const char *name, const char *trans) if (pd->d == NULL) continue; if (xbps_match_virtual_pkg_in_dict(pd->d, name, false)) { - if (trans == pd->trans) + if (trans && pd->trans && + (strcmp(trans, pd->trans) == 0)) return pd; } } @@ -96,7 +97,8 @@ pkgdep_find_idx(const char *name, const char *trans) if (pd->d == NULL) continue; if (xbps_match_virtual_pkg_in_dict(pd->d, name, false)) { - if (trans == pd->trans) + if (trans && pd->trans && + (strcmp(trans, pd->trans) == 0)) return idx; } @@ -156,8 +158,14 @@ pkgdep_end(prop_array_t sorted) * Do not add duplicate pkg dictionaries with the * same transaction reason into the sorted array. */ - sorted_pkgd = xbps_find_pkg_in_array_by_name(sorted, - pd->name); + sorted_pkgd = + xbps_find_pkg_in_array_by_name(sorted, pd->name); + if (sorted_pkgd == NULL) { + /* find virtualpkg if no match */ + sorted_pkgd = + xbps_find_virtualpkg_in_array_by_name( + sorted, pd->name); + } if (sorted_pkgd == NULL) { prop_array_add(sorted, pd->d); pkgdep_release(pd); @@ -233,10 +241,13 @@ again: free(pkgnamedep); continue; } + /* Find pkg by name */ curpkgd = xbps_find_pkg_in_dict_by_name(transd, "unsorted_deps", pkgnamedep); if (curpkgd == NULL) { - curpkgd = xbps_find_virtualpkg_in_dict_by_name(transd, + /* find virtualpkg by name if no match */ + curpkgd = + xbps_find_virtualpkg_in_dict_by_name(transd, "unsorted_deps", pkgnamedep); } if (curpkgd == NULL) {