From 06b3092f5f3b47e263c350ba810f1d07b4530519 Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Tue, 1 Jun 2021 18:06:18 +0200 Subject: [PATCH 01/17] sort: fix debug output for zeros / invalid numbers We were reporting "no match" when sorting something like "0 ". This is because we don't distinguish between 0 and invalid lines when sorting. For debug output we have to get this information back. --- src/uu/sort/src/numeric_str_cmp.rs | 17 ++++++++-- src/uu/sort/src/sort.rs | 34 ++++++++++++------- tests/by-util/test_sort.rs | 8 +++++ .../fixtures/sort/human_block_sizes.expected | 1 + .../sort/human_block_sizes.expected.debug | 3 ++ tests/fixtures/sort/human_block_sizes.txt | 1 + .../sort/numeric_trailing_chars.expected | 5 +++ .../numeric_trailing_chars.expected.debug | 15 ++++++++ .../fixtures/sort/numeric_trailing_chars.txt | 5 +++ 9 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 tests/fixtures/sort/numeric_trailing_chars.expected create mode 100644 tests/fixtures/sort/numeric_trailing_chars.expected.debug create mode 100644 tests/fixtures/sort/numeric_trailing_chars.txt diff --git a/src/uu/sort/src/numeric_str_cmp.rs b/src/uu/sort/src/numeric_str_cmp.rs index 03806b0c8..461f72670 100644 --- a/src/uu/sort/src/numeric_str_cmp.rs +++ b/src/uu/sort/src/numeric_str_cmp.rs @@ -46,7 +46,12 @@ impl Default for NumInfoParseSettings { impl NumInfo { /// Parse NumInfo for this number. - /// Also returns the range of num that should be passed to numeric_str_cmp later + /// Also returns the range of num that should be passed to numeric_str_cmp later. + /// + /// Leading zeros will be excluded from the returned range. If the number consists of only zeros, + /// an empty range (idx..idx) is returned so that idx is the char after the last zero. + /// If the input is not a number (which has to be treated as zero), the returned empty range + /// will be 0..0. pub fn parse(num: &str, parse_settings: NumInfoParseSettings) -> (Self, Range) { let mut exponent = -1; let mut had_decimal_pt = false; @@ -105,7 +110,15 @@ impl NumInfo { sign: if had_digit { sign } else { Sign::Positive }, exponent: 0, }, - 0..0, + if had_digit { + // In this case there were only zeroes. + // For debug output to work properly, we have to match the character after the last zero. + idx..idx + } else { + // This was no number at all. + // For debug output to work properly, we have to match 0..0. + 0..0 + }, ) }; } diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index ab3b06451..f47b561ed 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -414,19 +414,29 @@ impl<'a> Line<'a> { selection.start += num_range.start; selection.end = selection.start + num_range.len(); - // include a trailing si unit - if selector.settings.mode == SortMode::HumanNumeric - && self.line[selection.end..initial_selection.end] - .starts_with(&['k', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'][..]) - { - selection.end += 1; - } + if num_range != (0..0) { + // include a trailing si unit + if selector.settings.mode == SortMode::HumanNumeric + && self.line[selection.end..initial_selection.end] + .starts_with(&['k', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'][..]) + { + selection.end += 1; + } - // include leading zeroes, a leading minus or a leading decimal point - while self.line[initial_selection.start..selection.start] - .ends_with(&['-', '0', '.'][..]) - { - selection.start -= 1; + // include leading zeroes, a leading minus or a leading decimal point + while self.line[initial_selection.start..selection.start] + .ends_with(&['-', '0', '.'][..]) + { + selection.start -= 1; + } + } else { + // This was not a valid number. + // Report no match at the first non-whitespace character. + let leading_whitespace = self.line[selection.clone()] + .find(|c: char| !c.is_whitespace()) + .unwrap_or(0); + selection.start += leading_whitespace; + selection.end += leading_whitespace; } } SortMode::GeneralNumeric => { diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index d2b447925..02636b027 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -123,6 +123,14 @@ fn test_multiple_decimals_numeric() { ) } +#[test] +fn test_numeric_with_trailing_invalid_chars() { + test_helper( + "numeric_trailing_chars", + &["-n", "--numeric-sort", "--sort=numeric"], + ) +} + #[test] fn test_check_zero_terminated_failure() { new_ucmd!() diff --git a/tests/fixtures/sort/human_block_sizes.expected b/tests/fixtures/sort/human_block_sizes.expected index 74fad9fdf..0e4fdfbb6 100644 --- a/tests/fixtures/sort/human_block_sizes.expected +++ b/tests/fixtures/sort/human_block_sizes.expected @@ -1,3 +1,4 @@ +K 844K 981K 11M diff --git a/tests/fixtures/sort/human_block_sizes.expected.debug b/tests/fixtures/sort/human_block_sizes.expected.debug index 5f4860a85..cde98628e 100644 --- a/tests/fixtures/sort/human_block_sizes.expected.debug +++ b/tests/fixtures/sort/human_block_sizes.expected.debug @@ -1,3 +1,6 @@ +K +^ no match for key +_ 844K ____ ____ diff --git a/tests/fixtures/sort/human_block_sizes.txt b/tests/fixtures/sort/human_block_sizes.txt index 803666dbe..9cc2b3c6c 100644 --- a/tests/fixtures/sort/human_block_sizes.txt +++ b/tests/fixtures/sort/human_block_sizes.txt @@ -9,3 +9,4 @@ 844K 981K 13M +K \ No newline at end of file diff --git a/tests/fixtures/sort/numeric_trailing_chars.expected b/tests/fixtures/sort/numeric_trailing_chars.expected new file mode 100644 index 000000000..96226fd38 --- /dev/null +++ b/tests/fixtures/sort/numeric_trailing_chars.expected @@ -0,0 +1,5 @@ +-.05, +-x +0.abc +0foo +100 diff --git a/tests/fixtures/sort/numeric_trailing_chars.expected.debug b/tests/fixtures/sort/numeric_trailing_chars.expected.debug new file mode 100644 index 000000000..0226a636f --- /dev/null +++ b/tests/fixtures/sort/numeric_trailing_chars.expected.debug @@ -0,0 +1,15 @@ +-.05, +____ +_____ +-x +^ no match for key +__ +0.abc +__ +_____ +0foo +_ +____ +100 +___ +____ diff --git a/tests/fixtures/sort/numeric_trailing_chars.txt b/tests/fixtures/sort/numeric_trailing_chars.txt new file mode 100644 index 000000000..d6fe3e48d --- /dev/null +++ b/tests/fixtures/sort/numeric_trailing_chars.txt @@ -0,0 +1,5 @@ +0foo +0.abc +100 +-.05, +-x \ No newline at end of file From 67b83647ac41515f762506211ec6390c19fa0b2d Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Tue, 1 Jun 2021 18:09:39 +0200 Subject: [PATCH 02/17] sort: simplify handling of negative zeros We can simply parse the sign of negative zero as positive, instead of handling the comparison of zeros differently. --- src/uu/sort/src/numeric_str_cmp.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/uu/sort/src/numeric_str_cmp.rs b/src/uu/sort/src/numeric_str_cmp.rs index 461f72670..8cd3faab2 100644 --- a/src/uu/sort/src/numeric_str_cmp.rs +++ b/src/uu/sort/src/numeric_str_cmp.rs @@ -107,7 +107,7 @@ impl NumInfo { } else { ( NumInfo { - sign: if had_digit { sign } else { Sign::Positive }, + sign: Sign::Positive, exponent: 0, }, if had_digit { @@ -147,7 +147,7 @@ impl NumInfo { } else { ( NumInfo { - sign: if had_digit { sign } else { Sign::Positive }, + sign: Sign::Positive, exponent: 0, }, if had_digit { @@ -187,11 +187,7 @@ impl NumInfo { pub fn numeric_str_cmp((a, a_info): (&str, &NumInfo), (b, b_info): (&str, &NumInfo)) -> Ordering { // check for a difference in the sign if a_info.sign != b_info.sign { - return if a.is_empty() && b.is_empty() { - Ordering::Equal - } else { - a_info.sign.cmp(&b_info.sign) - }; + return a_info.sign.cmp(&b_info.sign); } // check for a difference in the exponent From 9b29ac98a59c5b8bc82a4a15177ad75053fbb067 Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Tue, 1 Jun 2021 18:12:37 +0200 Subject: [PATCH 03/17] seq: reject NaN arguments Move the validation logic to an argument validator. --- src/uu/seq/src/seq.rs | 68 ++++++++++++++------------------------- tests/by-util/test_seq.rs | 16 +++++++++ 2 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/uu/seq/src/seq.rs b/src/uu/seq/src/seq.rs index bdab044c5..60aa7e654 100644 --- a/src/uu/seq/src/seq.rs +++ b/src/uu/seq/src/seq.rs @@ -13,7 +13,6 @@ use num_traits::Zero; use num_traits::{Num, ToPrimitive}; use std::cmp; use std::io::{stdout, Write}; -use std::str::FromStr; static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Display numbers from FIRST to LAST, in steps of INCREMENT."; @@ -44,6 +43,18 @@ enum Number { } impl Number { + fn new(mut s: &str) -> Self { + if s.starts_with('+') { + s = &s[1..]; + } + + match s.parse::() { + Ok(n) => Number::BigInt(n), + // The argument validator made sure this is a valid float. + Err(_) => Number::F64(s.parse::().unwrap()), + } + } + fn is_zero(&self) -> bool { match self { Number::BigInt(n) => n.is_zero(), @@ -60,27 +71,6 @@ impl Number { } } -impl FromStr for Number { - type Err = String; - /// Tries to parse this string as a BigInt, or if that fails as an f64. - fn from_str(mut s: &str) -> Result { - if s.starts_with('+') { - s = &s[1..]; - } - - match s.parse::() { - Ok(n) => Ok(Number::BigInt(n)), - Err(_) => match s.parse::() { - Ok(n) => Ok(Number::F64(n)), - Err(e) => Err(format!( - "seq: invalid floating point argument `{}`: {}", - s, e - )), - }, - } - } -} - pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) @@ -116,7 +106,15 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .takes_value(true) .allow_hyphen_values(true) .max_values(3) - .required(true), + .required(true) + .validator(|value| { + match value.parse::() { + Ok(value) if value.is_nan() => Err("can not be NaN".to_string()), + Ok(_) => Ok(()), + Err(e) => Err(e.to_string()), + } + .map_err(|e| format!("invalid floating point argument `{}`: {}", value, e)) + }), ) .get_matches_from(args); @@ -136,13 +134,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let dec = slice.find('.').unwrap_or(len); largest_dec = len - dec; padding = dec; - match slice.parse() { - Ok(n) => n, - Err(s) => { - show_error!("{}", s); - return 1; - } - } + Number::new(slice) } else { Number::BigInt(BigInt::one()) }; @@ -152,13 +144,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let dec = slice.find('.').unwrap_or(len); largest_dec = cmp::max(largest_dec, len - dec); padding = cmp::max(padding, dec); - match slice.parse() { - Ok(n) => n, - Err(s) => { - show_error!("{}", s); - return 1; - } - } + Number::new(slice) } else { Number::BigInt(BigInt::one()) }; @@ -169,13 +155,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let last = { let slice = numbers[numbers.len() - 1]; padding = cmp::max(padding, slice.find('.').unwrap_or_else(|| slice.len())); - match slice.parse::() { - Ok(n) => n, - Err(s) => { - show_error!("{}", s); - return 1; - } - } + Number::new(slice) }; if largest_dec > 0 { largest_dec -= 1; diff --git a/tests/by-util/test_seq.rs b/tests/by-util/test_seq.rs index 98eb23598..7545ebde7 100644 --- a/tests/by-util/test_seq.rs +++ b/tests/by-util/test_seq.rs @@ -1,5 +1,21 @@ use crate::common::util::*; +#[test] +fn test_rejects_nan() { + new_ucmd!() + .args(&["NaN"]) + .fails() + .stderr_only("error: Invalid value for '...': invalid floating point argument `NaN`: can not be NaN"); +} + +#[test] +fn test_rejects_non_floats() { + new_ucmd!() + .args(&["foo"]) + .fails() + .stderr_only("error: Invalid value for '...': invalid floating point argument `foo`: invalid float literal"); +} + // ---- Tests for the big integer based path ---- #[test] From 5329d77cc2f928a4b59a6e1563761217789d47e8 Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Tue, 1 Jun 2021 20:35:18 +0200 Subject: [PATCH 04/17] seq: adapt output to GNU seq --- src/uu/seq/src/seq.rs | 61 +++++++++++++++++++++++---------------- tests/by-util/test_seq.rs | 4 +-- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/uu/seq/src/seq.rs b/src/uu/seq/src/seq.rs index 60aa7e654..8cf6513cb 100644 --- a/src/uu/seq/src/seq.rs +++ b/src/uu/seq/src/seq.rs @@ -13,6 +13,7 @@ use num_traits::Zero; use num_traits::{Num, ToPrimitive}; use std::cmp; use std::io::{stdout, Write}; +use std::str::FromStr; static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Display numbers from FIRST to LAST, in steps of INCREMENT."; @@ -43,18 +44,6 @@ enum Number { } impl Number { - fn new(mut s: &str) -> Self { - if s.starts_with('+') { - s = &s[1..]; - } - - match s.parse::() { - Ok(n) => Number::BigInt(n), - // The argument validator made sure this is a valid float. - Err(_) => Number::F64(s.parse::().unwrap()), - } - } - fn is_zero(&self) -> bool { match self { Number::BigInt(n) => n.is_zero(), @@ -71,6 +60,32 @@ impl Number { } } +impl FromStr for Number { + type Err = String; + fn from_str(mut s: &str) -> Result { + if s.starts_with('+') { + s = &s[1..]; + } + + match s.parse::() { + Ok(n) => Ok(Number::BigInt(n)), + Err(_) => match s.parse::() { + Ok(value) if value.is_nan() => Err(format!( + "invalid 'not-a-number' argument: '{}'\nTry '{} --help' for more information.", + s, + executable!(), + )), + Ok(value) => Ok(Number::F64(value)), + Err(_) => Err(format!( + "invalid floating point argument: '{}'\nTry '{} --help' for more information.", + s, + executable!(), + )), + }, + } + } +} + pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) @@ -106,15 +121,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .takes_value(true) .allow_hyphen_values(true) .max_values(3) - .required(true) - .validator(|value| { - match value.parse::() { - Ok(value) if value.is_nan() => Err("can not be NaN".to_string()), - Ok(_) => Ok(()), - Err(e) => Err(e.to_string()), - } - .map_err(|e| format!("invalid floating point argument `{}`: {}", value, e)) - }), + .required(true), ) .get_matches_from(args); @@ -134,7 +141,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let dec = slice.find('.').unwrap_or(len); largest_dec = len - dec; padding = dec; - Number::new(slice) + return_if_err!(1, slice.parse()) } else { Number::BigInt(BigInt::one()) }; @@ -144,18 +151,22 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let dec = slice.find('.').unwrap_or(len); largest_dec = cmp::max(largest_dec, len - dec); padding = cmp::max(padding, dec); - Number::new(slice) + return_if_err!(1, slice.parse()) } else { Number::BigInt(BigInt::one()) }; if increment.is_zero() { - show_error!("increment value: '{}'", numbers[1]); + show_error!( + "invalid Zero increment value: '{}'\nTry '{} --help' for more information.", + numbers[1], + executable!() + ); return 1; } let last = { let slice = numbers[numbers.len() - 1]; padding = cmp::max(padding, slice.find('.').unwrap_or_else(|| slice.len())); - Number::new(slice) + return_if_err!(1, slice.parse()) }; if largest_dec > 0 { largest_dec -= 1; diff --git a/tests/by-util/test_seq.rs b/tests/by-util/test_seq.rs index 7545ebde7..459eeeb3a 100644 --- a/tests/by-util/test_seq.rs +++ b/tests/by-util/test_seq.rs @@ -5,7 +5,7 @@ fn test_rejects_nan() { new_ucmd!() .args(&["NaN"]) .fails() - .stderr_only("error: Invalid value for '...': invalid floating point argument `NaN`: can not be NaN"); + .stderr_only("seq: invalid 'not-a-number' argument: 'NaN'\nTry 'seq --help' for more information."); } #[test] @@ -13,7 +13,7 @@ fn test_rejects_non_floats() { new_ucmd!() .args(&["foo"]) .fails() - .stderr_only("error: Invalid value for '...': invalid floating point argument `foo`: invalid float literal"); + .stderr_only("seq: invalid floating point argument: 'foo'\nTry 'seq --help' for more information."); } // ---- Tests for the big integer based path ---- From 23f89d1494b0fa071adca1552ad6757f21e40b39 Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Tue, 1 Jun 2021 22:04:19 +0200 Subject: [PATCH 05/17] cp: close file descriptors after cow on linux Instead of using into_raw_fd(), which transfers ownership and requires us to close the file descriptor manually, use as_raw_fd(), which does not transfer ownership to us but drops the file descriptor when the original file is dropped (in our case at the end of the function). --- src/uu/cp/src/cp.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index b7c64928f..3a5941284 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -41,7 +41,7 @@ use std::io; use std::io::{stdin, stdout, Write}; use std::mem; #[cfg(target_os = "linux")] -use std::os::unix::io::IntoRawFd; +use std::os::unix::io::AsRawFd; #[cfg(windows)] use std::os::windows::ffi::OsStrExt; use std::path::{Path, PathBuf, StripPrefixError}; @@ -1261,14 +1261,14 @@ fn copy_helper(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> fn copy_on_write_linux(source: &Path, dest: &Path, mode: ReflinkMode) -> CopyResult<()> { debug_assert!(mode != ReflinkMode::Never); - let src_file = File::open(source).unwrap().into_raw_fd(); + let src_file = File::open(source).unwrap().as_raw_fd(); let dst_file = OpenOptions::new() .write(true) .truncate(false) .create(true) .open(dest) .unwrap() - .into_raw_fd(); + .as_raw_fd(); match mode { ReflinkMode::Always => unsafe { let result = ficlone(dst_file, src_file as *const i32); From a323e9cda17c51849bd62d75e47303fb2a47a3d8 Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Tue, 1 Jun 2021 23:06:38 +0200 Subject: [PATCH 06/17] cp: show errors in cow on linux --- src/uu/cp/src/cp.rs | 6 ++++-- tests/by-util/test_cp.rs | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index b7c64928f..40266689c 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -1261,13 +1261,15 @@ fn copy_helper(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> fn copy_on_write_linux(source: &Path, dest: &Path, mode: ReflinkMode) -> CopyResult<()> { debug_assert!(mode != ReflinkMode::Never); - let src_file = File::open(source).unwrap().into_raw_fd(); + let src_file = File::open(source) + .context(&*context_for(source, dest))? + .into_raw_fd(); let dst_file = OpenOptions::new() .write(true) .truncate(false) .create(true) .open(dest) - .unwrap() + .context(&*context_for(source, dest))? .into_raw_fd(); match mode { ReflinkMode::Always => unsafe { diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index e995cc56c..c56e1ca57 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -7,6 +7,8 @@ use std::fs::set_permissions; #[cfg(not(windows))] use std::os::unix::fs; +#[cfg(target_os = "linux")] +use std::os::unix::fs::PermissionsExt; #[cfg(windows)] use std::os::windows::fs::symlink_file; @@ -1257,3 +1259,20 @@ fn test_cp_reflink_bad() { .fails() .stderr_contains("invalid argument"); } + +#[test] +#[cfg(target_os = "linux")] +fn test_cp_reflink_insufficient_permission() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.make_file("unreadable") + .set_permissions(PermissionsExt::from_mode(0o000)) + .unwrap(); + + ucmd.arg("-r") + .arg("--reflink=auto") + .arg("unreadable") + .arg(TEST_EXISTING_FILE) + .fails() + .stderr_only("cp: 'unreadable' -> 'existing_file.txt': Permission denied (os error 13)"); +} From fc2b61eb9623c855817e87ffef0dd672885f89a0 Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Tue, 1 Jun 2021 23:06:51 +0200 Subject: [PATCH 07/17] tests: typo --- tests/common/macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/common/macros.rs b/tests/common/macros.rs index 81878bf1b..03d2051d0 100644 --- a/tests/common/macros.rs +++ b/tests/common/macros.rs @@ -50,14 +50,14 @@ macro_rules! new_ucmd { /// Convenience macro for acquiring a [`UCommand`] builder and a test path. /// /// Returns a tuple containing the following: -/// - an [`AsPath`] that points to a unique temporary test directory +/// - an [`AtPath`] that points to a unique temporary test directory /// - a [`UCommand`] builder for invoking the binary to be tested /// /// This macro is intended for quick, single-call tests. For more complex tests /// that require multiple invocations of the tested binary, see [`TestScenario`] /// /// [`UCommand`]: crate::tests::common::util::UCommand -/// [`AsPath`]: crate::tests::common::util::AsPath +/// [`AtPath`]: crate::tests::common::util::AtPath /// [`TestScenario]: crate::tests::common::util::TestScenario #[macro_export] macro_rules! at_and_ucmd { From 48516cc06a313c6aa2d95b5fb866b25fb9721cae Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Wed, 2 Jun 2021 17:18:07 +0200 Subject: [PATCH 08/17] pr: fix usage of current time --- tests/by-util/test_pr.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/by-util/test_pr.rs b/tests/by-util/test_pr.rs index 4fef41ccd..def361fab 100644 --- a/tests/by-util/test_pr.rs +++ b/tests/by-util/test_pr.rs @@ -288,13 +288,14 @@ fn test_with_suppress_error_option() { fn test_with_stdin() { let expected_file_path = "stdin.log.expected"; let mut scenario = new_ucmd!(); + let now = now_time(); scenario .pipe_in_fixture("stdin.log") .args(&["--pages=1:2", "-n", "-"]) .run() .stdout_is_templated_fixture( expected_file_path, - vec![(&"{last_modified_time}".to_string(), &now_time())], + vec![(&"{last_modified_time}".to_string(), &now)], ); } @@ -381,22 +382,25 @@ fn test_with_mpr() { let expected_test_file_path = "mpr.log.expected"; let expected_test_file_path1 = "mpr1.log.expected"; let expected_test_file_path2 = "mpr2.log.expected"; + let now = now_time(); new_ucmd!() .args(&["--pages=1:2", "-m", "-n", test_file_path, test_file_path1]) .succeeds() .stdout_is_templated_fixture( expected_test_file_path, - vec![(&"{last_modified_time}".to_string(), &now_time())], + vec![(&"{last_modified_time}".to_string(), &now)], ); + let now = now_time(); new_ucmd!() .args(&["--pages=2:4", "-m", "-n", test_file_path, test_file_path1]) .succeeds() .stdout_is_templated_fixture( expected_test_file_path1, - vec![(&"{last_modified_time}".to_string(), &now_time())], + vec![(&"{last_modified_time}".to_string(), &now)], ); + let now = now_time(); new_ucmd!() .args(&[ "--pages=1:2", @@ -411,7 +415,7 @@ fn test_with_mpr() { .succeeds() .stdout_is_templated_fixture( expected_test_file_path2, - vec![(&"{last_modified_time}".to_string(), &now_time())], + vec![(&"{last_modified_time}".to_string(), &now)], ); } @@ -507,11 +511,12 @@ fn test_with_join_lines_option() { let test_file_2 = "test.log"; let expected_file_path = "joined.log.expected"; let mut scenario = new_ucmd!(); + let now = now_time(); scenario .args(&["+1:2", "-J", "-m", test_file_1, test_file_2]) .run() .stdout_is_templated_fixture( expected_file_path, - vec![(&"{last_modified_time}".to_string(), &now_time())], + vec![(&"{last_modified_time}".to_string(), &now)], ); } From 6aa53ead7c26ad8a4814466798a788eeea35f968 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 2 Jun 2021 18:43:35 +0200 Subject: [PATCH 09/17] rustfmt the recent change --- tests/by-util/test_seq.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/by-util/test_seq.rs b/tests/by-util/test_seq.rs index 459eeeb3a..be04bf1fd 100644 --- a/tests/by-util/test_seq.rs +++ b/tests/by-util/test_seq.rs @@ -2,18 +2,16 @@ use crate::common::util::*; #[test] fn test_rejects_nan() { - new_ucmd!() - .args(&["NaN"]) - .fails() - .stderr_only("seq: invalid 'not-a-number' argument: 'NaN'\nTry 'seq --help' for more information."); + new_ucmd!().args(&["NaN"]).fails().stderr_only( + "seq: invalid 'not-a-number' argument: 'NaN'\nTry 'seq --help' for more information.", + ); } #[test] fn test_rejects_non_floats() { - new_ucmd!() - .args(&["foo"]) - .fails() - .stderr_only("seq: invalid floating point argument: 'foo'\nTry 'seq --help' for more information."); + new_ucmd!().args(&["foo"]).fails().stderr_only( + "seq: invalid floating point argument: 'foo'\nTry 'seq --help' for more information.", + ); } // ---- Tests for the big integer based path ---- From d8c06dd6bb88b7392cdf58bd0502765c4974cd4f Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 2 Jun 2021 19:00:19 +0200 Subject: [PATCH 10/17] use clap::crate_version macro instead of the env variable --- src/uu/arch/src/arch.rs | 5 ++--- src/uu/basename/src/basename.rs | 5 ++--- src/uu/cat/src/cat.rs | 5 ++--- src/uu/chmod/src/chmod.rs | 5 ++--- src/uu/chown/src/chown.rs | 5 ++--- src/uu/chroot/src/chroot.rs | 5 ++--- src/uu/cksum/src/cksum.rs | 5 ++--- src/uu/comm/src/comm.rs | 5 ++--- src/uu/cp/src/cp.rs | 5 ++--- src/uu/csplit/src/csplit.rs | 5 ++--- src/uu/cut/src/cut.rs | 5 ++--- src/uu/date/src/date.rs | 5 ++--- src/uu/df/src/df.rs | 5 ++--- src/uu/dirname/src/dirname.rs | 5 ++--- src/uu/du/src/du.rs | 5 ++--- src/uu/expand/src/expand.rs | 5 ++--- src/uu/factor/src/cli.rs | 5 ++--- src/uu/fmt/src/fmt.rs | 5 ++--- src/uu/fold/src/fold.rs | 5 ++--- src/uu/groups/src/groups.rs | 5 ++--- src/uu/head/src/head.rs | 5 ++--- src/uu/hostname/src/hostname.rs | 5 ++--- src/uu/id/src/id.rs | 5 ++--- src/uu/install/src/install.rs | 5 ++--- src/uu/join/src/join.rs | 5 ++--- src/uu/kill/src/kill.rs | 5 ++--- src/uu/link/src/link.rs | 5 ++--- src/uu/ln/src/ln.rs | 5 ++--- src/uu/logname/src/logname.rs | 5 ++--- src/uu/ls/src/ls.rs | 5 ++--- src/uu/mkdir/src/mkdir.rs | 5 ++--- src/uu/mkfifo/src/mkfifo.rs | 5 ++--- src/uu/mknod/src/mknod.rs | 5 ++--- src/uu/mktemp/src/mktemp.rs | 5 ++--- src/uu/more/src/more.rs | 4 ++-- src/uu/mv/src/mv.rs | 5 ++--- src/uu/nice/src/nice.rs | 5 ++--- src/uu/nl/src/nl.rs | 5 ++--- src/uu/nohup/src/nohup.rs | 5 ++--- src/uu/nproc/src/nproc.rs | 5 ++--- src/uu/numfmt/src/numfmt.rs | 5 ++--- src/uu/od/src/od.rs | 17 ++--------------- src/uu/paste/src/paste.rs | 5 ++--- src/uu/pathchk/src/pathchk.rs | 5 ++--- src/uu/pinky/src/pinky.rs | 5 ++--- src/uu/printenv/src/printenv.rs | 5 ++--- src/uu/ptx/src/ptx.rs | 5 ++--- src/uu/pwd/src/pwd.rs | 5 ++--- src/uu/readlink/src/readlink.rs | 5 ++--- src/uu/realpath/src/realpath.rs | 5 ++--- src/uu/relpath/src/relpath.rs | 5 ++--- src/uu/rm/src/rm.rs | 5 ++--- src/uu/rmdir/src/rmdir.rs | 5 ++--- src/uu/seq/src/seq.rs | 5 ++--- src/uu/shred/src/shred.rs | 5 ++--- src/uu/shuf/src/shuf.rs | 5 ++--- src/uu/sleep/src/sleep.rs | 5 ++--- src/uu/sort/src/sort.rs | 9 ++++----- src/uu/split/src/split.rs | 5 ++--- src/uu/stat/src/stat.rs | 5 ++--- src/uu/stdbuf/src/stdbuf.rs | 5 ++--- src/uu/sum/src/sum.rs | 5 ++--- src/uu/sync/src/sync.rs | 5 ++--- src/uu/tac/src/tac.rs | 5 ++--- src/uu/tee/src/tee.rs | 5 ++--- src/uu/timeout/src/timeout.rs | 6 ++---- src/uu/touch/src/touch.rs | 5 ++--- src/uu/tr/src/tr.rs | 5 ++--- src/uu/truncate/src/truncate.rs | 5 ++--- src/uu/tsort/src/tsort.rs | 5 ++--- src/uu/tty/src/tty.rs | 5 ++--- src/uu/uname/src/uname.rs | 5 ++--- src/uu/unexpand/src/unexpand.rs | 5 ++--- src/uu/uniq/src/uniq.rs | 5 ++--- src/uu/unlink/src/unlink.rs | 5 ++--- src/uu/uptime/src/uptime.rs | 5 ++--- src/uu/users/src/users.rs | 5 ++--- src/uu/wc/src/wc.rs | 5 ++--- src/uu/who/src/who.rs | 5 ++--- 79 files changed, 160 insertions(+), 251 deletions(-) diff --git a/src/uu/arch/src/arch.rs b/src/uu/arch/src/arch.rs index 31278f000..eddd24502 100644 --- a/src/uu/arch/src/arch.rs +++ b/src/uu/arch/src/arch.rs @@ -11,15 +11,14 @@ extern crate uucore; use platform_info::*; -use clap::App; +use clap::{crate_version, App}; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Display machine architecture"; static SUMMARY: &str = "Determine architecture name for current machine."; pub fn uumain(args: impl uucore::Args) -> i32 { App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .after_help(SUMMARY) .get_matches_from(args); diff --git a/src/uu/basename/src/basename.rs b/src/uu/basename/src/basename.rs index ebd69de79..a0eed93f1 100644 --- a/src/uu/basename/src/basename.rs +++ b/src/uu/basename/src/basename.rs @@ -10,11 +10,10 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::path::{is_separator, PathBuf}; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static SUMMARY: &str = "Print NAME with any leading directory components removed If specified, also remove a trailing SUFFIX"; @@ -42,7 +41,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { // Argument parsing // let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(SUMMARY) .usage(&usage[..]) .arg( diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index 69ea902e6..1f2f441d8 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -16,7 +16,7 @@ extern crate unix_socket; extern crate uucore; // last synced with: cat (GNU coreutils) 8.13 -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs::{metadata, File}; use std::io::{self, Read, Write}; use thiserror::Error; @@ -38,7 +38,6 @@ use unix_socket::UnixStream; use uucore::InvalidEncodingHandling; static NAME: &str = "cat"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static SYNTAX: &str = "[OPTION]... [FILE]..."; static SUMMARY: &str = "Concatenate FILE(s), or standard input, to standard output With no FILE, or when FILE is -, read standard input."; @@ -173,7 +172,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .usage(SYNTAX) .about(SUMMARY) .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)) diff --git a/src/uu/chmod/src/chmod.rs b/src/uu/chmod/src/chmod.rs index 62faacffe..9cdabc7d6 100644 --- a/src/uu/chmod/src/chmod.rs +++ b/src/uu/chmod/src/chmod.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs; use std::os::unix::fs::{MetadataExt, PermissionsExt}; use std::path::Path; @@ -21,7 +21,6 @@ use uucore::mode; use uucore::InvalidEncodingHandling; use walkdir::WalkDir; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Change the mode of each FILE to MODE. With --reference, change the mode of each FILE to that of RFILE."; @@ -63,7 +62,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let after_help = get_long_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(&after_help[..]) diff --git a/src/uu/chown/src/chown.rs b/src/uu/chown/src/chown.rs index 3d0b25814..2bb5133fe 100644 --- a/src/uu/chown/src/chown.rs +++ b/src/uu/chown/src/chown.rs @@ -14,7 +14,7 @@ use uucore::fs::resolve_relative_path; use uucore::libc::{gid_t, uid_t}; use uucore::perms::{wrap_chown, Verbosity}; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use walkdir::WalkDir; @@ -26,7 +26,6 @@ use std::path::Path; use uucore::InvalidEncodingHandling; static ABOUT: &str = "change file owner and group"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); pub mod options { pub mod verbosity { @@ -75,7 +74,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/chroot/src/chroot.rs b/src/uu/chroot/src/chroot.rs index 9480830e5..a05bd4494 100644 --- a/src/uu/chroot/src/chroot.rs +++ b/src/uu/chroot/src/chroot.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::ffi::CString; use std::io::Error; use std::path::Path; @@ -18,7 +18,6 @@ use std::process::Command; use uucore::libc::{self, chroot, setgid, setgroups, setuid}; use uucore::{entries, InvalidEncodingHandling}; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static NAME: &str = "chroot"; static ABOUT: &str = "Run COMMAND with root directory set to NEWROOT."; static SYNTAX: &str = "[OPTION]... NEWROOT [COMMAND [ARG]...]"; @@ -37,7 +36,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .accept_any(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(SYNTAX) .arg(Arg::with_name(options::NEWROOT).hidden(true).required(true)) diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index b6f798d5e..49c0536f5 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs::File; use std::io::{self, stdin, BufReader, Read}; use std::path::Path; @@ -20,7 +20,6 @@ use uucore::InvalidEncodingHandling; const CRC_TABLE_LEN: usize = 256; const CRC_TABLE: [u32; CRC_TABLE_LEN] = generate_crc_table(); -const VERSION: &str = env!("CARGO_PKG_VERSION"); const NAME: &str = "cksum"; const SYNTAX: &str = "[OPTIONS] [FILE]..."; const SUMMARY: &str = "Print CRC and size for each file"; @@ -187,7 +186,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .about(SUMMARY) .usage(SYNTAX) .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)) diff --git a/src/uu/comm/src/comm.rs b/src/uu/comm/src/comm.rs index d1d07461c..f7190fb73 100644 --- a/src/uu/comm/src/comm.rs +++ b/src/uu/comm/src/comm.rs @@ -16,9 +16,8 @@ use std::io::{self, stdin, BufRead, BufReader, Stdin}; use std::path::Path; use uucore::InvalidEncodingHandling; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "compare two sorted files line by line"; static LONG_HELP: &str = ""; @@ -140,7 +139,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .accept_any(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(LONG_HELP) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 40266689c..63c322438 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -25,7 +25,7 @@ use winapi::um::fileapi::GetFileInformationByHandle; use std::borrow::Cow; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; use filetime::FileTime; use quick_error::ResultExt; use std::collections::HashSet; @@ -213,7 +213,6 @@ pub struct Options { verbose: bool, } -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY."; static LONG_HELP: &str = ""; static EXIT_OK: i32 = 0; @@ -294,7 +293,7 @@ static DEFAULT_ATTRIBUTES: &[Attribute] = &[ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .after_help(&*format!("{}\n{}", LONG_HELP, backup_control::BACKUP_CONTROL_LONG_HELP)) .usage(&usage[..]) diff --git a/src/uu/csplit/src/csplit.rs b/src/uu/csplit/src/csplit.rs index a2eb8604a..e3b2069ab 100644 --- a/src/uu/csplit/src/csplit.rs +++ b/src/uu/csplit/src/csplit.rs @@ -2,7 +2,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; use regex::Regex; use std::cmp::Ordering; use std::io::{self, BufReader}; @@ -19,7 +19,6 @@ use crate::csplit_error::CsplitError; use crate::split_name::SplitName; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static SUMMARY: &str = "split a file into sections determined by context lines"; static LONG_HELP: &str = "Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output."; @@ -713,7 +712,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .accept_any(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(SUMMARY) .usage(&usage[..]) .arg( diff --git a/src/uu/cut/src/cut.rs b/src/uu/cut/src/cut.rs index 535027237..819cbb989 100644 --- a/src/uu/cut/src/cut.rs +++ b/src/uu/cut/src/cut.rs @@ -11,7 +11,7 @@ extern crate uucore; use bstr::io::BufReadExt; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs::File; use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write}; use std::path::Path; @@ -24,7 +24,6 @@ use uucore::InvalidEncodingHandling; mod searcher; static NAME: &str = "cut"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static SYNTAX: &str = "[-d] [-s] [-z] [--output-delimiter] ((-f|-b|-c) {{sequence}}) {{sourcefile}}+"; static SUMMARY: &str = @@ -400,7 +399,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .usage(SYNTAX) .about(SUMMARY) .after_help(LONG_HELP) diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index 02aa7a60d..8a0e3ef3a 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -14,7 +14,7 @@ extern crate uucore; use chrono::{DateTime, FixedOffset, Local, Offset, Utc}; #[cfg(windows)] use chrono::{Datelike, Timelike}; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; #[cfg(all(unix, not(target_os = "macos")))] use libc::{clock_settime, timespec, CLOCK_REALTIME}; use std::fs::File; @@ -37,7 +37,6 @@ const SECOND: &str = "second"; const NS: &str = "ns"; const NAME: &str = "date"; -const VERSION: &str = env!("CARGO_PKG_VERSION"); const ABOUT: &str = "print or set the system date and time"; const OPT_DATE: &str = "date"; @@ -144,7 +143,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { NAME ); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&syntax[..]) .arg( diff --git a/src/uu/df/src/df.rs b/src/uu/df/src/df.rs index 07f8b0214..0836aa43d 100644 --- a/src/uu/df/src/df.rs +++ b/src/uu/df/src/df.rs @@ -12,7 +12,7 @@ extern crate uucore; use uucore::fsext::statfs_fn; use uucore::fsext::{read_fs_list, FsUsage, MountInfo}; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use number_prefix::NumberPrefix; use std::cell::Cell; @@ -30,7 +30,6 @@ use uucore::libc::{c_char, fsid_t, uid_t}; #[cfg(windows)] use std::path::Path; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Show information about the file system on which each FILE resides,\n\ or all file systems by default."; @@ -260,7 +259,7 @@ fn use_size(free_size: u64, total_size: u64) -> String { pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/dirname/src/dirname.rs b/src/uu/dirname/src/dirname.rs index 63693c982..ad42517d4 100644 --- a/src/uu/dirname/src/dirname.rs +++ b/src/uu/dirname/src/dirname.rs @@ -8,12 +8,11 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::path::Path; use uucore::InvalidEncodingHandling; static ABOUT: &str = "strip last component from file name"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); mod options { pub const ZERO: &str = "zero"; @@ -43,7 +42,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .about(ABOUT) .usage(&usage[..]) .after_help(&after_help[..]) - .version(VERSION) + .version(crate_version!()) .arg( Arg::with_name(options::ZERO) .long(options::ZERO) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 0bc8b30c8..cbb945423 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -10,7 +10,7 @@ extern crate uucore; use chrono::prelude::DateTime; use chrono::Local; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::collections::HashSet; use std::env; use std::fs; @@ -56,7 +56,6 @@ mod options { pub const FILE: &str = "FILE"; } -const VERSION: &str = env!("CARGO_PKG_VERSION"); const NAME: &str = "du"; const SUMMARY: &str = "estimate file space usage"; const LONG_HELP: &str = " @@ -398,7 +397,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(SUMMARY) .usage(&usage[..]) .after_help(LONG_HELP) diff --git a/src/uu/expand/src/expand.rs b/src/uu/expand/src/expand.rs index 67d24086c..08a514dbf 100644 --- a/src/uu/expand/src/expand.rs +++ b/src/uu/expand/src/expand.rs @@ -12,14 +12,13 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; use std::fs::File; use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write}; use std::iter::repeat; use std::str::from_utf8; use unicode_width::UnicodeWidthChar; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Convert tabs in each FILE to spaces, writing to standard output. With no FILE, or when FILE is -, read standard input."; @@ -111,7 +110,7 @@ impl Options { pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(LONG_HELP) diff --git a/src/uu/factor/src/cli.rs b/src/uu/factor/src/cli.rs index 69a368479..af5e3cdb0 100644 --- a/src/uu/factor/src/cli.rs +++ b/src/uu/factor/src/cli.rs @@ -13,7 +13,7 @@ use std::error::Error; use std::io::{self, stdin, stdout, BufRead, Write}; mod factor; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; pub use factor::*; mod miller_rabin; @@ -21,7 +21,6 @@ pub mod numeric; mod rho; pub mod table; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static SUMMARY: &str = "Print the prime factors of the given NUMBER(s). If none are specified, read from standard input."; @@ -38,7 +37,7 @@ fn print_factors_str(num_str: &str, w: &mut impl io::Write) -> Result<(), Box i32 { let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(SUMMARY) .arg(Arg::with_name(options::NUMBER).multiple(true)) .get_matches_from(args); diff --git a/src/uu/fmt/src/fmt.rs b/src/uu/fmt/src/fmt.rs index f10f4cf7f..91f59e076 100644 --- a/src/uu/fmt/src/fmt.rs +++ b/src/uu/fmt/src/fmt.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::cmp; use std::fs::File; use std::io::{stdin, stdout, Write}; @@ -32,7 +32,6 @@ mod linebreak; mod parasplit; static ABOUT: &str = "Reformat paragraphs from input files (or stdin) to stdout."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static MAX_WIDTH: usize = 2500; static OPT_CROWN_MARGIN: &str = "crown-margin"; @@ -79,7 +78,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 1f52748f1..e476fed5b 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; use std::path::Path; @@ -19,7 +19,6 @@ use uucore::InvalidEncodingHandling; const TAB_WIDTH: usize = 8; static NAME: &str = "fold"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static SYNTAX: &str = "[OPTION]... [FILE]..."; static SUMMARY: &str = "Writes each file (or standard input if no files are given) to standard output whilst breaking long lines"; @@ -39,7 +38,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let (args, obs_width) = handle_obsolete(&args[..]); let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .usage(SYNTAX) .about(SUMMARY) .arg( diff --git a/src/uu/groups/src/groups.rs b/src/uu/groups/src/groups.rs index 2ce5fe70e..5b9cd948a 100644 --- a/src/uu/groups/src/groups.rs +++ b/src/uu/groups/src/groups.rs @@ -12,9 +12,8 @@ extern crate uucore; use uucore::entries::{get_groups, gid2grp, Locate, Passwd}; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "display current group names"; static OPT_USER: &str = "user"; @@ -26,7 +25,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg(Arg::with_name(OPT_USER)) diff --git a/src/uu/head/src/head.rs b/src/uu/head/src/head.rs index ff5ef2355..28710e1fe 100644 --- a/src/uu/head/src/head.rs +++ b/src/uu/head/src/head.rs @@ -1,6 +1,6 @@ // spell-checker:ignore (vars) zlines -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::convert::TryFrom; use std::ffi::OsString; use std::io::{self, ErrorKind, Read, Seek, SeekFrom, Write}; @@ -10,7 +10,6 @@ const EXIT_FAILURE: i32 = 1; const EXIT_SUCCESS: i32 = 0; const BUF_SIZE: usize = 65536; -const VERSION: &str = env!("CARGO_PKG_VERSION"); const ABOUT: &str = "\ Print the first 10 lines of each FILE to standard output.\n\ With more than one FILE, precede each with a header giving the file name.\n\ @@ -38,7 +37,7 @@ use take::take_all_but; fn app<'a>() -> App<'a, 'a> { App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(USAGE) .arg( diff --git a/src/uu/hostname/src/hostname.rs b/src/uu/hostname/src/hostname.rs index d6f70be16..ff312fb58 100644 --- a/src/uu/hostname/src/hostname.rs +++ b/src/uu/hostname/src/hostname.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; use std::collections::hash_set::HashSet; use std::net::ToSocketAddrs; use std::str; @@ -21,7 +21,6 @@ use winapi::shared::minwindef::MAKEWORD; use winapi::um::winsock2::{WSACleanup, WSAStartup}; static ABOUT: &str = "Display or set the system's host name."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_DOMAIN: &str = "domain"; static OPT_IP_ADDRESS: &str = "ip-address"; @@ -54,7 +53,7 @@ fn get_usage() -> String { fn execute(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/id/src/id.rs b/src/uu/id/src/id.rs index 4536622c7..77b185f24 100644 --- a/src/uu/id/src/id.rs +++ b/src/uu/id/src/id.rs @@ -18,7 +18,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::ffi::CStr; use uucore::entries::{self, Group, Locate, Passwd}; pub use uucore::libc; @@ -71,7 +71,6 @@ mod audit { } static ABOUT: &str = "Display user and group information for the specified USER,\n or (when USER omitted) for the current user."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_AUDIT: &str = "audit"; static OPT_EFFECTIVE_USER: &str = "effective-user"; @@ -92,7 +91,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 7a4ad1fd1..7aa6f95ff 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -12,7 +12,7 @@ mod mode; #[macro_use] extern crate uucore; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; use file_diff::diff; use filetime::{set_file_times, FileTime}; use uucore::entries::{grp2gid, usr2uid}; @@ -64,7 +64,6 @@ impl Behavior { static ABOUT: &str = "Copy SOURCE to DEST or multiple SOURCE(s) to the existing DIRECTORY, while setting permission modes and owner/group"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_COMPARE: &str = "compare"; static OPT_BACKUP: &str = "backup"; @@ -99,7 +98,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/join/src/join.rs b/src/uu/join/src/join.rs index d02a54eb3..7a044789f 100644 --- a/src/uu/join/src/join.rs +++ b/src/uu/join/src/join.rs @@ -10,13 +10,12 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::cmp::{min, Ordering}; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Lines, Stdin}; static NAME: &str = "join"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); #[derive(Copy, Clone, PartialEq)] enum FileNum { @@ -444,7 +443,7 @@ impl<'a> State<'a> { pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(NAME) - .version(VERSION) + .version(crate_version!()) .about( "For each pair of input lines with identical join fields, write a line to standard output. The default join field is the first, delimited by blanks. diff --git a/src/uu/kill/src/kill.rs b/src/uu/kill/src/kill.rs index 362f13f18..6c2464c92 100644 --- a/src/uu/kill/src/kill.rs +++ b/src/uu/kill/src/kill.rs @@ -10,13 +10,12 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use libc::{c_int, pid_t}; use std::io::Error; use uucore::signals::ALL_SIGNALS; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Send signal to processes or list information about signals."; static EXIT_OK: i32 = 0; @@ -45,7 +44,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = format!("{} [OPTIONS]... PID...", executable!()); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/link/src/link.rs b/src/uu/link/src/link.rs index bd8b33355..08401ebaf 100644 --- a/src/uu/link/src/link.rs +++ b/src/uu/link/src/link.rs @@ -8,12 +8,11 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs::hard_link; use std::io::Error; use std::path::Path; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Call the link function to create a link named FILE2 to an existing FILE1."; pub mod options { @@ -34,7 +33,7 @@ pub fn normalize_error_message(e: Error) -> String { pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index 2a14f3c9c..cd5eef842 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::borrow::Cow; use std::ffi::OsStr; @@ -77,7 +77,6 @@ fn get_long_usage() -> String { } static ABOUT: &str = "change file owner and group"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_B: &str = "b"; static OPT_BACKUP: &str = "backup"; @@ -98,7 +97,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let long_usage = get_long_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(&long_usage[..]) diff --git a/src/uu/logname/src/logname.rs b/src/uu/logname/src/logname.rs index 14bf7ef3b..ba5880403 100644 --- a/src/uu/logname/src/logname.rs +++ b/src/uu/logname/src/logname.rs @@ -15,7 +15,7 @@ extern crate uucore; use std::ffi::CStr; use uucore::InvalidEncodingHandling; -use clap::App; +use clap::{crate_version, App}; extern "C" { // POSIX requires using getlogin (or equivalent code) @@ -34,7 +34,6 @@ fn get_userlogin() -> Option { } static SUMMARY: &str = "Print user's login name"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); fn get_usage() -> String { String::from(executable!()) @@ -47,7 +46,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let _ = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(SUMMARY) .usage(&usage[..]) .get_matches_from(args); diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 28ab13c71..3c7b22360 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -16,7 +16,7 @@ extern crate lazy_static; mod quoting_style; mod version_cmp; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use globset::{self, Glob, GlobSet, GlobSetBuilder}; use lscolors::LsColors; use number_prefix::NumberPrefix; @@ -45,7 +45,6 @@ use unicode_width::UnicodeWidthStr; #[cfg(unix)] use uucore::libc::{S_IXGRP, S_IXOTH, S_IXUSR}; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = " By default, ls will list the files and contents of any directories on the command line, expect that it will ignore files and directories @@ -559,7 +558,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let app = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index 861ef5075..d1461c0c9 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -8,12 +8,11 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs; use std::path::Path; static ABOUT: &str = "Create the given DIRECTORY(ies) if they do not exist"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_MODE: &str = "mode"; static OPT_PARENTS: &str = "parents"; static OPT_VERBOSE: &str = "verbose"; @@ -34,7 +33,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { // opts.optflag("Z", "context", "set SELinux security context" + // " of each created directory to CTX"), let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/mkfifo/src/mkfifo.rs b/src/uu/mkfifo/src/mkfifo.rs index 2fdd4abec..cf2fefa50 100644 --- a/src/uu/mkfifo/src/mkfifo.rs +++ b/src/uu/mkfifo/src/mkfifo.rs @@ -8,13 +8,12 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use libc::mkfifo; use std::ffi::CString; use uucore::InvalidEncodingHandling; static NAME: &str = "mkfifo"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static USAGE: &str = "mkfifo [OPTION]... NAME..."; static SUMMARY: &str = "Create a FIFO with the given name."; @@ -32,7 +31,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .usage(USAGE) .about(SUMMARY) .arg( diff --git a/src/uu/mknod/src/mknod.rs b/src/uu/mknod/src/mknod.rs index 57bdd3052..e5e6ef1fa 100644 --- a/src/uu/mknod/src/mknod.rs +++ b/src/uu/mknod/src/mknod.rs @@ -12,14 +12,13 @@ extern crate uucore; use std::ffi::CString; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; use libc::{dev_t, mode_t}; use libc::{S_IFBLK, S_IFCHR, S_IFIFO, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR}; use uucore::InvalidEncodingHandling; static NAME: &str = "mknod"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Create the special file NAME of the given TYPE."; static USAGE: &str = "mknod [OPTION]... NAME TYPE [MAJOR MINOR]"; static LONG_HELP: &str = "Mandatory arguments to long options are mandatory for short options too. @@ -91,7 +90,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { // opts.optopt("", "context", "like -Z, or if CTX is specified then set the SELinux or SMACK security context to CTX"); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .usage(USAGE) .after_help(LONG_HELP) .about(ABOUT) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index f7c87495c..67a88273d 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -11,7 +11,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::env; use std::iter; @@ -21,7 +21,6 @@ use rand::Rng; use tempfile::Builder; static ABOUT: &str = "create a temporary file or directory."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static DEFAULT_TEMPLATE: &str = "tmp.XXXXXXXXXX"; @@ -42,7 +41,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 482c5491d..deadba4e4 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -21,7 +21,7 @@ use std::{ #[cfg(all(unix, not(target_os = "fuchsia")))] extern crate nix; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use crossterm::{ event::{self, Event, KeyCode, KeyEvent, KeyModifiers}, execute, queue, @@ -49,7 +49,7 @@ const MULTI_FILE_TOP_PROMPT: &str = "::::::::::::::\n{}\n::::::::::::::\n"; pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .about("A file perusal filter for CRT viewing.") - .version(env!("CARGO_PKG_VERSION")) + .version(crate_version!()) // The commented arguments below are unimplemented: /* .arg( diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index c61c7caf1..6b6482702 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -11,7 +11,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; use std::env; use std::fs; use std::io::{self, stdin}; @@ -42,7 +42,6 @@ pub enum OverwriteMode { } static ABOUT: &str = "Move SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static LONG_HELP: &str = ""; static OPT_BACKUP: &str = "backup"; @@ -72,7 +71,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .after_help(&*format!("{}\n{}", LONG_HELP, backup_control::BACKUP_CONTROL_LONG_HELP)) .usage(&usage[..]) diff --git a/src/uu/nice/src/nice.rs b/src/uu/nice/src/nice.rs index c1d3345af..77baad0ca 100644 --- a/src/uu/nice/src/nice.rs +++ b/src/uu/nice/src/nice.rs @@ -15,8 +15,7 @@ use std::ffi::CString; use std::io::Error; use std::ptr; -use clap::{App, AppSettings, Arg}; -const VERSION: &str = env!("CARGO_PKG_VERSION"); +use clap::{crate_version, App, AppSettings, Arg}; // XXX: PRIO_PROCESS is 0 on at least FreeBSD and Linux. Don't know about Mac OS X. const PRIO_PROCESS: c_int = 0; @@ -49,7 +48,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .setting(AppSettings::TrailingVarArg) - .version(VERSION) + .version(crate_version!()) .usage(&usage[..]) .arg( Arg::with_name(options::ADJUSTMENT) diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index 69adbed41..c062eedd9 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -11,7 +11,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; use std::iter::repeat; @@ -21,7 +21,6 @@ use uucore::InvalidEncodingHandling; mod helper; static NAME: &str = "nl"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static USAGE: &str = "nl [OPTION]... [FILE]..."; // A regular expression matching everything. @@ -91,7 +90,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .usage(USAGE) .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)) .arg( diff --git a/src/uu/nohup/src/nohup.rs b/src/uu/nohup/src/nohup.rs index 93d9b5e45..ea379ff49 100644 --- a/src/uu/nohup/src/nohup.rs +++ b/src/uu/nohup/src/nohup.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, AppSettings, Arg}; +use clap::{crate_version, App, AppSettings, Arg}; use libc::{c_char, dup2, execvp, signal}; use libc::{SIGHUP, SIG_IGN}; use std::env; @@ -22,7 +22,6 @@ use std::path::{Path, PathBuf}; use uucore::fs::{is_stderr_interactive, is_stdin_interactive, is_stdout_interactive}; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Run COMMAND ignoring hangup signals."; static LONG_HELP: &str = " If standard input is terminal, it'll be replaced with /dev/null. @@ -48,7 +47,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .accept_any(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(LONG_HELP) diff --git a/src/uu/nproc/src/nproc.rs b/src/uu/nproc/src/nproc.rs index 285cf764f..13f1862d2 100644 --- a/src/uu/nproc/src/nproc.rs +++ b/src/uu/nproc/src/nproc.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::env; #[cfg(target_os = "linux")] @@ -25,7 +25,6 @@ pub const _SC_NPROCESSORS_CONF: libc::c_int = 1001; static OPT_ALL: &str = "all"; static OPT_IGNORE: &str = "ignore"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Print the number of cores available to the current process."; fn get_usage() -> String { @@ -35,7 +34,7 @@ fn get_usage() -> String { pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/numfmt/src/numfmt.rs b/src/uu/numfmt/src/numfmt.rs index 6eba699b2..086336437 100644 --- a/src/uu/numfmt/src/numfmt.rs +++ b/src/uu/numfmt/src/numfmt.rs @@ -11,7 +11,7 @@ extern crate uucore; use crate::format::format_and_print; use crate::options::*; use crate::units::{Result, Transform, Unit}; -use clap::{App, AppSettings, Arg, ArgMatches}; +use clap::{crate_version, App, AppSettings, Arg, ArgMatches}; use std::io::{BufRead, Write}; use uucore::ranges::Range; @@ -19,7 +19,6 @@ pub mod format; mod options; mod units; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Convert numbers from/to human-readable strings"; static LONG_HELP: &str = "UNIT options: none no auto-scaling is done; suffixes will trigger an error @@ -149,7 +148,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(LONG_HELP) diff --git a/src/uu/od/src/od.rs b/src/uu/od/src/od.rs index 7359047b2..33303f0fc 100644 --- a/src/uu/od/src/od.rs +++ b/src/uu/od/src/od.rs @@ -42,10 +42,9 @@ use crate::parse_nrofbytes::parse_number_of_bytes; use crate::partialreader::*; use crate::peekreader::*; use crate::prn_char::format_ascii_dump; -use clap::{self, AppSettings, Arg, ArgMatches}; +use clap::{self, crate_version, AppSettings, Arg, ArgMatches}; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); const PEEK_BUFFER_SIZE: usize = 4; // utf-8 can be 4 bytes static ABOUT: &str = "dump files in octal and other formats"; @@ -103,7 +102,6 @@ pub(crate) mod options { pub const OUTPUT_DUPLICATES: &str = "output-duplicates"; pub const TRADITIONAL: &str = "traditional"; pub const WIDTH: &str = "width"; - pub const VERSION: &str = "version"; pub const FILENAME: &str = "FILENAME"; } @@ -228,7 +226,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .accept_any(); let clap_opts = clap::App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(USAGE) .after_help(LONG_HELP) @@ -431,12 +429,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .default_value("32") .value_name("BYTES"), ) - .arg( - Arg::with_name(options::VERSION) - .long(options::VERSION) - .help("output version information and exit.") - .takes_value(false), - ) .arg( Arg::with_name(options::TRADITIONAL) .long(options::TRADITIONAL) @@ -459,11 +451,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .clone() // Clone to reuse clap_opts to print help .get_matches_from(args.clone()); - if clap_matches.is_present(options::VERSION) { - println!("{} {}", executable!(), VERSION); - return 0; - } - let od_options = match OdOptions::new(clap_matches, args) { Err(s) => { show_usage_error!("{}", s); diff --git a/src/uu/paste/src/paste.rs b/src/uu/paste/src/paste.rs index 751cc0a04..f2fa3c81c 100644 --- a/src/uu/paste/src/paste.rs +++ b/src/uu/paste/src/paste.rs @@ -10,13 +10,12 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; use std::iter::repeat; use std::path::Path; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Write lines consisting of the sequentially corresponding lines from each FILE, separated by TABs, to standard output."; @@ -39,7 +38,7 @@ fn read_line( pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .arg( Arg::with_name(options::SERIAL) diff --git a/src/uu/pathchk/src/pathchk.rs b/src/uu/pathchk/src/pathchk.rs index 5606c4d6a..9667e0ba1 100644 --- a/src/uu/pathchk/src/pathchk.rs +++ b/src/uu/pathchk/src/pathchk.rs @@ -12,7 +12,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs; use std::io::{ErrorKind, Write}; use uucore::InvalidEncodingHandling; @@ -26,7 +26,6 @@ enum Mode { } static NAME: &str = "pathchk"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Check whether file names are valid or portable"; mod options { @@ -51,7 +50,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .accept_any(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/pinky/src/pinky.rs b/src/uu/pinky/src/pinky.rs index d65775c2d..27dcc2421 100644 --- a/src/uu/pinky/src/pinky.rs +++ b/src/uu/pinky/src/pinky.rs @@ -19,13 +19,12 @@ use std::io::BufReader; use std::fs::File; use std::os::unix::fs::MetadataExt; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::path::PathBuf; use uucore::InvalidEncodingHandling; const BUFSIZE: usize = 1024; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "pinky - lightweight finger"; mod options { @@ -62,7 +61,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let after_help = get_long_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(&after_help[..]) diff --git a/src/uu/printenv/src/printenv.rs b/src/uu/printenv/src/printenv.rs index 25cb58185..5c2594835 100644 --- a/src/uu/printenv/src/printenv.rs +++ b/src/uu/printenv/src/printenv.rs @@ -10,11 +10,10 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::env; static ABOUT: &str = "Display the values of the specified environment VARIABLE(s), or (with no VARIABLE) display name and value pairs for them all."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_NULL: &str = "null"; @@ -28,7 +27,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/ptx/src/ptx.rs b/src/uu/ptx/src/ptx.rs index 5b0c35093..69960ac49 100644 --- a/src/uu/ptx/src/ptx.rs +++ b/src/uu/ptx/src/ptx.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use regex::Regex; use std::cmp; use std::collections::{BTreeSet, HashMap, HashSet}; @@ -20,7 +20,6 @@ use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write}; use uucore::InvalidEncodingHandling; static NAME: &str = "ptx"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static BRIEF: &str = "Usage: ptx [OPTION]... [INPUT]... (without -G) or: \ ptx -G [OPTION]... [INPUT [OUTPUT]] \n Output a permuted index, \ including context, of the words in the input files. \n\n Mandatory \ @@ -641,7 +640,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { // let mut opts = Options::new(); let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .usage(BRIEF) .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)) .arg( diff --git a/src/uu/pwd/src/pwd.rs b/src/uu/pwd/src/pwd.rs index 1786d33ee..9b4e5c600 100644 --- a/src/uu/pwd/src/pwd.rs +++ b/src/uu/pwd/src/pwd.rs @@ -8,13 +8,12 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::env; use std::io; use std::path::{Path, PathBuf}; static ABOUT: &str = "Display the full filename of the current working directory."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_LOGICAL: &str = "logical"; static OPT_PHYSICAL: &str = "physical"; @@ -41,7 +40,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/readlink/src/readlink.rs b/src/uu/readlink/src/readlink.rs index 43a4ca656..02e286315 100644 --- a/src/uu/readlink/src/readlink.rs +++ b/src/uu/readlink/src/readlink.rs @@ -10,14 +10,13 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs; use std::io::{stdout, Write}; use std::path::{Path, PathBuf}; use uucore::fs::{canonicalize, CanonicalizeMode}; const NAME: &str = "readlink"; -const VERSION: &str = env!("CARGO_PKG_VERSION"); const ABOUT: &str = "Print value of a symbolic link or canonical file name."; const OPT_CANONICALIZE: &str = "canonicalize"; const OPT_CANONICALIZE_MISSING: &str = "canonicalize-missing"; @@ -37,7 +36,7 @@ fn get_usage() -> String { pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/realpath/src/realpath.rs b/src/uu/realpath/src/realpath.rs index 937cee5bd..1a96b7f80 100644 --- a/src/uu/realpath/src/realpath.rs +++ b/src/uu/realpath/src/realpath.rs @@ -10,12 +10,11 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::path::{Path, PathBuf}; use uucore::fs::{canonicalize, CanonicalizeMode}; static ABOUT: &str = "print the resolved path"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_QUIET: &str = "quiet"; static OPT_STRIP: &str = "strip"; @@ -31,7 +30,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/relpath/src/relpath.rs b/src/uu/relpath/src/relpath.rs index f1b2c9a43..a997e1c5f 100644 --- a/src/uu/relpath/src/relpath.rs +++ b/src/uu/relpath/src/relpath.rs @@ -10,13 +10,12 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::env; use std::path::{Path, PathBuf}; use uucore::fs::{canonicalize, CanonicalizeMode}; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Convert TO destination to the relative path from the FROM dir. If FROM path is omitted, current working dir will be used."; @@ -37,7 +36,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 8010988bb..43a4f4780 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use remove_dir_all::remove_dir_all; use std::collections::VecDeque; use std::fs; @@ -38,7 +38,6 @@ struct Options { } static ABOUT: &str = "Remove (unlink) the FILE(s)"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_DIR: &str = "dir"; static OPT_INTERACTIVE: &str = "interactive"; static OPT_FORCE: &str = "force"; @@ -79,7 +78,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let long_usage = get_long_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(&long_usage[..]) diff --git a/src/uu/rmdir/src/rmdir.rs b/src/uu/rmdir/src/rmdir.rs index d39c33f77..d13a21f60 100644 --- a/src/uu/rmdir/src/rmdir.rs +++ b/src/uu/rmdir/src/rmdir.rs @@ -10,11 +10,10 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs; use std::path::Path; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Remove the DIRECTORY(ies), if they are empty."; static OPT_IGNORE_FAIL_NON_EMPTY: &str = "ignore-fail-on-non-empty"; static OPT_PARENTS: &str = "parents"; @@ -35,7 +34,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/seq/src/seq.rs b/src/uu/seq/src/seq.rs index 8cf6513cb..954d15f2f 100644 --- a/src/uu/seq/src/seq.rs +++ b/src/uu/seq/src/seq.rs @@ -6,7 +6,7 @@ #[macro_use] extern crate uucore; -use clap::{App, AppSettings, Arg}; +use clap::{crate_version, App, AppSettings, Arg}; use num_bigint::BigInt; use num_traits::One; use num_traits::Zero; @@ -15,7 +15,6 @@ use std::cmp; use std::io::{stdout, Write}; use std::str::FromStr; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Display numbers from FIRST to LAST, in steps of INCREMENT."; static OPT_SEPARATOR: &str = "separator"; static OPT_TERMINATOR: &str = "terminator"; @@ -90,7 +89,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) .setting(AppSettings::AllowLeadingHyphen) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index e371ad6b2..6a43ed478 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -8,7 +8,7 @@ // spell-checker:ignore (words) writeback wipesync -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use rand::{Rng, ThreadRng}; use std::cell::{Cell, RefCell}; use std::fs; @@ -23,7 +23,6 @@ use uucore::InvalidEncodingHandling; extern crate uucore; static NAME: &str = "shred"; -static VERSION_STR: &str = "1.0.0"; const BLOCK_SIZE: usize = 512; const NAME_CHARSET: &str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_."; @@ -278,7 +277,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let app = App::new(executable!()) - .version(VERSION_STR) + .version(crate_version!()) .about(ABOUT) .after_help(AFTER_HELP) .usage(&usage[..]) diff --git a/src/uu/shuf/src/shuf.rs b/src/uu/shuf/src/shuf.rs index 9c735673c..88a47585f 100644 --- a/src/uu/shuf/src/shuf.rs +++ b/src/uu/shuf/src/shuf.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use rand::Rng; use std::fs::File; use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write}; @@ -23,7 +23,6 @@ enum Mode { } static NAME: &str = "shuf"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static USAGE: &str = r#"shuf [OPTION]... [FILE] or: shuf -e [OPTION]... [ARG]... or: shuf -i LO-HI [OPTION]... @@ -59,7 +58,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .template(TEMPLATE) .usage(USAGE) .arg( diff --git a/src/uu/sleep/src/sleep.rs b/src/uu/sleep/src/sleep.rs index 5c1f06e5e..c78c1cfc9 100644 --- a/src/uu/sleep/src/sleep.rs +++ b/src/uu/sleep/src/sleep.rs @@ -11,9 +11,8 @@ extern crate uucore; use std::thread; use std::time::Duration; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Pause for NUMBER seconds."; static LONG_HELP: &str = "Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days. Unlike most implementations @@ -37,7 +36,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(LONG_HELP) diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index f47b561ed..5825e73bd 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -23,7 +23,7 @@ mod ext_sort; mod merge; mod numeric_str_cmp; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use custom_str_cmp::custom_str_cmp; use ext_sort::ext_sort; use fnv::FnvHasher; @@ -47,7 +47,6 @@ use uucore::InvalidEncodingHandling; static NAME: &str = "sort"; static ABOUT: &str = "Display sorted concatenation of all FILE(s)."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); const LONG_HELP_KEYS: &str = "The key format is FIELD[.CHAR][OPTIONS][,FIELD[.CHAR]][OPTIONS]. @@ -874,13 +873,13 @@ impl FieldSelector { fn get_usage() -> String { format!( - "{0} {1} + "{0} Usage: {0} [OPTION]... [FILE]... Write the sorted concatenation of all FILE(s) to standard output. Mandatory arguments for long options are mandatory for short options too. With no FILE, or when FILE is -, read standard input.", - NAME, VERSION + NAME ) } @@ -902,7 +901,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let mut settings: GlobalSettings = Default::default(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/split/src/split.rs b/src/uu/split/src/split.rs index 85ed5f183..6550c35ac 100644 --- a/src/uu/split/src/split.rs +++ b/src/uu/split/src/split.rs @@ -12,7 +12,7 @@ extern crate uucore; mod platform; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::env; use std::fs::File; use std::io::{stdin, BufRead, BufReader, BufWriter, Read, Write}; @@ -20,7 +20,6 @@ use std::path::Path; use std::{char, fs::remove_file}; static NAME: &str = "split"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static OPT_BYTES: &str = "bytes"; static OPT_LINE_BYTES: &str = "line-bytes"; @@ -56,7 +55,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let default_suffix_length_str = OPT_DEFAULT_SUFFIX_LENGTH.to_string(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about("Create output files containing consecutive or interleaved sections of input") .usage(&usage[..]) .after_help(&long_usage[..]) diff --git a/src/uu/stat/src/stat.rs b/src/uu/stat/src/stat.rs index 403134b4b..fa070d9b7 100644 --- a/src/uu/stat/src/stat.rs +++ b/src/uu/stat/src/stat.rs @@ -14,7 +14,7 @@ use uucore::fsext::{ }; use uucore::libc::mode_t; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; use std::borrow::Cow; use std::convert::AsRef; use std::os::unix::fs::{FileTypeExt, MetadataExt}; @@ -82,7 +82,6 @@ macro_rules! print_adjusted { } static ABOUT: &str = "Display file or file system status."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); pub mod options { pub static DEREFERENCE: &str = "dereference"; @@ -949,7 +948,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let long_usage = get_long_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(&long_usage[..]) diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index 134247060..852fe3ef9 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, AppSettings, Arg, ArgMatches}; +use clap::{crate_version, App, AppSettings, Arg, ArgMatches}; use std::convert::TryFrom; use std::fs::File; use std::io::{self, Write}; @@ -21,7 +21,6 @@ use tempfile::tempdir; use tempfile::TempDir; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Run COMMAND, with modified buffering operations for its standard streams.\n\n\ Mandatory arguments to long options are mandatory for short options too."; @@ -193,7 +192,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(LONG_HELP) diff --git a/src/uu/sum/src/sum.rs b/src/uu/sum/src/sum.rs index 95de707fa..4d42d7a97 100644 --- a/src/uu/sum/src/sum.rs +++ b/src/uu/sum/src/sum.rs @@ -10,14 +10,13 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs::File; use std::io::{stdin, Read, Result}; use std::path::Path; use uucore::InvalidEncodingHandling; static NAME: &str = "sum"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static USAGE: &str = "[OPTION]... [FILE]...\nWith no FILE, or when FILE is -, read standard input."; static SUMMARY: &str = "Checksum and count the blocks in a file."; @@ -101,7 +100,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .usage(USAGE) .about(SUMMARY) .arg(Arg::with_name(options::FILE).multiple(true).hidden(true)) diff --git a/src/uu/sync/src/sync.rs b/src/uu/sync/src/sync.rs index 59206db98..53d1a5701 100644 --- a/src/uu/sync/src/sync.rs +++ b/src/uu/sync/src/sync.rs @@ -12,13 +12,12 @@ extern crate libc; #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::path::Path; static EXIT_ERR: i32 = 1; static ABOUT: &str = "Synchronize cached writes to persistent storage"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); pub mod options { pub static FILE_SYSTEM: &str = "file-system"; pub static DATA: &str = "data"; @@ -168,7 +167,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/tac/src/tac.rs b/src/uu/tac/src/tac.rs index a638d578d..be1852ec5 100644 --- a/src/uu/tac/src/tac.rs +++ b/src/uu/tac/src/tac.rs @@ -10,13 +10,12 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::io::{stdin, stdout, BufReader, Read, Stdout, Write}; use std::{fs::File, path::Path}; use uucore::InvalidEncodingHandling; static NAME: &str = "tac"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static USAGE: &str = "[OPTION]... [FILE]..."; static SUMMARY: &str = "Write each file to standard output, last line first."; @@ -34,7 +33,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .usage(USAGE) .about(SUMMARY) .arg( diff --git a/src/uu/tee/src/tee.rs b/src/uu/tee/src/tee.rs index 82a06daa2..f5f24d944 100644 --- a/src/uu/tee/src/tee.rs +++ b/src/uu/tee/src/tee.rs @@ -8,7 +8,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use retain_mut::RetainMut; use std::fs::OpenOptions; use std::io::{copy, sink, stdin, stdout, Error, ErrorKind, Read, Result, Write}; @@ -17,7 +17,6 @@ use std::path::{Path, PathBuf}; #[cfg(unix)] use uucore::libc; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Copy standard input to each FILE, and also to standard output."; mod options { @@ -41,7 +40,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help("If a FILE is -, it refers to a file named - .") diff --git a/src/uu/timeout/src/timeout.rs b/src/uu/timeout/src/timeout.rs index dc8979143..4ef9b2331 100644 --- a/src/uu/timeout/src/timeout.rs +++ b/src/uu/timeout/src/timeout.rs @@ -12,7 +12,7 @@ extern crate uucore; extern crate clap; -use clap::{App, AppSettings, Arg}; +use clap::{crate_version, App, AppSettings, Arg}; use std::io::ErrorKind; use std::process::{Command, Stdio}; use std::time::Duration; @@ -20,7 +20,6 @@ use uucore::process::ChildExt; use uucore::signals::signal_by_name_or_value; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Start COMMAND, and kill it if still running after DURATION."; fn get_usage() -> String { @@ -33,7 +32,6 @@ pub mod options { pub static FOREGROUND: &str = "foreground"; pub static KILL_AFTER: &str = "kill-after"; pub static SIGNAL: &str = "signal"; - pub static VERSION: &str = "version"; pub static PRESERVE_STATUS: &str = "preserve-status"; // Positional args. @@ -106,7 +104,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let app = App::new("timeout") - .version(VERSION) + .version(crate_version!()) .usage(&usage[..]) .about(ABOUT) .arg( diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index b76e04b7a..b2df29d33 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -13,14 +13,13 @@ pub extern crate filetime; #[macro_use] extern crate uucore; -use clap::{App, Arg, ArgGroup}; +use clap::{crate_version, App, Arg, ArgGroup}; use filetime::*; use std::fs::{self, File}; use std::io::Error; use std::path::Path; use std::process; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Update the access and modification times of each FILE to the current time."; pub mod options { // Both SOURCES and sources are needed as we need to be able to refer to the ArgGroup. @@ -57,7 +56,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs index a44f2733c..3c362dcec 100644 --- a/src/uu/tr/src/tr.rs +++ b/src/uu/tr/src/tr.rs @@ -16,14 +16,13 @@ extern crate uucore; mod expand; use bit_set::BitSet; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use fnv::FnvHashMap; use std::io::{stdin, stdout, BufRead, BufWriter, Write}; use crate::expand::ExpandSet; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "translate or delete characters"; const BUFFER_LEN: usize = 1024; @@ -251,7 +250,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let after_help = get_long_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(&after_help[..]) diff --git a/src/uu/truncate/src/truncate.rs b/src/uu/truncate/src/truncate.rs index 50ab5c45e..8e785ad21 100644 --- a/src/uu/truncate/src/truncate.rs +++ b/src/uu/truncate/src/truncate.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs::{metadata, OpenOptions}; use std::io::ErrorKind; use std::path::Path; @@ -52,7 +52,6 @@ impl TruncateMode { } static ABOUT: &str = "Shrink or extend the size of each file to the specified size."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); pub mod options { pub static IO_BLOCKS: &str = "io-blocks"; @@ -94,7 +93,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let long_usage = get_long_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(&long_usage[..]) diff --git a/src/uu/tsort/src/tsort.rs b/src/uu/tsort/src/tsort.rs index c96939b20..8bd6dabef 100644 --- a/src/uu/tsort/src/tsort.rs +++ b/src/uu/tsort/src/tsort.rs @@ -9,14 +9,13 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::collections::{HashMap, HashSet}; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; use std::path::Path; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static SUMMARY: &str = "Topological sort the strings in FILE. Strings are defined as any sequence of tokens separated by whitespace (tab, space, or newline). If FILE is not passed in, stdin is used instead."; @@ -32,7 +31,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .accept_any(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .usage(USAGE) .about(SUMMARY) .arg( diff --git a/src/uu/tty/src/tty.rs b/src/uu/tty/src/tty.rs index ef2d848e9..074bcf182 100644 --- a/src/uu/tty/src/tty.rs +++ b/src/uu/tty/src/tty.rs @@ -12,12 +12,11 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::ffi::CStr; use uucore::fs::is_stdin_interactive; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Print the file name of the terminal connected to standard input."; mod options { @@ -35,7 +34,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .accept_any(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/uname/src/uname.rs b/src/uu/uname/src/uname.rs index 4586a084f..aa591ee18 100644 --- a/src/uu/uname/src/uname.rs +++ b/src/uu/uname/src/uname.rs @@ -13,10 +13,9 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use platform_info::*; -const VERSION: &str = env!("CARGO_PKG_VERSION"); const ABOUT: &str = "Print certain system information. With no OPTION, same as -s."; pub mod options { @@ -49,7 +48,7 @@ const HOST_OS: &str = "Redox"; pub fn uumain(args: impl uucore::Args) -> i32 { let usage = format!("{} [OPTION]...", executable!()); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg(Arg::with_name(options::ALL) diff --git a/src/uu/unexpand/src/unexpand.rs b/src/uu/unexpand/src/unexpand.rs index 22b6b807a..92b3c7520 100644 --- a/src/uu/unexpand/src/unexpand.rs +++ b/src/uu/unexpand/src/unexpand.rs @@ -11,7 +11,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::fs::File; use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Stdout, Write}; use std::str::from_utf8; @@ -19,7 +19,6 @@ use unicode_width::UnicodeWidthChar; use uucore::InvalidEncodingHandling; static NAME: &str = "unexpand"; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static USAGE: &str = "unexpand [OPTION]... [FILE]..."; static SUMMARY: &str = "Convert blanks in each FILE to tabs, writing to standard output.\n With no FILE, or when FILE is -, read standard input."; @@ -97,7 +96,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let matches = App::new(executable!()) .name(NAME) - .version(VERSION) + .version(crate_version!()) .usage(USAGE) .about(SUMMARY) .arg(Arg::with_name(options::FILE).hidden(true).multiple(true)) diff --git a/src/uu/uniq/src/uniq.rs b/src/uu/uniq/src/uniq.rs index 7e9862e65..aee024dd4 100644 --- a/src/uu/uniq/src/uniq.rs +++ b/src/uu/uniq/src/uniq.rs @@ -8,7 +8,7 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; use std::fs::File; use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Result, Write}; use std::path::Path; @@ -16,7 +16,6 @@ use std::str::FromStr; use strum_macros::{AsRefStr, EnumString}; static ABOUT: &str = "Report or omit repeated lines."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); pub mod options { pub static ALL_REPEATED: &str = "all-repeated"; pub static CHECK_CHARS: &str = "check-chars"; @@ -240,7 +239,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let long_usage = get_long_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(&long_usage[..]) diff --git a/src/uu/unlink/src/unlink.rs b/src/uu/unlink/src/unlink.rs index 9d9d6385b..343f2653f 100644 --- a/src/uu/unlink/src/unlink.rs +++ b/src/uu/unlink/src/unlink.rs @@ -12,14 +12,13 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use libc::{lstat, stat, unlink}; use libc::{S_IFLNK, S_IFMT, S_IFREG}; use std::ffi::CString; use std::io::{Error, ErrorKind}; use uucore::InvalidEncodingHandling; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Unlink the file at [FILE]."; static OPT_PATH: &str = "FILE"; @@ -35,7 +34,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg(Arg::with_name(OPT_PATH).hidden(true).multiple(true)) diff --git a/src/uu/uptime/src/uptime.rs b/src/uu/uptime/src/uptime.rs index 418b8317f..3683a4de0 100644 --- a/src/uu/uptime/src/uptime.rs +++ b/src/uu/uptime/src/uptime.rs @@ -9,7 +9,7 @@ // spell-checker:ignore (ToDO) getloadavg upsecs updays nusers loadavg boottime uphours upmins use chrono::{Local, TimeZone, Utc}; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; #[macro_use] extern crate uucore; @@ -17,7 +17,6 @@ extern crate uucore; pub use uucore::libc; use uucore::libc::time_t; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Display the current time, the length of time the system has been up,\n\ the number of users on the system, and the average number of jobs\n\ in the run queue over the last 1, 5 and 15 minutes."; @@ -40,7 +39,7 @@ fn get_usage() -> String { pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/users/src/users.rs b/src/uu/users/src/users.rs index 664ff55f3..5b1f1c037 100644 --- a/src/uu/users/src/users.rs +++ b/src/uu/users/src/users.rs @@ -11,10 +11,9 @@ #[macro_use] extern crate uucore; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use uucore::utmpx::{self, Utmpx}; -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Print the user names of users currently logged in to the current host"; static ARG_FILES: &str = "files"; @@ -36,7 +35,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let after_help = get_long_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(&after_help[..]) diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index d990c6679..031c25739 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -15,7 +15,7 @@ use count_bytes::count_bytes_fast; use countable::WordCountable; use word_count::{TitledWordCount, WordCount}; -use clap::{App, Arg, ArgMatches}; +use clap::{crate_version, App, Arg, ArgMatches}; use thiserror::Error; use std::fs::{self, File}; @@ -84,7 +84,6 @@ impl Settings { static ABOUT: &str = "Display newline, word, and byte counts for each FILE, and a total line if more than one FILE is specified."; -static VERSION: &str = env!("CARGO_PKG_VERSION"); pub mod options { pub static BYTES: &str = "bytes"; @@ -136,7 +135,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let usage = get_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .arg( diff --git a/src/uu/who/src/who.rs b/src/uu/who/src/who.rs index 2cddbf2d0..d2f64aa94 100644 --- a/src/uu/who/src/who.rs +++ b/src/uu/who/src/who.rs @@ -12,7 +12,7 @@ extern crate uucore; use uucore::libc::{ttyname, STDIN_FILENO, S_IWGRP}; use uucore::utmpx::{self, time, Utmpx}; -use clap::{App, Arg}; +use clap::{crate_version, App, Arg}; use std::borrow::Cow; use std::ffi::CStr; use std::os::unix::fs::MetadataExt; @@ -37,7 +37,6 @@ mod options { pub const FILE: &str = "FILE"; // if length=1: FILE, if length=2: ARG1 ARG2 } -static VERSION: &str = env!("CARGO_PKG_VERSION"); static ABOUT: &str = "Print information about users who are currently logged in."; #[cfg(any(target_os = "linux"))] @@ -66,7 +65,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let after_help = get_long_usage(); let matches = App::new(executable!()) - .version(VERSION) + .version(crate_version!()) .about(ABOUT) .usage(&usage[..]) .after_help(&after_help[..]) From e5c4681e04feb8c762fc224bdf4925548de5cbba Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Wed, 2 Jun 2021 18:06:56 +0200 Subject: [PATCH 11/17] tests: add the ability to set resource limits --- .../workspace.wordlist.txt | 1 + Cargo.lock | 11 +++++++ Cargo.toml | 1 + tests/common/util.rs | 31 +++++++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/.vscode/cspell.dictionaries/workspace.wordlist.txt b/.vscode/cspell.dictionaries/workspace.wordlist.txt index b567a6c21..e2a864f9c 100644 --- a/.vscode/cspell.dictionaries/workspace.wordlist.txt +++ b/.vscode/cspell.dictionaries/workspace.wordlist.txt @@ -30,6 +30,7 @@ peekreader quickcheck rand_chacha ringbuffer +rlimit smallvec tempdir tempfile diff --git a/Cargo.lock b/Cargo.lock index 17fa9e2b7..0455d7118 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,6 +233,7 @@ dependencies = [ "pretty_assertions", "rand 0.7.3", "regex", + "rlimit", "sha1", "tempfile", "textwrap", @@ -1410,6 +1411,16 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9c17925a9027d298a4603d286befe3f9dc0e8ed02523141914eb628798d6e5b" +[[package]] +name = "rlimit" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b02d62c38353a6fce45c25ca19783e25dd5f495ca681c674a4ee15aa4c1536" +dependencies = [ + "cfg-if 0.1.10", + "libc", +] + [[package]] name = "rust-ini" version = "0.13.0" diff --git a/Cargo.toml b/Cargo.toml index 9a6e8bd46..5f89a4077 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -354,6 +354,7 @@ walkdir = "2.2" atty = "0.2.14" [target.'cfg(unix)'.dev-dependencies] +rlimit = "0.4.0" rust-users = { version="0.10", package="users" } unix_socket = "0.5.0" diff --git a/tests/common/util.rs b/tests/common/util.rs index d466ba1e9..2f7d7dcc4 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -1,5 +1,10 @@ +//spell-checker: ignore (linux) rlimit prlimit Rlim + #![allow(dead_code)] + use pretty_assertions::assert_eq; +#[cfg(target_os = "linux")] +use rlimit::{prlimit, rlim}; use std::env; #[cfg(not(windows))] use std::ffi::CString; @@ -724,6 +729,8 @@ pub struct UCommand { stdout: Option, stderr: Option, bytes_into_stdin: Option>, + #[cfg(target_os = "linux")] + limits: Vec<(rlimit::Resource, rlim, rlim)>, } impl UCommand { @@ -758,6 +765,8 @@ impl UCommand { stdin: None, stdout: None, stderr: None, + #[cfg(target_os = "linux")] + limits: vec![], } } @@ -855,6 +864,17 @@ impl UCommand { self } + #[cfg(target_os = "linux")] + pub fn with_limit( + &mut self, + resource: rlimit::Resource, + soft_limit: rlim, + hard_limit: rlim, + ) -> &mut Self { + self.limits.push((resource, soft_limit, hard_limit)); + self + } + /// Spawns the command, feeds the stdin if any, and returns the /// child process immediately. pub fn run_no_wait(&mut self) -> Child { @@ -871,6 +891,17 @@ impl UCommand { .spawn() .unwrap(); + #[cfg(target_os = "linux")] + for &(resource, soft_limit, hard_limit) in &self.limits { + prlimit( + child.id() as i32, + resource, + Some((soft_limit, hard_limit)), + None, + ) + .unwrap(); + } + if let Some(ref input) = self.bytes_into_stdin { let write_result = child .stdin From 7ffc7d073cc5b14fbafbf4f03af48d4550e7539a Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Wed, 2 Jun 2021 18:08:09 +0200 Subject: [PATCH 12/17] cp: test that file descriptors are closed --- tests/by-util/test_cp.rs | 16 +++++++++++++++- tests/fixtures/cp/dir_with_10_files/0 | 0 tests/fixtures/cp/dir_with_10_files/1 | 0 tests/fixtures/cp/dir_with_10_files/2 | 0 tests/fixtures/cp/dir_with_10_files/3 | 0 tests/fixtures/cp/dir_with_10_files/4 | 0 tests/fixtures/cp/dir_with_10_files/5 | 0 tests/fixtures/cp/dir_with_10_files/6 | 0 tests/fixtures/cp/dir_with_10_files/7 | 0 tests/fixtures/cp/dir_with_10_files/8 | 0 tests/fixtures/cp/dir_with_10_files/9 | 0 11 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/cp/dir_with_10_files/0 create mode 100644 tests/fixtures/cp/dir_with_10_files/1 create mode 100644 tests/fixtures/cp/dir_with_10_files/2 create mode 100644 tests/fixtures/cp/dir_with_10_files/3 create mode 100644 tests/fixtures/cp/dir_with_10_files/4 create mode 100644 tests/fixtures/cp/dir_with_10_files/5 create mode 100644 tests/fixtures/cp/dir_with_10_files/6 create mode 100644 tests/fixtures/cp/dir_with_10_files/7 create mode 100644 tests/fixtures/cp/dir_with_10_files/8 create mode 100644 tests/fixtures/cp/dir_with_10_files/9 diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index c56e1ca57..ff607f984 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1,4 +1,4 @@ -// spell-checker:ignore (flags) reflink (fs) tmpfs +// spell-checker:ignore (flags) reflink (fs) tmpfs (linux) rlimit Rlim NOFILE use crate::common::util::*; #[cfg(not(windows))] @@ -14,6 +14,8 @@ use std::os::windows::fs::symlink_file; #[cfg(target_os = "linux")] use filetime::FileTime; +#[cfg(target_os = "linux")] +use rlimit::Resource; #[cfg(not(windows))] use std::env; #[cfg(target_os = "linux")] @@ -1276,3 +1278,15 @@ fn test_cp_reflink_insufficient_permission() { .fails() .stderr_only("cp: 'unreadable' -> 'existing_file.txt': Permission denied (os error 13)"); } + +#[cfg(target_os = "linux")] +#[test] +fn test_closes_file_descriptors() { + new_ucmd!() + .arg("-r") + .arg("--reflink=auto") + .arg("dir_with_10_files/") + .arg("dir_with_10_files_new/") + .with_limit(Resource::NOFILE, 9, 9) + .succeeds(); +} diff --git a/tests/fixtures/cp/dir_with_10_files/0 b/tests/fixtures/cp/dir_with_10_files/0 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/cp/dir_with_10_files/1 b/tests/fixtures/cp/dir_with_10_files/1 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/cp/dir_with_10_files/2 b/tests/fixtures/cp/dir_with_10_files/2 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/cp/dir_with_10_files/3 b/tests/fixtures/cp/dir_with_10_files/3 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/cp/dir_with_10_files/4 b/tests/fixtures/cp/dir_with_10_files/4 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/cp/dir_with_10_files/5 b/tests/fixtures/cp/dir_with_10_files/5 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/cp/dir_with_10_files/6 b/tests/fixtures/cp/dir_with_10_files/6 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/cp/dir_with_10_files/7 b/tests/fixtures/cp/dir_with_10_files/7 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/cp/dir_with_10_files/8 b/tests/fixtures/cp/dir_with_10_files/8 new file mode 100644 index 000000000..e69de29bb diff --git a/tests/fixtures/cp/dir_with_10_files/9 b/tests/fixtures/cp/dir_with_10_files/9 new file mode 100644 index 000000000..e69de29bb From 0105531b7f368ffa25464b17aaaba33ca3fa1608 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 2 Jun 2021 20:59:53 +0200 Subject: [PATCH 13/17] show the backtrace in case of a rust crash --- util/run-gnu-test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/util/run-gnu-test.sh b/util/run-gnu-test.sh index 61034e015..044c6c140 100644 --- a/util/run-gnu-test.sh +++ b/util/run-gnu-test.sh @@ -5,4 +5,5 @@ BUILDDIR="${PWD}/uutils/target/release" GNULIB_DIR="${PWD}/gnulib" pushd gnu +export RUST_BACKTRACE=1 timeout -sKILL 2h make -j "$(nproc)" check SUBDIRS=. RUN_EXPENSIVE_TESTS=yes RUN_VERY_EXPENSIVE_TESTS=yes VERBOSE=no || : # Kill after 4 hours in case something gets stuck in make From e7f59168646b1f2ccd533ce3991694a53970906c Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 2 Jun 2021 21:21:12 +0200 Subject: [PATCH 14/17] gnu/ci: allow to run a single gnu test (and document it) --- CONTRIBUTING.md | 1 + README.md | 4 ++++ util/run-gnu-test.sh | 8 +++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3793a0968..47793977e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,6 +18,7 @@ search the issues to make sure no one else is working on it. ## Best practices 1. Follow what GNU is doing in term of options and behavior. +1. If possible, look at the GNU test suite execution in the CI and make the test work if failing. 1. Use clap for argument management. 1. Make sure that the code coverage is covering all of the cases, including errors. 1. The code must be clippy-warning-free and rustfmt-compliant. diff --git a/README.md b/README.md index 8ab4c6128..fde01d64a 100644 --- a/README.md +++ b/README.md @@ -327,8 +327,12 @@ To run locally: ```bash $ bash util/build-gnu.sh $ bash util/run-gnu-test.sh +# To run a single test: +$ bash util/run-gnu-test.sh tests/touch/not-owner.sh # for example ``` +Note that it relies on individual utilities (not the multicall binary). + ## Contribute To contribute to uutils, please see [CONTRIBUTING](CONTRIBUTING.md). diff --git a/util/run-gnu-test.sh b/util/run-gnu-test.sh index 044c6c140..9d51a983e 100644 --- a/util/run-gnu-test.sh +++ b/util/run-gnu-test.sh @@ -6,4 +6,10 @@ GNULIB_DIR="${PWD}/gnulib" pushd gnu export RUST_BACKTRACE=1 -timeout -sKILL 2h make -j "$(nproc)" check SUBDIRS=. RUN_EXPENSIVE_TESTS=yes RUN_VERY_EXPENSIVE_TESTS=yes VERBOSE=no || : # Kill after 4 hours in case something gets stuck in make + +if test -n "$1"; then + # if set, run only the test passed + export RUN_TEST="TESTS=$1" +fi + +timeout -sKILL 2h make -j "$(nproc)" check $RUN_TEST SUBDIRS=. RUN_EXPENSIVE_TESTS=yes RUN_VERY_EXPENSIVE_TESTS=yes VERBOSE=no || : # Kill after 4 hours in case something gets stuck in make From eb2c06c37e29ebdc97a58eeb4002bccae7a46709 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 2 Jun 2021 22:53:10 +0200 Subject: [PATCH 15/17] touch/gnu compat: when touch fails because of a permission error, change the error message + return 1 as error code when having this error --- src/uu/touch/src/touch.rs | 24 ++++++++++++++++++++---- tests/by-util/test_touch.rs | 10 ++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index b76e04b7a..ed65cb659 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -155,6 +155,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 { (now, now) }; + let mut error_code = 0; + for filename in &files { let path = &filename[..]; @@ -202,14 +204,28 @@ pub fn uumain(args: impl uucore::Args) -> i32 { if matches.is_present(options::NO_DEREF) { if let Err(e) = set_symlink_file_times(path, atime, mtime) { - show_warning!("cannot touch '{}': {}", path, e); + // we found an error, it should fail in any case + error_code = 1; + if e.kind() == std::io::ErrorKind::PermissionDenied { + // GNU compatibility (not-owner.sh) + show_error!("setting times of '{}': {}", path, "Permission denied"); + } else { + show_error!("setting times of '{}': {}", path, e); + } } } else if let Err(e) = filetime::set_file_times(path, atime, mtime) { - show_warning!("cannot touch '{}': {}", path, e); + // we found an error, it should fail in any case + error_code = 1; + + if e.kind() == std::io::ErrorKind::PermissionDenied { + // GNU compatibility (not-owner.sh) + show_error!("setting times of '{}': {}", path, "Permission denied"); + } else { + show_error!("setting times of '{}': {}", path, e); + } } } - - 0 + error_code } fn stat(path: &str, follow: bool) -> (FileTime, FileTime) { diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index 3c803e1c6..cd780f670 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -449,3 +449,13 @@ fn test_touch_mtime_dst_fails() { ucmd.args(&["-m", "-t", &s, file]).fails(); } } + +#[test] +#[cfg(unix)] +fn test_touch_system_fails() { + let (_at, mut ucmd) = at_and_ucmd!(); + let file = "/"; + ucmd.args(&[file]) + .fails() + .stderr_contains("setting times of '/'"); +} From 31875a241fc1b1c3582b8e876cf3c44d1145d468 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 2 Jun 2021 23:43:16 +0200 Subject: [PATCH 16/17] touch/gnu compat: 'touch no-file' exit code should be 1 --- src/uu/touch/src/touch.rs | 1 + tests/by-util/test_touch.rs | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index ed65cb659..1b560553f 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -168,6 +168,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { if let Err(e) = File::create(path) { show_warning!("cannot touch '{}': {}", path, e); + error_code = 1; continue; }; diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index cd780f670..c861a50dd 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -459,3 +459,10 @@ fn test_touch_system_fails() { .fails() .stderr_contains("setting times of '/'"); } + +#[test] +fn test_touch_trailing_slash() { + let (_at, mut ucmd) = at_and_ucmd!(); + let file = "no-file/"; + ucmd.args(&[file]).fails(); +} From 05aeaf3061e78e669686ca04e576314d7b153cd4 Mon Sep 17 00:00:00 2001 From: Syukron Rifail M Date: Wed, 26 May 2021 12:27:15 +0700 Subject: [PATCH 17/17] du: fix --time behavior --- src/uu/du/src/du.rs | 56 +++++++++++++++++++++++++++------------- tests/by-util/test_du.rs | 29 +++++++++++++++++---- 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 0bc8b30c8..ee50c213e 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -14,6 +14,8 @@ use clap::{App, Arg}; use std::collections::HashSet; use std::env; use std::fs; +#[cfg(not(windows))] +use std::fs::Metadata; use std::io::{stderr, ErrorKind, Result, Write}; use std::iter; #[cfg(not(windows))] @@ -92,7 +94,7 @@ struct Stat { size: u64, blocks: u64, inode: Option, - created: u64, + created: Option, accessed: u64, modified: u64, } @@ -113,7 +115,7 @@ impl Stat { size: metadata.len(), blocks: metadata.blocks() as u64, inode: Some(file_info), - created: metadata.mtime() as u64, + created: birth_u64(&metadata), accessed: metadata.atime() as u64, modified: metadata.mtime() as u64, }); @@ -129,7 +131,7 @@ impl Stat { size: metadata.len(), blocks: size_on_disk / 1024 * 2, inode: file_info, - created: windows_time_to_unix_time(metadata.creation_time()), + created: windows_creation_time_to_unix_time(metadata.creation_time()), accessed: windows_time_to_unix_time(metadata.last_access_time()), modified: windows_time_to_unix_time(metadata.last_write_time()), }) @@ -137,10 +139,24 @@ impl Stat { } #[cfg(windows)] -// https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html#tymethod.creation_time +// https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html#tymethod.last_access_time // "The returned 64-bit value [...] which represents the number of 100-nanosecond intervals since January 1, 1601 (UTC)." +// "If the underlying filesystem does not support last access time, the returned value is 0." fn windows_time_to_unix_time(win_time: u64) -> u64 { - win_time / 10_000_000 - 11_644_473_600 + (win_time / 10_000_000).saturating_sub(11_644_473_600) +} + +#[cfg(windows)] +fn windows_creation_time_to_unix_time(win_time: u64) -> Option { + (win_time / 10_000_000).checked_sub(11_644_473_600) +} + +#[cfg(not(windows))] +fn birth_u64(meta: &Metadata) -> Option { + meta.created() + .ok() + .and_then(|t| t.duration_since(UNIX_EPOCH).ok()) + .map(|e| e.as_secs() as u64) } #[cfg(windows)] @@ -539,10 +555,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 { .value_name("WORD") .require_equals(true) .min_values(0) + .possible_values(&["atime", "access", "use", "ctime", "status", "birth", "creation"]) .help( "show time of the last modification of any file in the \ directory, or any of its subdirectories. If WORD is given, show time as WORD instead \ - of modification time: atime, access, use, ctime or status" + of modification time: atime, access, use, ctime, status, birth or creation" ) ) .arg( @@ -667,19 +684,22 @@ Try '{} --help' for more information.", let secs = { match matches.value_of(options::TIME) { Some(s) => match s { - "accessed" => stat.accessed, - "created" => stat.created, - "modified" => stat.modified, - _ => { - show_error!( - "invalid argument 'modified' for '--time' - Valid arguments are: - - 'accessed', 'created', 'modified' - Try '{} --help' for more information.", - NAME - ); - return 1; + "ctime" | "status" => stat.modified, + "access" | "atime" | "use" => stat.accessed, + "birth" | "creation" => { + if let Some(time) = stat.created { + time + } else { + show_error!( + "Invalid argument ‘{}‘ for --time. +‘birth‘ and ‘creation‘ arguments are not supported on this platform.", + s + ); + return 1; + } } + // below should never happen as clap already restricts the values. + _ => unreachable!("Invalid field for --time"), }, None => stat.modified, } diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index 9e585b03e..3c177c6bf 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -240,18 +240,37 @@ fn test_du_time() { scene .ccmd("touch") .arg("-a") - .arg("-m") .arg("-t") .arg("201505150000") .arg("date_test") .succeeds(); scene - .ucmd() - .arg("--time") + .ccmd("touch") + .arg("-m") + .arg("-t") + .arg("201606160000") .arg("date_test") - .succeeds() - .stdout_only("0\t2015-05-15 00:00\tdate_test\n"); + .succeeds(); + + let result = scene.ucmd().arg("--time").arg("date_test").succeeds(); + result.stdout_only("0\t2016-06-16 00:00\tdate_test\n"); + + let result = scene.ucmd().arg("--time=atime").arg("date_test").succeeds(); + result.stdout_only("0\t2015-05-15 00:00\tdate_test\n"); + + let result = scene.ucmd().arg("--time=ctime").arg("date_test").succeeds(); + result.stdout_only("0\t2016-06-16 00:00\tdate_test\n"); + + #[cfg(not(target_env = "musl"))] + { + use regex::Regex; + + let re_birth = + Regex::new(r"0\t[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}\tdate_test").unwrap(); + let result = scene.ucmd().arg("--time=birth").arg("date_test").succeeds(); + result.stdout_matches(&re_birth); + } } #[cfg(not(target_os = "windows"))]