Skip to main content

release_kit/cli/
stage.rs

1//! Arguments for `rk stage`.
2
3use camino::Utf8PathBuf;
4use clap::{Args, Subcommand};
5
6use super::profile_flags::ProfileFlags;
7
8/// Write the candidate this binary would land in a target into a
9/// disposable stage, beside the knowledge that explains it.
10///
11/// Reads the target and writes nothing inside it. The stage holds every
12/// proposed destination under `artifacts/`, the changelog, guidance,
13/// method, bindings, runbooks, forge notes, and setup skill under
14/// `reference/`, and one explanatory `stage.json`. Production landing
15/// never reads a stage; `rk stage clean <path>` removes one.
16#[derive(Debug, Args)]
17#[expect(
18    clippy::struct_excessive_bools,
19    reason = "each field is one clap flag, and an opt-in capability's flag is a boolean by design; a state machine would hide the command line this struct describes"
20)]
21pub struct StageArgs {
22    /// The one companion: remove a stage.
23    #[command(subcommand)]
24    pub action: Option<StageAction>,
25
26    /// The project profile and the Git workflow the candidate renders
27    /// under.
28    #[command(flatten)]
29    pub profile: ProfileFlags,
30
31    /// The repository the candidate is computed for; read, never written.
32    #[arg(long, default_value = ".")]
33    pub target: Utf8PathBuf,
34
35    /// Stage the Nix capability too.
36    #[arg(long, alias = "nix")]
37    pub nix_packaging: bool,
38
39    /// Stage the reporting policy too.
40    #[arg(long)]
41    pub reporting_policy: bool,
42
43    /// Stage the Scorecard capability too.
44    #[arg(long)]
45    pub scorecard: bool,
46
47    /// Stage the workflow guards too.
48    #[arg(long)]
49    pub workflow_guards: bool,
50
51    /// Stage the code scanning capability under this provider: codeql or
52    /// semgrep.
53    #[arg(long, value_name = "PROVIDER")]
54    pub code_scanning: Option<String>,
55
56    /// The exact directory to stage into; it must be absent or empty.
57    /// Without it, a target and version directory below `RK_STAGE_ROOT`,
58    /// else below the private state root.
59    #[arg(long)]
60    pub output: Option<Utf8PathBuf>,
61
62    /// Emit one JSON object on stdout instead of the human report.
63    #[arg(long)]
64    pub json: bool,
65}
66
67/// The stage subcommands.
68#[derive(Debug, Subcommand)]
69pub enum StageAction {
70    /// Remove exactly one stage directory, which must name itself in its
71    /// own stage.json.
72    Clean {
73        /// The stage directory, as `rk stage` printed it. No glob, no
74        /// parent, no link.
75        path: Utf8PathBuf,
76        /// Emit one JSON object on stdout instead of the human report.
77        #[arg(long)]
78        json: bool,
79    },
80
81    /// Compare a stage with the target: one row per destination, its
82    /// state, its kind, its provenance, and the word the landing prints.
83    Compare {
84        /// The stage directory, as `rk stage` printed it.
85        root: Utf8PathBuf,
86        /// The repository the stage was taken for.
87        #[arg(long, default_value = ".")]
88        target: Utf8PathBuf,
89        /// Emit one JSON object on stdout instead of the human report.
90        #[arg(long)]
91        json: bool,
92    },
93}