From Fedora Project Wiki
import rpm import os import sys import getopt def Usage(): print "Usage: " + os.path.basename(sys.argv[0] ) + "[options] dir1 dir2" print "Options:" print " --set1 pathname add pathname to set1" print " --set2 pathname add pathname to set2" print " --show [same|only1|only2|newer1|newer2] what info to show" print " --debug print debugging goop" print " (default is all but same)" sys.exit(255) def debugmsg(msg): if debuggingflag: sys.stderr.write(msg) def getevr(package): if package['epoch'] ==None: return ("0", package['version'] , package['release'] , package['buildhost'] ) else: return (str(package['epoch'] ), package['version'] , package['release'] , package['buildhost'] ) def rpmcompare(package1,package2): return rpm.labelCompare((str(package1['epoch'] ), package1['version'] , package1['release'] ), (str(package2['epoch'] ), package2['version'] , package2['release'] )) def readrpminfo(dirnames,setindicator="#"): dirrpms={} for dirname in dirnames: dirlist=os.listdir(dirname) dirlist.sort() for file in dirlist: if not file.endswith(".rpm"): continue debugmsg(setindicator) fdno = os.open(dirname + "/" + file, os.O_RDONLY) hdr = ts.hdrFromFdno(fdno) os.close(fdno) if hdr['name'] in dirrpms: if rpmcompare(hdr,dirrpms[hdr['name'] ) == 1: dirrpms[hdr['name'] =hdr else: pass else: dirrpms[hdr['name'] =hdr debugmsg("\n") return dirrpms def printprettyrpmlist(rpmlist,altlist=()): packagelist=rpmlist.keys() packagelist.sort() olist=[] elist=[] vlist=[] rlist=[] blist=[] print for p in packagelist: if p not in altlist: olist.append(p) elif rpmlist[p] [0] != altlist[p] [0] : elist.append(p) elif rpmlist[p] [1] != altlist[p] [1] : vlist.append(p) elif rpmlist[p] [2] != altlist[p] [2] : if rpmlist[p] [3] .endswith(".bu.edu"): blist.append(p) else: rlist.append(p) else: olist.append(p) for p in elist: pkgvers = "%16s -> %-16s" % (altlist[p] [0] + ":" + altlist[p] [1] + "-" + altlist[p] [2] , rpmlist[p] [0] + ":" + rpmlist[p] [1] + "-" + rpmlist[p] [2] ) print "E: %-30s %s" % (p,pkgvers) for p in vlist: pkgvers = "%16s -> %-16s" % (altlist[p] [1] + "-" + altlist[p] [2] , rpmlist[p] [1] + "-" + rpmlist[p] [2] ) print "V: %-30s %s" % (p,pkgvers) for p in rlist: pkgvers = "%16s -> %-16s" % (altlist[p] [1] + "-" + altlist[p] [2] , rpmlist[p] [1] + "-" + rpmlist[p] [2] ) print "R: %-30s %s" % (p,pkgvers) for p in blist: pkgvers = "%16s -> %-16s" % (altlist[p] [1] + "-" + altlist[p] [2] , rpmlist[p] [1] + "-" + rpmlist[p] [2] ) print "B: %-30s %s" % (p,pkgvers) for p in olist: print "O: %-30s" % (p) if len(olist)>0: print print try: optlist, args = getopt.gnu_getopt(sys.argv[1:] ,"1:2:s:d",["set1=","set2=","show=","debug"] ) except getopt.GetoptError, msg: print "Error: " + str(msg) sys.exit(255) set1dirs=[] set2dirs=[] if len(args) == 2: set1dirs.append(args[0] ) set2dirs.append(args[1] ) elif len(args) > 0: Usage() validreports=( "same","only1","only2","newer1","newer2" ) reportstoshow={} for r in validreports: reportstoshow[r] =False debuggingflag=False showflagfound=False for opt, optarg in optlist: if opt=="--set1" or opt=="-1": if optarg not in set1dirs: set1dirs.append(optarg) elif opt=="--set2" or opt=="-2": if optarg not in set2dirs: set2dirs.append(optarg) elif opt=="--show" or opt=="-s": if optarg in validreports: reportstoshow[optarg] =True showflagfound=True else: Usage() elif opt=="--debug" or opt=="-d": debuggingflag=True if not showflagfound: for r in validreports: reportstoshow[r] =True reportstoshow["same"] =False if len(set1dirs)<1 or len(set2dirs)<1: Usage() for dir in set1dirs + set2dirs: flag=False if not os.path.isdir(dir): print "Directory " + dir + " doesn't exist." flag=True if flag: sys.exit(254) ts = rpm.TransactionSet() ts.setVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)) set1dirsrpms=readrpminfo(set1dirs,"1") set2dirsrpms=readrpminfo(set2dirs,"2") set1dirsonly={} set2dirsonly={} set1dirsnewer={} set2dirsolder={} set2dirsnewer={} set1dirsolder={} bothsame={} for package in set1dirsrpms: if not set2dirsrpms.has_key(package): set1dirsonly[package] =getevr(set1dirsrpms[package] ) debugmsg("+") else: rc=rpmcompare(set1dirsrpms[package] ,set2dirsrpms[package] ) if rc==0: bothsame[package] =getevr(set1dirsrpms[package] ) debugmsg("=") elif rc>0: set1dirsnewer[package] =getevr(set1dirsrpms[package] ) set2dirsolder[package] =getevr(set2dirsrpms[package] ) debugmsg(">") elif rc<0: set2dirsnewer[package] =getevr(set2dirsrpms[package] ) set1dirsolder[package] =getevr(set1dirsrpms[package] ) debugmsg("<") for package in set2dirsrpms: if not set1dirsrpms.has_key(package): debugmsg("-") set2dirsonly[package] =getevr(set2dirsrpms[package] ) else: pass debugmsg("\n") returncode=1 if reportstoshow["same"] and len(bothsame)>0: print print "------------------------------------------------------------------------------" print "In both " + str(set1dirs) + " and " + str(set2dirs) + ":" printprettyrpmlist(bothsame) returncode=0 if reportstoshow["only1"] and len(set1dirsonly)>0: print print "------------------------------------------------------------------------------" print "In " + str(set1dirs) + " only:" printprettyrpmlist(set1dirsonly) returncode=0 if reportstoshow["only2"] and len(set2dirsonly)>0: print print "------------------------------------------------------------------------------" print "In " + str(set2dirs) + " only:" printprettyrpmlist(set2dirsonly) returncode=0 if reportstoshow["newer1"] and len(set1dirsnewer)>0: print print "------------------------------------------------------------------------------" print "Newer in " + str(set1dirs) + ":" printprettyrpmlist(set1dirsnewer,set2dirsolder) returncode=0 if reportstoshow["newer2"] and len(set2dirsnewer)>0: print "------------------------------------------------------------------------------" print "Newer in " + str(set2dirs) + ":" printprettyrpmlist(set2dirsnewer,set1dirsolder) returncode=0 sys.exit(returncode)