Skip to main content

canic_host/
lib.rs

1//! Host-side App build and desired-state Fleet reconciliation for Canic workspaces.
2
3use std::{
4    io,
5    process::{Command, Output},
6    thread,
7    time::Duration,
8};
9
10const EXECUTABLE_BUSY_RETRY_ATTEMPTS: usize = 8;
11const EXECUTABLE_BUSY_RETRY_DELAY: Duration = Duration::from_millis(10);
12
13mod artifact_io;
14pub mod binaryen;
15mod bootstrap_candid;
16mod bootstrap_coordinator;
17mod bootstrap_pool_ledger_recovery;
18mod bootstrap_store;
19mod build_profile;
20pub mod build_provenance;
21pub mod candid_endpoints;
22pub mod canic_metadata;
23pub mod canister_build;
24mod canister_protocol;
25pub use canister_protocol::{
26    CanisterProtocolError, call_with_arg as call_canister_with_arg,
27    query_with_arg as query_canister_with_arg,
28};
29pub mod canister_ready;
30mod cargo_metadata;
31pub mod component_topology;
32pub mod config_discovery;
33pub mod cycle_balance;
34pub mod diagnostics;
35pub mod durable_io;
36mod entropy;
37pub mod evidence_envelope;
38pub mod fleet_catalog;
39pub mod fleet_ensure;
40pub mod format;
41pub mod icp;
42pub mod icp_config;
43pub mod network;
44pub mod policy_gate;
45pub mod protocol_binding;
46pub mod registry;
47pub mod release_build;
48pub mod release_set;
49pub mod replica_query;
50pub mod role_contract;
51pub mod state_manifest;
52pub mod subnet_catalog;
53pub mod table;
54pub mod terminal;
55#[cfg(test)]
56mod test_support;
57mod workspace_discovery;
58
59pub(crate) fn cargo_command() -> Command {
60    let cargo = std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into());
61    let mut command = Command::new(cargo);
62
63    if let Some(toolchain) = std::env::var_os("RUSTUP_TOOLCHAIN") {
64        command.env("RUSTUP_TOOLCHAIN", toolchain);
65    }
66    command
67}
68
69pub(crate) fn output_with_executable_busy_retry(command: &mut Command) -> io::Result<Output> {
70    for attempt in 0..EXECUTABLE_BUSY_RETRY_ATTEMPTS {
71        match command.output() {
72            Err(error)
73                if error.kind() == io::ErrorKind::ExecutableFileBusy
74                    && attempt + 1 < EXECUTABLE_BUSY_RETRY_ATTEMPTS =>
75            {
76                thread::sleep(EXECUTABLE_BUSY_RETRY_DELAY);
77            }
78            result => return result,
79        }
80    }
81    unreachable!("bounded executable-busy retry always returns on its final attempt")
82}
83
84pub(crate) fn should_embed_candid_metadata(build_network: canic_core::ids::BuildNetwork) -> bool {
85    build_network == canic_core::ids::BuildNetwork::Local
86}
87
88#[cfg(test)]
89mod tests;