From 25ac072985f8799474298e6922043746888c0c06 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Wed, 22 Apr 2020 00:36:26 -0700 Subject: [PATCH] Allow positional input to `imdl torrent show` Input can now be passed to `imdl torrent show` without a flag: imdl torrent show 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/link.rs | 2 +- src/subcommand/torrent/show.rs | 123 +++++++++++++++++++++++++++++++-- 3 files changed, 121 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 862b555..30e94ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ Changelog UNRELEASED - 2020-04-22 ----------------------- -- :bug: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Fix help strings - _Casey Rodarmor _ +- :zap: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Allow positional input to `imdl torrent show` - Fixes [#375](https://github.com/casey/intermodal/issues/375) - _Casey Rodarmor _ +- :bug: [`cecd2f66a5d6`](https://github.com/casey/intermodal/commit/cecd2f66a5d6a6b44f27f8ca499e359d82d29ab7) Fix help strings - _Casey Rodarmor _ - :zap: [`ebec2d591a7a`](https://github.com/casey/intermodal/commit/ebec2d591a7a0e2a2c4cd55217db4ba46b5dd9ed) 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 _ diff --git a/src/subcommand/torrent/link.rs b/src/subcommand/torrent/link.rs index a5cfbbd..ac13e16 100644 --- a/src/subcommand/torrent/link.rs +++ b/src/subcommand/torrent/link.rs @@ -68,7 +68,7 @@ impl Link { &self.input_positional, )?; - let input = env.read(input.clone())?; + let input = env.read(input)?; let infohash = Infohash::from_input(&input)?; let metainfo = Metainfo::from_input(&input)?; diff --git a/src/subcommand/torrent/show.rs b/src/subcommand/torrent/show.rs index 7de0b3f..b80cb6d 100644 --- a/src/subcommand/torrent/show.rs +++ b/src/subcommand/torrent/show.rs @@ -1,5 +1,14 @@ use crate::common::*; +const INPUT_HELP: &str = "Show information about torrent at `INPUT`. If `INPUT` is `-`, read \ + torrent metainfo from standard input."; + +const INPUT_FLAG: &str = "input-flag"; + +const INPUT_POSITIONAL: &str = ""; + +const INPUT_VALUE: &str = "INPUT"; + #[derive(StructOpt)] #[structopt( help_message(consts::HELP_MESSAGE), @@ -8,20 +17,37 @@ use crate::common::*; )] pub(crate) struct Show { #[structopt( + name = INPUT_FLAG, long = "input", short = "i", - value_name = "PATH", + value_name = INPUT_VALUE, empty_values(false), parse(try_from_os_str = InputTarget::try_from_os_str), - help = "Show information about torrent at `PATH`. If `Path` is `-`, read torrent metainfo \ - from standard input.", + help = INPUT_HELP, )] - input: InputTarget, + input_flag: Option, + #[structopt( + name = INPUT_POSITIONAL, + value_name = INPUT_VALUE, + empty_values(false), + parse(try_from_os_str = InputTarget::try_from_os_str), + required_unless = INPUT_FLAG, + conflicts_with = INPUT_FLAG, + help = INPUT_HELP, + )] + input_positional: Option, } impl Show { pub(crate) fn run(self, env: &mut Env) -> Result<(), Error> { - let input = env.read(self.input)?; + let target = xor_args( + "input_flag", + &self.input_flag, + "input_positional", + &self.input_positional, + )?; + + let input = env.read(target)?; let summary = TorrentSummary::from_input(&input)?; summary.write(env)?; Ok(()) @@ -34,6 +60,55 @@ mod tests { use pretty_assertions::assert_eq; + #[test] + fn input_required() { + test_env! { + args: [ + "torrent", + "show", + ], + tree: { + }, + matches: Err(Error::Clap { .. }), + }; + + test_env! { + args: [ + "torrent", + "show", + "--input", + "foo", + ], + tree: { + }, + matches: Err(Error::Filesystem { .. }), + }; + + test_env! { + args: [ + "torrent", + "show", + "foo", + ], + tree: { + }, + matches: Err(Error::Filesystem { .. }), + }; + + test_env! { + args: [ + "torrent", + "show", + "--input", + "foo", + "foo", + ], + tree: { + }, + matches: Err(Error::Clap { .. }), + }; + } + #[test] fn output() -> Result<()> { let metainfo = Metainfo { @@ -99,6 +174,44 @@ Announce List Tier 1: announce assert_eq!(have, want); } + { + let mut env = TestEnvBuilder::new() + .arg_slice(&["imdl", "torrent", "show", "foo.torrent"]) + .out_is_term() + .build(); + + let path = env.resolve("foo.torrent")?; + + metainfo.dump(path).unwrap(); + + env.assert_ok(); + + let have = env.out(); + let want = " Name foo + Comment comment +Creation Date 1970-01-01 00:00:01 UTC + Created By created by + Source source + Info Hash e12253978dc6d50db11d05747abcea1ad03b51c5 + Torrent Size 339 bytes + Content Size 20 bytes + Private yes + Tracker announce +Announce List Tier 1: announce + b + Tier 2: c + DHT Nodes x:12 + 1.1.1.1:16 + [2001:db8:85a3::8a2e:370]:7334 + Piece Size 16 KiB + Piece Count 2 + File Count 1 + Files foo +"; + + assert_eq!(have, want); + } + { let mut env = TestEnvBuilder::new() .arg_slice(&["imdl", "torrent", "show", "--input", "foo.torrent"])