#!/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