Skip to main content

zoi_cli/cmd/
helper.rs

1//! Helper commands for the Zoi CLI.
2//!
3//! These commands are primarily used for internal operations, debugging, or
4//! utility tasks like hashing files and validating configuration.
5
6use anyhow::Result;
7use clap::{Parser, Subcommand};
8
9/// The root helper command.
10#[derive(Parser, Debug)]
11pub struct HelperCommand {
12    /// The specific helper subcommand to execute.
13    #[command(subcommand)]
14    pub command: HelperCommands
15}
16
17/// Available helper subcommands.
18#[derive(Subcommand, Debug)]
19pub enum HelperCommands {
20    /// Get a hash of a local file or a file from a URL
21    GetHash(GetHashCommand),
22
23    /// Validate a Zoi specification file (e.g. registries.json, repo.yaml,
24    /// advisories.json)
25    #[command(alias = "val")]
26    Validate(ValidateCommand),
27
28    /// Internal: Perform escalated installation of a package node (requires
29    /// root)
30    #[command(hide = true)]
31    ElevateInstallNode(ElevateInstallNodeCommand),
32
33    /// Internal: Perform escalated uninstallation of a package (requires root)
34    #[command(hide = true)]
35    ElevateUninstall(ElevateUninstallCommand)
36}
37
38/// Arguments for the escalated install-node command.
39#[derive(Parser, Debug)]
40pub struct ElevateInstallNodeCommand {
41    /// Path to the JSON file containing the serialized `InstallNode`
42    #[arg(long)]
43    pub node_json: std::path::PathBuf,
44    /// Path to the package archive (.zpa)
45    #[arg(long)]
46    pub archive: std::path::PathBuf,
47    /// The install method used (e.g. "source", "pre-compiled")
48    #[arg(long)]
49    pub install_method: String,
50    /// Automatically answer yes to prompts
51    #[arg(long)]
52    pub yes: bool,
53    /// Whether to create shims for binaries
54    #[arg(long)]
55    pub link_bins: bool
56}
57
58/// Arguments for the escalated uninstall command.
59#[derive(Parser, Debug)]
60pub struct ElevateUninstallCommand {
61    /// Path to the JSON file containing the serialized `InstallManifest`
62    #[arg(long)]
63    pub manifest_json: std::path::PathBuf,
64    /// Automatically answer yes to prompts
65    #[arg(long)]
66    pub yes: bool
67}
68
69/// Arguments for the get-hash command.
70#[derive(Parser, Debug)]
71pub struct GetHashCommand {
72    /// The local file path or URL to hash
73    #[arg(required = true)]
74    pub source: String,
75
76    /// The hash algorithm to use
77    #[arg(long, value_enum, default_value = "sha512")]
78    pub hash: HashAlgorithm
79}
80
81/// Arguments for the validate command.
82#[derive(Parser, Debug)]
83pub struct ValidateCommand {
84    /// The local file path to validate
85    #[arg(required = true)]
86    pub file: std::path::PathBuf
87}
88
89/// Supported hash algorithms for the get-hash command.
90#[derive(clap::ValueEnum, Clone, Debug, Copy)]
91pub enum HashAlgorithm {
92    /// SHA-512 algorithm.
93    Sha512,
94    /// SHA-256 algorithm.
95    Sha256
96}
97
98/// Run the helper command.
99///
100/// # Errors
101///
102/// Returns an error if any of the subcommands fail.
103pub fn run(args: HelperCommand) -> Result<()> {
104    match args.command {
105        HelperCommands::GetHash(cmd) => {
106            let hash_type = match cmd.hash {
107                HashAlgorithm::Sha512 => crate::pkg::helper::HashType::Sha512,
108                HashAlgorithm::Sha256 => crate::pkg::helper::HashType::Sha256
109            };
110            let hash = crate::pkg::helper::get_hash(&cmd.source, hash_type)?;
111            println!("{hash}");
112            Ok(())
113        }
114        HelperCommands::Validate(cmd) => {
115            crate::pkg::helper::validate::run(&cmd.file)
116        }
117        HelperCommands::ElevateInstallNode(cmd) => {
118            crate::pkg::helper::elevate_install_node(&cmd)
119        }
120        HelperCommands::ElevateUninstall(cmd) => {
121            crate::pkg::helper::elevate_uninstall(&cmd)
122        }
123    }
124}