Commit before big code restructuring.
[rpmdepsize.git] / repodeps.py
1 #!PYTHON
2 # repodeps - list recursive dependencies of a package in the repo
3 # (C) Copyright 2009 Red Hat Inc.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 #
19 # Written by Richard W.M. Jones <rjones@redhat.com>
20 # Heavily derived from a script by Seth Vidal.
21
22 import yum
23 import yum.misc
24 import sys
25
26 yb = yum.YumBase ()
27
28 basepkg = yb.pkgSack.returnPackages (patterns=[sys.argv[1]])[0]
29 deps = dict ({basepkg:False})
30
31 # Recursively find all the dependencies.
32 stable = False
33 while not stable:
34     stable = True
35     for pkg in deps.keys():
36         if deps[pkg] == False:
37             deps[pkg] = []
38             stable = False
39             for r in pkg.requires:
40                 ps = yb.whatProvides (r[0], r[1], r[2])
41                 best = yb._bestPackageFromList (ps.returnPackages ())
42                 if best.name != pkg.name:
43                     deps[pkg].append (best)
44                     if not deps.has_key (best):
45                         deps[best] = False
46             deps[pkg] = yum.misc.unique (deps[pkg])
47
48 # Get the data out of python as fast as possible so we can
49 # use a serious language for analysis of the tree.
50 print "(%s (" % basepkg
51 for pkg in deps.keys():
52     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)
53     print "(deps ("
54     for p in deps[pkg]:
55         print "%s " % p,
56     print ")))"
57 sys.stdout.write ("))")  # suppress trailing \n
58
59 # # Function to get the total size of a dependency (ie. size of
60 # # package + size of all dependencies).
61 # def total(pkg, seen=None):
62 #     if seen is None:
63 #         seen = dict()
64 #     if not seen.has_key (pkg):
65 #         seen[pkg] = True
66 #         sum = pkg.installedsize
67 #         for p in deps[pkg]:
68 #             sum = sum + total (p, seen)
69 #         return sum
70 #     else:
71 #         return 0
72
73 # # To speed things up, calculate the total size of each package.
74 # totals = dict ()
75 # for pkg in deps.keys():
76 #     totals[pkg] = total (pkg)
77
78 # # Sort the lists of dependencies by total size (largest first).
79 # def sort_by_totals(a, b):
80 #     if totals[a] > totals[b]:
81 #          return -1
82 #     if totals[a] == totals[b]:
83 #          return 0
84 #     if totals[a] < totals[b]:
85 #          return 1
86
87 # for pkg in deps.keys():
88 #     deps[pkg].sort (cmp=sort_by_totals)
89
90 # # Iterate over the tree and print out the package details.
91 # def pr(pkg, indent=0, seen=None):
92 #     if seen is None:
93 #         seen = dict()
94 #     if not seen.has_key (pkg):
95 #         seen[pkg] = True
96 #         print '%s%s %s/%s' % (" "*indent, pkg, pkg.installedsize, totals[pkg])
97 #         for p in deps[pkg]:
98 #             pr (p, indent+2, seen)
99
100 # pr (basepkg)