Skip to content

Commit

Permalink
Merge pull request #242 from moonbitlang/build_graph_vis
Browse files Browse the repository at this point in the history
feat: support build graph visualization
  • Loading branch information
Young-Flash authored Sep 9, 2024
2 parents f1db3a2 + e8ab626 commit c2043cf
Show file tree
Hide file tree
Showing 19 changed files with 158 additions and 38 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Options:
-v, --verbose Increase verbosity
--trace Trace the execution of the program
--dry-run Do not actually run the command
--build-graph generate build graph
-h, --help Print help
```
Expand Down
4 changes: 3 additions & 1 deletion changes.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@

- check latest toolchain version before moon upgrade and add a `--force` flag to force upgrade
- check latest toolchain version before moon upgrade and add a `--force` flag to force upgrade

- add `--build-graph` flag to generate build graph for build | check | test | bundle
1 change: 1 addition & 0 deletions crates/moon/src/cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ fn run_build_internal(
run_mode,
quiet: cli.quiet,
verbose: cli.verbose,
build_graph: cli.build_graph,
..Default::default()
};

Expand Down
1 change: 1 addition & 0 deletions crates/moon/src/cli/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ fn run_check_internal(
quiet: cli.quiet,
verbose: cli.verbose,
output_json: cmd.output_json,
build_graph: cli.build_graph,
..Default::default()
};

Expand Down
1 change: 1 addition & 0 deletions crates/moon/src/cli/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub fn run_fmt(cli: &UniversalFlags, cmd: FmtSubcommand) -> anyhow::Result<i32>
sort_input: cmd.sort_input,
run_mode,
fmt_opt: Some(FmtOpt { check: cmd.check }),
build_graph: cli.build_graph,
..Default::default()
};

Expand Down
1 change: 1 addition & 0 deletions crates/moon/src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ pub fn run_run_internal(cli: &UniversalFlags, cmd: RunSubcommand) -> anyhow::Res
args: cmd.args.clone(),
quiet: true,
verbose: cli.verbose,
build_graph: cli.build_graph,
..Default::default()
};

Expand Down
1 change: 1 addition & 0 deletions crates/moon/src/cli/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ fn run_test_internal(
quiet: true,
verbose: cli.verbose,
no_parallelize: cmd.no_parallelize,
build_graph: cli.build_graph,
..Default::default()
};

Expand Down
51 changes: 18 additions & 33 deletions crates/moon/tests/test_cases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ fn test_moon_help() {
-v, --verbose Increase verbosity
--trace Trace the execution of the program
--dry-run Do not actually run the command
--build-graph generate build graph
-h, --help Print help
"#]],
);
Expand Down Expand Up @@ -3502,18 +3503,18 @@ fn test_deny_warn() {
&get_stderr_on_success_with_args_and_replace_dir(&dir, ["check", "--sort-input"]),
expect![[r#"
Warning: [2000]
╭─[$ROOT/lib/hello.mbt:14:3]
╭─[$ROOT/lib/hello.mbt:13:3]
14alert_2();
13alert_1();
│ ───┬───
│ ╰───── Warning (Alert alert_2): alert_2
│ ╰───── Warning (Alert alert_1): alert_1
────╯
Warning: [2000]
╭─[$ROOT/lib/hello.mbt:13:3]
╭─[$ROOT/lib/hello.mbt:14:3]
13alert_1();
14alert_2();
│ ───┬───
│ ╰───── Warning (Alert alert_1): alert_1
│ ╰───── Warning (Alert alert_2): alert_2
────╯
Warning: [1002]
╭─[$ROOT/lib/hello.mbt:4:7]
Expand Down Expand Up @@ -3547,20 +3548,12 @@ fn test_deny_warn() {
"#]],
);

let out = snapbox::cmd::Command::new(moon_bin())
.current_dir(&dir)
.args(["check", "--deny-warn", "--sort-input"])
.assert()
.failure()
.get_output()
.stdout
.to_owned();

let s = std::str::from_utf8(&out).unwrap().to_string();

assert!(s.contains(
"failed: moonc check -error-format json -w @a -alert @all-raise-throw-unsafe+deprecated"
));
check(
&get_err_stdout_with_args_and_replace_dir(&dir, ["check", "--deny-warn", "--sort-input"]),
expect![[r#"
failed: moonc check -error-format json -w @a -alert @all-raise-throw-unsafe+deprecated $ROOT/lib/hello.mbt -o $ROOT/target/wasm-gc/release/check/lib/lib.mi -pkg username/hello/lib -std-path $MOON_HOME/lib/core/target/wasm-gc/release/bundle -pkg-sources username/hello/lib:$ROOT/lib -target wasm-gc
"#]],
);

check(
&get_stderr_on_success_with_args_and_replace_dir(&dir, ["build", "--sort-input"]),
Expand Down Expand Up @@ -3611,19 +3604,11 @@ fn test_deny_warn() {
"#]],
);

let out = snapbox::cmd::Command::new(moon_bin())
.current_dir(&dir)
.args(["build", "--deny-warn", "--sort-input"])
.assert()
.failure()
.get_output()
.stdout
.to_owned();

let s = std::str::from_utf8(&out).unwrap().to_string();

assert!(
s.contains("failed: moonc build-package -error-format json -w @a -alert @all-raise-throw-unsafe+deprecated")
check(
&get_err_stdout_with_args_and_replace_dir(&dir, ["build", "--deny-warn", "--sort-input"]),
expect![[r#"
failed: moonc build-package -error-format json -w @a -alert @all-raise-throw-unsafe+deprecated $ROOT/lib/hello.mbt -o $ROOT/target/wasm-gc/release/build/lib/lib.core -pkg username/hello/lib -std-path $MOON_HOME/lib/core/target/wasm-gc/release/bundle -pkg-sources username/hello/lib:$ROOT/lib -target wasm-gc
"#]],
);
}

Expand Down
24 changes: 22 additions & 2 deletions crates/moon/tests/test_cases/moon_build_package.in/moon.test
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,31 @@
moonc build-package ./src/lib/hello.mbt -o ./target/wasm-gc/release/build/lib/lib.core -pkg username/hello/lib -std-path $MOON_HOME/lib/core/target/wasm-gc/release/bundle -pkg-sources username/hello/lib:./src/lib -target wasm-gc
moonc build-package ./src/top.mbt -o ./target/wasm-gc/release/build/hello.core -pkg username/hello -std-path $MOON_HOME/lib/core/target/wasm-gc/release/bundle -i ./target/wasm-gc/release/build/lib/lib.mi:lib -pkg-sources username/hello:./src -target wasm-gc

$ moon build
$ moon build --build-graph --sort-input

generated build graph: ${WORK_DIR}/target/wasm-gc/release/build/build_graph.dot
Finished. moon: ran 2 tasks, now up to date

$ xls ./target/wasm-gc/release/build/lib/
lib.core lib.mi
$ xls ./target/wasm-gc/release/build/
.moon-lock build.moon_db build.output hello.core hello.mi lib moon.db
.moon-lock build.moon_db build.output build_graph.dot hello.core hello.mi lib moon.db
$ xcat ./target/wasm-gc/release/build/build_graph.dot
digraph BuildGraph {
"./target/wasm-gc/release/build/hello.core" [shape=box, style=filled, fillcolor=black, fontcolor=white];
"./target/wasm-gc/release/build/hello.mi" [shape=box, color=black, ];
"./src/top.mbt" [shape=box, color=black, ];
"./target/wasm-gc/release/build/lib/lib.mi" [shape=box, color=black, ];
"./target/wasm-gc/release/build/lib/lib.core" [shape=box, style=filled, fillcolor=black, fontcolor=white];
"./src/lib/hello.mbt" [shape=box, color=black, ];
"build-package: username/hello" [shape=ellipse];
"./src/top.mbt" -> "build-package: username/hello";
"./target/wasm-gc/release/build/lib/lib.mi" -> "build-package: username/hello";
"build-package: username/hello" -> "./target/wasm-gc/release/build/hello.core";
"build-package: username/hello" -> "./target/wasm-gc/release/build/hello.mi";
"build-package: username/hello/lib" [shape=ellipse];
"./src/lib/hello.mbt" -> "build-package: username/hello/lib";
"build-package: username/hello/lib" -> "./target/wasm-gc/release/build/lib/lib.core";
"build-package: username/hello/lib" -> "./target/wasm-gc/release/build/lib/lib.mi";
}

67 changes: 67 additions & 0 deletions crates/moonbuild/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ use indexmap::IndexMap;
use moonutil::module::ModuleDB;
use moonutil::package::Package;
use moonutil::path::PathComponent;
use n2::graph::FileId;
use n2::load::State;
use n2::progress::{DumbConsoleProgress, FancyConsoleProgress, Progress};
use n2::terminal;
use std::collections::HashSet;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::sync::atomic::AtomicBool;
Expand Down Expand Up @@ -107,6 +110,10 @@ pub fn n2_run_interface(
});
};

if moonbuild_opt.build_graph {
vis_build_graph(&state, moonbuild_opt);
}

let mut progress = create_progress_console(Some(Box::new(render_and_catch)));
let options = work::Options {
parallelism: default_parallelism()?,
Expand Down Expand Up @@ -164,6 +171,66 @@ pub fn n2_run_interface(
Ok(res)
}

fn vis_build_graph(state: &State, moonbuild_opt: &MoonbuildOpt) {
let path = moonbuild_opt.target_dir.join("build_graph.dot");
let source_dir = moonbuild_opt.source_dir.display().to_string();

let graph = &state.graph;
let files = &graph.files;
let builds = &graph.builds;
let default_artifact = state
.default
.clone()
.into_iter()
.collect::<HashSet<FileId>>();

let mut dot = String::from("digraph BuildGraph {\n");

for file_id in files.all_ids() {
let file_name = &files.by_id[file_id].name.replace(&source_dir, ".");
// mark the file if it's the default artifact that we really want
let (style, fontcolor) = if default_artifact.contains(&file_id) {
("style=filled, fillcolor=black", "fontcolor=white")
} else {
("color=black", "")
};
dot.push_str(&format!(
" \"{}\" [shape=box, {}, {}];\n",
file_name, style, fontcolor
));
}

let default_desc = "missing description".to_string();
for build in builds.iter() {
let build_desc = build
.desc
.as_ref()
.unwrap_or(&default_desc)
.replace(&source_dir, ".");
dot.push_str(&format!(" \"{}\" [shape=ellipse];\n", build_desc));

for &input_id in build.ins.ids.iter() {
let input_file_name = &files.by_id[input_id].name.replace(&source_dir, ".");
dot.push_str(&format!(
" \"{}\" -> \"{}\";\n",
input_file_name, build_desc
));
}

for &output_id in build.outs() {
let output_file_name = &files.by_id[output_id].name.replace(&source_dir, ".");
dot.push_str(&format!(
" \"{}\" -> \"{}\";\n",
build_desc, output_file_name
));
}
}

dot.push_str("}\n");
std::fs::write(&path, dot).expect("Unable to write dot file");
eprintln!("generated build graph: {}", path.display());
}

pub fn run_check(
moonc_opt: &MooncOpt,
moonbuild_opt: &MoonbuildOpt,
Expand Down
2 changes: 2 additions & 0 deletions crates/moonbuild/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ fn gen_inplace_fmt_command(graph: &mut n2graph::Graph, item: &FmtItem) -> (Build
.arg(&item.phony_out)
.build();
build.cmdline = Some(command);
build.desc = Some(format!("moonfmt {}", item.input));
(build, output_id)
}

Expand Down Expand Up @@ -264,6 +265,7 @@ fn gen_fmt_to_command(graph: &mut n2graph::Graph, item: &FmtItem) -> (Build, Fil
.arg(&item.output)
.build();
build.cmdline = Some(command);
build.desc = Some(format!("moonfmt {}", item.input));

(build, output_id)
}
Expand Down
2 changes: 2 additions & 0 deletions crates/moonbuild/src/gen/gen_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ pub fn gen_build_command(
.build();
log::debug!("Command: {}", command);
build.cmdline = Some(command);
build.desc = Some(format!("build-package: {}", item.package_full_name));
(build, core_output_id)
}

Expand Down Expand Up @@ -414,6 +415,7 @@ pub fn gen_link_command(
.build();
log::debug!("Command: {}", command);
build.cmdline = Some(command);
build.desc = Some(format!("link-core: {}", item.package_full_name));
(build, artifact_id)
}

Expand Down
2 changes: 2 additions & 0 deletions crates/moonbuild/src/gen/gen_bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ pub fn gen_build_command(
.build();
log::debug!("Command: {}", command);
build.cmdline = Some(command);
build.desc = Some(format!("build-package {}", item.package_full_name));
build
}

Expand Down Expand Up @@ -283,6 +284,7 @@ fn gen_bundle_all(

log::debug!("Command: {}", command);
build.cmdline = Some(command);
build.desc = Some(format!("bundle-core {}", bundle_all.name));
build
}

Expand Down
6 changes: 5 additions & 1 deletion crates/moonbuild/src/gen/gen_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use moonutil::package::Package;
use std::path::{Path, PathBuf};
use std::rc::Rc;

use moonutil::common::{MoonbuildOpt, MooncOpt, MOON_PKG_JSON};
use moonutil::common::{get_desc_name, MoonbuildOpt, MooncOpt, MOON_PKG_JSON};
use n2::graph::{self as n2graph, Build, BuildIns, BuildOuts, FileLoc};
use n2::load::State;
use n2::smallmap::SmallMap;
Expand Down Expand Up @@ -350,6 +350,10 @@ pub fn gen_check_command(
.build();
log::debug!("Command: {}", command);
build.cmdline = Some(command);
build.desc = Some(format!(
"check: {}",
get_desc_name(&item.package_full_name, &item.mi_out)
));
build
}

Expand Down
15 changes: 14 additions & 1 deletion crates/moonbuild/src/gen/gen_runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

use anyhow::{bail, Ok};
use colored::Colorize;
use moonutil::common::{DriverKind, GeneratedTestDriver, MOONBITLANG_CORE};
use moonutil::common::{get_desc_name, DriverKind, GeneratedTestDriver, MOONBITLANG_CORE};
use moonutil::module::ModuleDB;
use moonutil::package::Package;

Expand Down Expand Up @@ -801,6 +801,10 @@ pub fn gen_runtest_build_command(
.build();
log::debug!("Command: {}", command);
build.cmdline = Some(command);
build.desc = Some(format!(
"build-package: {}",
get_desc_name(&item.package_full_name, &item.core_out)
));
build
}

Expand Down Expand Up @@ -884,6 +888,10 @@ pub fn gen_runtest_link_command(
.build();
log::debug!("Command: {}", command);
build.cmdline = Some(command);
build.desc = Some(format!(
"link-core: {}",
get_desc_name(&item.package_full_name, &item.out)
));
(build, artifact_id)
}

Expand Down Expand Up @@ -978,5 +986,10 @@ fn gen_generate_test_driver_command(
.build();

build.cmdline = Some(command);
build.desc = Some(format!(
"gen-test-driver: {}_{}_test",
item.package_name,
item.driver_kind.to_string()
));
build
}
4 changes: 4 additions & 0 deletions crates/moonutil/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@ pub struct UniversalFlags {
/// Do not actually run the command
#[clap(long, global = true)]
pub dry_run: bool,

/// generate build graph
#[clap(long, global = true, conflicts_with = "dry_run")]
pub build_graph: bool,
}
Loading

0 comments on commit c2043cf

Please sign in to comment.