diff --git a/Cargo.lock b/Cargo.lock index 4160e14..8f1c0d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,6 +204,15 @@ dependencies = [ "strsim", ] +[[package]] +name = "clap_complete" +version = "4.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbca90c87c2a04da41e95d1856e8bcd22f159bdbfa147314d2ce5218057b0e58" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.5.5" @@ -298,6 +307,7 @@ dependencies = [ "ansi_term", "chrono", "clap", + "clap_complete", "console", "dialoguer", "dirs", diff --git a/Cargo.toml b/Cargo.toml index 85aa90a..0b34993 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,3 +22,4 @@ tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } urlencoding = "2.1.3" openssl = { version = "0.10", features = ["vendored"] } +clap_complete = "4.5.6" diff --git a/src/cli/args.rs b/src/cli/args.rs index 98f8bc6..f6a7128 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -1,12 +1,18 @@ use crate::cli::config::get_config_dir; use ansi_term::Colour; -use clap::{Parser, Subcommand}; +use clap::{Command, CommandFactory, Parser, Subcommand}; +use clap_complete::{generate, Generator, Shell}; use dialoguer::{theme::ColorfulTheme, Select}; +use std::io; #[derive(Parser)] -#[command(author, version, about, long_about = None)] +#[command(name = "elasticnow", about = "ElasticNow time tracking CLI", version)] pub struct Args { + // If provided, outputs the completion file for given shell + #[arg(long = "generate", value_enum)] + generator: Option, + #[command(subcommand)] - pub cmd: Commands, + pub cmd: Option, } #[derive(Subcommand, Debug, Clone)] @@ -56,7 +62,13 @@ pub enum Commands { } pub fn get_args() -> Args { - Args::parse() + let args = Args::parse(); + if let Some(shell) = args.generator { + let mut cmd = Args::command(); + print_completions(shell, &mut cmd); + std::process::exit(0); + } + args } pub fn choose_options(mut options: Vec) -> String { @@ -77,3 +89,7 @@ pub fn write_short_description() -> String { .interact() .unwrap() } + +pub fn print_completions(gen: G, cmd: &mut Command) { + generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout()); +} diff --git a/src/main.rs b/src/main.rs index 346feaf..8432ae5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +use std::process::exit; + use ansi_term::Colour; use elasticnow::cli::{self, config}; use elasticnow::elasticnow::elasticnow::{ElasticNow, SearchResult}; @@ -12,25 +14,28 @@ async fn main() { .init(); let args = cli::args::get_args(); match args.cmd { - cli::args::Commands::Timetrack { + Some(cli::args::Commands::Timetrack { new, comment, time_worked, search, bin, - } => { + }) => { run_timetrack(new, comment, time_worked, search, bin).await; } - cli::args::Commands::Setup { + Some(cli::args::Commands::Setup { id, instance, sn_instance, sn_username, sn_password, bin, - } => { + }) => { run_setup(id, instance, sn_instance, sn_username, sn_password, bin).await; } + _ => { + std::process::exit(1); + } } }