blob: 32d8ad7d67e35f3d3ad5e9afa37a125b6549ce62 [file] [log] [blame]
Joe Onorato89675232012-05-18 20:39:51 -07001#!/usr/bin/env python
2# vim: ts=2 sw=2
3
4import optparse
5import re
6import sys
7
8
9class 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
20class 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
75def 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
81def 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
144if __name__ == "__main__":
145 try:
146 main(sys.argv)
147 except KeyboardInterrupt:
148 print
149 except EOFError:
150 print
151