canic-cli 0.65.17

Operator CLI for Canic fleet setup, builds, evidence, catalog, backup, and restore workflows
Documentation
use super::value_arg;
use crate::cli::{
    clap::{passthrough_subcommand, render_usage},
    globals::internal_network_arg,
};
use canic_host::canister_build::CanisterBuildProfile;
use clap::Command as ClapCommand;

pub(super) const DEPLOYMENT_ARG: &str = "deployment";
pub(super) const PROFILE_ARG: &str = "profile";

#[derive(Clone, Copy)]
struct DeploySubcommand {
    name: &'static str,
    about: &'static str,
}

const DEPLOY_COMMANDS: &[DeploySubcommand] = &[
    DeploySubcommand {
        name: "authority",
        about: "Dry-run controller authority reconciliation",
    },
    DeploySubcommand {
        name: "external",
        about: "Build passive external lifecycle reports",
    },
    DeploySubcommand {
        name: "promote",
        about: "Build passive artifact promotion reports",
    },
    DeploySubcommand {
        name: "root",
        about: "Inspect or verify deployment-root evidence",
    },
    DeploySubcommand {
        name: "install",
        about: "Install through the current runner using a supplied deployment plan",
    },
    DeploySubcommand {
        name: "register",
        about: "Register minimal deployment-target state",
    },
    DeploySubcommand {
        name: "check",
        about: "Print the local deployment truth check",
    },
    DeploySubcommand {
        name: "inspect",
        about: "Inspect raw deployment truth artifacts",
    },
];

const DEPLOY_HELP_AFTER: &str = "\
Examples:
  canic deploy check demo
  canic deploy check demo --format text
  canic deploy inspect plan demo
  canic deploy inspect compare --left staging-check.json --right prod-check.json
  canic deploy inspect catalog list
  canic deploy inspect root --request root-verification.json
  canic deploy inspect resume-report --receipt receipt.json demo
  canic deploy register demo --fleet-template demo --root aaaaa-aa --allow-unverified
  canic deploy install demo-local --plan promoted-plan.json
  canic deploy authority check demo
  canic deploy external plan demo
  canic deploy promote plan --request promotion-plan.json
  canic deploy root verify demo-local --from-check deployment-check.json

Use `canic deploy inspect help` for raw plan, inventory, diff, report,
comparison, local catalog, root-verification, and resume-safety JSON artifacts.
Plan-mediated deployment-target mutation flows through `canic deploy install
<deployment> --plan <file>`. `canic install <fleet>` remains the fleet-template
bootstrap entrypoint.";

pub fn deploy_command() -> ClapCommand {
    DEPLOY_COMMANDS
        .iter()
        .fold(
            ClapCommand::new("deploy")
                .bin_name("canic deploy")
                .about("Check deployment truth before mutation")
                .disable_help_flag(true),
            |command, subcommand| command.subcommand(deploy_passthrough_command(*subcommand)),
        )
        .after_help(DEPLOY_HELP_AFTER)
}

pub fn deploy_truth_leaf_command(name: &'static str, about: &'static str) -> ClapCommand {
    deploy_truth_leaf_command_with_bin_name(name, format!("canic deploy {name}"), about)
}

pub(super) fn deploy_truth_leaf_command_with_bin_name(
    name: &'static str,
    bin_name: impl Into<String>,
    about: &'static str,
) -> ClapCommand {
    ClapCommand::new(name)
        .bin_name(bin_name.into())
        .about(about)
        .disable_help_flag(true)
        .arg(
            value_arg(DEPLOYMENT_ARG)
                .value_name(DEPLOYMENT_ARG)
                .required(true)
                .help("Deployment target name to check"),
        )
        .arg(
            value_arg(PROFILE_ARG)
                .long(PROFILE_ARG)
                .value_name("debug|fast|release")
                .num_args(1)
                .value_parser(clap::value_parser!(CanisterBuildProfile))
                .help("Expected canister wasm build profile"),
        )
        .arg(internal_network_arg())
}

pub fn usage() -> String {
    render_usage(deploy_command)
}

fn deploy_passthrough_command(spec: DeploySubcommand) -> ClapCommand {
    passthrough_subcommand(
        ClapCommand::new(spec.name)
            .about(spec.about)
            .disable_help_flag(true),
    )
}