Просмотр исходного кода

support dpkg debug mode in APT::StateChanges

Gbp-Dch: Ignore
David Kalnischkies лет назад: 10
Родитель
Сommit
27f38567fe
2 измененных файлов с 121 добавлено и 59 удалено
  1. 120 58
      apt-pkg/statechanges.cc
  2. 1 1
      test/integration/test-dpkg-assert-multi-arch

+ 120 - 58
apt-pkg/statechanges.cc

@@ -3,6 +3,7 @@
 #include <apt-pkg/debsystem.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/statechanges.h>
+#include <apt-pkg/prettyprinters.h>
 
 #include <algorithm>
 #include <memory>
@@ -63,6 +64,7 @@ bool StateChanges::empty() const
 
 bool StateChanges::Save(bool const DiscardOutput)
 {
+   bool const Debug = _config->FindB("Debug::pkgDpkgPm", false);
    d->error.clear();
    if (d->hold.empty() && d->unhold.empty() && d->install.empty() && d->deinstall.empty() && d->purge.empty())
       return true;
@@ -83,75 +85,135 @@ bool StateChanges::Save(bool const DiscardOutput)
 	 // FIXME: supported only since 1.17.7 in dpkg
 	 Args.push_back("-");
 	 int dummyAvail = -1;
-	 pid_t const dpkgMergeAvail = debSystem::ExecDpkg(Args, &dummyAvail, nullptr, true);
-
-	 FILE* dpkg = fdopen(dummyAvail, "w");
-	 for (auto const &V: makeDpkgAvailable)
-	    fprintf(dpkg, "Package: %s\nVersion: 0~\nArchitecture: %s\nMaintainer: Dummy Example <dummy@example.org>\n"
-		  "Description: dummy package record\n A record is needed to put a package on hold, so here it is.\n\n", V.ParentPkg().Name(), V.Arch());
-	 fclose(dpkg);
-
-	 ExecWait(dpkgMergeAvail, "dpkg --merge-avail", true);
+	 if (Debug)
+	 {
+	    for (auto const &V: makeDpkgAvailable)
+	    {
+	       std::clog << "echo 'Dummy record for " << V.ParentPkg().FullName(false) << "' | ";
+	       std::copy(Args.begin(), Args.end(), std::ostream_iterator<std::string>(std::clog, " "));
+	       std::clog << std::endl;
+	    }
+	 }
+	 else
+	 {
+	    pid_t const dpkgMergeAvail = debSystem::ExecDpkg(Args, &dummyAvail, nullptr, true);
+
+	    FILE* dpkg = fdopen(dummyAvail, "w");
+	    for (auto const &V: makeDpkgAvailable)
+	       fprintf(dpkg, "Package: %s\nVersion: 0~\nArchitecture: %s\nMaintainer: Dummy Example <dummy@example.org>\n"
+		     "Description: dummy package record\n A record is needed to put a package on hold, so here it is.\n\n", V.ParentPkg().Name(), V.Arch());
+	    fclose(dpkg);
+
+	    ExecWait(dpkgMergeAvail, "dpkg --merge-avail", true);
+	 }
 	 Args.erase(Args.begin() + BaseArgs, Args.end());
       }
    }
    bool const dpkgMultiArch = _system->MultiArchSupported();
 
    Args.push_back("--set-selections");
-   int selections = -1;
-   pid_t const dpkgSelections = debSystem::ExecDpkg(Args, &selections, nullptr, DiscardOutput);
-
-   FILE* dpkg = fdopen(selections, "w");
-   std::string state;
-   auto const dpkgName = [&](pkgCache::VerIterator const &V) {
-      pkgCache::PkgIterator P = V.ParentPkg();
-      if (dpkgMultiArch == false)
-	 fprintf(dpkg, "%s %s\n", P.FullName(true).c_str(), state.c_str());
-      else
-	 fprintf(dpkg, "%s:%s %s\n", P.Name(), V.Arch(), state.c_str());
-   };
-   for (auto const &V: d->unhold)
+   if (Debug)
    {
-      if (V.ParentPkg()->CurrentVer != 0)
-	 state = "install";
-      else
+      std::string state;
+      auto const dpkgName = [&](pkgCache::VerIterator const &V) {
+	 pkgCache::PkgIterator P = V.ParentPkg();
+	 if (strcmp(V.Arch(), "none") == 0)
+	    ioprintf(std::clog, "echo '%s %s' | ", P.Name(), state.c_str());
+	 else if (dpkgMultiArch == false)
+	    ioprintf(std::clog, "echo '%s %s' | ", P.FullName(true).c_str(), state.c_str());
+	 else
+	    ioprintf(std::clog, "echo '%s:%s %s' | ", P.Name(), V.Arch(), state.c_str());
+	 std::copy(Args.begin(), Args.end(), std::ostream_iterator<std::string>(std::clog, " "));
+	 std::clog << std::endl;
+      };
+      for (auto const &V: d->unhold)
+      {
+	 if (V.ParentPkg()->CurrentVer != 0)
+	    state = "install";
+	 else
+	    state = "deinstall";
+	 dpkgName(V);
+      }
+      if (d->purge.empty() == false)
+      {
+	 state = "purge";
+	 std::for_each(d->purge.begin(), d->purge.end(), dpkgName);
+      }
+      if (d->deinstall.empty() == false)
+      {
 	 state = "deinstall";
-      dpkgName(V);
-   }
-   if (d->purge.empty() == false)
-   {
-      state = "purge";
-      std::for_each(d->purge.begin(), d->purge.end(), dpkgName);
-   }
-   if (d->deinstall.empty() == false)
-   {
-      state = "deinstall";
-      std::for_each(d->deinstall.begin(), d->deinstall.end(), dpkgName);
-   }
-   if (d->hold.empty() == false)
-   {
-      state = "hold";
-      std::for_each(d->hold.begin(), d->hold.end(), dpkgName);
+	 std::for_each(d->deinstall.begin(), d->deinstall.end(), dpkgName);
+      }
+      if (d->hold.empty() == false)
+      {
+	 state = "hold";
+	 std::for_each(d->hold.begin(), d->hold.end(), dpkgName);
+      }
+      if (d->install.empty() == false)
+      {
+	 state = "install";
+	 std::for_each(d->install.begin(), d->install.end(), dpkgName);
+      }
    }
-   if (d->install.empty() == false)
+   else
    {
-      state = "install";
-      std::for_each(d->install.begin(), d->install.end(), dpkgName);
-   }
-   fclose(dpkg);
+      int selections = -1;
+      pid_t const dpkgSelections = debSystem::ExecDpkg(Args, &selections, nullptr, DiscardOutput);
+
+      FILE* dpkg = fdopen(selections, "w");
+      std::string state;
+      auto const dpkgName = [&](pkgCache::VerIterator const &V) {
+	 pkgCache::PkgIterator P = V.ParentPkg();
+	 if (strcmp(V.Arch(), "none") == 0)
+	    fprintf(dpkg, "%s %s\n", P.Name(), state.c_str());
+	 else if (dpkgMultiArch == false)
+	    fprintf(dpkg, "%s %s\n", P.FullName(true).c_str(), state.c_str());
+	 else
+	    fprintf(dpkg, "%s:%s %s\n", P.Name(), V.Arch(), state.c_str());
+      };
+      for (auto const &V: d->unhold)
+      {
+	 if (V.ParentPkg()->CurrentVer != 0)
+	    state = "install";
+	 else
+	    state = "deinstall";
+	 dpkgName(V);
+      }
+      if (d->purge.empty() == false)
+      {
+	 state = "purge";
+	 std::for_each(d->purge.begin(), d->purge.end(), dpkgName);
+      }
+      if (d->deinstall.empty() == false)
+      {
+	 state = "deinstall";
+	 std::for_each(d->deinstall.begin(), d->deinstall.end(), dpkgName);
+      }
+      if (d->hold.empty() == false)
+      {
+	 state = "hold";
+	 std::for_each(d->hold.begin(), d->hold.end(), dpkgName);
+      }
+      if (d->install.empty() == false)
+      {
+	 state = "install";
+	 std::for_each(d->install.begin(), d->install.end(), dpkgName);
+      }
+      fclose(dpkg);
 
-   if (ExecWait(dpkgSelections, "dpkg --set-selections") == false)
-   {
-      std::move(d->purge.begin(), d->purge.end(), std::back_inserter(d->error));
-      d->purge.clear();
-      std::move(d->deinstall.begin(), d->deinstall.end(), std::back_inserter(d->error));
-      d->deinstall.clear();
-      std::move(d->hold.begin(), d->hold.end(), std::back_inserter(d->error));
-      d->hold.clear();
-      std::move(d->unhold.begin(), d->unhold.end(), std::back_inserter(d->error));
-      d->unhold.clear();
-      std::move(d->install.begin(), d->install.end(), std::back_inserter(d->error));
-      d->install.clear();
+      if (ExecWait(dpkgSelections, "dpkg --set-selections") == false)
+      {
+	 std::move(d->purge.begin(), d->purge.end(), std::back_inserter(d->error));
+	 d->purge.clear();
+	 std::move(d->deinstall.begin(), d->deinstall.end(), std::back_inserter(d->error));
+	 d->deinstall.clear();
+	 std::move(d->hold.begin(), d->hold.end(), std::back_inserter(d->error));
+	 d->hold.clear();
+	 std::move(d->unhold.begin(), d->unhold.end(), std::back_inserter(d->error));
+	 d->unhold.clear();
+	 std::move(d->install.begin(), d->install.end(), std::back_inserter(d->error));
+	 d->install.clear();
+      }
    }
    return d->error.empty();
 }

+ 1 - 1
test/integration/test-dpkg-assert-multi-arch

@@ -18,7 +18,7 @@ testqualifier() {
 	msgtest 'Test with' $1 'for correct qualifier mode' $2
 	#aptget install $1 -qq -o Debug::pkgDPkgPM=1 || true
 	aptget install $1 -qq -o Debug::pkgDPkgPM=1 -o Dpkg::ExplicitLastConfigure=1 > testqualifier.output 2>&1 || true
-	GIVEN="$(grep -v -- '--unpack' testqualifier.output | sed -e 's/^.*--[^u][^ ]* \([^ ]*\).*$/\1/')"
+	GIVEN="$(grep -v -- '--unpack' testqualifier.output | sed -ne 's/^.*--[rpc][^ ]* \([^ ]*\).*$/\1/p')"
 	if [ "$GIVEN" = "$2" ]; then
 		msgpass
 	else