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