summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2020-05-16 14:46:05 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2020-05-18 15:55:36 +0200
commitdbed89f296106f82e9fe8f866fa87a4c14b44584 (patch)
treea94d74026911c010b710793b1d2505ff5196c6ec /apt-pkg
parent57df27397b1a10e50d5876482a30b9dedb2ad219 (diff)
Propagate protected to already satisfied dependencies
The previous commit deals with negative, now we add the positive side of things as well which makes this a recursive endevour. As we can push the protected flag forward only if a single solution for a dependency exists it is easy for trees to not get it, so if resolving becomes difficult it won't help at all.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/depcache.cc69
1 files changed, 36 insertions, 33 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index a36b1865e..842630ec6 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -1074,6 +1074,9 @@ struct CompareProviders /*{{{*/
bool pkgDepCache::MarkInstall_StateChange(pkgCache::PkgIterator const &Pkg, bool AutoInst, bool FromUser) /*{{{*/
{
auto &P = (*this)[Pkg];
+ if (P.Protect() && P.InstallVer == P.CandidateVer)
+ return true;
+
P.iFlags &= ~pkgDepCache::AutoKept;
/* Target the candidate version and remove the autoflag. We reset the
@@ -1141,7 +1144,7 @@ static bool MarkInstall_CollectDependencies(pkgDepCache const &Cache, pkgCache::
if ((Cache[Dep] & pkgDepCache::DepInstall) == pkgDepCache::DepInstall)
foundSolution = true;
}
- if (foundSolution && (not propagateProctected || not Start.IsNegative()))
+ if (foundSolution && not propagateProctected)
continue;
/* Check if this dep should be consider for install.
@@ -1290,9 +1293,26 @@ static bool MarkInstall_InstallDependencies(pkgDepCache &Cache, bool const Debug
auto const Copy = Dep;
pkgCache::DepIterator Start, End;
Dep.GlobOr(Start, End);
- if (std::any_of(Start, Dep, IsSatisfiedByInstalled))
+ bool foundSolution = std::any_of(Start, Dep, IsSatisfiedByInstalled);
+ if (foundSolution && not propagateProctected)
continue;
bool const IsCriticalDep = Start.IsCritical();
+ if (foundSolution)
+ {
+ // try propagating protected to this satisfied dependency
+ if (not IsCriticalDep)
+ continue;
+ auto const possibleSolutions = getAllPossibleSolutions(Cache, Start, End, APT::CacheSetHelper::CANDANDINST, false);
+ if (possibleSolutions.size() != 1)
+ continue;
+ auto const InstPkg = possibleSolutions.begin().ParentPkg();
+ if (Cache[InstPkg].Protect())
+ continue;
+ Cache.MarkProtected(InstPkg);
+ if (not Cache.MarkInstall(InstPkg, true, Depth + 1, false, ForceImportantDeps))
+ failedToInstallSomething = true;
+ continue;
+ }
/* Check if any ImportantDep() (but not Critical) were added
* since we installed the package. Also check for deps that
@@ -1345,35 +1365,16 @@ static bool MarkInstall_InstallDependencies(pkgDepCache &Cache, bool const Debug
}
}
- pkgCacheFile CacheFile{&Cache};
- APT::PackageVector toUpgrade, toNewInstall;
- do
- {
- if ((Cache[Start] & pkgDepCache::DepCVer) != pkgDepCache::DepCVer)
- continue;
-
- APT::VersionVector verlist = APT::VersionVector::FromDependency(CacheFile, Start, APT::CacheSetHelper::CANDIDATE);
- std::sort(verlist.begin(), verlist.end(), CompareProviders{Cache, Start});
- for (auto const &Ver : verlist)
- {
- auto P = Ver.ParentPkg();
- if (P->CurrentVer != 0)
- toUpgrade.emplace_back(std::move(P));
- else
- toNewInstall.emplace_back(std::move(P));
- }
- } while (Start++ != End);
-
- std::move(toNewInstall.begin(), toNewInstall.end(), std::back_inserter(toUpgrade));
- bool foundSolution = false;
- for (auto const &InstPkg : toUpgrade)
+ auto const possibleSolutions = getAllPossibleSolutions(Cache, Start, End, APT::CacheSetHelper::CANDIDATE, true);
+ for (auto const &InstVer : possibleSolutions)
{
+ auto const InstPkg = InstVer.ParentPkg();
if (Cache[InstPkg].CandidateVer == nullptr || Cache[InstPkg].CandidateVer == InstPkg.CurrentVer())
continue;
if (DebugAutoInstall)
std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.FullName()
<< " as " << End.DepType() << " of " << Pkg.FullName() << '\n';
- if (propagateProctected && IsCriticalDep && toUpgrade.size() == 1)
+ if (propagateProctected && IsCriticalDep && possibleSolutions.size() == 1)
{
if (not Cache.MarkInstall(InstPkg, false, Depth + 1, false, ForceImportantDeps))
continue;
@@ -1415,15 +1416,17 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg, bool AutoInst,
if (P.CandidateVer == 0)
return false;
- /* Check that it is not already marked for install and that it can be
- installed */
- if ((not P.InstPolicyBroken() && not P.InstBroken()) &&
- (P.Mode == ModeInstall ||
- P.CandidateVer == (Version *)Pkg.CurrentVer()))
+ // Check that it is not already marked for install and that it can be installed
+ if (not P.Protect() && not P.InstPolicyBroken() && not P.InstBroken())
{
- if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
- return MarkKeep(Pkg, false, FromUser, Depth + 1);
- return true;
+ if (P.CandidateVer == Pkg.CurrentVer())
+ {
+ if (P.InstallVer == 0)
+ return MarkKeep(Pkg, false, FromUser, Depth + 1);
+ return true;
+ }
+ else if (P.Mode == ModeInstall)
+ return true;
}
// check if we are allowed to install the package