| Joe Onorato | 8967523 | 2012-05-18 20:39:51 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python | 
|  | 2 | # vim: ts=2 sw=2 | 
|  | 3 |  | 
|  | 4 | import optparse | 
|  | 5 | import re | 
|  | 6 | import sys | 
|  | 7 |  | 
|  | 8 |  | 
|  | 9 | class Dependency: | 
|  | 10 | def __init__(self, tgt): | 
|  | 11 | self.tgt = tgt | 
|  | 12 | self.pos = "" | 
|  | 13 | self.prereqs = set() | 
|  | 14 | self.visit = 0 | 
|  | 15 |  | 
|  | 16 | def add(self, prereq): | 
|  | 17 | self.prereqs.add(prereq) | 
|  | 18 |  | 
|  | 19 |  | 
|  | 20 | class Dependencies: | 
|  | 21 | def __init__(self): | 
|  | 22 | self.lines = {} | 
|  | 23 | self.__visit = 0 | 
|  | 24 | self.count = 0 | 
|  | 25 |  | 
|  | 26 | def add(self, tgt, prereq): | 
|  | 27 | t = self.lines.get(tgt) | 
|  | 28 | if not t: | 
|  | 29 | t = Dependency(tgt) | 
|  | 30 | self.lines[tgt] = t | 
|  | 31 | p = self.lines.get(prereq) | 
|  | 32 | if not p: | 
|  | 33 | p = Dependency(prereq) | 
|  | 34 | self.lines[prereq] = p | 
|  | 35 | t.add(p) | 
|  | 36 | self.count = self.count + 1 | 
|  | 37 |  | 
|  | 38 | def setPos(self, tgt, pos): | 
|  | 39 | t = self.lines.get(tgt) | 
|  | 40 | if not t: | 
|  | 41 | t = Dependency(tgt) | 
|  | 42 | self.lines[tgt] = t | 
|  | 43 | t.pos = pos | 
|  | 44 |  | 
|  | 45 | def get(self, tgt): | 
|  | 46 | if self.lines.has_key(tgt): | 
|  | 47 | return self.lines[tgt] | 
|  | 48 | else: | 
|  | 49 | return None | 
|  | 50 |  | 
|  | 51 | def __iter__(self): | 
|  | 52 | return self.lines.iteritems() | 
|  | 53 |  | 
|  | 54 | def trace(self, tgt, prereq): | 
|  | 55 | self.__visit = self.__visit + 1 | 
|  | 56 | d = self.lines.get(tgt) | 
|  | 57 | if not d: | 
|  | 58 | return | 
|  | 59 | return self.__trace(d, prereq) | 
|  | 60 |  | 
|  | 61 | def __trace(self, d, prereq): | 
|  | 62 | if d.visit == self.__visit: | 
|  | 63 | return d.trace | 
|  | 64 | if d.tgt == prereq: | 
|  | 65 | return [ [ d ], ] | 
|  | 66 | d.visit = self.__visit | 
|  | 67 | result = [] | 
|  | 68 | for pre in d.prereqs: | 
|  | 69 | recursed = self.__trace(pre, prereq) | 
|  | 70 | for r in recursed: | 
|  | 71 | result.append([ d ] + r) | 
|  | 72 | d.trace = result | 
|  | 73 | return result | 
|  | 74 |  | 
|  | 75 | def help(): | 
|  | 76 | print "Commands:" | 
|  | 77 | print "  dep TARGET             Print the prerequisites for TARGET" | 
|  | 78 | print "  trace TARGET PREREQ    Print the paths from TARGET to PREREQ" | 
|  | 79 |  | 
|  | 80 |  | 
|  | 81 | def main(argv): | 
|  | 82 | opts = optparse.OptionParser() | 
|  | 83 | opts.add_option("-i", "--interactive", action="store_true", dest="interactive", | 
|  | 84 | help="Interactive mode") | 
|  | 85 | (options, args) = opts.parse_args() | 
|  | 86 |  | 
|  | 87 | deps = Dependencies() | 
|  | 88 |  | 
|  | 89 | filename = args[0] | 
|  | 90 | print "Reading %s" % filename | 
|  | 91 |  | 
|  | 92 | if True: | 
|  | 93 | f = open(filename) | 
|  | 94 | for line in f: | 
|  | 95 | line = line.strip() | 
|  | 96 | if len(line) > 0: | 
|  | 97 | if line[0] == '#': | 
|  | 98 | pos,tgt = line.rsplit(":", 1) | 
|  | 99 | pos = pos[1:].strip() | 
|  | 100 | tgt = tgt.strip() | 
|  | 101 | deps.setPos(tgt, pos) | 
|  | 102 | else: | 
|  | 103 | (tgt,prereq) = line.split(':', 1) | 
|  | 104 | tgt = tgt.strip() | 
|  | 105 | prereq = prereq.strip() | 
|  | 106 | deps.add(tgt, prereq) | 
|  | 107 | f.close() | 
|  | 108 |  | 
|  | 109 | print "Read %d dependencies. %d targets." % (deps.count, len(deps.lines)) | 
|  | 110 | while True: | 
|  | 111 | line = raw_input("target> ") | 
|  | 112 | if not line.strip(): | 
|  | 113 | continue | 
|  | 114 | split = line.split() | 
|  | 115 | cmd = split[0] | 
|  | 116 | if len(split) == 2 and cmd == "dep": | 
|  | 117 | tgt = split[1] | 
|  | 118 | d = deps.get(tgt) | 
|  | 119 | if d: | 
|  | 120 | for prereq in d.prereqs: | 
|  | 121 | print prereq.tgt | 
|  | 122 | elif len(split) == 3 and cmd == "trace": | 
|  | 123 | tgt = split[1] | 
|  | 124 | prereq = split[2] | 
|  | 125 | if False: | 
|  | 126 | print "from %s to %s" % (tgt, prereq) | 
|  | 127 | trace = deps.trace(tgt, prereq) | 
|  | 128 | if trace: | 
|  | 129 | width = 0 | 
|  | 130 | for g in trace: | 
|  | 131 | for t in g: | 
|  | 132 | if len(t.tgt) > width: | 
|  | 133 | width = len(t.tgt) | 
|  | 134 | for g in trace: | 
|  | 135 | for t in g: | 
|  | 136 | if t.pos: | 
|  | 137 | print t.tgt, " " * (width-len(t.tgt)), "  #", t.pos | 
|  | 138 | else: | 
|  | 139 | print t.tgt | 
|  | 140 | print | 
|  | 141 | else: | 
|  | 142 | help() | 
|  | 143 |  | 
|  | 144 | if __name__ == "__main__": | 
|  | 145 | try: | 
|  | 146 | main(sys.argv) | 
|  | 147 | except KeyboardInterrupt: | 
|  | 148 | print | 
|  | 149 | except EOFError: | 
|  | 150 | print | 
|  | 151 |  |