A little script to help resolve dependencies on installed packages (RPM,Linux,Python)

Warren Postma warrenpstma at h0tma1l.c0m
Tue Feb 11 01:17:21 EST 2003


I don't know if there was any easy way to do 
this already, but what I wanted to do was take a base
package (like qt-3.0) and see what packages depend on that
package, and then what packages depend on those, and so on.
Recursion. Ooh. Script time.  So here's what I wrote (python 2.x).

I am posting this on both the comp.lang.python and linux.redhat.misc
groups in hopes that (a) it might prove useful to someone searching 
for a little script like this, or (b) that someone might point out to me
that there was in fact a way to do this from the rpm command without 
invoking RPM potentially dozens or hundreds of times (the way I'm doing it
here).

Attached is the list of things that would break if you took qt-3.0 
off your redhat-8 box (ie sample script output) and after that is the
script itself.  Interesting factoid: total KDE packages installed on my
system, including kdevelop, is over 160 megabytes. I'm not complaining. I
think KDE is great. (I think redhat's hacked up KDE 3.0 is an example of how to
have the road to hell with your Good Intentions, though.)

Hope this is of interest to someone:

-- sample output from command line "python2 rpmhack.py qt-3.0" --

#  qt-3.0   has  28  dependant packages:
##############################################################################
# Feature                    Size       PackageName
##############################################################################
kcharselect                    130106       kcharselect-3.0.3-3
kdeaddons-kate                 2910895      kdeaddons-kate-3.0.3-1
kdeaddons-kicker               210455       kdeaddons-kicker-3.0.3-1
kdeaddons-knewsticker          31988        kdeaddons-knewsticker-3.0.3-1
kdeaddons-konqueror            942069       kdeaddons-konqueror-3.0.3-1
kdeadmin                       3107902      kdeadmin-3.0.3-3
kdeartwork-screensavers        1554756      kdeartwork-screensavers-3.0.3-3
kdebase                        40211160     kdebase-3.0.3-13
kdebase-devel                  179569       kdebase-devel-3.0.3-13
kdelibs                        27916386     kdelibs-3.0.3-8.3
kdelibs-devel                  22809546     kdelibs-devel-3.0.3-8
kdenetwork-devel               307928       kdenetwork-devel-3.0.3-3
kdenetwork-libs                1035512      kdenetwork-libs-3.0.3-3
kdeutils-laptop                318523       kdeutils-laptop-3.0.3-3
kdevelop                       19136514     kdevelop-2.1.3-3
kdf                            726802       kdf-3.0.3-3
kedit                          261774       kedit-3.0.3-3
kfloppy                        98093        kfloppy-3.0.3-3
khexedit                       881858       khexedit-3.0.3-3
klprfax                        137030       klprfax-3.0.3-3
kmail                          2780268      kmail-3.0.3-3
knewsticker                    1191574      knewsticker-3.0.3-3
kpppload                       154892       kpppload-1.04-43
kregexpeditor                  784631       kregexpeditor-3.0.3-3
ktimer                         84323        ktimer-3.0.3-3
qt-designer                    5647207      qt-designer-3.0.5-17
qt-devel                       31406759     qt-devel-3.0.5-17
sip                            92462        sip-20021210-1
#                 TOTAL SIZE: 165050982

# (apologies for any usenet-tab-breakage or line wrapping
# if anyone wants an unmangled copy, just email me.)
-- begin script rpmhack.py --

#!/usr/bin/python2
"""
  rpmhack.py
  Warren Postma (warren.postma at sympatico.ca)
 Use some quick hackery to get a complete list of --whatrequires x,
 and then from that list, keep recursing till you hopefully find the
 entire dependency tree.
"""
import os
import sys
import string

def noversion(name):
	"return first part of an rpm package name before the version number"
	result=''
	for i in name:
		if (i in string.digits)and(result[-1]=='-'):
	          return result[:-1]
		else:
	          result = result + i
	return result

def requires(basename,collectdeps={}):
	lastcommand='rpm -q --whatrequires '+basename
	lines = os.popen(lastcommand).readlines()
	#print basename
	if (lines[0][0:11]=='no package '):
		basename=noversion(basename)
		if basename:
			lastcommand= 'rpm -q --whatrequires '+basename
			#print "   ",repr(lastcommand)
			lines = os.popen(lastcommand).readlines()
		else:
			lines=[]
	else:
		#print "> ",basename
		#for i in lines:
		#	print " > ",i 
		pass
	if len(lines):
		for item in lines:
			dep = string.strip(item)
			if (dep[0:11]!='no package '):
			   basedep = noversion(dep)
			   if not collectdeps.has_key(basedep):
				size=string.strip(os.popen('rpm -q --queryformat %{SIZE} '+basedep).readlines()[0])
				collectdeps[basedep]= [ dep, size ]
				requires(dep,collectdeps) # recurse!
			   else:
				if collectdeps[basedep][0] != dep:
				    print "# ERROR: feature '"+basedep+"' has versions ",dep,collectdeps[basedep]
	else:
		print "No output for: ",lastcommand
		print "That's odd. Continuining."



alldeps={}
def run(keyword):
	global alldeps
	requires(keyword,alldeps)
	

packagenames = ''
def results():
	global packagenames
	keys = alldeps.keys()
	keys.sort()
	print '# ',packagenames," has ",len(keys)," dependant packages:"
	divider='#'*78
	spacer=' '*40
	print divider
	print "# Feature                    Size       PackageName"
	print divider
	tsize=0
	for i in keys:
		vals=alldeps[i]
		tsize=tsize+string.atoi(vals[1])
		print (i+spacer)[:30],(vals[1]+spacer)[:12],vals[0]
	print '#                 TOTAL SIZE:',tsize

for k in sys.argv[1:]:
	run(k)
	#version=os.popen('rpm -q '+k).readlines()
	#for v in version:
	#	print "finding dependencies for ",string.strip(v)
	#print "> ",k, len(alldeps)
	packagenames = packagenames + k + ' '
		
results()

#eof






More information about the Python-list mailing list