From f6cb42ee2d5379136611d41717c0e0034d42a67c Mon Sep 17 00:00:00 2001 From: DevSabb Date: Mon, 28 Mar 2022 10:17:07 -0400 Subject: [PATCH 1/5] shuf: accept multiple occurances of head-count argument --- src/uu/shuf/src/shuf.rs | 30 ++++++++++++++++++++---------- tests/by-util/test_shuf.rs | 14 ++++++++++++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/uu/shuf/src/shuf.rs b/src/uu/shuf/src/shuf.rs index 6a3e325c7..5950fe4e4 100644 --- a/src/uu/shuf/src/shuf.rs +++ b/src/uu/shuf/src/shuf.rs @@ -75,17 +75,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { }; let options = Options { - head_count: match matches.value_of(options::HEAD_COUNT) { - Some(count) => match count.parse::() { + head_count: { + let headcounts = matches + .values_of(options::HEAD_COUNT) + .unwrap_or_default() + .collect(); + match parse_head_count(&headcounts) { Ok(val) => val, - Err(_) => { - return Err(USimpleError::new( - 1, - format!("invalid line count: {}", count.quote()), - )); - } - }, - None => std::usize::MAX, + Err(msg) => return Err(USimpleError::new(1, msg)), + } }, output: matches.value_of(options::OUTPUT).map(String::from), random_source: matches.value_of(options::RANDOM_SOURCE).map(String::from), @@ -152,6 +150,7 @@ pub fn uu_app<'a>() -> Command<'a> { .short('n') .long(options::HEAD_COUNT) .takes_value(true) + .multiple_occurrences(true) .value_name("COUNT") .help("output at most COUNT lines"), ) @@ -299,6 +298,17 @@ fn parse_range(input_range: &str) -> Result<(usize, usize), String> { } } +fn parse_head_count(headcounts: &Vec<&str>) -> Result { + let mut result = std::usize::MAX; + for count in headcounts { + match count.parse::() { + Ok(pv) => result = std::cmp::min(result, pv), + Err(_) => return Err(format!("invalid line count: {}", count.quote())), + } + } + Ok(result) +} + enum WrappedRng { RngFile(rand_read_adapter::ReadRng), RngDefault(rand::rngs::ThreadRng), diff --git a/tests/by-util/test_shuf.rs b/tests/by-util/test_shuf.rs index 86828dc45..dc3355dff 100644 --- a/tests/by-util/test_shuf.rs +++ b/tests/by-util/test_shuf.rs @@ -196,3 +196,17 @@ fn test_shuf_invalid_input_line_count() { .fails() .stderr_contains("invalid line count: 'a'"); } + +#[test] +fn test_shuf_multiple_input_line_count() { + let result = new_ucmd!() + .args(&["-i10-200", "-n", "10", "-n", "5"]) + .succeeds(); + result.no_stderr(); + let result_seq: Vec<&str> = result + .stdout_str() + .split('\n') + .filter(|x| !x.is_empty()) + .collect(); + assert_eq!(result_seq.len(), 5, "Output should have 5 items"); +} From 16ad4bc0693b8ed349e9ee968750913078914999 Mon Sep 17 00:00:00 2001 From: DevSabb Date: Mon, 28 Mar 2022 10:31:27 -0400 Subject: [PATCH 2/5] fix clippy warning --- src/uu/shuf/src/shuf.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/shuf/src/shuf.rs b/src/uu/shuf/src/shuf.rs index 5950fe4e4..64e56a198 100644 --- a/src/uu/shuf/src/shuf.rs +++ b/src/uu/shuf/src/shuf.rs @@ -76,7 +76,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let options = Options { head_count: { - let headcounts = matches + let headcounts: Vec<&str> = matches .values_of(options::HEAD_COUNT) .unwrap_or_default() .collect(); @@ -298,7 +298,7 @@ fn parse_range(input_range: &str) -> Result<(usize, usize), String> { } } -fn parse_head_count(headcounts: &Vec<&str>) -> Result { +fn parse_head_count(headcounts: &[&str]) -> Result { let mut result = std::usize::MAX; for count in headcounts { match count.parse::() { From 68b1f04f7dbbe731c51f3a097f6b22019e15b0ea Mon Sep 17 00:00:00 2001 From: DevSabb Date: Mon, 28 Mar 2022 11:09:26 -0400 Subject: [PATCH 3/5] fix more clippy warnings --- src/uu/shuf/src/shuf.rs | 12 +++++------- tests/by-util/test_shuf.rs | 10 +++++----- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/uu/shuf/src/shuf.rs b/src/uu/shuf/src/shuf.rs index 64e56a198..0b62ec84a 100644 --- a/src/uu/shuf/src/shuf.rs +++ b/src/uu/shuf/src/shuf.rs @@ -7,7 +7,7 @@ // spell-checker:ignore (ToDO) cmdline evec seps rvec fdata -use clap::{crate_version, Arg, Command}; +use clap::{crate_version, Arg, Command, Values}; use rand::prelude::SliceRandom; use rand::RngCore; use std::fs::File; @@ -76,11 +76,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let options = Options { head_count: { - let headcounts: Vec<&str> = matches - .values_of(options::HEAD_COUNT) - .unwrap_or_default() - .collect(); - match parse_head_count(&headcounts) { + let mut headcounts: Values<'_> = + matches.values_of(options::HEAD_COUNT).unwrap_or_default(); + match parse_head_count(&mut headcounts) { Ok(val) => val, Err(msg) => return Err(USimpleError::new(1, msg)), } @@ -298,7 +296,7 @@ fn parse_range(input_range: &str) -> Result<(usize, usize), String> { } } -fn parse_head_count(headcounts: &[&str]) -> Result { +fn parse_head_count(headcounts: &mut Values<'_>) -> Result { let mut result = std::usize::MAX; for count in headcounts { match count.parse::() { diff --git a/tests/by-util/test_shuf.rs b/tests/by-util/test_shuf.rs index dc3355dff..1f67416da 100644 --- a/tests/by-util/test_shuf.rs +++ b/tests/by-util/test_shuf.rs @@ -202,11 +202,11 @@ fn test_shuf_multiple_input_line_count() { let result = new_ucmd!() .args(&["-i10-200", "-n", "10", "-n", "5"]) .succeeds(); - result.no_stderr(); - let result_seq: Vec<&str> = result + result.no_stderr(); + + let result_seq = result .stdout_str() .split('\n') - .filter(|x| !x.is_empty()) - .collect(); - assert_eq!(result_seq.len(), 5, "Output should have 5 items"); + .filter(|x| !x.is_empty()); + assert_eq!(result_seq.count(), 5, "Output should have 5 items"); } From bb64e699ec9355021853ccc8d2cd64bb9fc0b445 Mon Sep 17 00:00:00 2001 From: DevSabb Date: Mon, 28 Mar 2022 11:33:38 -0400 Subject: [PATCH 4/5] fix lint errors --- tests/by-util/test_shuf.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/by-util/test_shuf.rs b/tests/by-util/test_shuf.rs index 1f67416da..defa2d394 100644 --- a/tests/by-util/test_shuf.rs +++ b/tests/by-util/test_shuf.rs @@ -202,11 +202,9 @@ fn test_shuf_multiple_input_line_count() { let result = new_ucmd!() .args(&["-i10-200", "-n", "10", "-n", "5"]) .succeeds(); + result.no_stderr(); - let result_seq = result - .stdout_str() - .split('\n') - .filter(|x| !x.is_empty()); - assert_eq!(result_seq.count(), 5, "Output should have 5 items"); + let result_count = result.stdout_str().split('\n').filter(|x| !x.is_empty()).count(); + assert_eq!(result_count, 5, "Output should have 5 items"); } From eeafdc7021a45a06bc6ed3d43956d3f6ab2c4074 Mon Sep 17 00:00:00 2001 From: DevSabb Date: Mon, 28 Mar 2022 11:36:50 -0400 Subject: [PATCH 5/5] fix lint errors attempt 2 --- tests/by-util/test_shuf.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_shuf.rs b/tests/by-util/test_shuf.rs index defa2d394..682b0dab6 100644 --- a/tests/by-util/test_shuf.rs +++ b/tests/by-util/test_shuf.rs @@ -205,6 +205,10 @@ fn test_shuf_multiple_input_line_count() { result.no_stderr(); - let result_count = result.stdout_str().split('\n').filter(|x| !x.is_empty()).count(); + let result_count = result + .stdout_str() + .split('\n') + .filter(|x| !x.is_empty()) + .count(); assert_eq!(result_count, 5, "Output should have 5 items"); }