103 lines
2.7 KiB
Python
Executable File
103 lines
2.7 KiB
Python
Executable File
"""
|
|
Read snakefood dependencies and output a visual graph.
|
|
"""
|
|
# This file is part of the Snakefood open source package.
|
|
# See http://furius.ca/snakefood/ for licensing details.
|
|
|
|
import sys, os
|
|
from os.path import *
|
|
|
|
from snakefood.depends import read_depends, eliminate_redundant_depends
|
|
|
|
|
|
|
|
prefix = '''
|
|
# This file was generated by sfood-graph.
|
|
|
|
strict digraph "dependencies" {
|
|
graph [
|
|
rankdir = "LR",
|
|
overlap = "scale",
|
|
size = "8,10",
|
|
ratio = "fill",
|
|
fontsize = "16",
|
|
fontname = "Helvetica",
|
|
clusterrank = "local"
|
|
]
|
|
|
|
node [
|
|
fontsize=%s
|
|
shape=ellipse
|
|
// style=filled
|
|
// shape=box
|
|
];
|
|
|
|
'''
|
|
postfix = '''
|
|
|
|
}
|
|
'''
|
|
|
|
def graph(pairs, write, fontsize):
|
|
"Given (from, to) pairs of (root, fn) files, output a dot graph."
|
|
write(prefix % fontsize)
|
|
lines = []
|
|
for (froot, f), (troot, t) in pairs:
|
|
if opts.pythonify_filenames:
|
|
f = normpyfn(f)
|
|
t = normpyfn(t)
|
|
if opts.full_pathnames:
|
|
f = join(froot, f)
|
|
if troot:
|
|
t = join(troot, t)
|
|
if troot is None:
|
|
write('"%s" [style=filled];\n' % f)
|
|
else:
|
|
write('"%s" -> "%s";\n' % (f, t))
|
|
write(postfix)
|
|
|
|
def normpyfn(fn):
|
|
"Normalize the python filenames for output."
|
|
if fn is None:
|
|
return fn
|
|
if fn.endswith('.py'):
|
|
fn = fn[:-3]
|
|
fn = fn.replace(os.sep, '.')
|
|
return fn
|
|
|
|
def main():
|
|
import optparse
|
|
parser = optparse.OptionParser(__doc__.strip())
|
|
|
|
parser.add_option('-f', '--full-pathnames', '--full', action='store_true',
|
|
help="Output the full pathnames, not just the relative.")
|
|
|
|
parser.add_option('-p', '--pythonify-filenames', '--remove-extensions',
|
|
action='store_true',
|
|
help="Remove filename extensions in the graph and "
|
|
"replace slashes with dots.")
|
|
|
|
parser.add_option('-r', '--redundant', action='store_false', default=True,
|
|
help="Do not eliminate redundant dependencies.")
|
|
|
|
parser.add_option('--fontsize', action='store', type='int',
|
|
default=10,
|
|
help="The size of the font to use for nodes.")
|
|
|
|
global opts
|
|
opts, args = parser.parse_args()
|
|
|
|
if not args:
|
|
args = ['-']
|
|
for fn in args:
|
|
if fn == '-':
|
|
f = sys.stdin
|
|
else:
|
|
f = open(fn)
|
|
depends = read_depends(f)
|
|
if opts.redundant:
|
|
depends = eliminate_redundant_depends(depends)
|
|
graph(depends, sys.stdout.write, opts.fontsize)
|
|
|
|
|