summaryrefslogtreecommitdiff
path: root/apt-pkg/solver3.cc
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2024-08-12 15:27:31 +0200
committerJulian Andres Klode <julian.klode@canonical.com>2024-08-12 16:05:54 +0200
commit5d2c0e600656db690aaeb0768f3df8e71127808a (patch)
tree176549ec830513ef3841b72e0c21f0717934dd54 /apt-pkg/solver3.cc
parent4a65a92f0fe8c57342a21462eda9878c82e7d0bf (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.cc48
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)
{