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