summaryrefslogtreecommitdiff
path: root/pkgtools/pkg_install
diff options
context:
space:
mode:
authorjperkin <jperkin@pkgsrc.org>2020-07-01 09:46:04 +0000
committerjperkin <jperkin@pkgsrc.org>2020-07-01 09:46:04 +0000
commita2cea26309680a78140d1c27fde18c099d628a6a (patch)
treedf2374fb2992ec0b6a505bb6053584f93b044a93 /pkgtools/pkg_install
parent89b9ea73e48d3f4053ddc5939763aecc1d45fc3f (diff)
downloadpkgsrc-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/pkg_install')
-rw-r--r--pkgtools/pkg_install/files/add/perform.c99
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;