diff options
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/deb/debmetaindex.cc | 2 | ||||
-rw-r--r-- | apt-pkg/solver3.cc | 48 | ||||
-rw-r--r-- | apt-pkg/solver3.h | 5 |
3 files changed, 42 insertions, 13 deletions
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 5158931..266313b 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -817,6 +817,8 @@ bool debReleaseIndex::SetSignedBy(std::string const &pSignedBy) else { auto const normalSignedBy = NormalizeSignedBy(pSignedBy, true); + if (normalSignedBy.empty() == true) + return true; if (normalSignedBy != SignedBy) return _error->Error(_("Conflicting values set for option %s regarding source %s %s: %s != %s"), "Signed-By", URI.c_str(), Dist.c_str(), SignedBy.c_str(), normalSignedBy.c_str()); } diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index 0aec1ec..2ba6f60 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) { diff --git a/apt-pkg/solver3.h b/apt-pkg/solver3.h index 96faaa6..33067a0 100644 --- a/apt-pkg/solver3.h +++ b/apt-pkg/solver3.h @@ -104,8 +104,9 @@ class Solver return verStates[V->ID]; } - std::vector<char> pkgObsolete; - bool Obsolete(pkgCache::PkgIterator pkg); + mutable std::vector<char> pkgObsolete; + bool Obsolete(pkgCache::PkgIterator pkg) const; + bool ObsoletedByNewerSourceVersion(pkgCache::VerIterator cand) const; // \brief Heap of the remaining work. // |