Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions contrib/bst-graph
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ installed.
import argparse
import subprocess
import re
import urllib.parse

from graphviz import Digraph
from ruamel.yaml import YAML
Expand All @@ -55,6 +56,22 @@ def parse_args():
return parser.parse_args()


def unique_node_name(s):
'''Generate unique node name for `s`.

Graphviz node names cannot contain colons or backslashes so we use
url-encoding to generate the unique node name. (A cryptographic hash could
be used instead but that would make the graphviz file less readable.)

Args:
s: element name

Returns:
A string containing the unique node name
'''
return urllib.parse.quote_plus(s)


def parse_graph(lines):
'''Return nodes and edges of the parsed grpah.

Expand Down Expand Up @@ -99,12 +116,12 @@ def generate_graph(nodes, build_deps, runtime_deps):
A graphviz.Digraph object
'''
graph = Digraph()
for node in nodes:
graph.node(node)
for name in nodes:
graph.node(unique_node_name(name), label=name)
for source, target in build_deps:
graph.edge(source, target, label='build-dep')
graph.edge(unique_node_name(source), unique_node_name(target), label='build-dep')
for source, target in runtime_deps:
graph.edge(source, target, label='runtime-dep')
graph.edge(unique_node_name(source), unique_node_name(target), label='runtime-dep')
return graph


Expand All @@ -116,9 +133,11 @@ def main():
graph_lines = subprocess.check_output(cmd, universal_newlines=True)
# NOTE: We generate nodes and edges before giving them to graphviz as
# the library does not de-deuplicate them.
nodes, build_deps, runtime_deps = parse_graph(re.split("\|\|", graph_lines))
nodes, build_deps, runtime_deps = parse_graph(re.split(r"\|\|", graph_lines))
graph = generate_graph(nodes, build_deps, runtime_deps)

print(graph.source)

if args.format:
graph.render(cleanup=True,
filename='bst-graph',
Expand Down
Loading