Note to the developers: this patch is more of a proof of concept / personal
solution, without changing too much of the official developers' code.
Instead of trying to alter or manipulate the already defined objects , I
decided to create and use my own. The contributions to the algorithm
are minimal.

Thank you for your report and for your interest in improving Debian!
Bogdan Purcareata
=== modified file 'cmdline/apt-get.cc'
--- cmdline/apt-get.cc  2011-09-20 12:30:31 +0000
+++ cmdline/apt-get.cc  2012-04-06 07:52:00 +0000
@@ -67,6 +67,7 @@
 #include <regex.h>
 #include <sys/wait.h>
 #include <sstream>
+#include <algorithm>
 
 #define statfs statfs64
 #define statvfs statvfs64
@@ -82,6 +83,71 @@
 ofstream devnull("/dev/null");
 unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */
 
+// class AutoRemovePackage - to be displayed in DoAutomaticRemove      /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+class AutoRemovePackage
+{
+   private:
+   class AutoRemovePackageData
+   {
+      private:
+      string Name;
+      string Version;
+
+      public:
+      AutoRemovePackageData(string name, string version)
+      {
+        Name = name;
+         Version = version;
+      }
+
+      string getName()
+      {
+        return Name;
+      }
+      string getVersion()
+      {
+        return Version;
+      }
+   };
+   vector<AutoRemovePackageData> packages;
+
+   public:
+   static bool NameComp(AutoRemovePackageData firstPkg, AutoRemovePackageData 
secondPkg)
+   {
+      return firstPkg.getName().compare(secondPkg.getName()) < 0;
+   }
+
+   void AddPackage(string name, string version){
+      packages.push_back(AutoRemovePackageData(name, version));
+   }
+   void SortPackages()
+   {
+      sort(packages.begin(), packages.end(), &NameComp);
+   }
+
+   string BuildPackageNames()
+   {
+      vector<AutoRemovePackageData>::iterator it;
+      string result;
+      for(it = packages.begin(); it < packages.end(); ++it)
+        result += it->getName() + " ";
+      return result;
+   }
+   string BuildPackageVersions()
+   {
+      vector<AutoRemovePackageData>::iterator it;
+      string result;
+      for(it = packages.begin(); it < packages.end(); ++it)
+       result += it->getVersion() + " ";
+      return result;
+   }
+
+   AutoRemovePackage() {};
+   
+};
+
 // class CacheFile - Cover class for some dependency cache functions   /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -1661,6 +1727,7 @@
    string autoremovelist, autoremoveversions;
    unsigned long autoRemoveCount = 0;
    APT::PackageSet tooMuch;
+   AutoRemovePackage autoRemove;
    // look over the cache to see what can be removed
    for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg)
    {
@@ -1697,6 +1764,7 @@
               {
                 autoremovelist += Pkg.FullName(true) + " ";
                 autoremoveversions += string(Cache[Pkg].CandVersion) + "\n";
+                autoRemove.AddPackage(Pkg.FullName(true), 
string(Cache[Pkg].CandVersion));
               }
            }
         }
@@ -1739,6 +1807,7 @@
                    {
                       autoremovelist += Pkg.FullName(true) + " ";
                       autoremoveversions += string(Cache[Pkg].CandVersion) + 
"\n";
+                      autoRemove.AddPackage(Pkg.FullName(true), 
string(Cache[Pkg].CandVersion));
                    }
                 }
                 tooMuch.erase(Pkg);
@@ -1766,6 +1835,13 @@
    // if we don't remove them, we should show them!
    if (doAutoRemove == false && (autoremovelist.empty() == false || 
autoRemoveCount != 0))
    {
+      // reconstruct the display list with ordered packages
+      autoRemove.SortPackages();
+      autoremovelist.clear();
+      autoremovelist = autoRemove.BuildPackageNames();
+      autoremoveversions.clear();
+      autoremoveversions = autoRemove.BuildPackageVersions();
+
       if (smallList == false)
         ShowList(c1out, P_("The following package was automatically installed 
and is no longer required:",
                  "The following packages were automatically installed and are 
no longer required:",

=== modified file 'debian/changelog'
--- debian/changelog    2012-04-03 19:39:06 +0000
+++ debian/changelog    2012-04-06 08:05:04 +0000
@@ -1,3 +1,11 @@
+apt (0.8.15.11+nmu1) UNRELEASED; urgency=low
+
+  * Non-maintainer upload.
+  * On package removal, the automatically installed packages list is
+    sorted alphabetically. Closes #639008.
+
+ -- Bogdan Purcareata <bogdan.purcare...@gmail.com>  Fri, 06 Apr 2012 08:03:11 
+0000
+
 apt (0.8.15.11) UNRELEASED; urgency=low
 
   * Fix typo in apt-get(8). Closes: #664833

=== modified file 'test/integration/test-bug-613420-new-garbage-dependency'
--- test/integration/test-bug-613420-new-garbage-dependency     2011-02-15 
19:47:04 +0000
+++ test/integration/test-bug-613420-new-garbage-dependency     2012-04-06 
07:54:17 +0000
@@ -22,7 +22,7 @@
 Building dependency tree...
 Reading state information...
 The following packages were automatically installed and are no longer required:
-  openoffice.org-officebean libreoffice-officebean
+  libreoffice-officebean openoffice.org-officebean
 Use 'apt-get autoremove' to remove them.
 The following extra packages will be installed:
   libreoffice-core libreoffice-officebean openoffice.org-officebean

Reply via email to