xbps_get_pkg_fulldeptree: detect pkgs depending on itself via virtual pkgs.

Reported by Duncan Overbrook.

Update NEWS with recent changes.
This commit is contained in:
Juan RP 2015-03-20 08:03:06 +01:00
parent 1eeaa99438
commit dc47dfd593
5 changed files with 83 additions and 34 deletions

6
NEWS
View File

@ -1,5 +1,11 @@
xbps-0.44.1 (???):
* libxbps: fixed xbps_get_pkg_fulldeptree() when a pkg depends on itself via
virtual packages. Reported by Duncan Overbrook.
* portableproplib: fixed a regression introduced in 0.44 resulting in EBADF
while internalizing plists.
* xbps-uunshare(8): does not fork and run cmd in the child process anymore,
replaces the execution environment with cmd instead.

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2014 Juan Romero Pardines.
* Copyright (c) 2014-2015 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -43,53 +43,60 @@ static SLIST_HEAD(pkgdep_head, pkgdep) pkgdep_list =
static xbps_dictionary_t pkgdep_pvmap;
static int
collect_rdeps(struct xbps_handle *xhp, xbps_array_t rdeps, bool rpool)
collect_rdeps(struct xbps_handle *xhp, xbps_dictionary_t pkgd, bool rpool)
{
xbps_array_t currdeps;
xbps_dictionary_t pkgd;
const char *curdep;
for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) {
xbps_array_t rdeps, currdeps, provides = NULL;
struct pkgdep *pd;
const char *pkgver;
xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
assert(pkgver);
rdeps = xbps_dictionary_get(pkgd, "run_depends");
provides = xbps_dictionary_get(pkgd, "provides");
for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) {
xbps_dictionary_t curpkgd;
const char *curdep, *curpkgver;
char *curdepname;
bool virtual = false, found = false;
xbps_array_get_cstring_nocopy(rdeps, i, &curdep);
if (rpool) {
if ((pkgd = xbps_rpool_get_pkg(xhp, curdep)) == NULL) {
pkgd = xbps_rpool_get_virtualpkg(xhp, curdep);
if ((curpkgd = xbps_rpool_get_pkg(xhp, curdep)) == NULL) {
curpkgd = xbps_rpool_get_virtualpkg(xhp, curdep);
virtual = true;
}
} else {
if ((pkgd = xbps_pkgdb_get_pkg(xhp, curdep)) == NULL) {
pkgd = xbps_pkgdb_get_virtualpkg(xhp, curdep);
if ((curpkgd = xbps_pkgdb_get_pkg(xhp, curdep)) == NULL) {
curpkgd = xbps_pkgdb_get_virtualpkg(xhp, curdep);
virtual = true;
}
}
if (pkgd == NULL) {
if (curpkgd == NULL) {
xbps_dbg_printf(xhp, "%s: cannot find `%s' dependency\n",
__func__, curdep);
return ENOENT;
}
currdeps = xbps_dictionary_get(pkgd, "run_depends");
xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
assert(pkgver);
if (virtual) {
char *p;
if (((p = xbps_pkgpattern_name(curdep)) == NULL) &&
((p = xbps_pkg_name(curdep)) == NULL))
if (((curdepname = xbps_pkgpattern_name(curdep)) == NULL) &&
((curdepname = xbps_pkg_name(curdep)) == NULL))
return EINVAL;
if (pkgdep_pvmap == NULL)
pkgdep_pvmap = xbps_dictionary_create();
xbps_dictionary_get_cstring_nocopy(curpkgd, "pkgver", &curpkgver);
currdeps = xbps_dictionary_get(curpkgd, "run_depends");
xbps_dictionary_set_cstring_nocopy(pkgdep_pvmap, p, pkgver);
free(p);
if (provides && xbps_match_pkgname_in_array(provides, curdepname)) {
xbps_dbg_printf(xhp, "%s: ignoring dependency %s "
"already in provides\n", pkgver, curdep);
free(curdepname);
continue;
}
if (virtual) {
xbps_dictionary_set_cstring_nocopy(pkgdep_pvmap, curdepname, pkgver);
}
free(curdepname);
/* uniquify dependencies, sorting will be done later */
SLIST_FOREACH(pd, &pkgdep_list, pkgdep_entries) {
if (strcmp(pd->pkg, pkgver) == 0) {
if (strcmp(pd->pkg, curpkgver) == 0) {
found = true;
break;
}
@ -97,14 +104,14 @@ collect_rdeps(struct xbps_handle *xhp, xbps_array_t rdeps, bool rpool)
if (!found) {
pd = malloc(sizeof(*pd));
assert(pd);
pd->pkg = pkgver;
pd->pkg = curpkgver;
pd->rdeps = xbps_array_copy(currdeps);
SLIST_INSERT_HEAD(&pkgdep_list, pd, pkgdep_entries);
}
if (xbps_array_count(currdeps)) {
int rv;
if ((rv = collect_rdeps(xhp, currdeps, rpool)) != 0)
if ((rv = collect_rdeps(xhp, curpkgd, rpool)) != 0)
return rv;
}
}
@ -164,6 +171,7 @@ sortfulldeptree(void)
if (found && !xbps_match_string_in_array(result, pd->pkg)) {
xbps_array_add_cstring_nocopy(result, pd->pkg);
SLIST_REMOVE(&pkgdep_list, pd, pkgdep, pkgdep_entries);
free(pd);
}
}
return result;
@ -172,7 +180,6 @@ sortfulldeptree(void)
xbps_array_t HIDDEN
xbps_get_pkg_fulldeptree(struct xbps_handle *xhp, const char *pkg, bool rpool)
{
xbps_array_t rdeps;
xbps_dictionary_t pkgd;
int rv;
@ -185,10 +192,11 @@ xbps_get_pkg_fulldeptree(struct xbps_handle *xhp, const char *pkg, bool rpool)
((pkgd = xbps_pkgdb_get_virtualpkg(xhp, pkg)) == NULL))
return NULL;
}
if ((rdeps = xbps_dictionary_get(pkgd, "run_depends"))) {
if ((rv = collect_rdeps(xhp, rdeps, rpool)) != 0)
if (pkgdep_pvmap == NULL)
pkgdep_pvmap = xbps_dictionary_create();
if ((rv = collect_rdeps(xhp, pkgd, rpool)) != 0)
return NULL;
}
return sortfulldeptree();
}

View File

@ -19,3 +19,4 @@ atf_test_program{name="preserve_files_test"}
atf_test_program{name="update_shlibs"}
atf_test_program{name="update_hold"}
atf_test_program{name="update_repolock"}
atf_test_program{name="cyclic_deps"}

View File

@ -6,7 +6,7 @@ TESTSHELL = conf_files_test issue6_test issue18_test issue20_test remove_test
TESTSHELL+= replace_test installmode_test obsoletefiles_test
TESTSHELL+= issue31_test scripts_test incorrect_deps_test
TESTSHELL+= vpkg_test install_test preserve_files_test
TESTSHELL+= update_shlibs update_hold update_repolock
TESTSHELL+= update_shlibs update_hold update_repolock cyclic_deps
EXTRA_FILES = Kyuafile
include $(TOPDIR)/mk/test.mk

View File

@ -0,0 +1,34 @@
#!/usr/bin/env atf-sh
#
atf_test_case cyclic_dep_vpkg
cyclic_dep_vpkg_head() {
atf_set "descr" "Tests for cyclic deps: pkg depends on a cyclic vpkg"
}
cyclic_dep_vpkg_body() {
mkdir some_repo
mkdir -p pkg_{A,B,C,D}/usr/bin
cd some_repo
xbps-create -A noarch -n A-1.0_1 -s "A pkg" --provides "libGL-7.11_1" --dependencies "libGL>=7.11" ../pkg_A
atf_check_equal $? 0
xbps-create -A noarch -n B-1.0_1 -s "B pkg" --dependencies "libGL>=7.11" ../pkg_B
atf_check_equal $? 0
xbps-create -A noarch -n C-1.0_1 -s "C pkg" --dependencies "B>=0" ../pkg_C
atf_check_equal $? 0
xbps-rindex -d -a $PWD/*.xbps
atf_check_equal $? 0
cd ..
xbps-install -r root --repository=$PWD/some_repo -dy C
atf_check_equal $? 0
xbps-query -r root --fulldeptree -x C
atf_check_equal $? 0
}
atf_init_test_cases() {
atf_add_test_case cyclic_dep_vpkg
}