diff options
| author | Julian Andres Klode <jak@debian.org> | 2025-05-28 13:57:17 +0200 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2025-05-28 13:58:04 +0200 |
| commit | 3f8162ea008b8a3330a1113a94bc654f05000660 (patch) | |
| tree | ca4964720d28be2484cf4e962fa42c30a2a770d5 | |
| parent | adb67fa7abf9eb30d312fdd3284f9d86a2899cb2 (diff) | |
solver3: Only merge dependencies on the same package
Avoid or groups and dependencies on different (virtual) packages,
to avoid some common pitfalls like the added xorg test case.
| -rw-r--r-- | apt-pkg/solver3.cc | 20 | ||||
| -rwxr-xr-x | test/integration/test-ubuntu-bug-2111792-intersecting-dependencies | 53 |
2 files changed, 67 insertions, 6 deletions
diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index 95cff96f3..a458acb0b 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -673,18 +673,26 @@ static bool SameOrGroup(pkgCache::DepIterator a, pkgCache::DepIterator b) const APT::Solver::Clause *APT::Solver::RegisterClause(Clause &&clause) { auto &clauses = (*this)[clause.reason].clauses; - - if (not clause.negative) + pkgCache::DepIterator dep(cache, clause.dep); + + // Merge dependencies on the same name into a single one, and restrict their solution space. + // For example, given dependencies on + // bar Depends: pkg (<< 3), pkg (>> 2) + // foo Provides: pkg (= 1) + // The solution must always be pkg (= 2) and not say pkg (= 3), foo. + // FIXME: This would be nice to merge across or groups too, but we can't do that yet. + if (not clause.negative && not dep.end() && not(dep->CompareOp & pkgCache::Dep::Or)) { - // If we get multiple dependencies of the same class on related sets of packages, - // intersect them. In particular this deals with dependencies of the form - // Depends: pkg (>= 1-1), pkg (<= 1-1.1) - // which is a common pattern used to express dependencies on the same source version. bool merged = false; for (auto const &earlierClause : clauses) { if (earlierClause->negative) continue; + // Skip dependencies with or groups or dependencies on different names + if (pkgCache::DepIterator earlierDep(cache, earlierClause->dep); + earlierDep.end() || (earlierDep->CompareOp & pkgCache::Dep::Or) || + earlierDep.TargetPkg() != dep.TargetPkg()) + continue; if (std::none_of(earlierClause->solutions.begin(), earlierClause->solutions.end(), [&clause](auto earlierSol) { return std::find(clause.solutions.begin(), clause.solutions.end(), diff --git a/test/integration/test-ubuntu-bug-2111792-intersecting-dependencies b/test/integration/test-ubuntu-bug-2111792-intersecting-dependencies index 86866b233..b63991aa4 100755 --- a/test/integration/test-ubuntu-bug-2111792-intersecting-dependencies +++ b/test/integration/test-ubuntu-bug-2111792-intersecting-dependencies @@ -24,6 +24,16 @@ insertpackage 'unstable' 'git-rec-ng' 'amd64,i386' '1:2.26.2-1' 'Recommends: git Depends: git (<< 1:2.26.2-.)' insertpackage 'unstable' 'chaos-actor' 'amd64,i386' '1' 'Provides: git (2:1)' +# Another test case we don't want to merge +insertpackage 'unstable' 'xserver-xorg' 'amd64,i386' '1' 'Depends: xserver-xorg-input-all | xorg-driver-input, xserver-xorg-video-all | xorg-driver-video, xorg-driver-input, xorg-driver-video' +insertpackage 'unstable' 'xserver-xorg-noalt' 'amd64,i386' '1' 'Depends: xorg-driver-input, xorg-driver-video' + + +insertpackage 'unstable' 'xserver-xorg-input-all' 'amd64,i386' '1' 'Provides: xorg-driver-input' +insertpackage 'unstable' 'xserver-xorg-video-all' 'amd64,i386' '1' 'Provides: xorg-driver-video' +insertpackage 'unstable' 'xorgxrdp' 'amd64,i386' '1' 'Provides: xorg-driver-input, xorg-driver-video +Priority: extra' + setupaptarchive msgmsg 'The setup is' 'fine' @@ -178,3 +188,46 @@ The following NEW packages will be installed: 0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded. Inst git-rec-ng (1:2.26.2-1 unstable [amd64]) Conf git-rec-ng (1:2.26.2-1 unstable [amd64])' apt install git-rec-ng -s + +msgmsg 'Check that we do not merge unrelated things' + +testsuccessequal 'Reading package lists... +Building dependency tree... +Solving dependencies... +The following additional packages will be installed: + xserver-xorg-input-all xserver-xorg-video-all +The following NEW packages will be installed: + xserver-xorg xserver-xorg-input-all xserver-xorg-video-all +0 upgraded, 3 newly installed, 0 to remove and 2 not upgraded. +Inst xserver-xorg-input-all (1 unstable [amd64]) +Inst xserver-xorg-video-all (1 unstable [amd64]) +Inst xserver-xorg (1 unstable [amd64]) +Conf xserver-xorg-input-all (1 unstable [amd64]) +Conf xserver-xorg-video-all (1 unstable [amd64]) +Conf xserver-xorg (1 unstable [amd64])' apt install -s xserver-xorg + +testsuccessequal 'Reading package lists... +Building dependency tree... +Solving dependencies... +The following additional packages will be installed: + xserver-xorg-input-all xserver-xorg-video-all +The following NEW packages will be installed: + xserver-xorg-input-all xserver-xorg-noalt xserver-xorg-video-all +0 upgraded, 3 newly installed, 0 to remove and 2 not upgraded. +Inst xserver-xorg-input-all (1 unstable [amd64]) +Inst xserver-xorg-video-all (1 unstable [amd64]) +Inst xserver-xorg-noalt (1 unstable [amd64]) +Conf xserver-xorg-input-all (1 unstable [amd64]) +Conf xserver-xorg-video-all (1 unstable [amd64]) +Conf xserver-xorg-noalt (1 unstable [amd64])' apt install -s xserver-xorg-noalt + +testsuccessequal 'Reading package lists... +Building dependency tree... +Solving dependencies... +The following NEW packages will be installed: + xorgxrdp xserver-xorg +0 upgraded, 2 newly installed, 0 to remove and 2 not upgraded. +Inst xorgxrdp (1 unstable [amd64]) +Inst xserver-xorg (1 unstable [amd64]) +Conf xorgxrdp (1 unstable [amd64]) +Conf xserver-xorg (1 unstable [amd64])' apt install -s xserver-xorg xorgxrdp |
