diff options
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 25 | ||||
-rwxr-xr-x | test/integration/test-crossgrades | 32 |
2 files changed, 50 insertions, 7 deletions
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index abf91fe2a..d76b59449 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1525,11 +1525,30 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) continue; auto const Grp = I->Pkg.Group(); - size_t installedInstances = 0; + size_t installedInstances = 0, wannabeInstances = 0; + bool multiArchInstances = false; for (auto Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg)) - if (Pkg->CurrentVer != 0 || Cache[Pkg].Install()) + { + if (Pkg->CurrentVer != 0) + { ++installedInstances; - if (installedInstances == 2) + if (Cache[Pkg].Delete() == false) + ++wannabeInstances; + } + else if (PackageOps.find(Pkg.FullName()) != PackageOps.end()) + ++wannabeInstances; + if (multiArchInstances == false) + { + auto const V = Cache[Pkg].InstVerIter(Cache); + if (V.end() == false && (Pkg->CurrentVer == 0 || V != Pkg.CurrentVer())) + multiArchInstances = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same); + } + } + /* theoretically the installed check would be enough as some wannabe will + be first and hence be the crossgrade we were looking for, but #844300 + prevents this so we keep these situations explicit removes. + It is also the reason why neither of them can be a M-A:same package */ + if (installedInstances == 1 && wannabeInstances == 1 && multiArchInstances == false) { auto const FirstInstall = std::find_if_not(I, List.end(), [](Item const &i) { return i.Op == Item::Remove || i.Op == Item::Purge; }); diff --git a/test/integration/test-crossgrades b/test/integration/test-crossgrades index 30195d30f..6398e7e7f 100755 --- a/test/integration/test-crossgrades +++ b/test/integration/test-crossgrades @@ -26,8 +26,24 @@ singleinstance() { testdpkgnotinstalled 'crosser:i386' 'unrelated' testdpkginstalled 'crosser:amd64' - testsuccess apt purge crosser:amd64 -y --planner $1 - testdpkgnotinstalled 'crosser:amd64' + testsuccess apt install crosser:armel=3 -y -o Debug::pkgDpkgPm=1 -o Dpkg::Use-Pty=0 --purge --planner $1 + cp -a rootdir/tmp/testsuccess.output crosser.output + testsuccess grep -- '--remove.*crosser.*' crosser.output + testsuccess grep -- '--purge' crosser.output + testsuccess apt install crosser:armel=3 -y -o Debug::pkgDPkgProgressReporting=1 -o Dpkg::Use-Pty=0 --purge --planner $1 + testdpkgnotinstalled 'crosser:i386' 'crosser:amd64' 'unrelated' + testdpkginstalled 'crosser:armel' + + testsuccess apt install crosser=1 -y -o Debug::pkgDpkgPm=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades + cp -a rootdir/tmp/testsuccess.output crosser.output + testsuccess grep -- '--remove.*crosser.*' crosser.output + testsuccess grep -- '--purge' crosser.output + testsuccess apt install crosser=1 -y -o Debug::pkgDPkgProgressReporting=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades + testdpkgnotinstalled 'crosser:armel' 'crosser:amd64' 'unrelated' + testdpkginstalled 'crosser:i386' + + testsuccess apt purge crosser:i386 -y --planner $1 + testdpkgnotinstalled 'crosser:i386' } singleinstance 'internal' singleinstance 'apt' @@ -52,7 +68,15 @@ multiinstance() { testdpkgnotinstalled 'crosser:amd64' 'unrelated' testdpkginstalled 'crosser:i386' 'crosser:armel' - testsuccess apt purge crosser:i386 crosser:armel -y --planner $1 - testdpkgnotinstalled 'crosser:i386' 'crosser:armel' 'unrelated' + testsuccess apt install crosser:i386- crosser:armel=1 -y -o Debug::pkgDpkgPm=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades + cp -a rootdir/tmp/testsuccess.output crosser.output + testsuccess grep -- '--remove.*crosser.*' crosser.output + testsuccess grep -- '--purge' crosser.output + testsuccess apt install crosser:i386- crosser:armel=1 -y -o Debug::pkgDPkgProgressReporting=1 -o Dpkg::Use-Pty=0 --purge --planner $1 --allow-downgrades + testdpkgnotinstalled 'crosser:amd64' 'crosser:i386' 'unrelated' + testdpkginstalled 'crosser:armel' + + testsuccess apt purge crosser:armel -y --planner $1 -o Debug::pkgDPkgProgressReporting=1 + testdpkgnotinstalled 'crosser:i386' 'crosser:armel' 'crosser:amd64' 'unrelated' } multiinstance 'internal' |