#!PYTHON # repodeps - list recursive dependencies of a package in the repo # (C) Copyright 2009 Red Hat Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # Written by Richard W.M. Jones # Heavily derived from a script by Seth Vidal. import yum import yum.misc import sys yb = yum.YumBase () basepkg = yb.pkgSack.returnPackages (patterns=[sys.argv[1]])[0] deps = dict ({basepkg:False}) # Recursively find all the dependencies. stable = False while not stable: stable = True for pkg in deps.keys(): if deps[pkg] == False: deps[pkg] = [] stable = False for r in pkg.requires: ps = yb.whatProvides (r[0], r[1], r[2]) best = yb._bestPackageFromList (ps.returnPackages ()) if best.name != pkg.name: deps[pkg].append (best) if not deps.has_key (best): deps[best] = False deps[pkg] = yum.misc.unique (deps[pkg]) # Get the data out of python as fast as possible so we can # use a serious language for analysis of the tree. print "(%s (" % basepkg for pkg in deps.keys(): print "((nevra %s) (name %s) (epoch %s) (version %s) (release %s) (arch %s) (size %s)" % (pkg, pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch, pkg.installedsize) print "(deps (" for p in deps[pkg]: print "%s " % p, print ")))" sys.stdout.write ("))") # suppress trailing \n # # Function to get the total size of a dependency (ie. size of # # package + size of all dependencies). # def total(pkg, seen=None): # if seen is None: # seen = dict() # if not seen.has_key (pkg): # seen[pkg] = True # sum = pkg.installedsize # for p in deps[pkg]: # sum = sum + total (p, seen) # return sum # else: # return 0 # # To speed things up, calculate the total size of each package. # totals = dict () # for pkg in deps.keys(): # totals[pkg] = total (pkg) # # Sort the lists of dependencies by total size (largest first). # def sort_by_totals(a, b): # if totals[a] > totals[b]: # return -1 # if totals[a] == totals[b]: # return 0 # if totals[a] < totals[b]: # return 1 # for pkg in deps.keys(): # deps[pkg].sort (cmp=sort_by_totals) # # Iterate over the tree and print out the package details. # def pr(pkg, indent=0, seen=None): # if seen is None: # seen = dict() # if not seen.has_key (pkg): # seen[pkg] = True # print '%s%s %s/%s' % (" "*indent, pkg, pkg.installedsize, totals[pkg]) # for p in deps[pkg]: # pr (p, indent+2, seen) # pr (basepkg)