import rpm import os class Package: def __init__(self, name): self.name = name class PackageSet: def __init__(self, path): self.pkgs, self.requires, self.provides = {}, {}, {} os.path.walk(path, PackageSet.__find_rpms, self) for pkg in self.pkgs.values(): requires = {} for require in self.requires[pkg.name]: if self.provides.has_key(require): if self.provides[require] == pkg.name: continue if self.provides[require] == "jpackage-utils": continue if self.provides[require] == "java-1.4.2-gcj-compat" and \ pkg.name not in ("java-1.4.2-gcj-compat-devel", "eclipse-ecj"): continue requires[self.provides[require]] = 1 else: assert is_ignorable(require) requires = requires.keys() requires.sort() pkg.requires = requires def __find_rpms(self, dir, items): for item in items: if item.endswith(".rpm") and not item.endswith(".src.rpm"): self.__add_rpm(os.path.join(dir, item)) def __add_rpm(self, path): fd = os.open(path, os.O_RDONLY) try: hdr = rpm.TransactionSet().hdrFromFdno(fd) finally: os.close(fd) assert type(hdr) == rpm.hdr name = hdr["name"] assert not self.pkgs.has_key(name) self.pkgs[name] = Package(name) assert not self.requires.has_key(name) self.requires[name] = hdr["requirename"] if name in ("tomcat5", "tomcat5-jasper"): self.requires[name].remove("jakarta-commons-daemon") if name == "tomcat5": self.requires[name].append("puretls") for provide in hdr["providename"]: if (name, provide) == ("xerces-j2", "jaxp_parser_impl"): continue assert not self.provides.has_key(provide) self.provides[provide] = name def graph(self, start): nodes, edges = {}, [] for node in start: nodes[node] = False while True: todo = [k for k, v in nodes.items() if not v] if not todo: break for name in todo: pkg = self.pkgs[name] for require in pkg.requires: edges.append((name, require)) if not nodes.has_key(require): nodes[require] = False nodes[name] = True return edges def is_ignorable(dep): if dep.startswith("/"): return True if dep.startswith("rpmlib("): return True if dep.startswith("lib") and dep.find(".so") != -1: return True if dep in ("gcc-java", "gjdoc", "httpd-mmn", "libgcj", "libgcj-src"): return True return False if __name__ == "__main__": import glob, sys [path] = glob.glob(os.path.join(os.path.split( os.path.abspath( sys.argv[0]))[0], "pkgs-*")) pkgs = PackageSet(path) print "// Runtime dependencies for FC4 Java stack" print "// dot -Tps graph.dot -o graph.ps" print print "digraph G {" print ' page="8.27, 11.69";' print ' ratio="fill";' for requirer, provider in pkgs.graph( ("tomcat5", "tomcat5-webapps", "tomcat5-admin-webapps", "avalon-logkit")): print ' "%s" -> "%s";' % (requirer, provider) print "}"