Skip to content

Commit

Permalink
Merge pull request #1979 from harrysarson/harry/graph
Browse files Browse the repository at this point in the history
contrib/bst-graph: Escape names when using as node_id
  • Loading branch information
juergbi authored Feb 7, 2025
2 parents 936124f + 655e658 commit e99e6bb
Showing 1 changed file with 24 additions and 5 deletions.
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

0 comments on commit e99e6bb

Please sign in to comment.