From f64932c8f7a46745094c92faff7a95539f5d00bf Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 3 Jul 2018 18:22:36 +0100 Subject: [PATCH] Add DEPENDS matching for the full dependency tree. Previously pkgin would simply consider the latest available version of a package and recurse into its dependency tree, but this could lead to issues if it was later found that the latest version is not suitable for DEPENDS. This was shown most clearly by conflicts between net/samba (3.x) and net/samba4 (4.x). Packages that pulled in net/samba and a DEPENDS of samba>=3.x<4.0 would eventually fail when trying to install devel/talloc (a dependency of net/samba4) alongside net/samba as those two packages both try to install include/talloc.h. By correctly matching DEPENDS during the full tree scan, net/samba4 is no longer considered and devel/talloc is no longer pulled in as a dependency. The implementation isn't ideal, and eventually will be replaced with better logic, but the correct behaviour is desired first (along with appropriate test cases), improvements second. --- depends.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/depends.c b/depends.c index 8034f27..b9e088d 100644 --- a/depends.c +++ b/depends.c @@ -37,9 +37,10 @@ void full_dep_tree(const char *pkgname, const char *depquery, Plisthead *pdphead) { - Pkglist *pdp; - int level; - char query[BUFSIZ] = ""; + Pkglist *pdp, *dep; + Plistnumbered *dephead; + int level; + char query[BUFSIZ]; query[0] = '\0'; if (depquery == DIRECT_DEPS) { @@ -95,7 +96,35 @@ full_dep_tree(const char *pkgname, const char *depquery, Plisthead *pdphead) break; /* set all this range to the current level */ pdp->level = level; - snprintf(query, BUFSIZ, depquery, pdp->name); + + /* + * If we're searching remote dependencies we need + * to ensure that, when there are multiple versions + * available, the one we pick matches DEPENDS. + * + * Process them in order and pick the highest version + * that matches the dependency requirement. + */ + if (depquery == DIRECT_DEPS) { + snprintf(query, BUFSIZ, + "SELECT FULLPKGNAME FROM REMOTE_PKG " + "WHERE PKGNAME = '%s' " + "ORDER BY FULLPKGNAME DESC;", pdp->name); + if ((dephead = rec_pkglist(query)) == NULL) + continue; + SLIST_FOREACH(dep, dephead->P_Plisthead, next) { + snprintf(query, BUFSIZ, + EXACT_DIRECT_DEPS, dep->full); + if (pkg_match(pdp->depend, dep->full)) + break; + } + free_pkglist(&dephead->P_Plisthead); + free(dephead); + } else { + /* LOCAL_REVERSE_DEPS */ + snprintf(query, BUFSIZ, depquery, pdp->name); + } + /* * record pdp->name's direct dependencies in head * with level = 0