libxbps: detect and ignore incorrect deps of a pkg if those are virtual pkgs.

This commit is contained in:
Juan RP
2014-04-20 16:54:50 +02:00
parent 119d059c9b
commit bb491e2667
9 changed files with 76 additions and 59 deletions

View File

@ -52,11 +52,7 @@ get_pkg_in_array(xbps_array_t array, const char *str, bool virtual)
* Check if package pattern matches
* any virtual package version in dictionary.
*/
if (xbps_pkgpattern_version(str))
found = xbps_match_virtual_pkg_in_dict(obj, str, true);
else
found = xbps_match_virtual_pkg_in_dict(obj, str, false);
found = xbps_match_virtual_pkg_in_dict(obj, str);
if (found)
break;
} else if (xbps_pkgpattern_version(str)) {
@ -269,7 +265,7 @@ xbps_find_virtualpkg_in_dict(struct xbps_handle *xhp,
while ((obj = xbps_object_iterator_next(iter))) {
pkgd = xbps_dictionary_get_keysym(d, obj);
if (xbps_match_virtual_pkg_in_dict(pkgd, pkg, bypattern)) {
if (xbps_match_virtual_pkg_in_dict(pkgd, pkg)) {
xbps_object_iterator_release(iter);
return pkgd;
}

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2008-2012 Juan Romero Pardines.
* Copyright (c) 2008-2014 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -40,25 +40,27 @@
* all library functions.
*/
bool
xbps_match_virtual_pkg_in_dict(xbps_dictionary_t d,
const char *str,
bool bypattern)
xbps_match_virtual_pkg_in_array(xbps_array_t a, const char *str)
{
if ((xbps_match_pkgname_in_array(a, str)) ||
(xbps_match_pkgdep_in_array(a, str)) ||
(xbps_match_pkgpattern_in_array(a, str)))
return true;
return false;
}
bool
xbps_match_virtual_pkg_in_dict(xbps_dictionary_t d, const char *str)
{
xbps_array_t provides;
bool found = false;
assert(xbps_object_type(d) == XBPS_TYPE_DICTIONARY);
if ((provides = xbps_dictionary_get(d, "provides"))) {
if (bypattern)
found = xbps_match_pkgpattern_in_array(provides, str);
else {
if ((xbps_match_pkgname_in_array(provides, str)) ||
(xbps_match_pkgdep_in_array(provides, str)))
return true;
}
}
return found;
if ((provides = xbps_dictionary_get(d, "provides")))
return xbps_match_virtual_pkg_in_array(provides, str);
return false;
}
bool

View File

@ -152,13 +152,14 @@ static int
find_repo_deps(struct xbps_handle *xhp,
xbps_array_t unsorted, /* array of unsorted deps */
xbps_array_t pkg_rdeps_array, /* current pkg rundeps array */
xbps_array_t pkg_provides, /* current pkg provides array */
const char *curpkg, /* current pkgver */
unsigned short *depth) /* max recursion depth */
{
xbps_dictionary_t curpkgd = NULL;
xbps_object_t obj;
xbps_object_iterator_t iter;
xbps_array_t curpkgrdeps;
xbps_array_t curpkgrdeps = NULL, curpkgprovides = NULL;
pkg_state_t state;
const char *reqpkg, *pkgver_q, *reason = NULL;
char *pkgname, *reqpkgname;
@ -191,7 +192,16 @@ find_repo_deps(struct xbps_handle *xhp,
break;
}
/*
* Pass 1: check if required dependency has been already
* Pass 1: check if required dependency is provided as virtual
* package via "provides", if true ignore dependency.
*/
if (pkg_provides && xbps_match_virtual_pkg_in_array(pkg_provides, reqpkg)) {
xbps_dbg_printf_append(xhp, "%s is a vpkg provided by %s, ignored.\n", pkgname, curpkg);
free(pkgname);
continue;
}
/*
* Pass 2: check if required dependency has been already
* added in the transaction dictionary.
*/
if ((curpkgd = xbps_find_pkg_in_array(unsorted, reqpkg)) ||
@ -199,10 +209,11 @@ find_repo_deps(struct xbps_handle *xhp,
xbps_dictionary_get_cstring_nocopy(curpkgd,
"pkgver", &pkgver_q);
xbps_dbg_printf_append(xhp, " (%s queued)\n", pkgver_q);
free(pkgname);
continue;
}
/*
* Pass 2: check if required dependency is already installed
* Pass 3: check if required dependency is already installed
* and its version is fully matched.
*/
if (((curpkgd = xbps_pkgdb_get_pkg(xhp, pkgname)) == NULL) &&
@ -233,7 +244,7 @@ find_repo_deps(struct xbps_handle *xhp,
/* Check its state */
if ((rv = xbps_pkg_state_dictionary(curpkgd, &state)) != 0)
break;
if (xbps_match_virtual_pkg_in_dict(curpkgd, reqpkg, true)) {
if (xbps_match_virtual_pkg_in_dict(curpkgd, reqpkg)) {
/*
* Check if required dependency is a virtual
* package and is satisfied by an
@ -292,7 +303,7 @@ find_repo_deps(struct xbps_handle *xhp,
}
}
/*
* Pass 3: find required dependency in repository pool.
* Pass 4: find required dependency in repository pool.
* If dependency does not match add pkg into the missing
* deps array and pass to next one.
*/
@ -365,6 +376,8 @@ find_repo_deps(struct xbps_handle *xhp,
if (curpkgrdeps == NULL)
continue;
curpkgprovides = xbps_dictionary_get(curpkgd, "provides");
if (xhp->flags & XBPS_FLAG_DEBUG) {
xbps_dbg_printf(xhp, "");
for (unsigned short x = 0; x < *depth; x++)
@ -378,7 +391,7 @@ find_repo_deps(struct xbps_handle *xhp,
*/
(*depth)++;
rv = find_repo_deps(xhp, unsorted, curpkgrdeps,
pkgver_q, depth);
curpkgprovides, pkgver_q, depth);
if (rv != 0) {
xbps_dbg_printf(xhp, "Error checking %s for rundeps: %s\n",
reqpkg, strerror(rv));
@ -396,7 +409,7 @@ xbps_repository_find_deps(struct xbps_handle *xhp,
xbps_array_t unsorted,
xbps_dictionary_t repo_pkgd)
{
xbps_array_t pkg_rdeps;
xbps_array_t pkg_rdeps, pkg_provides = NULL;
const char *pkgver;
unsigned short depth = 0;
@ -410,5 +423,6 @@ xbps_repository_find_deps(struct xbps_handle *xhp,
* This will find direct and indirect deps, if any of them is not
* there it will be added into the missing_deps array.
*/
return find_repo_deps(xhp, unsorted, pkg_rdeps, pkgver, &depth);
pkg_provides = xbps_dictionary_get(repo_pkgd, "provides");
return find_repo_deps(xhp, unsorted, pkg_rdeps, pkg_provides, pkgver, &depth);
}

View File

@ -114,10 +114,7 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
* package that we want to replace we should respect
* the automatic-install object.
*/
if (xbps_match_virtual_pkg_in_dict(obj,
pattern, true) ||
xbps_match_virtual_pkg_in_dict(instd,
pkgname, false)) {
if (xbps_match_virtual_pkg_in_dict(obj, pattern)) {
xbps_dictionary_set_bool(obj,
"automatic-install", instd_auto);
}

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2009-2013 Juan Romero Pardines.
* Copyright (c) 2009-2014 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -79,7 +79,7 @@ pkgdep_find(const char *pkg)
if (xbps_pkgpattern_match(pkgver, pkg))
return pd;
/* virtualpkg expression match */
if (xbps_match_virtual_pkg_in_dict(pd->d, pkg, true))
if (xbps_match_virtual_pkg_in_dict(pd->d, pkg))
return pd;
}
@ -115,7 +115,7 @@ pkgdep_find_idx(const char *pkg)
if (xbps_pkgpattern_match(pkgver, pkg))
return idx;
/* virtualpkg expression match */
if (xbps_match_virtual_pkg_in_dict(pd->d, pkg, true))
if (xbps_match_virtual_pkg_in_dict(pd->d, pkg))
return idx;
idx++;
@ -164,9 +164,10 @@ sort_pkg_rundeps(struct xbps_handle *xhp,
xbps_array_t pkg_rundeps,
xbps_array_t unsorted)
{
xbps_array_t provides;
xbps_dictionary_t curpkgd;
struct pkgdep *lpd, *pdn;
const char *str, *tract;
const char *str;
int32_t pkgdepidx, curpkgidx;
uint32_t i, idx = 0;
int rv = 0;
@ -201,19 +202,18 @@ again:
}
if (((curpkgd = xbps_find_pkg_in_array(unsorted, str)) == NULL) &&
((curpkgd = xbps_find_virtualpkg_in_array(xhp, unsorted, str)) == NULL)) {
xbps_dbg_printf_append(xhp, "cannot find %s in unsorted array\n", str);
rv = EINVAL;
break;
}
if ((xbps_match_virtual_pkg_in_dict(curpkgd, str, true)) ||
(xbps_match_virtual_pkg_in_dict(curpkgd, str, false))) {
xbps_dbg_printf_append(xhp, "ignore wrong "
"dependency %s (depends on itself)\n", str);
continue;
if (pd->d) {
provides = xbps_dictionary_get(pd->d, "provides");
if (provides && xbps_match_virtual_pkg_in_array(provides, str)) {
xbps_dbg_printf_append(xhp, "%s is a vpkg provided by %s, ignored.\n", str, pd->name);
continue;
}
}
xbps_dictionary_get_cstring_nocopy(curpkgd,
"transaction", &tract);
lpd = pkgdep_alloc(curpkgd, str);
if (pdn == NULL) {
/*
* If package is not in the list, add to the tail