summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2020-04-26 21:09:14 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2020-04-27 13:49:43 +0200
commitca14e1e2c3f3c9782f374757ca4605ce7e5670ad (patch)
treecc9bb21e1e6d49e6b9b3ef857ac047c0292da863 /apt-pkg
parentf76a8d331a81bc7b102bdd4e0f8363e8a59f64f6 (diff)
Prefer upgrading installed orgroup members
In normal upgrade scenarios this is no problem as the orgroup member will be marked for upgrade already, but on a not fully upgraded system (or while you operate on a different target release) we would go with our usual "first come first serve" approach which might lead us to install another provider who comes earlier – bad if the providers conflict.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/depcache.cc98
1 files changed, 48 insertions, 50 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 03fc58f69..2254a9b5d 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -27,6 +27,7 @@
#include <algorithm>
#include <iostream>
+#include <iterator>
#include <list>
#include <set>
#include <string>
@@ -1018,52 +1019,52 @@ struct CompareProviders /*{{{*/
}
}
if (instA != instB)
- return instA == false;
+ return instA;
}
if ((A->CurrentVer == 0 || B->CurrentVer == 0) && A->CurrentVer != B->CurrentVer)
- return A->CurrentVer == 0;
+ return A->CurrentVer != 0;
// Prefer packages in the same group as the target; e.g. foo:i386, foo:amd64
if (A->Group != B->Group)
{
if (A->Group == Pkg->Group && B->Group != Pkg->Group)
- return false;
- else if (B->Group == Pkg->Group && A->Group != Pkg->Group)
return true;
+ else if (B->Group == Pkg->Group && A->Group != Pkg->Group)
+ return false;
}
// we like essentials
if ((A->Flags & pkgCache::Flag::Essential) != (B->Flags & pkgCache::Flag::Essential))
{
if ((A->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
- return false;
- else if ((B->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
return true;
+ else if ((B->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+ return false;
}
if ((A->Flags & pkgCache::Flag::Important) != (B->Flags & pkgCache::Flag::Important))
{
if ((A->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
- return false;
- else if ((B->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
return true;
+ else if ((B->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
+ return false;
}
// prefer native architecture
if (strcmp(A.Arch(), B.Arch()) != 0)
{
if (strcmp(A.Arch(), A.Cache()->NativeArch()) == 0)
- return false;
- else if (strcmp(B.Arch(), B.Cache()->NativeArch()) == 0)
return true;
+ else if (strcmp(B.Arch(), B.Cache()->NativeArch()) == 0)
+ return false;
std::vector<std::string> archs = APT::Configuration::getArchitectures();
for (std::vector<std::string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
if (*a == A.Arch())
- return false;
- else if (*a == B.Arch())
return true;
+ else if (*a == B.Arch())
+ return false;
}
// higher priority seems like a good idea
if (AV->Priority != BV->Priority)
- return AV->Priority > BV->Priority;
+ return AV->Priority < BV->Priority;
// unable to decide…
- return A->ID < B->ID;
+ return A->ID > B->ID;
}
};
/*}}}*/
@@ -1257,52 +1258,49 @@ bool pkgDepCache::MarkInstall_InstallDependencies(PkgIterator const &Pkg, unsign
}
}
- bool foundSolution = false;
- bool thereIsOnlyOne1 = Start == End;
+ pkgCacheFile CacheFile{this};
+ APT::PackageVector toUpgrade, toNewInstall;
do
{
if ((DepState[Start->ID] & DepCVer) != DepCVer)
continue;
- pkgCacheFile CacheFile(this);
- APT::VersionList verlist = APT::VersionList::FromDependency(CacheFile, Start, APT::CacheSetHelper::CANDIDATE);
- CompareProviders comp(Start);
- bool thereIsOnlyOne2 = thereIsOnlyOne1 && verlist.size() == 1;
-
- do
+ APT::VersionVector verlist = APT::VersionVector::FromDependency(CacheFile, Start, APT::CacheSetHelper::CANDIDATE);
+ std::sort(verlist.begin(), verlist.end(), CompareProviders{Start});
+ for (auto const &Ver : verlist)
{
- APT::VersionList::iterator InstVer = std::max_element(verlist.begin(), verlist.end(), comp);
- if (InstVer == verlist.end())
- break;
+ auto P = Ver.ParentPkg();
+ if (P->CurrentVer != 0)
+ toUpgrade.emplace_back(std::move(P));
+ else
+ toNewInstall.emplace_back(std::move(P));
+ }
+ } while (Start++ != End);
- pkgCache::PkgIterator InstPkg = InstVer.ParentPkg();
- if (DebugAutoInstall)
- std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name()
- << " as " << Start.DepType() << " of " << Pkg.Name() << '\n';
- if (thereIsOnlyOne2 && PkgState[Pkg->ID].Protect() && IsCriticalDep)
- {
- if (not MarkInstall(InstPkg, false, Depth + 1, false, ForceImportantDeps))
- {
- verlist.erase(InstVer);
- continue;
- }
- MarkProtected(InstPkg);
- }
- if (not MarkInstall(InstPkg, true, Depth + 1, false, ForceImportantDeps))
- {
- verlist.erase(InstVer);
+ std::move(toNewInstall.begin(), toNewInstall.end(), std::back_inserter(toUpgrade));
+ bool foundSolution = false;
+ for (auto const &InstPkg : toUpgrade)
+ {
+ if (PkgState[InstPkg->ID].CandidateVer == nullptr || PkgState[InstPkg->ID].CandidateVer == InstPkg.CurrentVer())
+ continue;
+ if (DebugAutoInstall)
+ std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.FullName()
+ << " as " << End.DepType() << " of " << Pkg.FullName() << '\n';
+ if (IsCriticalDep && toUpgrade.size() == 1 && PkgState[Pkg->ID].Protect())
+ {
+ if (not MarkInstall(InstPkg, false, Depth + 1, false, ForceImportantDeps))
continue;
- }
+ MarkProtected(InstPkg);
+ }
+ if (not MarkInstall(InstPkg, true, Depth + 1, false, ForceImportantDeps))
+ continue;
- if (toMoveAuto != nullptr && InstPkg->CurrentVer == 0)
- toMoveAuto->push_back(InstPkg);
+ if (toMoveAuto != nullptr && InstPkg->CurrentVer == 0)
+ toMoveAuto->push_back(InstPkg);
- foundSolution = true;
- break;
- } while (true);
- if (foundSolution)
- break;
- } while (Start++ != End);
+ foundSolution = true;
+ break;
+ }
if (not foundSolution && IsCriticalDep)
{
StateCache &State = PkgState[Pkg->ID];