diff options
| author | Julian Andres Klode <julian.klode@canonical.com> | 2024-08-12 15:27:31 +0200 |
|---|---|---|
| committer | Julian Andres Klode <julian.klode@canonical.com> | 2024-08-12 16:05:54 +0200 |
| commit | 5d2c0e600656db690aaeb0768f3df8e71127808a (patch) | |
| tree | 176549ec830513ef3841b72e0c21f0717934dd54 /apt-pkg/solver3.cc | |
| parent | 4a65a92f0fe8c57342a21462eda9878c82e7d0bf (diff) | |
Fix obsoleted-by handling for experimental
Basically this boils down to checking that the priority of the
source candidate candidate is higher or equal than the priority
of the package's candidate that is being under consideration.
It stands to reason if we maybe we should actually calculate a
source candidate version; this will look similar but may perhaps
perform slightly different.
Diffstat (limited to 'apt-pkg/solver3.cc')
| -rw-r--r-- | apt-pkg/solver3.cc | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index 0aec1ecba..2ba6f6065 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -247,8 +247,39 @@ std::string APT::Solver::WhyStr(Reason reason) return outstr; } -bool APT::Solver::Obsolete(pkgCache::PkgIterator pkg) +// This is essentially asking whether any other binary in the source package has a higher candidate +// version. This pretends that each package is installed at the same source version as the package +// under consideration. +bool APT::Solver::ObsoletedByNewerSourceVersion(pkgCache::VerIterator cand) const { + const auto pkg = cand.ParentPkg(); + const int candPriority = policy.GetPriority(cand); + + for (auto ver = cand.Cache()->FindGrp(cand.SourcePkgName()).VersionsInSource(); not ver.end(); ver = ver.NextInSource()) + { + // We are only interested in other packages in the same source package; built for the same architecture. + if (ver->ParentPkg == cand->ParentPkg || ver.ParentPkg()->Arch != cand.ParentPkg()->Arch || cache.VS->CmpVersion(ver.SourceVerStr(), cand.SourceVerStr()) <= 0) + continue; + + // We also take equal priority here, given that we have a higher version + const int priority = policy.GetPriority(ver, true); + if (priority == 0 || priority < candPriority) + continue; + + pkgObsolete[pkg->ID] = 2; + if (debug >= 3) + std::cerr << "Obsolete: " << cand.ParentPkg().FullName() << "=" << cand.VerStr() << " due to " << ver.ParentPkg().FullName() << "=" << ver.VerStr() << "\n"; + return true; + } + + return false; +} + +bool APT::Solver::Obsolete(pkgCache::PkgIterator pkg) const +{ + if (pkgObsolete[pkg->ID] != 0) + return pkgObsolete[pkg->ID] == 2; + auto ver = policy.GetCandidateVer(pkg); if (ver.end() && not StrictPinning) @@ -256,18 +287,13 @@ bool APT::Solver::Obsolete(pkgCache::PkgIterator pkg) if (ver.end()) { std::cerr << "Obsolete: " << pkg.FullName() << " - not installable\n"; + pkgObsolete[pkg->ID] = 2; return true; } - if (pkgObsolete[pkg->ID] != 0) - return pkgObsolete[pkg->ID] == 2; - for (auto bin = ver.Cache()->FindGrp(ver.SourcePkgName()).VersionsInSource(); not bin.end(); bin = bin.NextInSource()) - if (bin != ver && bin.ParentPkg()->Arch == ver.ParentPkg()->Arch && bin->ParentPkg != ver->ParentPkg && (not StrictPinning || policy.GetCandidateVer(bin.ParentPkg()) == bin) && _system->VS->CmpVersion(bin.SourceVerStr(), ver.SourceVerStr()) > 0) - { - pkgObsolete[pkg->ID] = 2; - if (debug >= 3) - std::cerr << "Obsolete: " << ver.ParentPkg().FullName() << "=" << ver.VerStr() << " due to " << bin.ParentPkg().FullName() << "=" << bin.VerStr() << "\n"; - return true; - } + + if (ObsoletedByNewerSourceVersion(ver)) + return true; + for (auto file = ver.FileList(); !file.end(); file++) if ((file.File()->Flags & pkgCache::Flag::NotSource) == 0) { |
