From a2628a5f630821e03463339ee94279796326ab4b Mon Sep 17 00:00:00 2001 From: Vivian Berger Date: Wed, 5 Jun 2024 17:00:00 +0200 Subject: [PATCH] CLEO -> Implemented auto-completion. --- Cargo.lock | 10 +++++++++ Cargo.toml | 1 + opendut-cleo/Cargo.toml | 1 + opendut-cleo/src/commands/completions.rs | 8 ++++++++ opendut-cleo/src/commands/mod.rs | 1 + opendut-cleo/src/main.rs | 26 +++++++++++++++++++----- 6 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 opendut-cleo/src/commands/completions.rs diff --git a/Cargo.lock b/Cargo.lock index e55f2281d..7cc25c175 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -573,6 +573,15 @@ dependencies = [ "terminal_size", ] +[[package]] +name = "clap_complete" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.5.4" @@ -2760,6 +2769,7 @@ dependencies = [ "anyhow", "assert_fs", "clap", + "clap_complete", "cli-table", "config", "console", diff --git a/Cargo.toml b/Cargo.toml index 603d90ead..71fb65124 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ cargo_toml = "0.18.0" cfg-if = "1.0.0" chrono = { version = "0.4.35", default-features = false } clap = "4.4.18" +clap_complete = "4.5.2" cli-table = "0.4" config = { version = "0.14.0", default-features = false, features = ["toml"] } console = "0.15.8" diff --git a/opendut-cleo/Cargo.toml b/opendut-cleo/Cargo.toml index 06a773c4a..cf543a005 100644 --- a/opendut-cleo/Cargo.toml +++ b/opendut-cleo/Cargo.toml @@ -12,6 +12,7 @@ opendut-util = { workspace = true } clap = { workspace = true, features = ["derive"] } +clap_complete = { workspace = true} cli-table = { workspace = true } config = { workspace = true } console = { workspace = true } diff --git a/opendut-cleo/src/commands/completions.rs b/opendut-cleo/src/commands/completions.rs new file mode 100644 index 000000000..b32ad8c0d --- /dev/null +++ b/opendut-cleo/src/commands/completions.rs @@ -0,0 +1,8 @@ +use std::io; + +use clap::Command; +use clap_complete::{generate, Generator}; + +pub fn print_completions(gen: G, cmd: &mut Command) { + generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout()); +} diff --git a/opendut-cleo/src/commands/mod.rs b/opendut-cleo/src/commands/mod.rs index e718377fb..05406f866 100644 --- a/opendut-cleo/src/commands/mod.rs +++ b/opendut-cleo/src/commands/mod.rs @@ -6,3 +6,4 @@ pub mod network_interface; pub mod executor; pub mod decode_setup_string; pub mod generate_setup_string; +pub mod completions; diff --git a/opendut-cleo/src/main.rs b/opendut-cleo/src/main.rs index 420448573..165762335 100644 --- a/opendut-cleo/src/main.rs +++ b/opendut-cleo/src/main.rs @@ -3,13 +3,14 @@ use std::path::PathBuf; use std::process::ExitCode; use std::str::FromStr; -use clap::{Parser, Subcommand, ValueEnum}; +use clap::{CommandFactory, Parser, Subcommand, ValueEnum}; +use clap_complete::Shell; use console::Style; use opendut_carl_api::carl::CarlClient; use opendut_types::peer::PeerSetup; use opendut_types::topology::DeviceName; -use opendut_util::settings::{FileFormat, load_config}; +use opendut_util::settings::{FileFormat, load_config, LoadedConfig}; mod commands; pub mod parse; @@ -73,6 +74,12 @@ enum Commands { resource: DeleteResource, }, Config, + /// Generates shell completion + Completions { + /// Shell to generate completions for + #[arg(value_enum)] + shell: Shell + }, } #[derive(Subcommand)] @@ -199,7 +206,7 @@ async fn execute() -> Result<()> { .expect("Failed to load config"); // TODO: Point the user to the source of the error. - let mut carl = { + let carl = { let host = settings.config.get_string("network.carl.host") .expect("Configuration should contain a valid host name to connect to CARL"); @@ -220,7 +227,12 @@ async fn execute() -> Result<()> { let args = Args::parse(); - match args.command { + execute_command(args.command, carl, &settings).await?; + Ok(()) +} + +async fn execute_command(commands: Commands, mut carl: CarlClient, settings: &LoadedConfig) -> Result<()>{ + match commands { Commands::List { resource, output } => { match resource { ListResource::ClusterConfigurations(implementation) => { @@ -313,6 +325,10 @@ async fn execute() -> Result<()> { Commands::Config => { println!("Show cleo configuration: {:?}", settings); } + Commands::Completions { shell } => { + let mut cmd = Args::command(); + commands::completions::print_completions(shell, &mut cmd); + } } Ok(()) } @@ -326,4 +342,4 @@ impl FromStr for ParseableSetupString { .map(|setup| ParseableSetupString(Box::new(setup))) .map_err(|error| error.to_string()) } -} +} \ No newline at end of file