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;
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;