summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/depcache.cc98
-rwxr-xr-xtest/integration/test-bug-618848-always-respect-user-requests1
-rwxr-xr-xtest/integration/test-explore-or-groups-in-markinstall33
3 files changed, 75 insertions, 57 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];
diff --git a/test/integration/test-bug-618848-always-respect-user-requests b/test/integration/test-bug-618848-always-respect-user-requests
index c2e62b834..230683a99 100755
--- a/test/integration/test-bug-618848-always-respect-user-requests
+++ b/test/integration/test-bug-618848-always-respect-user-requests
@@ -18,7 +18,6 @@ Building dependency tree...
MarkDelete libdb4.8:i386 < 1.0 @ii pmK > FU=1
MarkDelete exim4-daemon-light:i386 < 1.0 @ii mK Ib > FU=0
MarkInstall exim4-daemon-heavy:i386 < none -> 1.0 @un uN Ib > FU=0
- Ignore MarkInstall of libdb4.8:i386 < 1.0 @ii pmR > as its mode (Delete) is protected
MarkDelete exim4:i386 < 1.0 @ii mK Ib > FU=0
The following packages will be REMOVED:
exim4 exim4-daemon-light libdb4.8
diff --git a/test/integration/test-explore-or-groups-in-markinstall b/test/integration/test-explore-or-groups-in-markinstall
index db97574bb..259155854 100755
--- a/test/integration/test-explore-or-groups-in-markinstall
+++ b/test/integration/test-explore-or-groups-in-markinstall
@@ -7,16 +7,28 @@ setupenvironment
configarchitecture 'amd64'
insertpackage 'unstable' 'okay' 'all' '1'
+insertpackage 'unstable' 'upgrade' 'all' '2'
insertpackage 'unstable' 'unneeded' 'all' '1'
insertpackage 'unstable' 'later' 'all' '1'
insertpackage 'unstable' 'bad-level0' 'all' '1' 'Depends: unneeded, unknown'
insertpackage 'unstable' 'bad-level1' 'all' '1' 'Depends: bad-level0'
+insertpackage 'unstable' 'bad-upgrade-level0' 'all' '2' 'Depends: unneeded, unknown'
+insertpackage 'unstable' 'bad-upgrade-level1' 'all' '2' 'Depends: bad-upgrade-level0 (>= 2)'
+
+insertinstalledpackage 'upgrade' 'all' '1'
+insertinstalledpackage 'bad-upgrade' 'all' '1'
+insertinstalledpackage 'bad-upgrade-level0' 'all' '1'
+insertinstalledpackage 'bad-upgrade-level1' 'all' '1'
insertfoos() {
- insertpackage 'unstable' "foo-${1}-level0" 'all' '1' "${2}: unknown | okay | later"
- insertpackage 'unstable' "foo-${1}-level1" 'all' '1' "${2}: bad-level0 | okay | later"
- insertpackage 'unstable' "foo-${1}-level2" 'all' '1' "${2}: bad-level1 | okay | later"
+ insertpackage 'unstable' "foo-${1}-level0" 'all' '1' "${2}: unknown | unknown | okay | later"
+ insertpackage 'unstable' "foo-${1}-level1" 'all' '1' "${2}: bad-level0 | bad-level0 | okay | later"
+ insertpackage 'unstable' "foo-${1}-level2" 'all' '1' "${2}: bad-level1 | bad-level1 | okay | later"
+
+ insertpackage 'unstable' "foo-${1}-upgrade-level0" 'all' '1' "${2}: bad-upgrade (>= 2) | okay | upgrade (>= 2) | later"
+ insertpackage 'unstable' "foo-${1}-upgrade-level1" 'all' '1' "${2}: bad-upgrade-level0 (>= 2) | bad-upgrade-level0 (>= 2) | bad-level0 | okay | upgrade (>= 2) | later"
+ insertpackage 'unstable' "foo-${1}-upgrade-level2" 'all' '1' "${2}: bad-upgrade-level1 (>= 2) | bad-upgrade-level1 (>= 2) | bad-level1 | okay | upgrade (>= 2) | later"
}
insertfoos 'd' 'Depends'
insertfoos 'r' 'Recommends'
@@ -35,14 +47,23 @@ testsuccessheadequal() {
}
checkfoos() {
msgmsg 'Install checks with foos dependency type' "$2"
- for i in 0 1 2; do
+ for level in 0 1 2; do
testsuccessheadequal 7 "Reading package lists...
Building dependency tree...
The following additional packages will be installed:
okay
The following NEW packages will be installed:
- foo-${1}-level${i} okay
-0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded." apt install foo-${1}-level${i} -s
+ foo-${1}-level${level} okay
+0 upgraded, 2 newly installed, 0 to remove and 3 not upgraded." apt install foo-${1}-level${level} -s
+ testsuccessheadequal 9 "Reading package lists...
+Building dependency tree...
+The following additional packages will be installed:
+ upgrade
+The following NEW packages will be installed:
+ foo-${1}-upgrade-level${level}
+The following packages will be upgraded:
+ upgrade
+1 upgraded, 1 newly installed, 0 to remove and $((2-${level})) not upgraded." apt install foo-${1}-upgrade-level${level} -s
done
}
checkfoos 'd' 'Depends'