152 lines
3.3 KiB
Python
152 lines
3.3 KiB
Python
|
#!/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
|
||
|
|