From 4a8f7a74d20d3e66d61119b4624cd97d28924f49 Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Sun, 19 Jun 2022 12:37:40 -0400 Subject: [PATCH] reimplement completion subcommand --- Cargo.lock | 26 ++++++++++++++++++-------- Cargo.toml | 1 + src/cli.rs | 12 +++++++++--- src/main.rs | 40 ++++++++++++++++++++-------------------- 4 files changed, 48 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9d684f..2ff717f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,26 +183,35 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.18" +version = "3.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" +checksum = "d53da17d37dba964b9b3ecb5c5a1f193a2762c700e6829201e645b9381c99dc7" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", "indexmap", - "lazy_static 1.4.0", + "once_cell", "strsim", "termcolor", "textwrap", ] [[package]] -name = "clap_derive" -version = "3.1.18" +name = "clap_complete" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" +checksum = "0f6ebaab5f25e4f0312dfa07cb30a755204b96e6531457c2cfdecfdf5f2adf40" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_derive" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11d40217d16aee8508cc8e5fde8b4ff24639758608e5374e731b53f85749fb9" dependencies = [ "heck", "proc-macro-error", @@ -213,9 +222,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" dependencies = [ "os_str_bytes", ] @@ -1859,6 +1868,7 @@ dependencies = [ "base64", "block-modes", "clap", + "clap_complete", "cookie 0.14.4", "dirs", "hmac-sha1", diff --git a/Cargo.toml b/Cargo.toml index 791a2fb..caf1ed4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ rsa = "0.5.0" rand = "0.8.4" standback = "0.2.17" # required to fix a compilation error on a transient dependency clap = { version = "3.1.18", features = ["derive", "cargo"] } +clap_complete = "3.2.1" log = "0.4.14" stderrlog = "0.4" cookie = "0.14" diff --git a/src/cli.rs b/src/cli.rs index 51f7590..d085681 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,5 +1,6 @@ use std::str::FromStr; use clap::Parser; +use clap_complete::Shell; #[derive(Debug, Clone, Parser)] #[clap(author, version, about = "Generate Steam 2FA codes and confirm Steam trades from the command line.", long_about = None)] @@ -23,9 +24,7 @@ pub(crate) struct Args { #[derive(Debug, Clone, Parser)] pub(crate) enum Subcommands { Debug(ArgsDebug), - // Completions { - // TODO: Add completions - // }, + Completion(ArgsCompletions), Setup(ArgsSetup), Import(ArgsImport), Trade(ArgsTrade), @@ -78,6 +77,13 @@ pub(crate) struct ArgsDebug { pub demo_conf_menu: bool } +#[derive(Debug, Clone, Parser)] +#[clap(about="Generate shell completions")] +pub(crate) struct ArgsCompletions { + #[clap(arg_enum, help = "The shell to generate completions for.")] + pub shell: Shell, +} + #[derive(Debug, Clone, Parser)] #[clap(about = "Set up a new account with steamguard-cli")] pub(crate) struct ArgsSetup { diff --git a/src/main.rs b/src/main.rs index 8de98f1..f3c60d1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ extern crate rpassword; -use clap::{crate_version, App, Arg, ArgMatches, Parser, Subcommand}; +use clap::{crate_version, App, Arg, ArgMatches, Parser, IntoApp}; use log::*; use std::{ io::{stdout, Write}, @@ -11,7 +11,7 @@ use steamguard::{ SteamGuardAccount, UserLogin, }; -use crate::{accountmanager::ManifestAccountLoadError, cli::Subcommands}; +use crate::{accountmanager::ManifestAccountLoadError}; #[macro_use] extern crate lazy_static; @@ -65,16 +65,15 @@ fn cli() -> App<'static> { .help("Specify your encryption passkey.") .takes_value(true) ) - // .subcommand( - // App::new("completion") - // .about("Generate shell completions") - // .arg( - // Arg::with_name("shell") - // .long("shell") - // .takes_value(true) - // .possible_values(&Shell::variants()) - // ) - // ) + .subcommand( + App::new("completion") + .about("Generate shell completions") + .arg( + Arg::with_name("shell") + .long("shell") + .takes_value(true) + ) + ) .subcommand( App::new("trade") .about("Interactive interface for trade confirmations") @@ -152,14 +151,9 @@ fn run() -> anyhow::Result<()> { Some(cli::Subcommands::Debug(args)) => { return do_subcmd_debug(args); }, - // Subcommand::Completions{shell} => { - // // cli().gen_completions_to( - // // "steamguard", - // // Shell::from_str(completion_matches.value_of("shell").unwrap()).unwrap(), - // // &mut std::io::stdout(), - // // ); - // return Ok(()); - // }, + Some(cli::Subcommands::Completion(args)) => { + return do_subcmd_completion(args); + }, _ => {}, }; @@ -417,6 +411,12 @@ fn do_subcmd_debug(args: cli::ArgsDebug) -> anyhow::Result<()> { return Ok(()); } +fn do_subcmd_completion(args: cli::ArgsCompletions) -> Result<(), anyhow::Error> { + let mut app = cli::Args::command_for_update(); + clap_complete::generate(args.shell, &mut app, "steamguard", &mut std::io::stdout()); + return Ok(()); +} + fn do_subcmd_setup(args: cli::ArgsSetup, manifest: &mut accountmanager::Manifest) -> anyhow::Result<()> { println!("Log in to the account that you want to link to steamguard-cli"); print!("Username: ");