Add state to dot->svg tool

Add a helper tool that can convert the
allowed state transitions into a dot graph
which itself then converts it into a browser
compatible svg file, which can then be looked
at to have a pretty state diagram.

Change-Id: I3cbbc75bd58182700ddc07f00395da5d1093a26c
This commit is contained in:
Joshua Harlow
2013-10-07 13:26:10 -07:00
parent 0bc77eecfb
commit 01fcad6616
2 changed files with 66 additions and 1 deletions

View File

@@ -109,7 +109,7 @@ def check_flow_transition(old_state, new_state):
If transition can be performed, it returns True. If transition If transition can be performed, it returns True. If transition
should be ignored, it returns False. If transition is not should be ignored, it returns False. If transition is not
invalid, it raises InvalidStateException. valid, it raises InvalidStateException.
""" """
if old_state == new_state: if old_state == new_state:
return False return False

65
tools/state_graph.py Normal file
View File

@@ -0,0 +1,65 @@
#!/usr/bin/env python
import os
import sys
top_dir = os.path.abspath(os.path.join(os.path.dirname(__file__),
os.pardir))
sys.path.insert(0, top_dir)
import optparse
import subprocess
import tempfile
import networkx as nx
from taskflow import states
from taskflow.utils import graph_utils as gu
def mini_exec(cmd, ok_codes=(0,)):
stdout = subprocess.PIPE
stderr = subprocess.PIPE
proc = subprocess.Popen(cmd, stdout=stdout, stderr=stderr, stdin=None)
(stdout, stderr) = proc.communicate()
rc = proc.returncode
if rc not in ok_codes:
raise RuntimeError("Could not run %s [%s]", cmd, rc)
return (stdout, stderr)
def make_svg(graph, output_filename):
# NOTE(harlowja): requires pydot!
gdot = gu.export_graph_to_dot(graph)
with tempfile.NamedTemporaryFile(suffix=".dot") as fh:
fh.write(gdot)
fh.flush()
cmd = ['dot', '-Tsvg', fh.name]
stdout, _stderr = mini_exec(cmd)
with open(output_filename, "wb") as fh:
fh.write(stdout)
# NOTE(harlowja): if u want a png instead u can run the following which
# requires ImageMagick and its little helper `convert` program.
#
# $ convert input.svg output.png
def main():
parser = optparse.OptionParser()
parser.add_option("-f", "--file", dest="filename",
help="write svg to FILE", metavar="FILE",
default="states.svg")
(options, args) = parser.parse_args()
g = nx.DiGraph(name="State transitions")
for (u, v) in states._ALLOWED_FLOW_TRANSITIONS:
if not g.has_node(u):
g.add_node(u)
if not g.has_node(v):
g.add_node(v)
g.add_edge(u, v)
make_svg(g, options.filename)
print("Created svg at '%s'" % (options.filename))
if __name__ == '__main__':
main()