apicurio_cli/commands/
mod.rs

1//! Command implementations for the Apicurio CLI
2//!
3//! This module contains all the command implementations for the CLI tool.
4//! Each command is implemented in its own module and handles a specific
5//! aspect of dependency management or registry interaction.
6//!
7//! ## Command Categories
8//!
9//! ### Core Dependency Management
10//! - `init` - Initialize a new project
11//! - `pull` - Fetch dependencies
12//! - `update` - Update dependencies to latest matching versions
13//! - `lock` - Update lock file without downloading
14//!
15//! ### Dependency Lifecycle
16//! - `add` - Add new dependencies
17//! - `remove` - Remove existing dependencies
18//! - `list` - List configured dependencies
19//! - `status` - Check for outdated dependencies
20//!
21//! ### Registry Operations
22//! - `registry` - Manage registry configurations
23//! - `publish` - Publish artifacts to registries
24//!
25//! ### Validation & Utilities
26//! - `verify` - Verify integrity of downloaded files
27//! - `doctor` - Validate configuration and connectivity
28//! - `completions` - Generate shell completion scripts
29
30use anyhow::Result;
31use clap::Subcommand;
32
33pub mod add;
34pub mod completions;
35pub mod doctor;
36pub mod init;
37pub mod list;
38pub mod lock;
39pub mod publish;
40pub mod pull;
41pub mod registry;
42pub mod remove;
43pub mod status;
44pub mod update;
45pub mod verify;
46
47/// All available CLI commands
48///
49/// Each variant corresponds to a subcommand that can be executed.
50/// Commands are organized by functionality and include comprehensive
51/// help text for user guidance.
52#[derive(Subcommand, Debug)]
53pub enum Commands {
54    #[command(about = concat!(
55        "Scaffold a blank config (and empty lock) in a new repo"
56    ))]
57    Init,
58    #[command(
59        about = "Fetch exactly what's in the lock; if no lock, resolve specs ⇒ download ⇒ lock"
60    )]
61    Pull,
62    #[command(
63        about = "Re-resolve semver ranges in config to latest matches; download ⇒ overwrite lock"
64    )]
65    Update,
66    #[command(
67        about = "Add a new dependency entry to the config using format registry/group_id/artifact_id@version"
68    )]
69    Add {
70        #[arg(
71            help = "Dependency identifier in format registry/group_id/artifact_id@version (all parts optional, will prompt for missing)"
72        )]
73        identifier: Option<String>,
74    },
75    #[command(about = "Remove an existing dependency by identifier")]
76    Remove {
77        #[arg(
78            help = "Dependency identifier in format registry/group_id/artifact_id@version (partial matches supported)"
79        )]
80        identifier: String,
81    },
82    #[command(
83        about = "Print all configured deps (spec'd & locked versions), and registries (no network)"
84    )]
85    List,
86    #[command(about = "Compare lock vs. latest matching version in registry; flag outdated deps")]
87    Status,
88    #[command(about = "Re-hash downloaded files & confirm against lockfile hashes")]
89    Verify,
90    #[command(about = "Subcommand: manage global registries file (add/list/remove)")]
91    Registry {
92        #[command(subcommand)]
93        cmd: registry::RegistryCommands,
94    },
95    #[command(
96        about = "Validate config + lock semantics (semver syntax, missing fields, unreachable URLs)"
97    )]
98    Doctor,
99    #[command(about = "Emit shell completion scripts (bash/zsh/fish)")]
100    Completions { shell: String },
101    #[command(about = "Publish to registries")]
102    Publish {
103        #[arg(
104            help = "Specific publish name to publish (if not provided, publishes all configured artifacts)"
105        )]
106        name: Option<String>,
107    },
108    #[command(about = "Update the lockfile based on current dependencies")]
109    Lock,
110}
111
112/// Command dispatcher that routes to the appropriate command implementation
113///
114/// Takes a parsed command and delegates to the corresponding module's run function.
115/// All commands are async to support network operations and file I/O.
116///
117/// # Arguments
118/// * `cmd` - The command to execute
119///
120/// # Returns
121/// Result indicating success or failure of the command execution
122pub async fn run(cmd: Commands) -> Result<()> {
123    match cmd {
124        Commands::Pull => pull::run().await,
125        Commands::Update => update::run().await,
126        Commands::Init => init::run().await,
127        Commands::Add { identifier } => add::run(identifier).await,
128        Commands::Remove { identifier } => remove::run(identifier).await,
129        Commands::List => list::run().await,
130        Commands::Status => status::run().await,
131        Commands::Verify => verify::run().await,
132        Commands::Registry { cmd } => registry::run(cmd).await,
133        Commands::Doctor => doctor::run().await,
134        Commands::Completions { shell } => completions::run(shell),
135        Commands::Publish { name } => publish::run(name).await,
136        Commands::Lock => lock::run().await,
137    }
138}