summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-02-25 07:55:16 -0600
committerDan McGee <dan@archlinux.org>2011-02-25 07:55:16 -0600
commit2f96764058b89ff32c928a736308c5095f1ff764 (patch)
treeb85aa9d1b41b62d38f0ac8aba87bdbcd806d9375
parentd4d304cdb7b59e3b5ab7d5825404593a3476f127 (diff)
downloadpacman-2f96764058b89ff32c928a736308c5095f1ff764.tar.xz
Continue resolving dependencies rather than bailing on first error
This allows error messages emitted by the frontend to be a bit more descriptive and not have the annoying "well why didn't you tell me that the first time" problem. If a package had multiple missing deps, we would bail on the first one before rather than finish processing all missing dependencies, and only print one error message. Instead, continue through this entire set of missing deps and append all eventual errors. The added pactest tests this case, as the to be installed package has two missing dependencies. However, pactest does not actually test or see the difference in output from before and after, so it passes in both cases, but it is clearly visible in the logs. Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--lib/libalpm/deps.c36
-rw-r--r--test/pacman/tests/upgrade077.py17
2 files changed, 37 insertions, 16 deletions
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 81d8f0dd..25852fe7 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -149,12 +149,15 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)
else if(nextchild->state == -1) {
pmpkg_t *vertexpkg = vertex->data;
pmpkg_t *childpkg = nextchild->data;
+ const char *message;
+
_alpm_log(PM_LOG_WARNING, _("dependency cycle detected:\n"));
if(reverse) {
- _alpm_log(PM_LOG_WARNING, _("%s will be removed after its %s dependency\n"), vertexpkg->name, childpkg->name);
+ message =_("%s will be removed after its %s dependency\n");
} else {
- _alpm_log(PM_LOG_WARNING, _("%s will be installed before its %s dependency\n"), vertexpkg->name, childpkg->name);
+ message =_("%s will be installed before its %s dependency\n");
}
+ _alpm_log(PM_LOG_WARNING, message, vertexpkg->name, childpkg->name);
}
}
if(!found) {
@@ -670,6 +673,7 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk
alpm_list_t *preferred, alpm_list_t **packages,
alpm_list_t *remove, alpm_list_t **data)
{
+ int ret = 0;
alpm_list_t *i, *j;
alpm_list_t *targ;
alpm_list_t *deps = NULL;
@@ -701,6 +705,7 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk
/* check if one of the packages in the [*packages] list already satisfies
* this dependency */
if(_alpm_find_dep_satisfier(*packages, missdep)) {
+ _alpm_depmiss_free(miss);
continue;
}
/* check if one of the packages in the [preferred] list already satisfies
@@ -713,33 +718,32 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk
if(!spkg) {
pm_errno = PM_ERR_UNSATISFIED_DEPS;
char *missdepstring = alpm_dep_compute_string(missdep);
- _alpm_log(PM_LOG_WARNING, _("cannot resolve \"%s\", a dependency of \"%s\"\n"),
+ _alpm_log(PM_LOG_WARNING,
+ _("cannot resolve \"%s\", a dependency of \"%s\"\n"),
missdepstring, tpkg->name);
free(missdepstring);
if(data) {
- pmdepmissing_t *missd = _alpm_depmiss_new(miss->target,
- miss->depend, miss->causingpkg);
- if(missd) {
- *data = alpm_list_add(*data, missd);
- }
+ *data = alpm_list_add(*data, miss);
}
- alpm_list_free(*packages);
- *packages = packages_copy;
- alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free);
- alpm_list_free(deps);
- return(-1);
+ ret = -1;
} else {
_alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n",
alpm_pkg_get_name(spkg), alpm_pkg_get_name(tpkg));
*packages = alpm_list_add(*packages, spkg);
+ _alpm_depmiss_free(miss);
}
}
- alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free);
alpm_list_free(deps);
}
- alpm_list_free(packages_copy);
+
+ if(ret != 0) {
+ alpm_list_free(*packages);
+ *packages = packages_copy;
+ } else {
+ alpm_list_free(packages_copy);
+ }
_alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n");
- return(0);
+ return(ret);
}
/* Does pkg1 depend on pkg2, ie. does pkg2 satisfy a dependency of pkg1? */
diff --git a/test/pacman/tests/upgrade077.py b/test/pacman/tests/upgrade077.py
new file mode 100644
index 00000000..c1d7a54c
--- /dev/null
+++ b/test/pacman/tests/upgrade077.py
@@ -0,0 +1,17 @@
+self.description = "Install a package with multiple missing dependencies"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+p.depends = ["dep1", "dep2", "dep3"]
+self.addpkg(p)
+
+p2 = pmpkg("dep2")
+self.addpkg(p2)
+
+self.args = "-U %s %s" % (p.filename(), p2.filename())
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=dummy")
+for f in p.files:
+ self.addrule("!FILE_EXIST=%s" % f)