Erlang Dependency Graph
=======================
Got distracted and wrote a small parser for dialyzer [1] to print the
dependencies for a set of Erlang beam files. Just used CouchDB sources as that's
what I had handy.
Script [2]
----------
#! /usr/bin/env python
import os
import re
import subprocess as sp
import sys
edge_re = re.compile(r"(couch[^:]+):([^/]+)/\d+")
def dialyze(file):
command = ' '.join([
"dialyzer",
"--build_plt",
"-pa", "src/ibrowse",
"-pa", "src/mochiweb",
"-pa", "/usr/local/lib/erlang/lib",
"-c", file
])
pipe = sp.Popen(
command, shell=True, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE
)
(stdout, stderr) = pipe.communicate(input="")
for line in stdout.split("\n"):
match = edge_re.match(line.strip())
if not match:
continue
yield (match.group(1), match.group(2))
def start_graph():
print "digraph G {"
def add_edges(file, edges):
src = os.path.split(file)[1][:-len(".beam")]
edges[src] = set()
for (mod, fun) in dialyze(file):
edges[src].add(mod)
def end_graph():
print "}"
def main():
if len(sys.argv) != 2:
print "usage: %s code_dir" % sys.argv[0]
exit(-1)
start_graph()
edges = {}
for root, dnames, fnames in os.walk(sys.argv[1]):
for fname in fnames:
if not fname.endswith(".beam"):
continue
add_edges(os.path.join(root, fname), edges)
keys = edges.keys()
keys.sort(key=lambda x: len(edges[x]), reverse=True)
for k in keys:
for m in edges[k]:
print " %s -> %s;" % (k, m)
end_graph()
if __name__ == '__main__':
main()
Result
------
Can be fount at [3].
References
----------
[1]: http://www.erlang.org/doc/apps/dialyzer/index.html
[2]: /res/2009-06-09-erlang-deps-graph.py
[3]: /res/2009-06-09-erlang-deps-graph.jpg
Copyright Notice
----------------
Copyright 2008-2010 Paul Joseph Davis
License
-------
http://creativecommons.org/licenses/by/3.0/