tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 892b6f147d7636997f4b5b5e7288090277866e70
parent aacb4231f4e83711eca543405ec798f6015b700d
Author: Ben Hearsum <ben@mozilla.com>
Date:   Thu, 13 Nov 2025 01:50:17 +0000

Bug 1999355: add support for outputting mermaid flowcharts of kinds r=taskgraph-reviewers,ahal

taskgraph recently gained support for outputting mermaid flowchart source files for kinds. This can be particularly useful for understanding certain sequences of tasks in Gecko, where we have complex webs of kinds. Let's add support for dumping them with `./mach taskgraph`, and as an output to `./mach decision` as well.

Differential Revision: https://phabricator.services.mozilla.com/D272099

Diffstat:
Mtaskcluster/gecko_taskgraph/decision.py | 7++++++-
Mtaskcluster/gecko_taskgraph/main.py | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtaskcluster/mach_commands.py | 15+++++++++++++++
3 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/taskcluster/gecko_taskgraph/decision.py b/taskcluster/gecko_taskgraph/decision.py @@ -15,6 +15,7 @@ from redo import retry from taskgraph import create from taskgraph.create import create_tasks from taskgraph.generator import TaskGraphGenerator +from taskgraph.main import format_kind_graph_mermaid from taskgraph.parameters import Parameters from taskgraph.taskgraph import TaskGraph from taskgraph.util import json @@ -204,6 +205,9 @@ def taskgraph_decision(options, parameters=None): full_task_json = tgg.full_task_graph.to_json() write_artifact("full-task-graph.json", full_task_json) + # write out kind graph + write_artifact("kind-graph.mm", format_kind_graph_mermaid(tgg.kind_graph)) + # write out the public/runnable-jobs.json file write_artifact( "runnable-jobs.json", full_task_graph_to_runnable_jobs(full_task_json) @@ -506,7 +510,8 @@ def write_artifact(filename, data): with gzip.open(path, "wb") as f: f.write(json.dumps(data).encode("utf-8")) else: - raise TypeError(f"Don't know how to write to {filename}") + with open(path, "w") as f: + f.write(data) def read_artifact(filename): diff --git a/taskcluster/gecko_taskgraph/main.py b/taskcluster/gecko_taskgraph/main.py @@ -22,7 +22,9 @@ from taskgraph.main import ( command, commands, dump_output, + format_kind_graph_mermaid, generate_taskgraph, + get_taskgraph_generator, ) from gecko_taskgraph import GECKO @@ -48,6 +50,80 @@ FORMAT_METHODS["yaml"] = format_taskgraph_yaml @command( + "kind-graph", + help="Show the kind dependency graph as a Mermaid flowchart diagram.", +) +@argument("--root", "-r", help="root of the taskgraph definition relative to topsrcdir") +@argument("--quiet", "-q", action="store_true", help="suppress all logging output") +@argument( + "--verbose", "-v", action="store_true", help="include debug-level logging output" +) +@argument( + "--parameters", + "-p", + default=None, + help="Parameters to use for the generation. Can be a path to file (.yml or " + ".json; see `taskcluster/docs/parameters.rst`), a url, of the form " + "`project=mozilla-central` to download latest parameters file for the specified " + "project from CI, or of the form `task-id=<decision task id>` to download " + "parameters from the specified decision task.", +) +@argument( + "-o", + "--output-file", + default=None, + help="file path to store generated output.", +) +@argument( + "-k", + "--target-kind", + dest="target_kinds", + action="append", + default=[], + help="only return kinds and their dependencies.", +) +def show_kinds(options): + from taskgraph.parameters import parameters_loader # noqa: PLC0415 + + if options.pop("verbose", False): + logging.root.setLevel(logging.DEBUG) + + setup_logging() + + target_kinds = options.get("target_kinds", []) + parameters = options.get("parameters") + if not parameters: + parameters = parameters_loader( + None, strict=False, overrides={"target-kinds": target_kinds} + ) + elif isinstance(parameters, str): + parameters = parameters_loader( + parameters, + overrides={"target-kinds": target_kinds}, + strict=False, + ) + else: + # Parameters object already exists (from tests) + if target_kinds: + parameters["target-kinds"] = target_kinds + + tgg = get_taskgraph_generator(options.get("root"), parameters) + kind_graph = tgg.kind_graph + + output = format_kind_graph_mermaid(kind_graph) + + output_file = options.get("output_file") + if output_file: + with open(output_file, "w") as fh: + print(output, file=fh) + print(f"Kind graph written to {output_file}", file=sys.stderr) + else: + print(output) + + return 0 + + +@command( "tasks", help="Show all tasks in the taskgraph.", defaults={"graph_attr": "full_task_set"}, diff --git a/taskcluster/mach_commands.py b/taskcluster/mach_commands.py @@ -118,6 +118,21 @@ def taskgraph_command(command_context): @SubCommand( "taskgraph", + "kind-graph", + description="Generate a graph of the relationship between taskgraph kinds", + parser=partial(get_taskgraph_command_parser, "kind-graph"), +) +def taskgraph_kind_graph(command_context, **options): + try: + setup_logging(command_context) + return taskgraph_commands["kind-graph"].func(options) + except Exception: + traceback.print_exc() + sys.exit(1) + + +@SubCommand( + "taskgraph", "tasks", description="Show all tasks in the taskgraph", parser=partial(get_taskgraph_command_parser, "tasks"),