diff options
author | Pawel Hajdan, Jr <phajdan.jr@gentoo.org> | 2011-09-19 05:08:25 +0200 |
---|---|---|
committer | Pawel Hajdan, Jr <phajdan.jr@gentoo.org> | 2011-09-19 05:08:25 +0200 |
commit | 07e7a0eb8cf5656bb7b15f9a9b78eda6101910ac (patch) | |
tree | 2083f9fa48742b6c2365853acedbf2b195b9d8c7 | |
parent | Add batch stabilization tool. (diff) | |
download | arch-tools-07e7a0eb8cf5656bb7b15f9a9b78eda6101910ac.tar.gz arch-tools-07e7a0eb8cf5656bb7b15f9a9b78eda6101910ac.tar.bz2 arch-tools-07e7a0eb8cf5656bb7b15f9a9b78eda6101910ac.zip |
Add a tool to find reverse dependencies.
-rwxr-xr-x | reverse-dependencies.py | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/reverse-dependencies.py b/reverse-dependencies.py new file mode 100755 index 0000000..88d79aa --- /dev/null +++ b/reverse-dependencies.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# Copyright 2011 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import optparse +import os +import types + +os.environ["PORTDIR_OVERLAY"] = "" + +import portage + +def process_deps(deps, use=None): + if not use: + use = [] + result = [] + for index, x in enumerate(deps): + if type(x) == types.ListType: + continue + elif x == "||": # Any-of. + result.extend(process_deps(deps[index + 1], use)) + elif x[-1] == "?": # Use-conditional. + result.extend(process_deps(deps[index + 1], use + [x[:-1]])) + elif x[0] == "!": # Blocker. + result.append((portage.dep_getkey(x), True, use)) + else: + result.append((portage.dep_getkey(x), False, use)) + return result + +if __name__ == "__main__": + parser = optparse.OptionParser() + parser.add_option("-i", "--input", dest="input_filename", default="package.keywords", help="Input filename for generated package.keywords file [default=%default]") + parser.add_option("-o", "--output", dest="output_filename", default="package.rdeps", help="Output filename for generated package.rdeps file [default=%default]") + parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False) + + (options, args) = parser.parse_args() + if not options.input_filename: + parser.error("--input option is required") + if not options.output_filename: + parser.error("--output option is required") + if args: + parser.error("unrecognized command-line args") + + reverse_deps = {} + for pkg in portage.portdb.cp_all(): + deps = [] + for match in portage.portdb.match(pkg): + deps.extend(process_deps(portage.dep.paren_reduce(portage.portdb.aux_get(match, ['DEPEND', 'RDEPEND', 'PDEPEND'])[0]))) + for cp, blocker, use in deps: + if blocker: + continue + if cp not in reverse_deps: + reverse_deps[cp] = {} + if pkg not in reverse_deps[cp]: + reverse_deps[cp][pkg] = [] + if use not in reverse_deps[cp][pkg]: + reverse_deps[cp][pkg].append(use) + + with open(options.input_filename, "r") as input_file: + with open(options.output_filename, "w") as output_file: + for line in input_file: + if line == "\n" or line.startswith("#"): + continue + + if not line.endswith("\n"): + line += "\n" + cpv = line[1:-1] + pn = portage.versions.pkgsplit(cpv)[0] + if pn in reverse_deps: + output_file.write("# Reverse dependencies for %s\n" % pn) + for cp, use_combinations in reverse_deps[pn].items(): + if use_combinations != [[]]: + output_file.write("# One of the following USE flag combinations is required:\n") + for use_combination in use_combinations: + output_file.write("#\t%s\n" % ",".join(use_combination)) + output_file.write("%s\n" % cp) + elif options.verbose: + print 'No reverse dependencies for %s' % pn |