canic-host 0.92.5

Host-side build, install, deployment, and fleet-template library for Canic workspaces
Documentation
use crate::{
    canister_build::{CanisterBuildProfile, WorkspaceBuildContext},
    icp::{self, LocalReplicaTarget},
    icp_config::resolve_icp_build_environment_from_root,
    replica_query,
};
use std::path::Path;

pub(super) fn resolve_install_build_context(
    workspace_root: &Path,
    icp_root: &Path,
    config_path: &Path,
    network: &str,
    role: &str,
    build_profile: Option<CanisterBuildProfile>,
) -> Result<WorkspaceBuildContext, Box<dyn std::error::Error>> {
    let profile = build_profile.unwrap_or(CanisterBuildProfile::Release);
    let build_network = resolve_icp_build_environment_from_root(icp_root, network)?;

    Ok(WorkspaceBuildContext {
        role: role.to_string(),
        profile,
        environment: network.to_string(),
        build_network: build_network.as_str().to_string(),
        workspace_root: workspace_root.to_path_buf(),
        icp_root: icp_root.to_path_buf(),
        config_path: config_path.to_path_buf(),
        local_replica: local_replica_icp_target(network, icp_root),
        refresh_canonical_wasm_store_did: false,
    })
}

pub(super) fn local_replica_icp_target(
    network: &str,
    icp_root: &Path,
) -> Option<LocalReplicaTarget> {
    if !replica_query::should_use_local_replica_query(Some(network)) {
        return None;
    }
    if icp_ping(icp_root, network).unwrap_or(false) {
        return None;
    }
    let root_key = replica_query::local_replica_root_key_from_root(Some(network), icp_root)
        .ok()
        .flatten()?;
    Some(LocalReplicaTarget {
        url: replica_query::local_replica_endpoint_from_root(Some(network), icp_root),
        root_key,
    })
}

pub(super) fn ensure_icp_environment_ready(
    icp_root: &Path,
    network: &str,
) -> Result<(), Box<dyn std::error::Error>> {
    if icp_ping(icp_root, network)? {
        return Ok(());
    }
    if replica_query::should_use_local_replica_query(Some(network))
        && replica_query::local_replica_status_reachable_from_root(Some(network), icp_root)
    {
        println!(
            "Replica reachable via HTTP status endpoint even though ICP CLI reports network '{network}' stopped; continuing from ICP root {}.",
            icp_root.display()
        );
        return Ok(());
    }

    Err(format!(
        "icp environment is not running for network '{network}'\nStart the target replica in another terminal with `canic replica start` and rerun."
    )
    .into())
}

fn icp_ping(icp_root: &Path, network: &str) -> Result<bool, Box<dyn std::error::Error>> {
    let mut command = icp::default_command_in(icp_root);
    command.args(["network", "ping", network]);
    Ok(icp::run_success(&mut command)?)
}