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
This commit is contained in:
Casey Rodarmor 2020-04-21 23:57:04 -07:00
parent 134c241ae7
commit ebec2d591a
No known key found for this signature in database
GPG Key ID: 556186B153EC6FE0
2 changed files with 75 additions and 5 deletions

View File

@ -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 <casey@rodarmor.com>_
- :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 <casey@rodarmor.com>_
- :art: [`134c241ae7f8`](https://github.com/casey/intermodal/commit/134c241ae7f8e374d8a9266e7eb0c4a9c3844c30) Use `lexiclean` crate for lexical path cleaning - _Casey Rodarmor <casey@rodarmor.com>_
- :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 <casey@rodarmor.com>_
- :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 <casey@rodarmor.com>_
- :wrench: [`c22df5a08326`](https://github.com/casey/intermodal/commit/c22df5a083265b03abd5531b1f5b2aad60aa68cd) Don't commit man pages - _Casey Rodarmor <casey@rodarmor.com>_

View File

@ -1,5 +1,11 @@
use crate::common::*;
const SHELL_FLAG: &str = "shell-flag";
const SHELL_POSITIONAL: &str = "<SHELL>";
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,
required_unless = "dir",
help = "Print completion script for `SHELL`.",
help = SHELL_HELP,
)]
shell: Option<Shell>,
shell_flag: Option<Shell>,
#[structopt(
name = SHELL_POSITIONAL,
value_name = "SHELL",
possible_values = Shell::VARIANTS,
required_unless = "dir",
required_unless = SHELL_FLAG,
conflicts_with = SHELL_FLAG,
help = SHELL_HELP,
)]
shell_positional: Option<Shell>,
#[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! {