Skip to main content

harmont_cli/
cli.rs

1use clap::{Parser, Subcommand};
2use std::path::PathBuf;
3
4#[derive(Debug, Parser)]
5#[command(
6    name = "hm",
7    version,
8    about = "hm — CLI for the Harmont CI platform",
9    long_about = "hm is the command-line interface for Harmont.\n\n\
10                   Run `hm run` to push local code through a pipeline without committing.",
11    propagate_version = true,
12    arg_required_else_help = true,
13    disable_help_subcommand = true
14)]
15pub struct Cli {
16    /// Override the API base URL. Hidden flag — set `HARMONT_API_URL` instead.
17    #[arg(long, global = true, env = "HARMONT_API_URL", hide = true)]
18    pub api_url: Option<String>,
19
20    /// Enable verbose/debug logging.
21    #[arg(long, short, global = true)]
22    pub verbose: bool,
23
24    /// Disable colored output.
25    #[arg(long, global = true)]
26    pub no_color: bool,
27
28    #[command(subcommand)]
29    pub command: Command,
30}
31
32#[derive(Debug, Clone, Subcommand)]
33pub enum Command {
34    /// Run a pipeline locally via Docker.
35    Run(RunArgs),
36
37    /// Show hm version and plugin protocol API version.
38    Version,
39
40    /// Manage plugins.
41    #[command(subcommand)]
42    Plugin(PluginCommand),
43
44    /// Plugin-provided subcommand. Captured raw; the dispatcher
45    /// looks it up in the registry and invokes the matching plugin.
46    #[command(external_subcommand)]
47    External(Vec<String>),
48}
49
50// ---------------------------------------------------------------------------
51// Run (the killer feature)
52// ---------------------------------------------------------------------------
53
54#[derive(Debug, Clone, Parser)]
55pub struct RunArgs {
56    /// Pipeline slug. Required when the repo declares more than one
57    /// `@hm.pipeline`; the CLI lists available slugs when omitted.
58    #[arg()]
59    pub pipeline: Option<String>,
60
61    /// Branch to record on the build.
62    #[arg(short, long)]
63    pub branch: Option<String>,
64
65    /// Build message.
66    #[arg(short, long)]
67    pub message: Option<String>,
68
69    /// Environment variables (KEY=VALUE).
70    #[arg(short, long)]
71    pub env: Vec<String>,
72
73    /// Source root (defaults to cwd).
74    #[arg(short, long)]
75    pub dir: Option<PathBuf>,
76
77    /// Skip watching the build after it's created.
78    #[arg(long)]
79    pub no_watch: bool,
80
81    /// Maximum number of chains to run concurrently. Defaults to the
82    /// host's available parallelism. `0` is treated as `1`.
83    #[arg(long, value_name = "N")]
84    pub parallelism: Option<usize>,
85
86    /// Output formatter (matches an installed output-formatter plugin
87    /// `name`). Built-ins: `human`, `json`. Default: `human`.
88    #[arg(long, value_name = "NAME", default_value = "human", global = false)]
89    pub format: String,
90}
91
92// ---------------------------------------------------------------------------
93// Plugin
94// ---------------------------------------------------------------------------
95
96#[derive(Debug, Clone, Subcommand)]
97pub enum PluginCommand {
98    /// List installed plugins (embedded + user + project).
99    List,
100
101    /// Show one plugin's manifest in detail.
102    Info {
103        /// Plugin name (matches `name` field of the manifest).
104        name: String,
105    },
106
107    /// Install a plugin from a file path or HTTPS URL.
108    ///
109    /// HTTPS URLs require `--pin <sha256>` for integrity.
110    Install {
111        /// Plugin source: local path (`./foo.wasm`) or HTTPS URL.
112        source: String,
113
114        /// SHA-256 hex digest to verify against. Required for HTTPS
115        /// sources; optional for local paths.
116        #[arg(long, value_name = "SHA256_HEX")]
117        pin: Option<String>,
118    },
119
120    /// Remove an installed plugin by name.
121    Remove {
122        /// Plugin name.
123        name: String,
124    },
125}