From Fedora Project Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.







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)