diff --git a/Cargo.lock b/Cargo.lock index 7b2a8f1bdd..f5626e8495 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -968,6 +968,15 @@ dependencies = [ "strsim", ] +[[package]] +name = "clap_complete" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f7a2e0a962c45ce25afce14220bc24f9dade0a1787f185cecf96bfba7847cd8" +dependencies = [ + "clap 3.2.24", +] + [[package]] name = "clap_derive" version = "3.2.24" @@ -5585,6 +5594,7 @@ dependencies = [ "cargo-target-dep", "chrono", "clap 3.2.24", + "clap_complete", "clearscreen", "comfy-table", "command-group", @@ -6845,7 +6855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", - "rand 0.7.3", + "rand 0.8.5", "static_assertions", ] diff --git a/Cargo.toml b/Cargo.toml index 6ffa016c4d..80fa2eac15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ bindle = { workspace = true } bytes = "1.1" chrono = "0.4" clap = { version = "3.2.24", features = ["derive", "env"] } +clap_complete = "3.1.4" clearscreen = "2.0.1" command-group = "2.1" comfy-table = "5.0" diff --git a/src/bin/spin.rs b/src/bin/spin.rs index a8a8a96f0e..a08815e57e 100644 --- a/src/bin/spin.rs +++ b/src/bin/spin.rs @@ -8,6 +8,7 @@ use spin_cli::commands::{ cloud::{DeployCommand, LoginCommand}, doctor::DoctorCommand, external::execute_external_subcommand, + generate_completions::GenerateCompletionsCommand, new::{AddCommand, NewCommand}, plugins::PluginCommands, registry::RegistryCommands, @@ -129,6 +130,8 @@ enum SpinApp { Plugins(PluginCommands), #[clap(subcommand, hide = true)] Trigger(TriggerCommands), + #[clap(hide = true, name = "generate-completions")] + GenerateCompletions(GenerateCompletionsCommand), #[clap(external_subcommand)] External(Vec), Watch(WatchCommand), @@ -162,6 +165,7 @@ impl SpinApp { Self::External(cmd) => execute_external_subcommand(cmd, app).await, Self::Watch(cmd) => cmd.run().await, Self::Doctor(cmd) => cmd.run().await, + Self::GenerateCompletions(cmd) => cmd.run(SpinApp::into_app()).await, } } } diff --git a/src/commands.rs b/src/commands.rs index ad8f039728..bf99aaaf98 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -8,6 +8,8 @@ pub mod cloud; pub mod doctor; /// Commands for external subcommands (i.e. plugins) pub mod external; +/// Command to generate shell completions +pub mod generate_completions; /// Command for creating a new application. pub mod new; /// Command for adding a plugin to Spin diff --git a/src/commands/generate_completions.rs b/src/commands/generate_completions.rs new file mode 100644 index 0000000000..7fe37827b3 --- /dev/null +++ b/src/commands/generate_completions.rs @@ -0,0 +1,22 @@ +use anyhow::Result; +use clap::Parser; + +/// Generate shell completions. +#[derive(Parser, Debug)] +#[clap(about = "Generate completions")] +pub struct GenerateCompletionsCommand { + #[clap(value_parser = clap::value_parser!(clap_complete::Shell))] + pub shell: clap_complete::Shell, +} + +impl GenerateCompletionsCommand { + pub async fn run(&self, mut cmd: clap::Command<'_>) -> Result<()> { + // let mut cmd: clap::Command = SpinApp::into_app(); + print_completions(self.shell, &mut cmd); + Ok(()) + } +} + +fn print_completions(gen: G, cmd: &mut clap::Command) { + clap_complete::generate(gen, cmd, cmd.get_name().to_string(), &mut std::io::stdout()) +}