mirror of
https://github.com/containers/bootc.git
synced 2026-02-05 15:45:53 +01:00
cli: Add shell completion generation command
- Add completion subcommand supporting bash, zsh, and fish Assisted-by: Cursor (Auto) Signed-off-by: Shion Tanaka <shtanaka@redhat.com>
This commit is contained in:
committed by
Colin Walters
parent
0ee11dbfe2
commit
d2eb1b69e2
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -239,6 +239,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"chrono",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_mangen",
|
||||
"comfy-table",
|
||||
"composefs",
|
||||
@@ -508,6 +509,15 @@ dependencies = [
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39615915e2ece2550c0149addac32fb5bd312c657f43845bb9088cb9c8a7c992"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.49"
|
||||
|
||||
@@ -33,6 +33,7 @@ cap-std-ext = { workspace = true, features = ["fs_utf8"] }
|
||||
cfg-if = { workspace = true }
|
||||
chrono = { workspace = true, features = ["serde"] }
|
||||
clap = { workspace = true, features = ["derive","cargo"] }
|
||||
clap_complete = "4"
|
||||
clap_mangen = { workspace = true, optional = true }
|
||||
composefs = { workspace = true }
|
||||
composefs-boot = { workspace = true }
|
||||
|
||||
@@ -12,6 +12,7 @@ use anyhow::{anyhow, ensure, Context, Result};
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use cap_std_ext::cap_std;
|
||||
use cap_std_ext::cap_std::fs::Dir;
|
||||
use clap::CommandFactory;
|
||||
use clap::Parser;
|
||||
use clap::ValueEnum;
|
||||
use composefs::dumpfile;
|
||||
@@ -745,6 +746,15 @@ pub(crate) enum Opt {
|
||||
/// Diff current /etc configuration versus default
|
||||
#[clap(hide = true)]
|
||||
ConfigDiff,
|
||||
/// Generate shell completion script for supported shells.
|
||||
///
|
||||
/// Example: `bootc completion bash` prints a bash completion script to stdout.
|
||||
#[clap(hide = true)]
|
||||
Completion {
|
||||
/// Shell type to generate (bash, zsh, fish)
|
||||
#[clap(value_enum)]
|
||||
shell: clap_complete::aot::Shell,
|
||||
},
|
||||
#[clap(hide = true)]
|
||||
DeleteDeployment {
|
||||
depl_id: String,
|
||||
@@ -1582,6 +1592,15 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
Opt::Completion { shell } => {
|
||||
use clap_complete::aot::generate;
|
||||
|
||||
let mut cmd = Opt::command();
|
||||
let mut stdout = std::io::stdout();
|
||||
let bin_name = "bootc";
|
||||
generate(shell, &mut cmd, bin_name, &mut stdout);
|
||||
Ok(())
|
||||
}
|
||||
Opt::Image(opts) => match opts {
|
||||
ImageOpts::List {
|
||||
list_type,
|
||||
@@ -2012,4 +2031,29 @@ mod tests {
|
||||
]));
|
||||
assert_eq!(args.as_slice(), ["container", "image", "pull"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generate_completion_scripts_contain_commands() {
|
||||
use clap_complete::aot::{generate, Shell};
|
||||
|
||||
// For each supported shell, generate the completion script and
|
||||
// ensure obvious subcommands appear in the output. This mirrors
|
||||
// the style of completion checks used in other projects (e.g.
|
||||
// podman) where the generated script is examined for expected
|
||||
// tokens.
|
||||
|
||||
// `completion` is intentionally hidden from --help / suggestions;
|
||||
// ensure other visible subcommands are present instead.
|
||||
let want = ["install", "upgrade"];
|
||||
|
||||
for shell in [Shell::Bash, Shell::Zsh, Shell::Fish] {
|
||||
let mut cmd = Opt::command();
|
||||
let mut buf = Vec::new();
|
||||
generate(shell, &mut cmd, "bootc", &mut buf);
|
||||
let s = String::from_utf8(buf).expect("completion should be utf8");
|
||||
for w in &want {
|
||||
assert!(s.contains(w), "{shell:?} completion missing {w}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user