summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/deb/dpkgpm.cc21
-rw-r--r--test/integration/framework2
-rwxr-xr-xtest/integration/test-apt-get-autoremove3
3 files changed, 19 insertions, 7 deletions
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index b0700bcc6..a2c7770b3 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -1339,10 +1339,16 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
std::distance(List.cbegin(), List.cend());
ExpandPendingCalls(List, Cache);
- auto const StripAlreadyDoneFromPending = [&](APT::VersionVector & Pending) {
+ /* if dpkg told us that it has already done everything to the package we wanted it to do,
+ we shouldn't ask it for "more" later. That can e.g. happen if packages without conffiles
+ are purged as they will have pass through the purge states on remove already */
+ auto const StripAlreadyDoneFrom = [&](APT::VersionVector & Pending) {
Pending.erase(std::remove_if(Pending.begin(), Pending.end(), [&](pkgCache::VerIterator const &Ver) {
auto const PN = Ver.ParentPkg().FullName();
- return PackageOps[PN].size() <= PackageOpsDone[PN];
+ auto const POD = PackageOpsDone.find(PN);
+ if (POD == PackageOpsDone.end())
+ return false;
+ return PackageOps[PN].size() <= POD->second;
}), Pending.end());
};
@@ -1701,7 +1707,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
else if (I->Op == Item::RemovePending)
{
++I;
- StripAlreadyDoneFromPending(approvedStates.Remove());
+ StripAlreadyDoneFrom(approvedStates.Remove());
if (approvedStates.Remove().empty())
continue;
}
@@ -1710,7 +1716,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
++I;
// explicit removes of packages without conffiles passthrough the purge states instantly, too.
// Setting these non-installed packages up for purging generates 'unknown pkg' warnings from dpkg
- StripAlreadyDoneFromPending(approvedStates.Purge());
+ StripAlreadyDoneFrom(approvedStates.Purge());
if (approvedStates.Purge().empty())
continue;
std::remove_reference<decltype(approvedStates.Remove())>::type approvedRemoves;
@@ -1962,8 +1968,8 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
if (d->dpkg_error.empty() == false)
{
// no point in reseting packages we already completed removal for
- StripAlreadyDoneFromPending(approvedStates.Remove());
- StripAlreadyDoneFromPending(approvedStates.Purge());
+ StripAlreadyDoneFrom(approvedStates.Remove());
+ StripAlreadyDoneFrom(approvedStates.Purge());
APT::StateChanges undo;
auto && undoRem = approvedStates.Remove();
std::move(undoRem.begin(), undoRem.end(), std::back_inserter(undo.Install()));
@@ -1973,6 +1979,9 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
if (undo.Save(false) == false)
_error->Error("Couldn't revert dpkg selection for approved remove/purge after an error was encountered!");
}
+
+ StripAlreadyDoneFrom(currentStates.Remove());
+ StripAlreadyDoneFrom(currentStates.Purge());
if (currentStates.Save(false) == false)
_error->Error("Couldn't restore dpkg selection states which were present before this interaction!");
diff --git a/test/integration/framework b/test/integration/framework
index d40c9f356..0daf776f5 100644
--- a/test/integration/framework
+++ b/test/integration/framework
@@ -1989,7 +1989,7 @@ testaptautotestnodpkgwarning() {
if expr match "$2" '^-dy\?' >/dev/null 2>&1; then return; fi # download-only mode
shift
done
- testfailure grep '^dpkg: warning:.*ignor.*' "${TMPWORKINGDIRECTORY}/rootdir/tmp-before/${TESTCALL}.output"
+ testfailure grep '^dpkg: warning:.*\(ignor\|unknown\).*' "${TMPWORKINGDIRECTORY}/rootdir/tmp-before/${TESTCALL}.output"
}
aptautotest_aptget_install() { testaptautotestnodpkgwarning "$@"; }
diff --git a/test/integration/test-apt-get-autoremove b/test/integration/test-apt-get-autoremove
index cfee748af..8af864acb 100755
--- a/test/integration/test-apt-get-autoremove
+++ b/test/integration/test-apt-get-autoremove
@@ -152,3 +152,6 @@ Remv foo-multi2-1 [1]
Remv foo-multi2-2 [1]
Remv foo-plus-1 [1]
Remv foo-plus-2 [1]' apt autoremove -s
+
+testdpkgstatus 'pi' '1' 'unrelated'
+testsuccess apt purge unrelated -y