You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
3.3 KiB
151 lines
3.3 KiB
#!/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 |
|
|
|
|