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}