Visualization
This guide explains how to use class Build::Graph::Visualization to generate Mermaid flowchart diagrams from a build graph.
Overview
When debugging or documenting a build graph, it is useful to see the relationships between inputs and outputs visually. Build::Graph::Visualization produces a Mermaid flowchart LR diagram from a completed class Build::Graph::Walker, showing each file as a node and each build step as a directed edge.
Usage
After running a walker, pass it to Build::Graph::Visualization#generate:
require "build/graph/visualization"
walker = Build::Graph::Walker.new do |walker, node|
task = Build::Graph::Task.new(walker, node)
task.visit do
# perform the actual build step here
end
end
walker.update(root_node)
visualization = Build::Graph::Visualization.new
diagram = visualization.generate(walker)
puts diagram
The output is a Mermaid diagram string that can be embedded in documentation, printed to the terminal, or written to a file:
flowchart LR
_src_main_c[main.c]
_obj_main_o[main.o]
_src_main_c --> _obj_main_o
_obj_main_o[main.o]
_bin_program[program]
_obj_main_o --> _bin_program
Traversal Without Building
To generate a diagram without actually executing any build steps (e.g. for documentation or dry-run inspection), use Build::Graph::Task#traverse instead of visit in the walker block:
walker = Build::Graph::Walker.new do |walker, node|
task = Build::Graph::Task.new(walker, node)
task.traverse
end
walker.update(root_node)
diagram = Build::Graph::Visualization.new.generate(walker)
Unlike visit, traverse skips input validation and does not require any files to exist on disk. It registers all node outputs with the walker so that dependent nodes can still be resolved correctly.
However, traverse only follows declared edges — the inputs and outputs as written in the build definition. Some build systems discover additional dependencies at build time (for example, a C compiler producing a .d file that lists every header it included). Those discovered edges will not appear in the diagram.
Complete Graph Visualization
To get a complete and accurate picture of the graph, including any dependencies discovered during execution, use Build::Graph::Task#visit with an empty block instead of traverse:
walker = Build::Graph::Walker.new do |walker, node|
task = Build::Graph::Task.new(walker, node)
task.visit do
# perform the actual build step here, e.g. compile, link, etc.
end
end
walker.update(root_node)
diagram = Build::Graph::Visualization.new.generate(walker)
This executes the build steps and captures the full set of inputs and outputs — including any that are only known after running the task — giving a diagram that accurately reflects what was built and why.