From ebec2d591a7a0e2a2c4cd55217db4ba46b5dd9ed Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 21 Apr 2020 23:57:04 -0700 Subject: [PATCH] Allow positional shell to `imdl completions` The shell can now be passed to `imdl completions` without a flag: imdl completions bash Passing the shell by flag continues to work. type: changed fixes: - https://github.com/casey/intermodal/issues/375 --- CHANGELOG.md | 3 +- src/subcommand/completions.rs | 75 +++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16a3c51e..13f4e849 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ Changelog UNRELEASED - 2020-04-22 ----------------------- -- :art: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Use `lexiclean` crate for lexical path cleaning - _Casey Rodarmor _ +- :zap: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Allow positional shell to `imdl completions` - Fixes [#375](https://github.com/casey/intermodal/issues/375) - _Casey Rodarmor _ +- :art: [`134c241ae7f8`](https://github.com/casey/intermodal/commit/134c241ae7f8e374d8a9266e7eb0c4a9c3844c30) Use `lexiclean` crate for lexical path cleaning - _Casey Rodarmor _ - :zap: [`323434d0aa21`](https://github.com/casey/intermodal/commit/323434d0aa21ebfda5be85ecd4a38a55ed3fec0a) Allow positional input to `imdl torrent verify` - Fixes [#375](https://github.com/casey/intermodal/issues/375) - _Casey Rodarmor _ - :zap: [`5ba885dbc4f2`](https://github.com/casey/intermodal/commit/5ba885dbc4f24781d6a3240ddfc0c03177b12f1e) Take input to `imdl torrent create` as positional - Fixes [#375](https://github.com/casey/intermodal/issues/375) - _Casey Rodarmor _ - :wrench: [`c22df5a08326`](https://github.com/casey/intermodal/commit/c22df5a083265b03abd5531b1f5b2aad60aa68cd) Don't commit man pages - _Casey Rodarmor _ diff --git a/src/subcommand/completions.rs b/src/subcommand/completions.rs index a86edb95..a6071b91 100644 --- a/src/subcommand/completions.rs +++ b/src/subcommand/completions.rs @@ -1,5 +1,11 @@ use crate::common::*; +const SHELL_FLAG: &str = "shell-flag"; + +const SHELL_POSITIONAL: &str = ""; + +const SHELL_HELP: &str = "Print completion script for `SHELL`."; + #[derive(StructOpt)] #[structopt( help_message(consts::HELP_MESSAGE), @@ -8,14 +14,24 @@ use crate::common::*; )] pub(crate) struct Completions { #[structopt( + name = SHELL_FLAG, long = "shell", short = "s", value_name = "SHELL", possible_values = Shell::VARIANTS, + help = SHELL_HELP, + )] + shell_flag: Option, + #[structopt( + name = SHELL_POSITIONAL, + value_name = "SHELL", + possible_values = Shell::VARIANTS, required_unless = "dir", - help = "Print completion script for `SHELL`.", + required_unless = SHELL_FLAG, + conflicts_with = SHELL_FLAG, + help = SHELL_HELP, )] - shell: Option, + shell_positional: Option, #[structopt( long = "dir", short = "d", @@ -30,7 +46,14 @@ pub(crate) struct Completions { impl Completions { pub(crate) fn run(self, env: &mut Env) -> Result<()> { - if let Some(shell) = self.shell { + if self.shell_flag.is_some() || self.shell_positional.is_some() { + let shell = xor_args( + "shell_flag", + &self.shell_flag, + "shell_positional", + &self.shell_positional, + )?; + if let Some(dir) = self.dir { Self::write(env, &dir, shell)?; } else { @@ -62,6 +85,18 @@ impl Completions { mod tests { use super::*; + #[test] + fn shell_required() { + let mut env = test_env! { + args: [ + "completions", + ], + tree: {}, + }; + + assert_matches!(env.run(), Err(Error::Clap { .. })); + } + #[test] fn output() { let mut env = test_env! { @@ -78,6 +113,21 @@ mod tests { assert!(env.out().starts_with("_imdl() {")); } + #[test] + fn output_positional() { + let mut env = test_env! { + args: [ + "completions", + "bash", + ], + tree: {}, + }; + + env.assert_ok(); + + assert!(env.out().starts_with("_imdl() {")); + } + #[test] fn single_dir() { let mut env = test_env! { @@ -98,6 +148,25 @@ mod tests { assert!(script.starts_with("_imdl() {")); } + #[test] + fn single_positional() { + let mut env = test_env! { + args: [ + "completions", + "bash", + "--dir", + ".", + ], + tree: {}, + }; + + env.assert_ok(); + + let script = env.read_to_string("imdl.bash"); + + assert!(script.starts_with("_imdl() {")); + } + #[test] fn all_dir() { let mut env = test_env! {