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 152