소스 검색

forward manual-installed bit on package disappearance

David Kalnischkies 16 년 전
부모
커밋
eb6f9bac96
3개의 변경된 파일63개의 추가작업 그리고 2개의 파일을 삭제
  1. 46 1
      apt-pkg/deb/dpkgpm.cc
  2. 15 0
      apt-pkg/deb/dpkgpm.h
  3. 2 1
      debian/changelog

+ 46 - 1
apt-pkg/deb/dpkgpm.cc

@@ -470,7 +470,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 	 std::clog << "send: '" << status.str() << "'" << endl;
 
       if (strncmp(action, "disappear", strlen("disappear")) == 0)
-	 disappearedPkgs.insert(string(pkg_or_trigger));
+	 handleDisappearAction(pkg_or_trigger);
       return;
    }
 
@@ -530,6 +530,51 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
 		<< " action: " << action << endl;
 }
 									/*}}}*/
+// DPkgPM::handleDisappearAction					/*{{{*/
+void pkgDPkgPM::handleDisappearAction(string const &pkgname)
+{
+   // record the package name for display and stuff later
+   disappearedPkgs.insert(pkgname);
+
+   pkgCache::PkgIterator Pkg = Cache.FindPkg(pkgname);
+   if (unlikely(Pkg.end() == true))
+      return;
+   // the disappeared package was auto-installed - nothing to do
+   if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto)
+      return;
+   pkgCache::VerIterator PkgVer = Pkg.CurrentVer();
+   if (unlikely(PkgVer.end() == true))
+      return;
+   /* search in the list of dependencies for (Pre)Depends,
+      check if this dependency has a Replaces on our package
+      and if so transfer the manual installed flag to it */
+   for (pkgCache::DepIterator Dep = PkgVer.DependsList(); Dep.end() != true; ++Dep)
+   {
+      if (Dep->Type != pkgCache::Dep::Depends &&
+	  Dep->Type != pkgCache::Dep::PreDepends)
+	 continue;
+      pkgCache::PkgIterator Tar = Dep.TargetPkg();
+      if (unlikely(Tar.end() == true))
+	 continue;
+      // the package is already marked as manual
+      if ((Cache[Tar].Flags & pkgCache::Flag::Auto) != pkgCache::Flag::Auto)
+	 continue;
+      pkgCache::VerIterator TarVer = Tar.CurrentVer();
+      for (pkgCache::DepIterator Rep = TarVer.DependsList(); Rep.end() != true; ++Rep)
+      {
+	 if (Rep->Type != pkgCache::Dep::Replaces)
+	    continue;
+	 if (Pkg != Rep.TargetPkg())
+	    continue;
+	 // okay, they are strongly connected - transfer manual-bit
+	 if (Debug == true)
+	    std::clog << "transfer manual-bit from disappeared »" << pkgname << "« to »" << Tar.FullName() << "«" << std::endl;
+	 Cache[Tar].Flags &= ~Flag::Auto;
+	 break;
+      }
+   }
+}
+									/*}}}*/
 // DPkgPM::DoDpkgStatusFd						/*{{{*/
 // ---------------------------------------------------------------------
 /*

+ 15 - 0
apt-pkg/deb/dpkgpm.h

@@ -32,6 +32,21 @@ class pkgDPkgPM : public pkgPackageManager
    FILE *history_out;
    string dpkg_error;
 
+   /** \brief record the disappear action and handle accordingly
+
+      dpkg let packages disappear then they have no files any longer and
+      nothing depends on them. We need to collect this as dpkg as well as
+      APT doesn't know beforehand that the package will disappear, so the
+      only possible option is to tell the user afterwards about it.
+      To enhance the experience we also try to forward the auto-install
+      flag so the disappear-causer(s) are not autoremoved next time -
+      for the transfer to happen the disappeared version needs to depend
+      on the package the flag should be forwarded to and this package
+      needs to declare a Replaces on the disappeared package.
+      \param pkgname Name of the package that disappeared
+   */
+   void handleDisappearAction(string const &pkgname);
+
    protected:
 
    // progress reporting

+ 2 - 1
debian/changelog

@@ -3,8 +3,9 @@ apt (0.7.26~exp6) UNRELEASED; urgency=low
   [ David Kalnischkies ]
   * apt-pkg/deb/dpkgpm.cc:
     - write Disappeared also to the history.log
+    - forward manual-installed bit on package disappearance
 
- -- David Kalnischkies <kalnischkies@gmail.com>  Thu, 27 May 2010 15:12:02 +0200
+ -- David Kalnischkies <kalnischkies@gmail.com>  Thu, 27 May 2010 17:34:51 +0200
 
 apt (0.7.26~exp5) experimental; urgency=low