From 323434d0aa21ebfda5be85ecd4a38a55ed3fec0a Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 21 Apr 2020 22:23:54 -0700 Subject: [PATCH] Allow positional input to `imdl torrent verify` Input can now be passed to `imdl torrent verify` without a flag: imdl torrent verify foo.torrent Passing input by flag continues to work. type: changed fixes: - https://github.com/casey/intermodal/issues/375 --- CHANGELOG.md | 3 +- src/subcommand/torrent/verify.rs | 101 +++++++++++++++++++++++++------ 2 files changed, 84 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9d0f469..535130b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ Changelog UNRELEASED - 2020-04-22 ----------------------- -- :zap: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Take input to `imdl torrent create` as positional - Fixes [#375](https://github.com/casey/intermodal/issues/375) - _Casey Rodarmor _ +- :zap: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) 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 _ - :wrench: [`4d67d3a10d17`](https://github.com/casey/intermodal/commit/4d67d3a10d17db3c63af092a936eb5994ee107b1) Don't commit the book - _Casey Rodarmor _ - :wrench: [`28114c3d64dd`](https://github.com/casey/intermodal/commit/28114c3d64dde5e0275c936b0019eaf4760ba559) Don't commit shell completion scripts - _Casey Rodarmor _ diff --git a/src/subcommand/torrent/verify.rs b/src/subcommand/torrent/verify.rs index 24e3065f..cc671aaa 100644 --- a/src/subcommand/torrent/verify.rs +++ b/src/subcommand/torrent/verify.rs @@ -3,6 +3,13 @@ use verify_step::VerifyStep; mod verify_step; +const METAINFO_HELP: &str = "Verify torrent contents against torrent metainfo in `METAINFO`. If \ + `METAINFO` is `-`, read metainfo from standard input."; + +const INPUT_POSITIONAL: &str = ""; + +const INPUT_FLAG: &str = "input-flag"; + #[derive(StructOpt)] #[structopt( help_message(consts::HELP_MESSAGE), @@ -10,16 +17,6 @@ mod verify_step; about("Verify files against a .torrent file.") )] pub(crate) struct Verify { - #[structopt( - long = "input", - short = "i", - value_name = "METAINFO", - empty_values(false), - parse(try_from_os_str = InputTarget::try_from_os_str), - help = "Verify torrent contents against torrent metainfo in `METAINFO`. If `METAINFO` is `-`, \ - read metainfo from standard input.", - )] - metainfo: InputTarget, #[structopt( long = "content", short = "c", @@ -30,25 +27,49 @@ pub(crate) struct Verify { of torrent info dictionary." )] content: Option, + #[structopt( + name = INPUT_POSITIONAL, + value_name = "INPUT", + empty_values = false, + required_unless = INPUT_FLAG, + conflicts_with = INPUT_FLAG, + parse(try_from_os_str = InputTarget::try_from_os_str), + help = METAINFO_HELP, + )] + input_positional: Option, + #[structopt( + name = INPUT_FLAG, + long = "input", + short = "i", + value_name = "METAINFO", + empty_values = false, + parse(try_from_os_str = InputTarget::try_from_os_str), + help = METAINFO_HELP, + )] + input_flag: Option, } impl Verify { pub(crate) fn run(self, env: &mut Env, options: &Options) -> Result<(), Error> { + let target = xor_args( + "input_positional", + &self.input_positional, + "input_flag", + &self.input_flag, + )?; + if !options.quiet { - VerifyStep::Loading { - metainfo: &self.metainfo, - } - .print(env)?; + VerifyStep::Loading { metainfo: &target }.print(env)?; } - let input = env.read(self.metainfo.clone())?; + let input = env.read(target.clone())?; let metainfo = Metainfo::from_input(&input)?; let content = if let Some(content) = &self.content { content.clone() } else { - match &self.metainfo { + match target { InputTarget::Path(path) => path.join("..").join(&metainfo.info.name).clean(), InputTarget::Stdin => PathBuf::from(&metainfo.info.name), } @@ -94,12 +115,33 @@ mod tests { use pretty_assertions::assert_eq; #[test] - fn require_metainfo_argument() { + fn require_input() { + let mut env = test_env! { + args: ["torrent", "verify"], + tree: {}, + }; + assert_matches!(env.run(), Err(Error::Clap { .. })); + + // flag is ok + let mut env = test_env! { + args: ["torrent", "verify", "--input", "foo"], + tree: {}, + }; + assert_matches!(env.run(), Err(Error::Filesystem { .. })); + + // positional is ok let mut env = test_env! { - args: [], + args: ["torrent", "verify", "foo"], tree: {}, }; - assert!(matches!(env.run(), Err(Error::Clap { .. }))); + assert_matches!(env.run(), Err(Error::Filesystem { .. })); + + // both are fail + let mut env = test_env! { + args: ["torrent", "verify", "--input", "foo", "foo"], + tree: {}, + }; + assert_matches!(env.run(), Err(Error::Clap { .. })); } #[test] @@ -148,6 +190,27 @@ mod tests { assert_eq!(verify_env.err(), want); assert_eq!(verify_env.out(), ""); + let mut verify_env = test_env! { + args: [ + "torrent", + "verify", + &torrent, + ], + tree: {}, + }; + + verify_env.assert_ok(); + + let want = format!( + "[1/2] \u{1F4BE} Loading metainfo from `{}`…\n[2/2] \u{1F9EE} Verifying pieces from \ + `{}`…\n\u{2728}\u{2728} Verification succeeded! \u{2728}\u{2728}\n", + torrent.display(), + create_env.resolve("foo")?.display() + ); + + assert_eq!(verify_env.err(), want); + assert_eq!(verify_env.out(), ""); + Ok(()) }