|
1 #!/usr/bin/env python |
|
2 |
|
3 import sys |
|
4 sys.path.append('/usr/lib/graphviz/python/') |
|
5 |
|
6 import cPickle |
|
7 import os |
|
8 import graph |
|
9 import gv |
|
10 |
|
11 def parseFile(file_name): |
|
12 if os.path.exists("imports.dat"): |
|
13 log = open("imports.dat", "r") |
|
14 all_imports = cPickle.load(log) |
|
15 log.close() |
|
16 else: |
|
17 all_imports = {} |
|
18 |
|
19 if file_name in all_imports: |
|
20 print "Overwriting previous data on '%s'." % file_name |
|
21 |
|
22 imports = [] |
|
23 |
|
24 file = open(file_name) |
|
25 |
|
26 for line in file: |
|
27 if line.lstrip().startswith('import soc'): |
|
28 splitline = line[:-1].split(' ') |
|
29 mod = splitline[1] |
|
30 imports.append(mod) |
|
31 |
|
32 if line.lstrip().startswith('from soc'): |
|
33 splitline = line[:-1].split(' ') |
|
34 mod = splitline[1] + '.' + splitline[3] |
|
35 imports.append(mod) |
|
36 |
|
37 for idx, imp in enumerate(imports): |
|
38 if imp in set(imports[idx+1:]): |
|
39 print "Warning: file '%s' has a redundant import: '%s'." % (file_name, imp) |
|
40 |
|
41 normalized = "soc.%s" % file_name[:-3].replace('/', '.') |
|
42 |
|
43 print "Writing imports for file %s (%s)." % (file_name, normalized) |
|
44 all_imports[normalized] = imports |
|
45 |
|
46 log = open("imports.dat", "w") |
|
47 cPickle.dump(all_imports, log) |
|
48 log.close() |
|
49 |
|
50 return 0 |
|
51 |
|
52 |
|
53 def buildGraph(): |
|
54 log = open("imports.dat", "r") |
|
55 all_imports = cPickle.load(log) |
|
56 |
|
57 gr = graph.graph() |
|
58 |
|
59 gr.add_nodes(all_imports.keys()) |
|
60 |
|
61 for file_name, imports in all_imports.iteritems(): |
|
62 for imp in imports: |
|
63 if imp not in gr: |
|
64 gr.add_node(imp) |
|
65 gr.add_edge(file_name, imp) |
|
66 |
|
67 return gr |
|
68 |
|
69 |
|
70 def showGraph(): |
|
71 gr = buildGraph() |
|
72 for node in gr: |
|
73 print "%s: " % node |
|
74 for edge in gr[node]: |
|
75 print "\t%s" % edge |
|
76 |
|
77 |
|
78 def drawGraph(): |
|
79 gr = buildGraph() |
|
80 dot = gr.write(fmt='dot') |
|
81 gvv = gv.readstring(dot) |
|
82 gv.layout(gvv,'dot') |
|
83 gv.render(gvv,'png','imports.png') |
|
84 |
|
85 |
|
86 def main(args): |
|
87 if len(args) == 1: |
|
88 if args[0] == '.': |
|
89 return showGraph() |
|
90 |
|
91 if args[0] == '..': |
|
92 return drawGraph() |
|
93 |
|
94 if not args: |
|
95 print "Please specify a filename to parse, or '.' to list the parsed imports" |
|
96 return -1 |
|
97 |
|
98 res = 0 |
|
99 |
|
100 for file_name in args: |
|
101 res += parseFile(file_name) |
|
102 |
|
103 print "Done parsing." |
|
104 |
|
105 return res |
|
106 |
|
107 if __name__ == '__main__': |
|
108 import sys |
|
109 res = main(sys.argv[1:]) |
|
110 sys.exit(res) |
|
111 |