Skip to main content

build_artifact/
build_artifact.rs

1use canic_host::canister_build::{
2    CanisterBuildProfile, WorkspaceBuildContext, build_workspace_canister_artifact,
3    copy_icp_wasm_output, print_workspace_build_context_once,
4};
5use canic_host::icp_config::resolve_icp_build_environment_from_root;
6use std::path::{Path, PathBuf};
7
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9    let mut args = std::env::args().skip(1);
10    let (
11        Some(canister_name),
12        Some(profile),
13        Some(workspace_root),
14        Some(icp_root),
15        Some(config_path),
16    ) = (
17        args.next(),
18        args.next(),
19        args.next(),
20        args.next(),
21        args.next(),
22    )
23    else {
24        return Err(
25            "usage: cargo run -p canic-host --example build_artifact -- <canister-name> <debug|fast|release> <workspace-root> <icp-root> <config-path> [--refresh-wasm-store-did]"
26                .into(),
27        );
28    };
29    let refresh_canonical_wasm_store_did = match args.next().as_deref() {
30        None => false,
31        Some("--refresh-wasm-store-did") if canister_name == "wasm_store" => true,
32        Some("--refresh-wasm-store-did") => {
33            return Err("--refresh-wasm-store-did requires canister-name wasm_store".into());
34        }
35        Some(_) => return Err("unknown build_artifact argument".into()),
36    };
37    if args.next().is_some() {
38        return Err("build_artifact accepts at most six arguments".into());
39    }
40    let profile = profile.parse::<CanisterBuildProfile>()?;
41
42    let workspace_root = PathBuf::from(workspace_root).canonicalize()?;
43    let icp_root = PathBuf::from(icp_root).canonicalize()?;
44    let config_path = resolve_path(&workspace_root, &config_path).canonicalize()?;
45    let environment = std::env::var("ICP_ENVIRONMENT").unwrap_or_else(|_| "local".to_string());
46    let build_network = resolve_icp_build_environment_from_root(&icp_root, &environment)?;
47    let context = WorkspaceBuildContext {
48        role: canister_name.clone(),
49        profile,
50        environment,
51        build_network: build_network.as_str().to_string(),
52        config_path,
53        workspace_root,
54        icp_root,
55        local_replica: None,
56        refresh_canonical_wasm_store_did,
57    };
58    print_workspace_build_context_once(&context)?;
59    let output = build_workspace_canister_artifact(&context)?;
60    copy_icp_wasm_output(&canister_name, &output)?;
61    println!("{}", output.wasm_gz_path.display());
62    Ok(())
63}
64
65fn resolve_path(root: &Path, path: &str) -> PathBuf {
66    let path = PathBuf::from(path);
67    if path.is_absolute() {
68        path
69    } else {
70        root.join(path)
71    }
72}