]> git.saurik.com Git - apt.git/commitdiff
pass --force-remove-essential to dpkg only if needed
authorDavid Kalnischkies <david@kalnischkies.de>
Sun, 3 Jul 2016 11:57:25 +0000 (13:57 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Wed, 10 Aug 2016 21:18:04 +0000 (23:18 +0200)
APT (usually) knows which package is essential or not, so we can avoid
passing this force flag to dpkg unconditionally  if the user hasn't
chosen a non-default essential handling obscuring the information.

apt-pkg/deb/dpkgpm.cc
test/integration/test-essential-force-loopbreak
test/integration/test-ubuntu-bug-761175-remove-purge

index 3d0fd622c5ebf56132ab49cbc962603b85ccb1b3..8938cb3d4d1509217f453e40ce4e1eb13e32de00 100644 (file)
@@ -1233,6 +1233,15 @@ void pkgDPkgPM::StopPtyMagic()                                           /*{{{*/
  */
 bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
 {
+   auto const ItemIsEssential = [](pkgDPkgPM::Item const &I) {
+      static auto const cachegen = _config->Find("pkgCacheGen::Essential");
+      if (cachegen == "none" || cachegen == "native")
+        return true;
+      if (unlikely(I.Pkg.end()))
+        return true;
+      return (I.Pkg->Flags & pkgCache::Flag::Essential) != 0;
+   };
+
    pkgPackageManager::SigINTStop = false;
    d->progress = progress;
 
@@ -1350,13 +1359,15 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
       {
         case Item::Remove:
         ADDARGC("--force-depends");
-        ADDARGC("--force-remove-essential");
+        if (std::any_of(I, J, ItemIsEssential))
+           ADDARGC("--force-remove-essential");
         ADDARGC("--remove");
         break;
 
         case Item::Purge:
         ADDARGC("--force-depends");
-        ADDARGC("--force-remove-essential");
+        if (std::any_of(I, J, ItemIsEssential))
+           ADDARGC("--force-remove-essential");
         ADDARGC("--purge");
         break;
 
index 6f7d99cb602e3b4356e3f394d90c8a2c7b16d0e1..f585e9c424b02061e3356bc03092315c265a9466 100755 (executable)
@@ -43,6 +43,9 @@ E: Internal Error, Could not early remove sysvinit:$(dpkg --print-architecture)
 
        # with enough force however …
        cp -a dpkg.status.backup rootdir/var/lib/dpkg/status
+       testsuccess aptget install systemd-sysv -y -t "$1" -o APT::Force-LoopBreak=1 -o Debug::pkgDpkgPm=1
+       cp rootdir/tmp/testsuccess.output apt.output
+       testsuccess grep -- '--force-remove-essential --remove sysvinit' apt.output
        testsuccess aptget install systemd-sysv -y -t "$1" -o APT::Force-LoopBreak=1
        testdpkginstalled 'sysvinit' 'systemd-sysv'
 }
index aae394ad8c6dad05fb97be972fedd62e7f68591c..6ae1a04e85738224a498a0c18b7bf9f389d93baa 100755 (executable)
@@ -30,6 +30,8 @@ runtests() {
        testsuccess aptget install compiz-core-${PKG} -t "${RELEASE}" "$@"
        testdpkginstalled compiz-core-${PKG}
 
+       testsuccess aptget remove compiz-core-${PKG} -y "$@" -o Debug::pkgDpkgPm=1
+       testfailure grep -- '--force-remove-essential' rootdir/tmp/testsuccess.output
        testsuccess aptget remove compiz-core-${PKG} -y "$@"
        testdpkgnotinstalled compiz-core-${PKG}
        testdpkgstatus 'rc' '1' "compiz-core-${PKG}"
@@ -61,6 +63,8 @@ The following packages will be REMOVED:
 0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
 Purg compiz-core-${PKG}" aptget purge compiz-core-${PKG} -s "$@"
        fi
+       testsuccess aptget purge compiz-core-${PKG} -y "$@" -o Debug::pkgDpkgPm=1
+       testfailure grep -- '--force-remove-essential' rootdir/tmp/testsuccess.output
        testsuccess aptget purge compiz-core-${PKG} -y "$@"
        echo -n '' > rootdir/var/lib/dpkg/available # dpkg -l < 1.16.2 reads the available file by default, where the package can be found
        testequalor2 "dpkg-query: no packages found matching compiz-core-${PKG}" "No packages found matching compiz-core-${PKG}." dpkg -l compiz-core-${PKG}