From 9b482fb51ed28ac75b6d4847729f72717f2ea431 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 5 Feb 2025 20:48:28 +0100 Subject: solver3: Support comparing packages and versions When comparing packages, we compare the best version for the package. To determine the best version, the rules for comparisons are applied normally. This allows us to mix packages and versions in a clause as the solutions for a dependency, which means we'll be able to defer the selection of a particular version of a package to a later time. --- apt-pkg/solver3.cc | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index 09ba920fa..6288912f6 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -44,21 +44,28 @@ struct APT::Solver::CompareProviders3 /*{{{*/ pkgCache::PkgIterator const Pkg; APT::Solver &Solver; - bool operator()(pkgCache::Version *AV, pkgCache::Version *BV) + pkgCache::VerIterator bestVersion(pkgCache::PkgIterator pkg) { - return (*this)(pkgCache::VerIterator(Cache, AV), pkgCache::VerIterator(Cache, BV)); + pkgCache::VerIterator res = pkg.VersionList(); + for (auto v = res; not v.end(); ++v) + res = std::max(res, v, *this); + return res; } bool operator()(Var a, Var b) { - if (auto va = a.Ver(Cache)) - { - if (auto vb = b.Ver(Cache)) - return (*this)(va, vb); - } - abort(); + pkgCache::VerIterator va = a.Ver(Cache); + pkgCache::VerIterator vb = b.Ver(Cache); + if (auto pa = a.Pkg(Cache)) + va = bestVersion(pa); + if (auto pb = b.Pkg(Cache)) + vb = bestVersion(pb); + + assert(not va.end() && not vb.end()); + return (*this)(va, vb); } bool operator()(pkgCache::VerIterator const &AV, pkgCache::VerIterator const &BV) { + assert(not AV.end() && not BV.end()); pkgCache::PkgIterator const A = AV.ParentPkg(); pkgCache::PkgIterator const B = BV.ParentPkg(); // Compare versions for the same package. FIXME: Move this to the real implementation -- cgit v1.2.3-70-g09d2