diff options
author | jperkin <jperkin@pkgsrc.org> | 2020-07-01 09:46:04 +0000 |
---|---|---|
committer | jperkin <jperkin@pkgsrc.org> | 2020-07-01 09:46:04 +0000 |
commit | a2cea26309680a78140d1c27fde18c099d628a6a (patch) | |
tree | df2374fb2992ec0b6a505bb6053584f93b044a93 /pkgtools | |
parent | 89b9ea73e48d3f4053ddc5939763aecc1d45fc3f (diff) | |
download | pkgsrc-a2cea26309680a78140d1c27fde18c099d628a6a.tar.gz |
pkg_install: Handle recursive upgrades correctly.
The list of dependencies held by packages during recursive upgrades was not
refreshed after dependencies were themselves upgraded, leading to failures
attempting to read +REQUIRED_BY files in package directories that no longer
exist ("registration is incomplete!"). We now only perform the package
match after the upgrades have completed.
While here, hide the warning about dependencies not being fulfilled behind
ForceDepending, as the whole point of using that mode is to ignore such
issues with the assumption that the final state after updating will be
correct.
Diffstat (limited to 'pkgtools')
-rw-r--r-- | pkgtools/pkg_install/files/add/perform.c | 99 |
1 files changed, 61 insertions, 38 deletions
diff --git a/pkgtools/pkg_install/files/add/perform.c b/pkgtools/pkg_install/files/add/perform.c index c0111998c23..c5bf251555d 100644 --- a/pkgtools/pkg_install/files/add/perform.c +++ b/pkgtools/pkg_install/files/add/perform.c @@ -1,4 +1,4 @@ -/* $NetBSD: perform.c,v 1.110 2018/02/26 23:45:01 ginsbach Exp $ */ +/* $NetBSD: perform.c,v 1.111 2020/07/01 09:46:04 jperkin Exp $ */ #if HAVE_CONFIG_H #include "config.h" #endif @@ -6,7 +6,7 @@ #if HAVE_SYS_CDEFS_H #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: perform.c,v 1.110 2018/02/26 23:45:01 ginsbach Exp $"); +__RCSID("$NetBSD: perform.c,v 1.111 2020/07/01 09:46:04 jperkin Exp $"); /*- * Copyright (c) 2003 Grant Beattie <grant@NetBSD.org> @@ -505,10 +505,12 @@ check_other_installed(struct pkg_task *pkg) continue; if (pkg_match(p->name, pkg->pkgname) == 1) continue; /* Both match, ok. */ - warnx("Dependency of %s fulfilled by %s, but not by %s", - iter, pkg->other_version, pkg->pkgname); - if (!ForceDepending) + if (!ForceDepending) { + warnx("Dependency of %s fulfilled by %s, " + "but not by %s", iter, pkg->other_version, + pkg->pkgname); status = -1; + } break; } free_plist(&plist); @@ -1102,6 +1104,40 @@ check_implicit_conflict(struct pkg_task *pkg) return status; } +/* + * Install a required dependency and verify its installation. + */ +static int +install_depend_pkg(const char *dep) +{ + /* XXX check cyclic dependencies? */ + if (Fake || NoRecord) { + if (!Force) { + warnx("Missing dependency %s\n", dep); + return 1; + } + warnx("Missing dependency %s, continuing", dep); + } + + if (pkg_do(dep, 1, 0)) { + if (!ForceDepends) { + warnx("Can't install dependency %s", dep); + return 1; + } + warnx("Can't install dependency %s, continuing", dep); + } + + if (find_best_matching_installed_pkg(dep) == NULL) { + if (!ForceDepends) { + warnx("Just installed dependency %s disappeared", dep); + return 1; + } + warnx("Missing dependency %s ignored", dep); + } + + return 0; +} + static int check_dependencies(struct pkg_task *pkg) { @@ -1112,6 +1148,9 @@ check_dependencies(struct pkg_task *pkg) status = 0; + /* + * Recursively handle dependencies, installing as required. + */ for (p = pkg->plist.head; p != NULL; p = p->next) { if (p->type == PLIST_IGNORE) { p = p->next; @@ -1119,43 +1158,27 @@ check_dependencies(struct pkg_task *pkg) } else if (p->type != PLIST_PKGDEP) continue; - best_installed = find_best_matching_installed_pkg(p->name); - - if (best_installed == NULL) { - /* XXX check cyclic dependencies? */ - if (Fake || NoRecord) { - if (!Force) { - warnx("Missing dependency %s\n", - p->name); - status = -1; - break; - } - warnx("Missing dependency %s, continuing", - p->name); - continue; - } - if (pkg_do(p->name, 1, 0)) { - if (ForceDepends) { - warnx("Can't install dependency %s, " - "continuing", p->name); - continue; - } else { - warnx("Can't install dependency %s", - p->name); - status = -1; - break; - } - } - best_installed = find_best_matching_installed_pkg(p->name); - if (best_installed == NULL && ForceDepends) { - warnx("Missing dependency %s ignored", p->name); - continue; - } else if (best_installed == NULL) { - warnx("Just installed dependency %s disappeared", p->name); + if (find_best_matching_installed_pkg(p->name) == NULL) { + if (install_depend_pkg(p->name) != 0) { status = -1; break; } } + } + + /* + * Now that all dependencies have been processed we can find the best + * matches for pkg_register_depends() to store in our +REQUIRED_BY. + */ + for (p = pkg->plist.head; p != NULL; p = p->next) { + if (p->type == PLIST_IGNORE) { + p = p->next; + continue; + } else if (p->type != PLIST_PKGDEP) + continue; + + best_installed = find_best_matching_installed_pkg(p->name); + for (i = 0; i < pkg->dep_length; ++i) { if (strcmp(best_installed, pkg->dependencies[i]) == 0) break; |