#!/usr/bin/env python # vim: ts=2 sw=2 from __future__ import print_function import optparse import sys try: raw_input except NameError: raw_input = input class Dependency: def __init__(self, tgt): self.tgt = tgt self.pos = "" self.prereqs = set() self.visit = 0 def add(self, prereq): self.prereqs.add(prereq) class Dependencies: def __init__(self): self.lines = {} self.__visit = 0 self.count = 0 def add(self, tgt, prereq): t = self.lines.get(tgt) if not t: t = Dependency(tgt) self.lines[tgt] = t p = self.lines.get(prereq) if not p: p = Dependency(prereq) self.lines[prereq] = p t.add(p) self.count = self.count + 1 def setPos(self, tgt, pos): t = self.lines.get(tgt) if not t: t = Dependency(tgt) self.lines[tgt] = t t.pos = pos def get(self, tgt): if tgt in self.lines: return self.lines[tgt] else: return None def __iter__(self): if hasattr(self.lines, 'iteritems'): return self.lines.iteritems() return iter(self.lines.items()) def trace(self, tgt, prereq): self.__visit = self.__visit + 1 d = self.lines.get(tgt) if not d: return return self.__trace(d, prereq) def __trace(self, d, prereq): if d.visit == self.__visit: return d.trace if d.tgt == prereq: return [ [ d ], ] d.visit = self.__visit result = [] for pre in d.prereqs: recursed = self.__trace(pre, prereq) for r in recursed: result.append([ d ] + r) d.trace = result return result def help(): print("Commands:") print(" dep TARGET Print the prerequisites for TARGET") print(" trace TARGET PREREQ Print the paths from TARGET to PREREQ") def main(argv): opts = optparse.OptionParser() opts.add_option("-i", "--interactive", action="store_true", dest="interactive", help="Interactive mode") (options, args) = opts.parse_args() deps = Dependencies() filename = args[0] print("Reading %s" % filename) if True: f = open(filename) for line in f: line = line.strip() if len(line) > 0: if line[0] == '#': pos,tgt = line.rsplit(":", 1) pos = pos[1:].strip() tgt = tgt.strip() deps.setPos(tgt, pos) else: (tgt,prereq) = line.split(':', 1) tgt = tgt.strip() prereq = prereq.strip() deps.add(tgt, prereq) f.close() print("Read %d dependencies. %d targets." % (deps.count, len(deps.lines))) while True: line = raw_input("target> ") if not line.strip(): continue split = line.split() cmd = split[0] if len(split) == 2 and cmd == "dep": tgt = split[1] d = deps.get(tgt) if d: for prereq in d.prereqs: print(prereq.tgt) elif len(split) == 3 and cmd == "trace": tgt = split[1] prereq = split[2] if False: print("from %s to %s" % (tgt, prereq)) trace = deps.trace(tgt, prereq) if trace: width = 0 for g in trace: for t in g: if len(t.tgt) > width: width = len(t.tgt) for g in trace: for t in g: if t.pos: print(t.tgt, " " * (width-len(t.tgt)), " #", t.pos) else: print(t.tgt) print() else: help() if __name__ == "__main__": try: main(sys.argv) except KeyboardInterrupt: print() except EOFError: print()