[PATCH] package-cleanup output formatting patch set

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Here's a patch set for package-cleanup whose combined result is sorted package 
list output and query formatting like rpm.

My primary use case for these changes is running 
package-cleanup --leaves --all before and after some package management 
operation as well as comparing its output between boxes, sorted output 
and --qf="%{NAME}" makes the output easier to diff.

The patches are 0002: ground work, 0003: sorting, 0004: query formatting.
From 8f916d73c19958aa4a431d289185301e933f9171 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Skytt=C3=A4?= <ville.skytta@xxxxxx>
Date: Wed, 25 Mar 2009 00:41:22 +0200
Subject: [PATCH] Operate more on yum package objects rather than tuples.

---
 package-cleanup.py |   60 ++++++++++++++++++++++++---------------------------
 1 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/package-cleanup.py b/package-cleanup.py
index 11d8415..8c10b87 100755
--- a/package-cleanup.py
+++ b/package-cleanup.py
@@ -69,14 +69,13 @@ def getLocalRequires(my):
     """Get a list of all requirements in the local rpmdb"""
     pkgs = {}
     for po in my.rpmdb.returnPackages():
-        tup = po.pkgtup
         header = po.hdr
         requires = zip(
             header[rpm.RPMTAG_REQUIRENAME],
             header[rpm.RPMTAG_REQUIREFLAGS],
             header[rpm.RPMTAG_REQUIREVERSION],
         )
-        pkgs[tup] = requires
+        pkgs[po] = requires
     return pkgs
 
 def buildProviderList(my, pkgs, reportProblems):
@@ -87,7 +86,7 @@ def buildProviderList(my, pkgs, reportProblems):
     providers = {} # To speed depsolving, don't recheck deps that have 
                    # already been checked
     provsomething = {}
-    for (pkg,reqs) in pkgs.items():
+    for (po,reqs) in pkgs.items():
         for (req,flags,ver)  in reqs:
             if ver == '':
                 ver = None
@@ -102,13 +101,13 @@ def buildProviderList(my, pkgs, reportProblems):
                 if not errors:
                     print "Missing dependencies:"
                 errors = True
-                print "Package %s requires %s" % (pkg[0],
+                print "Package %s requires %s" % (po,
                   miscutils.formatRequire(req,ver,rflags))
             else:
                 for rpkg in resolve_sack:
                     # Skip packages that provide something for themselves
                     # as these can still be leaves
-                    if rpkg != pkg:
+                    if rpkg != po.pkgtup:
                         provsomething[rpkg] = 1
                 # Store the resolve_sack so that we can re-use it if another
                 # package has the same requirement
@@ -191,11 +190,8 @@ def printDupes(my):
                 continue
             dupes.append(po)
 
-    for pkg in dupes:
-        if pkg.epoch != '0':
-            print '%s:%s-%s-%s.%s' % (pkg.epoch, pkg.name, pkg.ver, pkg.rel, pkg.arch)
-        else:
-            print '%s-%s-%s.%s' % (pkg.name, pkg.ver, pkg.rel, pkg.arch)
+    for po in dupes:
+        print "%s" % po
 
 def cleanOldDupes(my, confirmed):
     """remove all the older duplicates"""
@@ -238,19 +234,14 @@ def cleanOldDupes(my, confirmed):
                  
 
 
-def _shouldShowLeaf(my, pkg, leaf_regex, exclude_devel, exclude_bin):
+def _shouldShowLeaf(my, po, leaf_regex, exclude_devel, exclude_bin):
     """
     Determine if the given pkg should be displayed as a leaf or not.
 
     Return True if the pkg should be shown, False if not.
     """
-    if pkg[0] == 'gpg-pubkey':
+    if po.name == 'gpg-pubkey':
         return False
-    pos = my.rpmdb.searchNevra(name=pkg[0], epoch=str(pkg[2]), ver=pkg[3],
-            rel=pkg[4], arch=pkg[1])
-    # This should give us an exact match
-    assert len(pos) == 1
-    po = pos[0]
     name = po.name
     if exclude_devel and name.endswith('devel'):
         return False
@@ -263,27 +254,32 @@ def _shouldShowLeaf(my, pkg, leaf_regex, exclude_devel, exclude_bin):
     return False
 
 def listLeaves(my, all_nodes, leaf_regex, exclude_devel, exclude_bin):
-    """return a packagtuple of any installed packages that
-       are not required by any other package on the system"""
+    """Print packages that are not required by any other package
+       on the system"""
+
+    # Could use my.rpmdb.returnLeafNodes() directly but it's slow
     ts = transaction.initReadOnlyTransaction()
-    leaves = ts.returnLeafNodes()
-    for pkg in leaves:
-        name = pkg[0]
-        if all_nodes or _shouldShowLeaf(my, pkg, leaf_regex, exclude_devel,
+    leaves = [list(x) for x in ts.returnLeafNodes()]
+    # Epoch can be a number, stringify to work with getInstalledPackageObject
+    for lst in leaves:
+        lst[2] = str(lst[2])
+    leaves = (my.getInstalledPackageObject(x) for x in leaves)
+
+    for po in leaves:
+        if all_nodes or _shouldShowLeaf(my, po, leaf_regex, exclude_devel,
                 exclude_bin):
-            print "%s-%s-%s.%s" % (pkg[0],pkg[3],pkg[4],pkg[1])
+            print "%s" % po
 
 def listOrphans(my):
     """ This is "yum list extras". """
     avail = my.pkgSack.simplePkgList()
     avail = set(avail)
     for po in sorted(my.rpmdb.returnPackages()):
-        (n,a,e,v,r) = po.pkgtup
-        if n == "gpg-pubkey": # Not needed as of at least 3.2.19, but meh
+        if po.name == "gpg-pubkey": # Not needed as of at least 3.2.19, but meh
             continue
 
         if po.pkgtup not in avail:
-            print "%s-%s-%s.%s" % (n, v, r, a)
+            print "%s" % po
 
 def getKernels(my):
     """return a list of all installed kernels, sorted newest to oldest"""
@@ -384,17 +380,17 @@ def removeKernels(my, count, confirmed, keepdevel):
         print "No kernel related packages to remove"
         return
 
+    toremove = [my.getInstalledPackageObject(x) for x in toremove]
+
     print "I will remove the following %s kernel related packages:" % len(toremove)
-    for kernel in toremove:
-        (n,a,e,v,r) = kernel
-        print "%s-%s-%s" % (n,v,r) 
+    for po in toremove:
+        print "%s" % po
 
     if not confirmed:
         if not userconfirm():
             sys.exit(0)
 
-    for kernel in toremove:
-        po = my.rpmdb.searchPkgTuple(kernel)[0]
+    for po in toremove:
         my.tsInfo.addErase(po)
 
     # Now perform the action transaction
-- 
1.6.0.6

From 9a361719192aa601615446f43a160c7be2e7200d Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Skytt=C3=A4?= <ville.skytta@xxxxxx>
Date: Wed, 25 Mar 2009 00:54:59 +0200
Subject: [PATCH] Sort package list output.

---
 package-cleanup.py |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/package-cleanup.py b/package-cleanup.py
index 8c10b87..236590f 100755
--- a/package-cleanup.py
+++ b/package-cleanup.py
@@ -190,7 +190,7 @@ def printDupes(my):
                 continue
             dupes.append(po)
 
-    for po in dupes:
+    for po in sorted(dupes):
         print "%s" % po
 
 def cleanOldDupes(my, confirmed):
@@ -214,9 +214,9 @@ def cleanOldDupes(my, confirmed):
     if len(removedupes) == 0:
         print "No dupes to clean"
         sys.exit(0)
-        
+
     print "I will remove the following old duplicate packages:"
-    for po in removedupes:
+    for po in sorted(removedupes):
         print "%s" % po
 
     if not confirmed:
@@ -263,7 +263,7 @@ def listLeaves(my, all_nodes, leaf_regex, exclude_devel, exclude_bin):
     # Epoch can be a number, stringify to work with getInstalledPackageObject
     for lst in leaves:
         lst[2] = str(lst[2])
-    leaves = (my.getInstalledPackageObject(x) for x in leaves)
+    leaves = sorted((my.getInstalledPackageObject(x) for x in leaves))
 
     for po in leaves:
         if all_nodes or _shouldShowLeaf(my, po, leaf_regex, exclude_devel,
@@ -380,7 +380,7 @@ def removeKernels(my, count, confirmed, keepdevel):
         print "No kernel related packages to remove"
         return
 
-    toremove = [my.getInstalledPackageObject(x) for x in toremove]
+    toremove = sorted((my.getInstalledPackageObject(x) for x in toremove))
 
     print "I will remove the following %s kernel related packages:" % len(toremove)
     for po in toremove:
-- 
1.6.0.6

From d04e1ba0b7e8918634c66ffa321906a0685d3441 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Skytt=C3=A4?= <ville.skytta@xxxxxx>
Date: Wed, 25 Mar 2009 01:01:25 +0200
Subject: [PATCH] Add query formatting.

---
 package-cleanup.py |   40 ++++++++++++++++++++++------------------
 1 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/package-cleanup.py b/package-cleanup.py
index 236590f..7f9c878 100755
--- a/package-cleanup.py
+++ b/package-cleanup.py
@@ -78,7 +78,7 @@ def getLocalRequires(my):
         pkgs[po] = requires
     return pkgs
 
-def buildProviderList(my, pkgs, reportProblems):
+def buildProviderList(my, pkgs, reportProblems, qf):
     """Resolve all dependencies in pkgs and build a dictionary of packages
      that provide something for a package other than itself"""
 
@@ -101,7 +101,7 @@ def buildProviderList(my, pkgs, reportProblems):
                 if not errors:
                     print "Missing dependencies:"
                 errors = True
-                print "Package %s requires %s" % (po,
+                print "Package %s requires %s" % (po.hdr.sprintf(qf),
                   miscutils.formatRequire(req,ver,rflags))
             else:
                 for rpkg in resolve_sack:
@@ -177,7 +177,7 @@ def findDupes(my):
     
     return refined
     
-def printDupes(my):
+def printDupes(my, qf):
     """print out the dupe listing"""
     dupedict = findDupes(my)
     dupes = []    
@@ -191,9 +191,9 @@ def printDupes(my):
             dupes.append(po)
 
     for po in sorted(dupes):
-        print "%s" % po
+        print po.hdr.sprintf(qf)
 
-def cleanOldDupes(my, confirmed):
+def cleanOldDupes(my, confirmed, qf):
     """remove all the older duplicates"""
     dupedict = findDupes(my)
     removedupes = []
@@ -217,7 +217,7 @@ def cleanOldDupes(my, confirmed):
 
     print "I will remove the following old duplicate packages:"
     for po in sorted(removedupes):
-        print "%s" % po
+        print po.hdr.sprintf(qf)
 
     if not confirmed:
         if not userconfirm():
@@ -253,7 +253,7 @@ def _shouldShowLeaf(my, po, leaf_regex, exclude_devel, exclude_bin):
         return True
     return False
 
-def listLeaves(my, all_nodes, leaf_regex, exclude_devel, exclude_bin):
+def listLeaves(my, all_nodes, leaf_regex, exclude_devel, exclude_bin, qf):
     """Print packages that are not required by any other package
        on the system"""
 
@@ -268,9 +268,9 @@ def listLeaves(my, all_nodes, leaf_regex, exclude_devel, exclude_bin):
     for po in leaves:
         if all_nodes or _shouldShowLeaf(my, po, leaf_regex, exclude_devel,
                 exclude_bin):
-            print "%s" % po
+            print po.hdr.sprintf(qf)
 
-def listOrphans(my):
+def listOrphans(my, qf):
     """ This is "yum list extras". """
     avail = my.pkgSack.simplePkgList()
     avail = set(avail)
@@ -279,7 +279,7 @@ def listOrphans(my):
             continue
 
         if po.pkgtup not in avail:
-            print "%s" % po
+            print po.hdr.sprintf(qf)
 
 def getKernels(my):
     """return a list of all installed kernels, sorted newest to oldest"""
@@ -333,7 +333,7 @@ def userconfirm():
     else:            
         return True
     
-def removeKernels(my, count, confirmed, keepdevel):
+def removeKernels(my, count, confirmed, keepdevel, qf):
     """Remove old kernels, keep at most count kernels (and always keep the running
      kernel"""
 
@@ -384,7 +384,7 @@ def removeKernels(my, count, confirmed, keepdevel):
 
     print "I will remove the following %s kernel related packages:" % len(toremove)
     for po in toremove:
-        print "%s" % po
+        print po.hdr.sprintf(qf)
 
     if not confirmed:
         if not userconfirm():
@@ -442,6 +442,9 @@ def parseArgs():
       help="Do not remove kernel-devel packages when removing kernels")
     parser.add_option("-c", dest="conffile", action="store",
                 default='/etc/yum.conf', help="config file location")
+    parser.add_option("--qf", "--queryformat", dest="qf", action="store",
+                      default='%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}',
+                      help="Query format to use for output.")
 
     (opts, args) = parser.parse_args()
     if not exactlyOne((opts.problems,opts.leaves,opts.kernels,opts.orphans, opts.dupes, opts.cleandupes)): 
@@ -460,20 +463,21 @@ def main():
         if os.geteuid() != 0:
             print "Error: Cannot remove kernels as a user, must be root"
             sys.exit(1)
-        removeKernels(my, opts.kernelcount, opts.confirmed, opts.keepdevel)
+        removeKernels(my, opts.kernelcount, opts.confirmed, opts.keepdevel,
+                      opts.qf)
         sys.exit(0)
     
     if (opts.leaves):
         listLeaves(my, opts.all_nodes, re.compile(opts.leaf_regex, re.IGNORECASE),
-                opts.exclude_devel, opts.exclude_bin)
+                opts.exclude_devel, opts.exclude_bin, opts.qf)
         sys.exit(0)
 
     if (opts.orphans):
-        listOrphans(my)
+        listOrphans(my, opts.qf)
         sys.exit(0)
 
     if opts.dupes:
-        printDupes(my)
+        printDupes(my, opts.qf)
         sys.exit(0)
 
     if opts.cleandupes:
@@ -481,7 +485,7 @@ def main():
             print "Error: Cannot remove packages as a user, must be root"
             sys.exit(1)
     
-        cleanOldDupes(my, opts.confirmed)
+        cleanOldDupes(my, opts.confirmed, opts.qf)
         sys.exit(0)
             
     if not opts.quiet:
@@ -489,7 +493,7 @@ def main():
     pkgs = getLocalRequires(my)
     if not opts.quiet:
         print "Processing all local requires"
-    provsomething = buildProviderList(my,pkgs,opts.problems)
+    provsomething = buildProviderList(my,pkgs,opts.problems,opts.qf)
     
 if __name__ == '__main__':
     main()
-- 
1.6.0.6

_______________________________________________
Yum mailing list
Yum@xxxxxxxxxxxxxxxxx
http://lists.baseurl.org/mailman/listinfo/yum

[Index of Archives]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]

  Powered by Linux