Browse Source

clean up default-stanzas from extended_states on write

The existing cleanup was happening only for packages which had a status
change (install -> uninstalled) which is the most frequent but no the
only case – you can e.g. set autobits explicitly with apt-mark.

This would leave stanzas in the states file declaring a package to be
manually installed – which is the default value for a package not listed
at all, so we can just as well drop it from the file.
David Kalnischkies 7 years ago
parent
commit
e5c3f3ccd9
2 changed files with 22 additions and 13 deletions
  1. 14 13
      apt-pkg/depcache.cc
  2. 8 0
      test/integration/framework

+ 14 - 13
apt-pkg/depcache.cc

@@ -274,23 +274,27 @@ bool pkgDepCache::writeStateFile(OpProgress * const /*prog*/, bool const Install
 	    continue;
 	 StateCache const &P = PkgState[pkg->ID];
 	 bool newAuto = (P.Flags & Flag::Auto);
-	 // skip not installed or now-removed ones if requested
+	 // reset to default (=manual) not installed or now-removed ones if requested
 	 if (InstalledOnly && (
 	     (pkg->CurrentVer == 0 && P.Mode != ModeInstall) ||
 	     (pkg->CurrentVer != 0 && P.Mode == ModeDelete)))
+	    newAuto = false;
+	 if (newAuto == false)
 	 {
 	    // The section is obsolete if it contains no other tag
-	    unsigned int const count = section.Count();
+	    auto const count = section.Count();
 	    if (count < 2 ||
 		(count == 2 && section.Exists("Auto-Installed")) ||
 		(count == 3 && section.Exists("Auto-Installed") && section.Exists("Architecture")))
+	    {
+	       if(debug_autoremove)
+		  std::clog << "Drop obsolete section with " << count << " fields for " << APT::PrettyPkg(this, pkg) << std::endl;
 	       continue;
-	    else
-	       newAuto = false;
+	    }
 	 }
-	 if(_config->FindB("Debug::pkgAutoRemove",false))
-	    std::clog << "Update existing AutoInstall info: " 
-		      << pkg.FullName() << std::endl;
+
+	 if(debug_autoremove)
+	    std::clog << "Update existing AutoInstall to " << newAuto << " for " << APT::PrettyPkg(this, pkg) << std::endl;
 
 	 std::vector<pkgTagSection::Tag> rewrite;
 	 rewrite.push_back(pkgTagSection::Tag::Rewrite("Architecture", pkg.Arch()));
@@ -307,7 +311,7 @@ bool pkgDepCache::writeStateFile(OpProgress * const /*prog*/, bool const Install
       if(P.Flags & Flag::Auto) {
 	 if (pkgs_seen.find(pkg.FullName()) != pkgs_seen.end()) {
 	    if(debug_autoremove)
-	       std::clog << "Skipping already written " << pkg.FullName() << std::endl;
+	       std::clog << "Skipping already written " << APT::PrettyPkg(this, pkg) << std::endl;
 	    continue;
 	 }
 	 // skip not installed ones if requested
@@ -315,14 +319,11 @@ bool pkgDepCache::writeStateFile(OpProgress * const /*prog*/, bool const Install
 	     (pkg->CurrentVer == 0 && P.Mode != ModeInstall) ||
 	     (pkg->CurrentVer != 0 && P.Mode == ModeDelete)))
 	    continue;
-	 const char* const pkgarch = pkg.Arch();
-	 if (strcmp(pkgarch, "all") == 0)
-	    continue;
 	 if(debug_autoremove)
-	    std::clog << "Writing new AutoInstall: " << pkg.FullName() << std::endl;
+	    std::clog << "Writing new AutoInstall: " << APT::PrettyPkg(this, pkg) << std::endl;
 	 std::string stanza = "Package: ";
 	 stanza.append(pkg.Name())
-	      .append("\nArchitecture: ").append(pkgarch)
+	      .append("\nArchitecture: ").append(pkg.Arch())
 	      .append("\nAuto-Installed: 1\n\n");
 	 if (OutFile.Write(stanza.c_str(), stanza.length()) == false)
 	    return false;

+ 8 - 0
test/integration/framework

@@ -2001,3 +2001,11 @@ aptautotest_aptget_purge() { testaptautotestnodpkgwarning "$@"; }
 aptautotest_apt_install() { testaptautotestnodpkgwarning "$@"; }
 aptautotest_apt_remove() { testaptautotestnodpkgwarning "$@"; }
 aptautotest_apt_purge() { testaptautotestnodpkgwarning "$@"; }
+
+testaptmarknodefaultsections() {
+	testfailure grep '^Auto-Installed: 0$' "${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/extended_states"
+}
+aptautotest_aptmark_auto() { testaptmarknodefaultsections "$@"; }
+aptautotest_aptmark_manual() { testaptmarknodefaultsections "$@"; }
+aptautotest_aptget_markauto() { testaptmarknodefaultsections "$@"; }
+aptautotest_aptget_markmanual() { testaptmarknodefaultsections "$@"; }