-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathgen.py
More file actions
81 lines (62 loc) · 1.92 KB
/
Copy pathgen.py
File metadata and controls
81 lines (62 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from graphviz import Digraph
from docopt import docopt
import yaml
__doc__ = """SOA Graph Generator.
Usage:
gen.py [options] all <descriptor>
gen.py [options] <node> <descriptor>
Options:
-h --help Show this screen.
--format=<fmt> Format [default: pdf]
--engine=<engine> Engine [default: dot]
"""
def isa(o, key):
return key in o and o[key]
_added = set()
def add_node(g, name, **attrs):
if name in _added:
return
# _added.add(name)
g.node(name, label=name, **attrs)
def eprops(n):
if isinstance(n, basestring):
return n, {}
if isinstance(n, dict):
return n.pop('node'), n
assert False, n
def add_edge(g, out, in_):
outs, outp = eprops(out)
ins, inp = eprops(in_)
kwargs = (outp or inp)
kwargs.pop('style', {})
g.edge(outs, ins, **kwargs)
def build(desc, g):
for node in desc:
if isinstance(node, basestring):
add_node(g, node)
elif isinstance(node, list):
pass
elif isa(node, 'subgraph'):
sg = Digraph()
build(node['nodes'], sg)
g.subgraph(sg)
elif isa(node, 'style'):
for k, v in node['style'].items():
getattr(g, '%s_attr' % k).update(**v)
else:
add_node(g, node['name'], **node.pop('attrs', {}))
for node in desc:
if isinstance(node, dict) and 'name' in node:
for e in node.get('out', []):
add_edge(g, node['name'], e)
for e in node.get('in', []):
add_edge(g, e, node['name'])
def render(descfn):
fn = dot.render(descfn + ".gv")
print "Generated:", fn
if __name__ == '__main__':
arguments = docopt(__doc__, version='0.1')
desc = yaml.load(open(arguments['<descriptor>']))
dot = Digraph(format=arguments['--format'], engine=arguments['--engine'])
build(desc, dot)
render(arguments['<descriptor>'])