ic_testkit/artifacts/
wasm.rs1use std::{
2 fs,
3 path::{Path, PathBuf},
4 process::Command,
5};
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12pub enum WasmBuildProfile {
13 Debug,
14 Fast,
15 Release,
16}
17
18impl WasmBuildProfile {
19 #[must_use]
21 pub const fn cargo_args(self) -> &'static [&'static str] {
22 match self {
23 Self::Debug => &[],
24 Self::Fast => &["--profile", "fast"],
25 Self::Release => &["--release"],
26 }
27 }
28
29 #[must_use]
31 pub const fn target_dir_name(self) -> &'static str {
32 match self {
33 Self::Debug => "debug",
34 Self::Fast => "fast",
35 Self::Release => "release",
36 }
37 }
38}
39
40#[must_use]
42pub fn wasm_path(target_dir: &Path, crate_name: &str, profile: WasmBuildProfile) -> PathBuf {
43 target_dir
44 .join("wasm32-unknown-unknown")
45 .join(profile.target_dir_name())
46 .join(format!("{crate_name}.wasm"))
47}
48
49#[must_use]
51pub fn wasm_artifacts_ready(
52 target_dir: &Path,
53 canisters: &[&str],
54 profile: WasmBuildProfile,
55) -> bool {
56 canisters
57 .iter()
58 .all(|name| wasm_path(target_dir, name, profile).is_file())
59}
60
61#[must_use]
63pub fn read_wasm(target_dir: &Path, crate_name: &str, profile: WasmBuildProfile) -> Vec<u8> {
64 let path = wasm_path(target_dir, crate_name, profile);
65 fs::read(&path).unwrap_or_else(|err| panic!("failed to read {crate_name} wasm: {err}"))
66}
67
68pub fn build_wasm_canisters(
70 workspace_root: &Path,
71 target_dir: &Path,
72 packages: &[&str],
73 profile: WasmBuildProfile,
74 extra_env: &[(&str, &str)],
75) {
76 let mut cmd = cargo_command();
77 cmd.current_dir(workspace_root);
78 cmd.env("CARGO_TARGET_DIR", target_dir);
79 cmd.args(["build", "--target", "wasm32-unknown-unknown"]);
80 cmd.args(profile.cargo_args());
81
82 for (key, value) in extra_env {
83 cmd.env(key, value);
84 }
85
86 for name in packages {
87 cmd.args(["-p", name]);
88 }
89
90 let output = cmd.output().expect("failed to run cargo build");
91 assert!(
92 output.status.success(),
93 "cargo build failed: {}",
94 String::from_utf8_lossy(&output.stderr)
95 );
96}
97
98fn cargo_command() -> Command {
99 let cargo = std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into());
100 let mut command = Command::new(cargo);
101
102 if let Some(toolchain) = std::env::var_os("RUSTUP_TOOLCHAIN") {
103 command.env("RUSTUP_TOOLCHAIN", toolchain);
104 }
105
106 command
107}