| #!/usr/bin/env python |
| # vim: ts=2 sw=2 |
| |
| import optparse |
| import re |
| import sys |
| |
| |
| 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 self.lines.has_key(tgt): |
| return self.lines[tgt] |
| else: |
| return None |
| |
| def __iter__(self): |
| return self.lines.iteritems() |
| |
| 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 |
| |