feat(3216): swarmctl shell completions
Mirrors hivectl exactly: a `completions <shell>` verb that walks the live clap tree, and a package that pipes it into installShellCompletion for bash/zsh/fish. Generating from the command tree rather than writing a script by hand is what keeps completions from drifting away from the verbs they complete — the same reason `markdown-docs` renders the docs from that tree. Dispatched before PathArgs::resolve() for the same reason markdown-docs is: emitting a completion script needs none of the SWARMCTL_AUTHELIA_* deployment env vars, and requiring them would make the package's own build-time invocation fail — exactly where it runs. swarmctl leaves mkBinPackage for its own derivation, since the extractor installs a binary and nothing else.
This commit is contained in:
parent
0b1b08dfe6
commit
75f99ecafb
5 changed files with 72 additions and 1 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -4439,6 +4439,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
"clap-markdown",
|
"clap-markdown",
|
||||||
|
"clap_complete",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ This document contains the help content for the `swarmctl` command-line program.
|
||||||
* [`swarmctl user`↴](#swarmctl-user)
|
* [`swarmctl user`↴](#swarmctl-user)
|
||||||
* [`swarmctl user add`↴](#swarmctl-user-add)
|
* [`swarmctl user add`↴](#swarmctl-user-add)
|
||||||
* [`swarmctl user update`↴](#swarmctl-user-update)
|
* [`swarmctl user update`↴](#swarmctl-user-update)
|
||||||
|
* [`swarmctl completions`↴](#swarmctl-completions)
|
||||||
|
|
||||||
## `swarmctl`
|
## `swarmctl`
|
||||||
|
|
||||||
|
|
@ -18,6 +19,7 @@ swarm-level operator CLI
|
||||||
###### **Subcommands:**
|
###### **Subcommands:**
|
||||||
|
|
||||||
* `user` — Manage subjects in the swarm's SSO provider
|
* `user` — Manage subjects in the swarm's SSO provider
|
||||||
|
* `completions` — Generate a shell completion script for `swarmctl` and print it to stdout
|
||||||
|
|
||||||
###### **Options:**
|
###### **Options:**
|
||||||
|
|
||||||
|
|
@ -81,6 +83,25 @@ Every flag is optional and they compose, so one call can set several things at o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `swarmctl completions`
|
||||||
|
|
||||||
|
Generate a shell completion script for `swarmctl` and print it to stdout.
|
||||||
|
|
||||||
|
Supports bash, zsh, fish, elvish and powershell. The nix package already installs bash/zsh/fish system-wide; this is for ad-hoc or other-shell use.
|
||||||
|
|
||||||
|
Dispatched before `PathArgs::resolve()` for the same reason as `markdown-docs`: emitting a completion script needs none of the `SWARMCTL_AUTHELIA_*` deployment env vars, and requiring them would make the package's own build-time invocation fail.
|
||||||
|
|
||||||
|
**Usage:** `swarmctl completions <SHELL>`
|
||||||
|
|
||||||
|
###### **Arguments:**
|
||||||
|
|
||||||
|
* `<SHELL>` — Shell to emit completions for
|
||||||
|
|
||||||
|
Possible values: `bash`, `elvish`, `fish`, `powershell`, `zsh`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
<small><i>
|
<small><i>
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,27 @@ in
|
||||||
# the one host that runs the controller, and belongs in that hive's
|
# the one host that runs the controller, and belongs in that hive's
|
||||||
# closure only. Kept a separate derivation rather than a second binary
|
# closure only. Kept a separate derivation rather than a second binary
|
||||||
# in the daemon's package so a hive can pin one without the other.
|
# in the daemon's package so a hive can pin one without the other.
|
||||||
swarmctl = mkBinPackage "swarmctl" "hyperhive swarm-level operator CLI";
|
#
|
||||||
|
# Not `mkBinPackage`, because of the completions: they come from the
|
||||||
|
# binary's own `completions <shell>` verb, which walks the live clap
|
||||||
|
# tree, so they cannot drift from the actual verbs. Same shape as
|
||||||
|
# `hivectlPkg` above.
|
||||||
|
swarmctl =
|
||||||
|
pkgs.runCommand "swarmctl"
|
||||||
|
{
|
||||||
|
nativeBuildInputs = [ pkgs.installShellFiles ];
|
||||||
|
meta = {
|
||||||
|
description = "hyperhive swarm-level operator CLI";
|
||||||
|
mainProgram = "swarmctl";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
''
|
||||||
|
install -Dm755 ${workspaceBuild}/bin/swarmctl $out/bin/swarmctl
|
||||||
|
installShellCompletion --cmd swarmctl \
|
||||||
|
--bash <("$out/bin/swarmctl" completions bash) \
|
||||||
|
--zsh <("$out/bin/swarmctl" completions zsh) \
|
||||||
|
--fish <("$out/bin/swarmctl" completions fish)
|
||||||
|
'';
|
||||||
|
|
||||||
# Static build of the swarm-level UI shell — see ./swarm-ui.nix. Same
|
# Static build of the swarm-level UI shell — see ./swarm-ui.nix. Same
|
||||||
# "swarm-scoped, not core-bundle" reasoning as swarm-controller/swarmctl
|
# "swarm-scoped, not core-bundle" reasoning as swarm-controller/swarmctl
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ path = "src/main.rs"
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
clap.workspace = true
|
clap.workspace = true
|
||||||
clap-markdown = "0.1"
|
clap-markdown = "0.1"
|
||||||
|
clap_complete.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,21 @@ enum Verb {
|
||||||
/// outside a real deployment — exactly where the docs build runs it.
|
/// outside a real deployment — exactly where the docs build runs it.
|
||||||
#[command(hide = true)]
|
#[command(hide = true)]
|
||||||
MarkdownDocs,
|
MarkdownDocs,
|
||||||
|
/// Generate a shell completion script for `swarmctl` and print it to
|
||||||
|
/// stdout.
|
||||||
|
///
|
||||||
|
/// Supports bash, zsh, fish, elvish and powershell. The nix package
|
||||||
|
/// already installs bash/zsh/fish system-wide; this is for ad-hoc or
|
||||||
|
/// other-shell use.
|
||||||
|
///
|
||||||
|
/// Dispatched before `PathArgs::resolve()` for the same reason as
|
||||||
|
/// `markdown-docs`: emitting a completion script needs none of the
|
||||||
|
/// `SWARMCTL_AUTHELIA_*` deployment env vars, and requiring them would
|
||||||
|
/// make the package's own build-time invocation fail.
|
||||||
|
Completions {
|
||||||
|
/// Shell to emit completions for.
|
||||||
|
shell: clap_complete::Shell,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
|
|
@ -209,6 +224,19 @@ fn main() -> Result<()> {
|
||||||
print!("{}", clap_markdown::help_markdown::<Cli>());
|
print!("{}", clap_markdown::help_markdown::<Cli>());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Verb::Completions { shell } => {
|
||||||
|
// Generated from the live clap tree — the same single source
|
||||||
|
// of truth `markdown-docs` renders — so completions cannot
|
||||||
|
// drift from the actual verbs and flags.
|
||||||
|
use clap::CommandFactory as _;
|
||||||
|
clap_complete::generate(
|
||||||
|
shell,
|
||||||
|
&mut Cli::command(),
|
||||||
|
"swarmctl",
|
||||||
|
&mut std::io::stdout(),
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue