libxbps: detect and ignore incorrect deps of a pkg if those are virtual pkgs.
This commit is contained in:
parent
119d059c9b
commit
bb491e2667
4
NEWS
4
NEWS
@ -1,5 +1,9 @@
|
|||||||
xbps-0.36 (???):
|
xbps-0.36 (???):
|
||||||
|
|
||||||
|
* libxbps: the dependency solver is now able to detect and ignore invalid
|
||||||
|
dependencies of a package that are depending on itself, if those are
|
||||||
|
declared as virtual packages.
|
||||||
|
|
||||||
* xbps-install(8): the -n,--dry-run option does not acquire the pkgdb file lock
|
* xbps-install(8): the -n,--dry-run option does not acquire the pkgdb file lock
|
||||||
anymore, so that any user can use this mode even without write permission to
|
anymore, so that any user can use this mode even without write permission to
|
||||||
the target pkgdb.
|
the target pkgdb.
|
||||||
|
@ -114,7 +114,7 @@ search_array_cb(struct xbps_handle *xhp _unused,
|
|||||||
for (x = 0; x < sd->npatterns; x++) {
|
for (x = 0; x < sd->npatterns; x++) {
|
||||||
bool vpkgfound = false;
|
bool vpkgfound = false;
|
||||||
|
|
||||||
if (xbps_match_virtual_pkg_in_dict(obj, sd->patterns[x], false))
|
if (xbps_match_virtual_pkg_in_dict(obj, sd->patterns[x]))
|
||||||
vpkgfound = true;
|
vpkgfound = true;
|
||||||
|
|
||||||
if ((xbps_pkgpattern_match(pkgver, sd->patterns[x])) ||
|
if ((xbps_pkgpattern_match(pkgver, sd->patterns[x])) ||
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
*
|
*
|
||||||
* This header documents the full API for the XBPS Library.
|
* This header documents the full API for the XBPS Library.
|
||||||
*/
|
*/
|
||||||
#define XBPS_API_VERSION "20140304"
|
#define XBPS_API_VERSION "20140420"
|
||||||
|
|
||||||
#ifndef XBPS_VERSION
|
#ifndef XBPS_VERSION
|
||||||
#define XBPS_VERSION "UNSET"
|
#define XBPS_VERSION "UNSET"
|
||||||
@ -909,21 +909,28 @@ int xbps_array_foreach_cb_multi(struct xbps_handle *xhp,
|
|||||||
xbps_dictionary_t dict,
|
xbps_dictionary_t dict,
|
||||||
int (*fn)(struct xbps_handle *, xbps_object_t obj, const char *, void *arg, bool *done),
|
int (*fn)(struct xbps_handle *, xbps_object_t obj, const char *, void *arg, bool *done),
|
||||||
void *arg);
|
void *arg);
|
||||||
|
/**
|
||||||
|
* Match a virtual package name or pattern by looking at proplib array
|
||||||
|
* of strings.
|
||||||
|
*
|
||||||
|
* @param[in] array Proplib array of strings.
|
||||||
|
* @param[in] str Virtual package name or package pattern to match.
|
||||||
|
*
|
||||||
|
* @return True if \a str matches a virtual package in \a array, false
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
bool xbps_match_virtual_pkg_in_array(xbps_array_t array, const char *str);
|
||||||
/**
|
/**
|
||||||
* Match a virtual package name or pattern by looking at package's
|
* Match a virtual package name or pattern by looking at package's
|
||||||
* dictionary "provides" array object.
|
* dictionary "provides" array object.
|
||||||
*
|
*
|
||||||
* @param[in] pkgd Package dictionary.
|
* @param[in] pkgd Package dictionary.
|
||||||
* @param[in] str Virtual package name or package pattern to match.
|
* @param[in] str Virtual package name or package pattern to match.
|
||||||
* @param[in] bypattern If true, \a str should be a package name,
|
|
||||||
* otherwise it should be a package pattern, i.e `foo>=0' or `foo<1'.
|
|
||||||
*
|
*
|
||||||
* @return True if \a str matches a virtual package in \a pkgd, false
|
* @return True if \a str matches a virtual package in \a pkgd, false
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
bool xbps_match_virtual_pkg_in_dict(xbps_dictionary_t pkgd,
|
bool xbps_match_virtual_pkg_in_dict(xbps_dictionary_t pkgd, const char *str);
|
||||||
const char *str,
|
|
||||||
bool bypattern);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Match any virtual package from array \a provides in they array \a rundeps
|
* Match any virtual package from array \a provides in they array \a rundeps
|
||||||
|
@ -52,11 +52,7 @@ get_pkg_in_array(xbps_array_t array, const char *str, bool virtual)
|
|||||||
* Check if package pattern matches
|
* Check if package pattern matches
|
||||||
* any virtual package version in dictionary.
|
* any virtual package version in dictionary.
|
||||||
*/
|
*/
|
||||||
if (xbps_pkgpattern_version(str))
|
found = xbps_match_virtual_pkg_in_dict(obj, str);
|
||||||
found = xbps_match_virtual_pkg_in_dict(obj, str, true);
|
|
||||||
else
|
|
||||||
found = xbps_match_virtual_pkg_in_dict(obj, str, false);
|
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
break;
|
break;
|
||||||
} else if (xbps_pkgpattern_version(str)) {
|
} 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))) {
|
while ((obj = xbps_object_iterator_next(iter))) {
|
||||||
pkgd = xbps_dictionary_get_keysym(d, obj);
|
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);
|
xbps_object_iterator_release(iter);
|
||||||
return pkgd;
|
return pkgd;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2008-2012 Juan Romero Pardines.
|
* Copyright (c) 2008-2014 Juan Romero Pardines.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -40,25 +40,27 @@
|
|||||||
* all library functions.
|
* all library functions.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
xbps_match_virtual_pkg_in_dict(xbps_dictionary_t d,
|
xbps_match_virtual_pkg_in_array(xbps_array_t a, const char *str)
|
||||||
const char *str,
|
{
|
||||||
bool bypattern)
|
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;
|
xbps_array_t provides;
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
assert(xbps_object_type(d) == XBPS_TYPE_DICTIONARY);
|
assert(xbps_object_type(d) == XBPS_TYPE_DICTIONARY);
|
||||||
|
|
||||||
if ((provides = xbps_dictionary_get(d, "provides"))) {
|
if ((provides = xbps_dictionary_get(d, "provides")))
|
||||||
if (bypattern)
|
return xbps_match_virtual_pkg_in_array(provides, str);
|
||||||
found = xbps_match_pkgpattern_in_array(provides, str);
|
|
||||||
else {
|
return false;
|
||||||
if ((xbps_match_pkgname_in_array(provides, str)) ||
|
|
||||||
(xbps_match_pkgdep_in_array(provides, str)))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -152,13 +152,14 @@ static int
|
|||||||
find_repo_deps(struct xbps_handle *xhp,
|
find_repo_deps(struct xbps_handle *xhp,
|
||||||
xbps_array_t unsorted, /* array of unsorted deps */
|
xbps_array_t unsorted, /* array of unsorted deps */
|
||||||
xbps_array_t pkg_rdeps_array, /* current pkg rundeps array */
|
xbps_array_t pkg_rdeps_array, /* current pkg rundeps array */
|
||||||
|
xbps_array_t pkg_provides, /* current pkg provides array */
|
||||||
const char *curpkg, /* current pkgver */
|
const char *curpkg, /* current pkgver */
|
||||||
unsigned short *depth) /* max recursion depth */
|
unsigned short *depth) /* max recursion depth */
|
||||||
{
|
{
|
||||||
xbps_dictionary_t curpkgd = NULL;
|
xbps_dictionary_t curpkgd = NULL;
|
||||||
xbps_object_t obj;
|
xbps_object_t obj;
|
||||||
xbps_object_iterator_t iter;
|
xbps_object_iterator_t iter;
|
||||||
xbps_array_t curpkgrdeps;
|
xbps_array_t curpkgrdeps = NULL, curpkgprovides = NULL;
|
||||||
pkg_state_t state;
|
pkg_state_t state;
|
||||||
const char *reqpkg, *pkgver_q, *reason = NULL;
|
const char *reqpkg, *pkgver_q, *reason = NULL;
|
||||||
char *pkgname, *reqpkgname;
|
char *pkgname, *reqpkgname;
|
||||||
@ -191,7 +192,16 @@ find_repo_deps(struct xbps_handle *xhp,
|
|||||||
break;
|
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.
|
* added in the transaction dictionary.
|
||||||
*/
|
*/
|
||||||
if ((curpkgd = xbps_find_pkg_in_array(unsorted, reqpkg)) ||
|
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,
|
xbps_dictionary_get_cstring_nocopy(curpkgd,
|
||||||
"pkgver", &pkgver_q);
|
"pkgver", &pkgver_q);
|
||||||
xbps_dbg_printf_append(xhp, " (%s queued)\n", pkgver_q);
|
xbps_dbg_printf_append(xhp, " (%s queued)\n", pkgver_q);
|
||||||
|
free(pkgname);
|
||||||
continue;
|
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.
|
* and its version is fully matched.
|
||||||
*/
|
*/
|
||||||
if (((curpkgd = xbps_pkgdb_get_pkg(xhp, pkgname)) == NULL) &&
|
if (((curpkgd = xbps_pkgdb_get_pkg(xhp, pkgname)) == NULL) &&
|
||||||
@ -233,7 +244,7 @@ find_repo_deps(struct xbps_handle *xhp,
|
|||||||
/* Check its state */
|
/* Check its state */
|
||||||
if ((rv = xbps_pkg_state_dictionary(curpkgd, &state)) != 0)
|
if ((rv = xbps_pkg_state_dictionary(curpkgd, &state)) != 0)
|
||||||
break;
|
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
|
* Check if required dependency is a virtual
|
||||||
* package and is satisfied by an
|
* 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
|
* If dependency does not match add pkg into the missing
|
||||||
* deps array and pass to next one.
|
* deps array and pass to next one.
|
||||||
*/
|
*/
|
||||||
@ -365,6 +376,8 @@ find_repo_deps(struct xbps_handle *xhp,
|
|||||||
if (curpkgrdeps == NULL)
|
if (curpkgrdeps == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
curpkgprovides = xbps_dictionary_get(curpkgd, "provides");
|
||||||
|
|
||||||
if (xhp->flags & XBPS_FLAG_DEBUG) {
|
if (xhp->flags & XBPS_FLAG_DEBUG) {
|
||||||
xbps_dbg_printf(xhp, "");
|
xbps_dbg_printf(xhp, "");
|
||||||
for (unsigned short x = 0; x < *depth; x++)
|
for (unsigned short x = 0; x < *depth; x++)
|
||||||
@ -378,7 +391,7 @@ find_repo_deps(struct xbps_handle *xhp,
|
|||||||
*/
|
*/
|
||||||
(*depth)++;
|
(*depth)++;
|
||||||
rv = find_repo_deps(xhp, unsorted, curpkgrdeps,
|
rv = find_repo_deps(xhp, unsorted, curpkgrdeps,
|
||||||
pkgver_q, depth);
|
curpkgprovides, pkgver_q, depth);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
xbps_dbg_printf(xhp, "Error checking %s for rundeps: %s\n",
|
xbps_dbg_printf(xhp, "Error checking %s for rundeps: %s\n",
|
||||||
reqpkg, strerror(rv));
|
reqpkg, strerror(rv));
|
||||||
@ -396,7 +409,7 @@ xbps_repository_find_deps(struct xbps_handle *xhp,
|
|||||||
xbps_array_t unsorted,
|
xbps_array_t unsorted,
|
||||||
xbps_dictionary_t repo_pkgd)
|
xbps_dictionary_t repo_pkgd)
|
||||||
{
|
{
|
||||||
xbps_array_t pkg_rdeps;
|
xbps_array_t pkg_rdeps, pkg_provides = NULL;
|
||||||
const char *pkgver;
|
const char *pkgver;
|
||||||
unsigned short depth = 0;
|
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
|
* This will find direct and indirect deps, if any of them is not
|
||||||
* there it will be added into the missing_deps array.
|
* 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);
|
||||||
}
|
}
|
||||||
|
@ -114,10 +114,7 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
|
|||||||
* package that we want to replace we should respect
|
* package that we want to replace we should respect
|
||||||
* the automatic-install object.
|
* the automatic-install object.
|
||||||
*/
|
*/
|
||||||
if (xbps_match_virtual_pkg_in_dict(obj,
|
if (xbps_match_virtual_pkg_in_dict(obj, pattern)) {
|
||||||
pattern, true) ||
|
|
||||||
xbps_match_virtual_pkg_in_dict(instd,
|
|
||||||
pkgname, false)) {
|
|
||||||
xbps_dictionary_set_bool(obj,
|
xbps_dictionary_set_bool(obj,
|
||||||
"automatic-install", instd_auto);
|
"automatic-install", instd_auto);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2009-2013 Juan Romero Pardines.
|
* Copyright (c) 2009-2014 Juan Romero Pardines.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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))
|
if (xbps_pkgpattern_match(pkgver, pkg))
|
||||||
return pd;
|
return pd;
|
||||||
/* virtualpkg expression match */
|
/* 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;
|
return pd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ pkgdep_find_idx(const char *pkg)
|
|||||||
if (xbps_pkgpattern_match(pkgver, pkg))
|
if (xbps_pkgpattern_match(pkgver, pkg))
|
||||||
return idx;
|
return idx;
|
||||||
/* virtualpkg expression match */
|
/* 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;
|
return idx;
|
||||||
|
|
||||||
idx++;
|
idx++;
|
||||||
@ -164,9 +164,10 @@ sort_pkg_rundeps(struct xbps_handle *xhp,
|
|||||||
xbps_array_t pkg_rundeps,
|
xbps_array_t pkg_rundeps,
|
||||||
xbps_array_t unsorted)
|
xbps_array_t unsorted)
|
||||||
{
|
{
|
||||||
|
xbps_array_t provides;
|
||||||
xbps_dictionary_t curpkgd;
|
xbps_dictionary_t curpkgd;
|
||||||
struct pkgdep *lpd, *pdn;
|
struct pkgdep *lpd, *pdn;
|
||||||
const char *str, *tract;
|
const char *str;
|
||||||
int32_t pkgdepidx, curpkgidx;
|
int32_t pkgdepidx, curpkgidx;
|
||||||
uint32_t i, idx = 0;
|
uint32_t i, idx = 0;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
@ -201,19 +202,18 @@ again:
|
|||||||
}
|
}
|
||||||
if (((curpkgd = xbps_find_pkg_in_array(unsorted, str)) == NULL) &&
|
if (((curpkgd = xbps_find_pkg_in_array(unsorted, str)) == NULL) &&
|
||||||
((curpkgd = xbps_find_virtualpkg_in_array(xhp, 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;
|
rv = EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((xbps_match_virtual_pkg_in_dict(curpkgd, str, true)) ||
|
if (pd->d) {
|
||||||
(xbps_match_virtual_pkg_in_dict(curpkgd, str, false))) {
|
provides = xbps_dictionary_get(pd->d, "provides");
|
||||||
xbps_dbg_printf_append(xhp, "ignore wrong "
|
if (provides && xbps_match_virtual_pkg_in_array(provides, str)) {
|
||||||
"dependency %s (depends on itself)\n", str);
|
xbps_dbg_printf_append(xhp, "%s is a vpkg provided by %s, ignored.\n", str, pd->name);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
xbps_dictionary_get_cstring_nocopy(curpkgd,
|
|
||||||
"transaction", &tract);
|
|
||||||
lpd = pkgdep_alloc(curpkgd, str);
|
lpd = pkgdep_alloc(curpkgd, str);
|
||||||
|
|
||||||
if (pdn == NULL) {
|
if (pdn == NULL) {
|
||||||
/*
|
/*
|
||||||
* If package is not in the list, add to the tail
|
* If package is not in the list, add to the tail
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2012 Juan Romero Pardines.
|
* Copyright (c) 2012-2014 Juan Romero Pardines.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -80,12 +80,9 @@ ATF_TC_BODY(match_virtual_pkg_dict_test, tc)
|
|||||||
xbps_dictionary_t d;
|
xbps_dictionary_t d;
|
||||||
|
|
||||||
d = pkgdict_init();
|
d = pkgdict_init();
|
||||||
ATF_REQUIRE_EQ(
|
ATF_REQUIRE_EQ(xbps_match_virtual_pkg_in_dict(d, "cron-daemon"), true);
|
||||||
xbps_match_virtual_pkg_in_dict(d, "cron-daemon", false), true);
|
ATF_REQUIRE_EQ(xbps_match_virtual_pkg_in_dict(d, "cron-daemon>=0"), true);
|
||||||
ATF_REQUIRE_EQ(
|
ATF_REQUIRE_EQ(xbps_match_virtual_pkg_in_dict(d, "cron-daemon>2"), false);
|
||||||
xbps_match_virtual_pkg_in_dict(d, "cron-daemon>=0", true), true);
|
|
||||||
ATF_REQUIRE_EQ(
|
|
||||||
xbps_match_virtual_pkg_in_dict(d, "cron-daemon>2", true), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ATF_TC(match_any_virtualpkg_rundeps_test);
|
ATF_TC(match_any_virtualpkg_rundeps_test);
|
||||||
|
Loading…
Reference in New Issue
Block a user