From 04b63b187017a03a87b032a57e9735984aa9fb42 Mon Sep 17 00:00:00 2001 From: Joe Onorato Date: Fri, 9 Feb 2024 16:35:27 -0800 Subject: [PATCH] Add option to show dependency tags in soongdbg Test: soongdbg between --svg ~/Desktop/foo.svg --deptags android.content.pm.flags-aconfig PackageInstaller Change-Id: I00786ff982ecff71e6f3cdc8d72bba5f23a093b5 --- bin/soongdbg | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/bin/soongdbg b/bin/soongdbg index a4c23982c..215d9d2b8 100755 --- a/bin/soongdbg +++ b/bin/soongdbg @@ -30,6 +30,7 @@ class Graph: dep = get_or_make_node(self.nodes, d.id, None) node.deps.add(dep) dep.rdeps.add(node) + node.dep_tags.setdefault(dep, list()).append(d) def find_paths(self, id1, id2): # Throws KeyError if one of the names isn't found @@ -63,6 +64,7 @@ class Node: self.module = module self.deps = set() self.rdeps = set() + self.dep_tags = {} PROVIDERS = [ @@ -71,6 +73,20 @@ PROVIDERS = [ ] +def format_dep_label(node, dep): + tags = node.dep_tags.get(dep) + labels = [] + if tags: + labels = [tag.tag_type.split("/")[-1] for tag in tags] + labels = sorted(set(labels)) + if labels: + result = "<" + for label in labels: + result += f"" + result += "
{label}
>" + return result + + def format_node_label(node, module_formatter): result = "<" @@ -196,6 +212,8 @@ def load_and_filter_modules(args): def print_args(parser): parser.add_argument("--label", action="append", metavar="JQ_FILTER", help="jq query for each module metadata") + parser.add_argument("--deptags", action="store_true", + help="show dependency tags (makes the graph much more complex)") group = parser.add_argument_group("output formats", "If no format is provided, a dot file will be written to" @@ -209,13 +227,24 @@ def print_args(parser): def print_nodes(args, nodes, module_formatter): # Generate the graphviz + dep_tag_id = 0 dot = io.StringIO() dot.write("digraph {\n") + dot.write("node [shape=box];") + for node in nodes: - dot.write(f"\"{node.id}\"[label={format_node_label(node, module_formatter)}];\n") + dot.write(f"\"{node.id}\" [label={format_node_label(node, module_formatter)}];\n") for dep in node.deps: if dep in nodes: - dot.write(f"\"{node.id}\" -> \"{dep.id}\";\n") + if args.deptags: + dot.write(f"\"{node.id}\" -> \"__dep_tag_{dep_tag_id}\" [ arrowhead=none ];\n") + dot.write(f"\"__dep_tag_{dep_tag_id}\" -> \"{dep.id}\";\n") + dot.write(f"\"__dep_tag_{dep_tag_id}\"" + + f"[label={format_dep_label(node, dep)} shape=ellipse" + + " color=\"#666666\" fontcolor=\"#666666\"];\n") + else: + dot.write(f"\"{node.id}\" -> \"{dep.id}\";\n") + dep_tag_id += 1 dot.write("}\n") text = dot.getvalue() @@ -224,7 +253,7 @@ def print_nodes(args, nodes, module_formatter): with open(args.dot, "w") as f: f.write(text) elif args.svg: - subprocess.run(["dot", "-Tsvg", "-Nshape=box", "-o", args.svg], + subprocess.run(["dot", "-Tsvg", "-o", args.svg], input=text, text=True, check=True) else: sys.stdout.write(text)