From abc5cfb9508c4d139b39bff335c4aa6a288a7886 Mon Sep 17 00:00:00 2001 From: Bart Massey Date: Tue, 14 Feb 2023 00:21:16 -0800 Subject: [PATCH 001/477] coreutils: fixed panic when multi-call binary has empty or non-UTF-8 name The multi-call `coreutils` binary starts by trying to convert its invocation path into a UTF-8 string, panicking if this doesn't work. This patch makes `coreutils` exit gracefully in this case. --- src/bin/coreutils.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/bin/coreutils.rs b/src/bin/coreutils.rs index 08c0774ba7..75e64e17ba 100644 --- a/src/bin/coreutils.rs +++ b/src/bin/coreutils.rs @@ -41,8 +41,8 @@ fn binary_path(args: &mut impl Iterator) -> PathBuf { } } -fn name(binary_path: &Path) -> &str { - binary_path.file_stem().unwrap().to_str().unwrap() +fn name(binary_path: &Path) -> Option<&str> { + binary_path.file_stem()?.to_str() } fn main() { @@ -52,7 +52,10 @@ fn main() { let mut args = uucore::args_os(); let binary = binary_path(&mut args); - let binary_as_util = name(&binary); + let binary_as_util = name(&binary).unwrap_or_else(|| { + usage(&utils, ""); + process::exit(0); + }); // binary name equals util name? if let Some(&(uumain, _)) = utils.get(binary_as_util) { From af4ce911c8315e3f339ea809ccf04b65ef834075 Mon Sep 17 00:00:00 2001 From: ZauJulio Date: Thu, 16 Feb 2023 17:48:23 -0300 Subject: [PATCH 002/477] mktemp: fix PrefixContainsDirSeparator verification --- src/uu/mktemp/src/mktemp.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 390c77bfaf..fed946577a 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -281,7 +281,11 @@ impl Params { .join(prefix_from_template) .display() .to_string(); - if options.treat_as_template && prefix.contains(MAIN_SEPARATOR) { + + // Check that the prefix is valid. + let prefix_of_template = Path::new(prefix_from_template).display().to_string(); + + if options.treat_as_template && prefix_of_template.contains(MAIN_SEPARATOR) { return Err(MkTempError::PrefixContainsDirSeparator(options.template)); } if tmpdir.is_some() && Path::new(prefix_from_template).is_absolute() { From 9e2c543cd40c6b237097f17ae66141e8fc9d4413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Za=C3=BA=20J=C3=BAlio?= Date: Thu, 16 Feb 2023 18:43:32 -0300 Subject: [PATCH 003/477] mktemp: prefix prefix_of_template use to_string_lossy Co-authored-by: Terts Diepraam --- src/uu/mktemp/src/mktemp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index fed946577a..1764b8e84d 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -283,7 +283,7 @@ impl Params { .to_string(); // Check that the prefix is valid. - let prefix_of_template = Path::new(prefix_from_template).display().to_string(); + let prefix_of_template = Path::new(prefix_from_template).to_string_lossy(); if options.treat_as_template && prefix_of_template.contains(MAIN_SEPARATOR) { return Err(MkTempError::PrefixContainsDirSeparator(options.template)); From 3d2f3fc5b155a1ba9161e921ffbdf763f671712f Mon Sep 17 00:00:00 2001 From: ZauJulio Date: Wed, 22 Feb 2023 20:22:16 -0300 Subject: [PATCH 004/477] mktemp: add test to . in template prefix --- tests/by-util/test_mktemp.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index d6926c41b2..6d4a7fb6f0 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -21,6 +21,7 @@ static TEST_TEMPLATE6: &str = "tempXXXlate"; // spell-checker:disable-line static TEST_TEMPLATE7: &str = "XXXtemplate"; // spell-checker:disable-line #[cfg(unix)] static TEST_TEMPLATE8: &str = "tempXXXl/ate"; +static TEST_TEMPLATE9: &str = "a.XXXX"; #[cfg(windows)] static TEST_TEMPLATE8: &str = "tempXXXl\\ate"; @@ -569,6 +570,14 @@ fn test_template_path_separator() { )); } +/// Test that a prefix with a point is valid. +#[test] +fn test_prefix_template_separator() { + new_ucmd!() + .args(&["-t", TEST_TEMPLATE9]) + .succeeds(); +} + /// Test that a suffix with a path separator is invalid. #[test] fn test_suffix_path_separator() { From dc1fd027a6ca0f609cf9ba3eb63c6bc75ec9c011 Mon Sep 17 00:00:00 2001 From: ZauJulio Date: Sat, 25 Feb 2023 18:35:35 -0300 Subject: [PATCH 005/477] mktemp: fix fmt of test_prefix_template_separator --- tests/by-util/test_mktemp.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index dc09204b61..081e4da1ba 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -575,9 +575,7 @@ fn test_template_path_separator() { /// Test that a prefix with a point is valid. #[test] fn test_prefix_template_separator() { - new_ucmd!() - .args(&["-t", TEST_TEMPLATE9]) - .succeeds(); + new_ucmd!().args(&["-t", TEST_TEMPLATE9]).succeeds(); } /// Test that a suffix with a path separator is invalid. From a87bc9f9291fe707900f3434a8bdc7803366eb44 Mon Sep 17 00:00:00 2001 From: ZauJulio Date: Mon, 27 Feb 2023 01:13:16 -0300 Subject: [PATCH 006/477] mktemp: remove unnecessary convertion for path -> str just use prefix_from_template --- src/uu/mktemp/src/mktemp.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 1764b8e84d..5d43089580 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -281,11 +281,7 @@ impl Params { .join(prefix_from_template) .display() .to_string(); - - // Check that the prefix is valid. - let prefix_of_template = Path::new(prefix_from_template).to_string_lossy(); - - if options.treat_as_template && prefix_of_template.contains(MAIN_SEPARATOR) { + if options.treat_as_template && prefix_from_template.contains(MAIN_SEPARATOR) { return Err(MkTempError::PrefixContainsDirSeparator(options.template)); } if tmpdir.is_some() && Path::new(prefix_from_template).is_absolute() { From 9b4fb0cb6eb46b3e3cba1d318e317b821dfa9328 Mon Sep 17 00:00:00 2001 From: ZauJulio Date: Tue, 28 Feb 2023 12:38:18 -0300 Subject: [PATCH 007/477] mktemp: add tests UNIX and POSIX to check path in prefix --- tests/by-util/test_mktemp.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 081e4da1ba..7c3d621506 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -578,6 +578,26 @@ fn test_prefix_template_separator() { new_ucmd!().args(&["-t", TEST_TEMPLATE9]).succeeds(); } +#[test] +fn test_prefix_template_with_path_separator() { + #[cfg(not(windows))] + new_ucmd!() + .args(&["-t", "a/XXX"]) + .fails() + .stderr_only(format!( + "mktemp: invalid template, {}, contains directory separator\n", + "a/XXX".quote() + )); + #[cfg(windows)] + new_ucmd!() + .args(&["-t", r"a\XXX"]) + .fails() + .stderr_only(format!( + "mktemp: invalid template, {}, contains directory separator\n", + r"a\XXX".quote() + )); +} + /// Test that a suffix with a path separator is invalid. #[test] fn test_suffix_path_separator() { From cf7b90bbe7cb87099499876622f413a65a699038 Mon Sep 17 00:00:00 2001 From: Thomas Hurst Date: Tue, 28 Feb 2023 17:45:14 +0000 Subject: [PATCH 008/477] dd: use an alarm thread instead of elapsed() calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quick benchmark on FreeBSD 13.1-RELEASE: Summary './dd-thread-alarm if=/dev/zero of=/dev/null count=4000000 status=progress' ran 1.17 ± 0.17 times faster than './dd-baseline if=/dev/zero of=/dev/null count=4000000 status=progress' --- src/uu/dd/src/dd.rs | 47 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index eaf89ca55e..2baa12106f 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -65,6 +65,46 @@ struct Settings { status: Option, } +use std::thread::sleep; +use std::time::Duration; + +use std::sync::{ + atomic::{AtomicBool, Ordering::Relaxed}, + Arc, +}; + +#[derive(Debug, Clone)] +pub struct Alarm { + interval: Duration, + trigger: Arc, +} + +impl Alarm { + pub fn with_interval(interval: Duration) -> Alarm { + let trigger = Arc::new(AtomicBool::default()); + + let weak_trigger = Arc::downgrade(&trigger); + std::thread::spawn(move || loop { + sleep(interval); + if let Some(trigger) = weak_trigger.upgrade() { + trigger.store(true, Relaxed); + } else { + break; + } + }); + + Alarm { interval, trigger } + } + + pub fn is_triggered(&self) -> bool { + self.trigger.swap(false, Relaxed) + } + + pub fn get_interval(&self) -> Duration { + self.interval + } +} + /// A number in blocks or bytes /// /// Some values (seek, skip, iseek, oseek) can have values either in blocks or in bytes. @@ -628,7 +668,6 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // information. let (prog_tx, rx) = mpsc::channel(); let output_thread = thread::spawn(gen_prog_updater(rx, i.settings.status)); - let mut progress_as_secs = 0; // Optimization: if no blocks are to be written, then don't // bother allocating any buffers. @@ -639,6 +678,7 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // Create a common buffer with a capacity of the block size. // This is the max size needed. let mut buf = vec![BUF_INIT_BYTE; bsize]; + let alarm = Alarm::with_interval(Duration::from_secs(1)); // The main read/write loop. // @@ -667,9 +707,8 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // error. rstat += rstat_update; wstat += wstat_update; - let prog_update = ProgUpdate::new(rstat, wstat, start.elapsed(), false); - if prog_update.duration.as_secs() >= progress_as_secs { - progress_as_secs = prog_update.duration.as_secs() + 1; + if alarm.is_triggered() { + let prog_update = ProgUpdate::new(rstat, wstat, start.elapsed(), false); prog_tx.send(prog_update).unwrap_or(()); } } From 52c93a4d107a6252c4cfe85c572075cacc493272 Mon Sep 17 00:00:00 2001 From: Thomas Hurst Date: Wed, 1 Mar 2023 13:56:18 +0000 Subject: [PATCH 009/477] dd: Simplify loop of progress Alarm thread --- src/uu/dd/src/dd.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 2baa12106f..15c7e8ed4a 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -80,20 +80,18 @@ pub struct Alarm { } impl Alarm { - pub fn with_interval(interval: Duration) -> Alarm { + pub fn with_interval(interval: Duration) -> Self { let trigger = Arc::new(AtomicBool::default()); let weak_trigger = Arc::downgrade(&trigger); - std::thread::spawn(move || loop { - sleep(interval); - if let Some(trigger) = weak_trigger.upgrade() { + std::thread::spawn(move || { + while let Some(trigger) = weak_trigger.upgrade() { + sleep(interval); trigger.store(true, Relaxed); - } else { - break; } }); - Alarm { interval, trigger } + Self { interval, trigger } } pub fn is_triggered(&self) -> bool { From e9bd69e0519c380663a0cda9abffb75209679acb Mon Sep 17 00:00:00 2001 From: ZauJulio Date: Wed, 1 Mar 2023 15:45:41 -0300 Subject: [PATCH 010/477] mktemp: fix test_prefix_template_separator adding -p param --- tests/by-util/test_mktemp.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 7c3d621506..b6e3b2076c 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -21,9 +21,9 @@ static TEST_TEMPLATE6: &str = "tempXXXlate"; // spell-checker:disable-line static TEST_TEMPLATE7: &str = "XXXtemplate"; // spell-checker:disable-line #[cfg(unix)] static TEST_TEMPLATE8: &str = "tempXXXl/ate"; -static TEST_TEMPLATE9: &str = "a.XXXX"; #[cfg(windows)] static TEST_TEMPLATE8: &str = "tempXXXl\\ate"; +static TEST_TEMPLATE9: &str = "a.XXXX"; #[cfg(not(windows))] const TMPDIR: &str = "TMPDIR"; @@ -575,7 +575,7 @@ fn test_template_path_separator() { /// Test that a prefix with a point is valid. #[test] fn test_prefix_template_separator() { - new_ucmd!().args(&["-t", TEST_TEMPLATE9]).succeeds(); + new_ucmd!().args(&["-p", ".", "-t", TEST_TEMPLATE9]).succeeds(); } #[test] From b94a0d2ebea6e151ad52f32f96b8ea9f09bb5a4d Mon Sep 17 00:00:00 2001 From: ZauJulio Date: Thu, 2 Mar 2023 15:30:55 -0300 Subject: [PATCH 011/477] mktemp: fix test fmt --- tests/by-util/test_mktemp.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index b6e3b2076c..8d615899cf 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -575,7 +575,9 @@ fn test_template_path_separator() { /// Test that a prefix with a point is valid. #[test] fn test_prefix_template_separator() { - new_ucmd!().args(&["-p", ".", "-t", TEST_TEMPLATE9]).succeeds(); + new_ucmd!() + .args(&["-p", ".", "-t", TEST_TEMPLATE9]) + .succeeds(); } #[test] From d41591f2936d4396e91dcb165ebe23315c6bd046 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 18 Mar 2023 17:41:27 +0100 Subject: [PATCH 012/477] CI: move the intermittent list into a file --- .github/workflows/GnuTests.yml | 2 +- .github/workflows/ignore-intermittent.txt | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ignore-intermittent.txt diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 7c8c307ec2..a347801730 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -203,7 +203,7 @@ jobs: REPO_DEFAULT_BRANCH='${{ steps.vars.outputs.repo_default_branch }}' # https://github.com/uutils/coreutils/issues/4294 # https://github.com/uutils/coreutils/issues/4295 - IGNORE_INTERMITTENT='tests/tail-2/inotify-dir-recreate tests/misc/timeout tests/rm/rm1' + IGNORE_INTERMITTENT='.github/workflows/ignore-intermittent.txt' mkdir -p ${{ steps.vars.outputs.path_reference }} diff --git a/.github/workflows/ignore-intermittent.txt b/.github/workflows/ignore-intermittent.txt new file mode 100644 index 0000000000..759bd96eb8 --- /dev/null +++ b/.github/workflows/ignore-intermittent.txt @@ -0,0 +1,3 @@ +tests/tail-2/inotify-dir-recreate +tests/misc/timeout +tests/rm/rm1 From 7fd0e1e64dcf9bf507bc06d209f29b17a717228f Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 18 Mar 2023 17:42:08 +0100 Subject: [PATCH 013/477] CI: Also ignore intermittent when starting to pass Example: Congrats! The gnu test tests/tail-2/inotify-dir-recreate is no longer failing! --- .github/workflows/GnuTests.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index a347801730..eb38f75a0e 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -226,9 +226,17 @@ jobs: for LINE in ${REF_FAILING} do if ! grep -Fxq ${LINE}<<<"${NEW_FAILING}"; then - MSG="Congrats! The gnu test ${LINE} is no longer failing!" - echo "::warning ::$MSG" - echo $MSG >> ${COMMENT_LOG} + if ! grep ${LINE} ${IGNORE_INTERMITTENT} + then + MSG="Congrats! The gnu test ${LINE} is no longer failing!" + echo "::warning ::$MSG" + echo $MSG >> ${COMMENT_LOG} + else + MSG="Skipping an intermittent issue ${LINE}" + echo "::warning ::$MSG" + echo $MSG >> ${COMMENT_LOG} + echo "" + fi fi done for LINE in ${NEW_FAILING} From 1de1a84ed22c11f688323c6c07eaeb70c143216a Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Sun, 22 Jan 2023 22:23:45 -0500 Subject: [PATCH 014/477] mktemp: uncomment fixed test case Uncomment a test case fixed by commit 53c4b0b81e528adc340dd803bf597fa3fad1bb4c (pull request https://github.com/uutils/coreutils/pull/4091). --- tests/by-util/test_mktemp.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 109963edff..b67c3440e0 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -704,16 +704,18 @@ fn test_tmpdir_env_var() { assert_suffix_matches_template!("tmp.XXXXXXXXXX", filename); assert!(at.file_exists(filename)); - // FIXME This is not working because --tmpdir is configured to - // require a value. - // - // // `TMPDIR=. mktemp --tmpdir` - // let (at, mut ucmd) = at_and_ucmd!(); - // let result = ucmd.env(TMPDIR, ".").arg("--tmpdir").succeeds(); - // let filename = result.no_stderr().stdout_str().trim_end(); - // let template = format!(".{}tmp.XXXXXXXXXX", MAIN_SEPARATOR); - // assert_matches_template!(&template, filename); - // assert!(at.file_exists(filename)); + // `TMPDIR=. mktemp --tmpdir` + let (at, mut ucmd) = at_and_ucmd!(); + let result = ucmd.env(TMPDIR, ".").arg("--tmpdir").succeeds(); + let filename = result.no_stderr().stdout_str().trim_end(); + #[cfg(not(windows))] + { + let template = format!(".{MAIN_SEPARATOR}tmp.XXXXXXXXXX"); + assert_matches_template!(&template, filename); + } + #[cfg(windows)] + assert_suffix_matches_template!("tmp.XXXXXXXXXX", filename); + assert!(at.file_exists(filename)); // `TMPDIR=. mktemp --tmpdir XXX` let (at, mut ucmd) = at_and_ucmd!(); From f8e0a73fb5b7603f25fac39d4f4b6868d992cf07 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 25 Mar 2023 08:48:33 +0100 Subject: [PATCH 015/477] manage an potential error in util/remaining-gnu-error.py when GNU isn't up to date --- util/remaining-gnu-error.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/util/remaining-gnu-error.py b/util/remaining-gnu-error.py index c64ee974ef..9a6bd91db4 100755 --- a/util/remaining-gnu-error.py +++ b/util/remaining-gnu-error.py @@ -8,6 +8,7 @@ import os import glob import json +import sys base = "../gnu/tests/" urllib.request.urlretrieve( @@ -51,7 +52,11 @@ def show_list(l): # the tests pass, we don't care anymore if data[d][e] == "PASS": - list_of_files.remove(a) + try: + list_of_files.remove(a) + except ValueError: + print("Could not find test '%s'. Maybe update the GNU repo?" % a) + sys.exit(1) # if it is SKIP or ERROR, show it if data[d][e] == "SKIP" or data[d][e] == "ERROR": From 355d242e7af74b73531907ca00fd0fa04f5a1b23 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 25 Mar 2023 08:53:40 +0100 Subject: [PATCH 016/477] python: simplify the code a bit --- util/remaining-gnu-error.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/remaining-gnu-error.py b/util/remaining-gnu-error.py index 9a6bd91db4..eda37094dd 100755 --- a/util/remaining-gnu-error.py +++ b/util/remaining-gnu-error.py @@ -59,7 +59,7 @@ def show_list(l): sys.exit(1) # if it is SKIP or ERROR, show it - if data[d][e] == "SKIP" or data[d][e] == "ERROR": + if data[d][e] in ("SKIP", "ERROR"): list_of_files.remove(a) error_or_skip_tests.append(a) From 68e90eacbbf1479fed903171c0d93a6bbde017fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Sun, 26 Mar 2023 20:25:38 +0200 Subject: [PATCH 017/477] lint: Fix all issues in preparation for enabling clippy::if_not_else --- src/uu/base32/src/base_common.rs | 24 ++-- src/uu/chmod/src/chmod.rs | 12 +- src/uu/chown/src/chown.rs | 12 +- src/uu/date/src/date.rs | 6 +- src/uu/dd/src/dd.rs | 12 +- src/uu/df/src/filesystem.rs | 6 +- src/uu/dirname/src/dirname.rs | 6 +- src/uu/env/src/env.rs | 8 +- src/uu/expr/src/syntax_tree.rs | 8 +- src/uu/factor/src/numeric/montgomery.rs | 12 +- src/uu/fmt/src/parasplit.rs | 6 +- src/uu/hostname/src/hostname.rs | 6 +- src/uu/id/src/id.rs | 6 +- src/uu/install/src/install.rs | 12 +- src/uu/ls/src/ls.rs | 14 +- src/uu/numfmt/src/format.rs | 2 +- src/uu/numfmt/src/options.rs | 12 +- src/uu/od/src/od.rs | 12 +- src/uu/pinky/src/pinky.rs | 18 +-- src/uu/rm/src/rm.rs | 6 +- src/uu/sort/src/merge.rs | 6 +- src/uu/sort/src/numeric_str_cmp.rs | 12 +- src/uu/sort/src/sort.rs | 32 ++--- src/uu/split/src/number.rs | 6 +- src/uu/stat/src/stat.rs | 128 +++++++++--------- src/uu/tail/src/chunks.rs | 8 +- src/uu/tail/src/tail.rs | 16 +-- src/uu/tee/src/tee.rs | 6 +- src/uu/users/src/users.rs | 6 +- src/uu/who/src/who.rs | 16 +-- src/uucore/src/lib/features/encoding.rs | 6 +- src/uucore/src/lib/features/entries.rs | 6 +- src/uucore/src/lib/features/fs.rs | 2 + src/uucore/src/lib/features/fsext.rs | 12 +- src/uucore/src/lib/features/perms.rs | 6 +- src/uucore/src/lib/features/process.rs | 12 +- src/uucore/src/lib/features/tokenize/sub.rs | 36 ++--- .../lib/features/tokenize/unescaped_text.rs | 6 +- src/uucore/src/lib/features/utmpx.rs | 6 +- src/uucore/src/lib/mods/quoting_style.rs | 6 +- src/uucore/src/lib/parser/parse_size.rs | 6 +- 41 files changed, 269 insertions(+), 271 deletions(-) diff --git a/src/uu/base32/src/base_common.rs b/src/uu/base32/src/base_common.rs index f68aa6b86c..78698e8b94 100644 --- a/src/uu/base32/src/base_common.rs +++ b/src/uu/base32/src/base_common.rs @@ -160,18 +160,7 @@ pub fn handle_input( data = data.line_wrap(wrap); } - if !decode { - match data.encode() { - Ok(s) => { - wrap_print(&data, &s); - Ok(()) - } - Err(_) => Err(USimpleError::new( - 1, - "error: invalid input (length must be multiple of 4 characters)", - )), - } - } else { + if decode { match data.decode() { Ok(s) => { // Silent the warning as we want to the error message @@ -184,5 +173,16 @@ pub fn handle_input( } Err(_) => Err(USimpleError::new(1, "error: invalid input")), } + } else { + match data.encode() { + Ok(s) => { + wrap_print(&data, &s); + Ok(()) + } + Err(_) => Err(USimpleError::new( + 1, + "error: invalid input (length must be multiple of 4 characters)", + )), + } } } diff --git a/src/uu/chmod/src/chmod.rs b/src/uu/chmod/src/chmod.rs index 14d761cf9e..a798860376 100644 --- a/src/uu/chmod/src/chmod.rs +++ b/src/uu/chmod/src/chmod.rs @@ -274,10 +274,10 @@ impl Chmoder { ) )); } - if !self.recursive { - r = self.chmod_file(file).and(r); - } else { + if self.recursive { r = self.walk_dir(file); + } else { + r = self.chmod_file(file).and(r); } } r @@ -360,10 +360,10 @@ impl Chmoder { naively_expected_new_mode = naive_mode; } Err(f) => { - if !self.quiet { - return Err(USimpleError::new(1, f)); - } else { + if self.quiet { return Err(ExitCode::new(1)); + } else { + return Err(USimpleError::new(1, f)); } } } diff --git a/src/uu/chown/src/chown.rs b/src/uu/chown/src/chown.rs index 3faecd571e..2d810564e3 100644 --- a/src/uu/chown/src/chown.rs +++ b/src/uu/chown/src/chown.rs @@ -198,7 +198,9 @@ fn parse_spec(spec: &str, sep: char) -> UResult<(Option, Option)> { let user = args.next().unwrap_or(""); let group = args.next().unwrap_or(""); - let uid = if !user.is_empty() { + let uid = if user.is_empty() { + None + } else { Some(match Passwd::locate(user) { Ok(u) => u.uid, // We have been able to get the uid Err(_) => @@ -225,10 +227,10 @@ fn parse_spec(spec: &str, sep: char) -> UResult<(Option, Option)> { } } }) - } else { - None }; - let gid = if !group.is_empty() { + let gid = if group.is_empty() { + None + } else { Some(match Group::locate(group) { Ok(g) => g.gid, Err(_) => match group.parse() { @@ -241,8 +243,6 @@ fn parse_spec(spec: &str, sep: char) -> UResult<(Option, Option)> { } }, }) - } else { - None }; if user.chars().next().map(char::is_numeric).unwrap_or(false) diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index 8ff6283c50..667eafe816 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -414,10 +414,10 @@ fn set_system_datetime(date: DateTime) -> UResult<()> { let result = unsafe { clock_settime(CLOCK_REALTIME, ×pec) }; - if result != 0 { - Err(std::io::Error::last_os_error().map_err_context(|| "cannot set date".to_string())) - } else { + if result == 0 { Ok(()) + } else { + Err(std::io::Error::last_os_error().map_err_context(|| "cannot set date".to_string())) } } diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 00be1558c8..6f75f4707d 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -265,10 +265,10 @@ fn make_linux_iflags(iflags: &IFlags) -> Option { flag |= libc::O_SYNC; } - if flag != 0 { - Some(flag) - } else { + if flag == 0 { None + } else { + Some(flag) } } @@ -784,10 +784,10 @@ fn make_linux_oflags(oflags: &OFlags) -> Option { flag |= libc::O_SYNC; } - if flag != 0 { - Some(flag) - } else { + if flag == 0 { None + } else { + Some(flag) } } diff --git a/src/uu/df/src/filesystem.rs b/src/uu/df/src/filesystem.rs index aac63ac9de..461815e671 100644 --- a/src/uu/df/src/filesystem.rs +++ b/src/uu/df/src/filesystem.rs @@ -83,9 +83,7 @@ where impl Filesystem { // TODO: resolve uuid in `mount_info.dev_name` if exists pub(crate) fn new(mount_info: MountInfo, file: Option) -> Option { - let _stat_path = if !mount_info.mount_dir.is_empty() { - mount_info.mount_dir.clone() - } else { + let _stat_path = if mount_info.mount_dir.is_empty() { #[cfg(unix)] { mount_info.dev_name.clone() @@ -95,6 +93,8 @@ impl Filesystem { // On windows, we expect the volume id mount_info.dev_id.clone() } + } else { + mount_info.mount_dir.clone() }; #[cfg(unix)] let usage = FsUsage::new(statfs(_stat_path).ok()?); diff --git a/src/uu/dirname/src/dirname.rs b/src/uu/dirname/src/dirname.rs index 687aaa5500..cecd6aec8b 100644 --- a/src/uu/dirname/src/dirname.rs +++ b/src/uu/dirname/src/dirname.rs @@ -38,7 +38,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { .map(|s| s.to_owned()) .collect(); - if !dirnames.is_empty() { + if dirnames.is_empty() { + return Err(UUsageError::new(1, "missing operand")); + } else { for path in &dirnames { let p = Path::new(path); match p.parent() { @@ -59,8 +61,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } print!("{separator}"); } - } else { - return Err(UUsageError::new(1, "missing operand")); } Ok(()) diff --git a/src/uu/env/src/env.rs b/src/uu/env/src/env.rs index a29ee3b0fd..0ef191b8d4 100644 --- a/src/uu/env/src/env.rs +++ b/src/uu/env/src/env.rs @@ -299,7 +299,10 @@ fn run_env(args: impl uucore::Args) -> UResult<()> { env::set_var(name, val); } - if !opts.program.is_empty() { + if opts.program.is_empty() { + // no program provided, so just dump all env vars to stdout + print_env(opts.null); + } else { // we need to execute a command let (prog, args) = build_command(&mut opts.program); @@ -344,9 +347,6 @@ fn run_env(args: impl uucore::Args) -> UResult<()> { Err(_) => return Err(126.into()), Ok(_) => (), } - } else { - // no program provided, so just dump all env vars to stdout - print_env(opts.null); } Ok(()) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 936760f279..1d2ddbced4 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -185,14 +185,14 @@ pub fn tokens_to_ast( maybe_dump_rpn(&out_stack); let result = ast_from_rpn(&mut out_stack); - if !out_stack.is_empty() { + if out_stack.is_empty() { + maybe_dump_ast(&result); + result + } else { Err( "syntax error (first RPN token does not represent the root of the expression AST)" .to_owned(), ) - } else { - maybe_dump_ast(&result); - result } }) } diff --git a/src/uu/factor/src/numeric/montgomery.rs b/src/uu/factor/src/numeric/montgomery.rs index dd4523022d..d411d0d419 100644 --- a/src/uu/factor/src/numeric/montgomery.rs +++ b/src/uu/factor/src/numeric/montgomery.rs @@ -82,10 +82,10 @@ impl Montgomery { // (x + n*m) / R // in case of overflow, this is (2¹²⁸ + xnm)/2⁶⁴ - n = xnm/2⁶⁴ + (2⁶⁴ - n) let y = T::from_double_width(xnm >> t_bits) - + if !overflow { - T::zero() - } else { + + if overflow { n.wrapping_neg() + } else { + T::zero() }; if y >= *n { @@ -132,10 +132,10 @@ impl Arithmetic for Montgomery { let (r, overflow) = a.overflowing_add(&b); // In case of overflow, a+b = 2⁶⁴ + r = (2⁶⁴ - n) + r (working mod n) - let r = if !overflow { - r - } else { + let r = if overflow { r + self.n.wrapping_neg() + } else { + r }; // Normalize to [0; n[ diff --git a/src/uu/fmt/src/parasplit.rs b/src/uu/fmt/src/parasplit.rs index c60be0a47d..d2e3d292dd 100644 --- a/src/uu/fmt/src/parasplit.rs +++ b/src/uu/fmt/src/parasplit.rs @@ -580,11 +580,11 @@ impl<'a> Iterator for WordSplit<'a> { // points to whitespace character OR end of string let mut word_nchars = 0; self.position = match self.string[word_start..].find(|x: char| { - if !x.is_whitespace() { + if x.is_whitespace() { + true + } else { word_nchars += char_width(x); false - } else { - true } }) { None => self.length, diff --git a/src/uu/hostname/src/hostname.rs b/src/uu/hostname/src/hostname.rs index 0e959b4719..83a22a82f3 100644 --- a/src/uu/hostname/src/hostname.rs +++ b/src/uu/hostname/src/hostname.rs @@ -41,10 +41,10 @@ mod wsa { let mut data = std::mem::MaybeUninit::::uninit(); WSAStartup(0x0202, data.as_mut_ptr()) }; - if err != 0 { - Err(io::Error::from_raw_os_error(err)) - } else { + if err == 0 { Ok(WsaHandle(())) + } else { + Err(io::Error::from_raw_os_error(err)) } } diff --git a/src/uu/id/src/id.rs b/src/uu/id/src/id.rs index 4a80099adc..7a8e40059b 100644 --- a/src/uu/id/src/id.rs +++ b/src/uu/id/src/id.rs @@ -203,9 +203,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } for i in 0..=users.len() { - let possible_pw = if !state.user_specified { - None - } else { + let possible_pw = if state.user_specified { match Passwd::locate(users[i].as_str()) { Ok(p) => Some(p), Err(_) => { @@ -218,6 +216,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } } + } else { + None }; // GNU's `id` does not support the flags: -p/-P/-A. diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 98fdb47d69..039aa1b153 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -399,13 +399,13 @@ fn behavior(matches: &ArgMatches) -> UResult { .unwrap_or("") .to_string(); - let owner_id = if !owner.is_empty() { + let owner_id = if owner.is_empty() { + None + } else { match usr2uid(&owner) { Ok(u) => Some(u), Err(_) => return Err(InstallError::InvalidUser(owner.clone()).into()), } - } else { - None }; let group = matches @@ -414,13 +414,13 @@ fn behavior(matches: &ArgMatches) -> UResult { .unwrap_or("") .to_string(); - let group_id = if !group.is_empty() { + let group_id = if group.is_empty() { + None + } else { match grp2gid(&group) { Ok(g) => Some(g), Err(_) => return Err(InstallError::InvalidGroup(group.clone()).into()), } - } else { - None }; Ok(Behavior { diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index c5d8118340..309ae1a769 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -2008,16 +2008,16 @@ fn enter_directory( continue; } Ok(rd) => { - if !listed_ancestors + if listed_ancestors .insert(FileInformation::from_path(&e.p_buf, e.must_dereference)?) { - out.flush()?; - show!(LsError::AlreadyListedError(e.p_buf.clone())); - } else { writeln!(out, "\n{}:", e.p_buf.display())?; enter_directory(e, rd, config, out, listed_ancestors)?; listed_ancestors .remove(&FileInformation::from_path(&e.p_buf, e.must_dereference)?); + } else { + out.flush()?; + show!(LsError::AlreadyListedError(e.p_buf.clone())); } } } @@ -2867,10 +2867,10 @@ fn display_file_name( // to get correct alignment from later calls to`display_grid()`. if config.context { if let Some(pad_count) = prefix_context { - let security_context = if !matches!(config.format, Format::Commas) { - pad_left(&path.security_context, pad_count) - } else { + let security_context = if matches!(config.format, Format::Commas) { path.security_context.to_owned() + } else { + pad_left(&path.security_context, pad_count) }; name = format!("{security_context} {name}"); width += security_context.len() + 1; diff --git a/src/uu/numfmt/src/format.rs b/src/uu/numfmt/src/format.rs index 3e20d00eec..eb75f7554f 100644 --- a/src/uu/numfmt/src/format.rs +++ b/src/uu/numfmt/src/format.rs @@ -55,7 +55,7 @@ impl<'a> Iterator for WhitespaceSplitter<'a> { .unwrap_or(field.len()), ); - self.s = if !rest.is_empty() { Some(rest) } else { None }; + self.s = if rest.is_empty() { None } else { Some(rest) }; Some((prefix, field)) } diff --git a/src/uu/numfmt/src/options.rs b/src/uu/numfmt/src/options.rs index 79d7461ae1..131ad378b5 100644 --- a/src/uu/numfmt/src/options.rs +++ b/src/uu/numfmt/src/options.rs @@ -190,14 +190,12 @@ impl FromStr for FormatOptions { } } - if !precision.is_empty() { - if let Ok(p) = precision.parse() { - options.precision = Some(p); - } else { - return Err(format!("invalid precision in format '{s}'")); - } - } else { + if precision.is_empty() { options.precision = Some(0); + } else if let Ok(p) = precision.parse() { + options.precision = Some(p); + } else { + return Err(format!("invalid precision in format '{s}'")); } } diff --git a/src/uu/od/src/od.rs b/src/uu/od/src/od.rs index 5e8f8814d0..09765ed2b4 100644 --- a/src/uu/od/src/od.rs +++ b/src/uu/od/src/od.rs @@ -171,12 +171,7 @@ impl OdOptions { None => Radix::Octal, Some(s) => { let st = s.as_bytes(); - if st.len() != 1 { - return Err(USimpleError::new( - 1, - "Radix must be one of [d, o, n, x]".to_string(), - )); - } else { + if st.len() == 1 { let radix: char = *(st .first() .expect("byte string of length 1 lacks a 0th elem")) @@ -193,6 +188,11 @@ impl OdOptions { )) } } + } else { + return Err(USimpleError::new( + 1, + "Radix must be one of [d, o, n, x]".to_string(), + )); } } }; diff --git a/src/uu/pinky/src/pinky.rs b/src/uu/pinky/src/pinky.rs index 7e21fba9ea..18f72638be 100644 --- a/src/uu/pinky/src/pinky.rs +++ b/src/uu/pinky/src/pinky.rs @@ -218,10 +218,10 @@ impl Capitalize for str { fn capitalize(&self) -> String { self.char_indices() .fold(String::with_capacity(self.len()), |mut acc, x| { - if x.0 != 0 { - acc.push(x.1); - } else { + if x.0 == 0 { acc.push(x.1.to_ascii_uppercase()); + } else { + acc.push(x.1); } acc }) @@ -281,10 +281,10 @@ impl Pinky { match pts_path.metadata() { #[allow(clippy::unnecessary_cast)] Ok(meta) => { - mesg = if meta.mode() & S_IWGRP as u32 != 0 { - ' ' - } else { + mesg = if meta.mode() & S_IWGRP as u32 == 0 { '*' + } else { + ' ' }; last_change = meta.atime(); } @@ -312,10 +312,10 @@ impl Pinky { print!(" {}{:<8.*}", mesg, utmpx::UT_LINESIZE, ut.tty_device()); if self.include_idle { - if last_change != 0 { - print!(" {:<6}", idle_string(last_change)); - } else { + if last_change == 0 { print!(" {:<6}", "?????"); + } else { + print!(" {:<6}", idle_string(last_change)); } } diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 05d03cee2b..02aa96e241 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -257,14 +257,14 @@ fn remove(files: &[String], options: &Options) -> bool { // TODO: When the error is not about missing files // (e.g., permission), even rm -f should fail with // outputting the error, but there's no easy eay. - if !options.force { + if options.force { + false + } else { show_error!( "cannot remove {}: No such file or directory", filename.quote() ); true - } else { - false } } } diff --git a/src/uu/sort/src/merge.rs b/src/uu/sort/src/merge.rs index a7b4417e34..f6da0ee329 100644 --- a/src/uu/sort/src/merge.rs +++ b/src/uu/sort/src/merge.rs @@ -362,16 +362,16 @@ impl<'a> Compare for FileComparator<'a> { // Wait for the child to exit and check its exit code. fn check_child_success(mut child: Child, program: &str) -> UResult<()> { - if !matches!( + if matches!( child.wait().map(|e| e.code()), Ok(Some(0)) | Ok(None) | Err(_) ) { + Ok(()) + } else { Err(SortError::CompressProgTerminatedAbnormally { prog: program.to_owned(), } .into()) - } else { - Ok(()) } } diff --git a/src/uu/sort/src/numeric_str_cmp.rs b/src/uu/sort/src/numeric_str_cmp.rs index 70f8c2cd8e..21d733877d 100644 --- a/src/uu/sort/src/numeric_str_cmp.rs +++ b/src/uu/sort/src/numeric_str_cmp.rs @@ -198,15 +198,13 @@ pub fn human_numeric_str_cmp( let a_unit = get_unit(a.chars().next_back()); let b_unit = get_unit(b.chars().next_back()); let ordering = a_unit.cmp(&b_unit); - if ordering != Ordering::Equal { - if a_info.sign == Sign::Negative { - ordering.reverse() - } else { - ordering - } - } else { + if ordering == Ordering::Equal { // 3. Number numeric_str_cmp((a, a_info), (b, b_info)) + } else if a_info.sign == Sign::Negative { + ordering.reverse() + } else { + ordering } } diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index a681026f64..5b309e4135 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -185,7 +185,9 @@ impl Display for SortError { line, silent, } => { - if !silent { + if *silent { + Ok(()) + } else { write!( f, "{}:{}: disorder: {}", @@ -193,8 +195,6 @@ impl Display for SortError { line_number, line ) - } else { - Ok(()) } } Self::OpenFailed { path, error } => { @@ -582,7 +582,15 @@ impl<'a> Line<'a> { selection.start += num_range.start; selection.end = selection.start + num_range.len(); - if num_range != (0..0) { + if num_range == (0..0) { + // 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; + } else { // include a trailing si unit if selector.settings.mode == SortMode::HumanNumeric && self.line[selection.end..initial_selection.end] @@ -597,14 +605,6 @@ impl<'a> Line<'a> { { 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 => { @@ -1572,10 +1572,7 @@ fn compare_by<'a>( let mut num_info_index = 0; let mut parsed_float_index = 0; for selector in &global_settings.selectors { - let (a_str, b_str) = if !selector.needs_selection { - // We can select the whole line. - (a.line, b.line) - } else { + let (a_str, b_str) = if selector.needs_selection { let selections = ( a_line_data.selections [a.index * global_settings.precomputed.selections_per_line + selection_index], @@ -1584,6 +1581,9 @@ fn compare_by<'a>( ); selection_index += 1; selections + } else { + // We can select the whole line. + (a.line, b.line) }; let settings = &selector.settings; diff --git a/src/uu/split/src/number.rs b/src/uu/split/src/number.rs index 778e24f7cf..567526538a 100644 --- a/src/uu/split/src/number.rs +++ b/src/uu/split/src/number.rs @@ -200,10 +200,10 @@ impl FixedWidthNumber { break; } } - if suffix_start != 0 { - Err(Overflow) - } else { + if suffix_start == 0 { Ok(Self { radix, digits }) + } else { + Err(Overflow) } } diff --git a/src/uu/stat/src/stat.rs b/src/uu/stat/src/stat.rs index fbbed8c210..586803db4a 100644 --- a/src/uu/stat/src/stat.rs +++ b/src/uu/stat/src/stat.rs @@ -375,9 +375,7 @@ impl Stater { }); } '\\' => { - if !use_printf { - tokens.push(Token::Char('\\')); - } else { + if use_printf { i += 1; if i >= bound { show_warning!("backslash at end of format"); @@ -414,6 +412,8 @@ impl Stater { tokens.push(Token::Char(c)); } } + } else { + tokens.push(Token::Char('\\')); } } @@ -519,7 +519,67 @@ impl Stater { OsString::from(file) }; - if !self.show_fs { + if self.show_fs { + #[cfg(unix)] + let p = file.as_bytes(); + #[cfg(not(unix))] + let p = file.into_string().unwrap(); + match statfs(p) { + Ok(meta) => { + let tokens = &self.default_tokens; + + for t in tokens.iter() { + match *t { + Token::Char(c) => print!("{c}"), + Token::Directive { + flag, + width, + precision, + format, + } => { + let output = match format { + // free blocks available to non-superuser + 'a' => OutputType::Unsigned(meta.avail_blocks()), + // total data blocks in file system + 'b' => OutputType::Unsigned(meta.total_blocks()), + // total file nodes in file system + 'c' => OutputType::Unsigned(meta.total_file_nodes()), + // free file nodes in file system + 'd' => OutputType::Unsigned(meta.free_file_nodes()), + // free blocks in file system + 'f' => OutputType::Unsigned(meta.free_blocks()), + // file system ID in hex + 'i' => OutputType::UnsignedHex(meta.fsid()), + // maximum length of filenames + 'l' => OutputType::Unsigned(meta.namelen()), + // file name + 'n' => OutputType::Str(display_name.to_string()), + // block size (for faster transfers) + 's' => OutputType::Unsigned(meta.io_size()), + // fundamental block size (for block counts) + 'S' => OutputType::Integer(meta.block_size()), + // file system type in hex + 't' => OutputType::UnsignedHex(meta.fs_type() as u64), + // file system type in human readable form + 'T' => OutputType::Str(pretty_fstype(meta.fs_type()).into()), + _ => OutputType::Unknown, + }; + + print_it(&output, flag, width, precision); + } + } + } + } + Err(e) => { + show_error!( + "cannot read file system information for {}: {}", + display_name.quote(), + e + ); + return 1; + } + } + } else { let result = if self.follow || stdin_is_fifo && display_name == "-" { fs::metadata(&file) } else { @@ -660,66 +720,6 @@ impl Stater { return 1; } } - } else { - #[cfg(unix)] - let p = file.as_bytes(); - #[cfg(not(unix))] - let p = file.into_string().unwrap(); - match statfs(p) { - Ok(meta) => { - let tokens = &self.default_tokens; - - for t in tokens.iter() { - match *t { - Token::Char(c) => print!("{c}"), - Token::Directive { - flag, - width, - precision, - format, - } => { - let output = match format { - // free blocks available to non-superuser - 'a' => OutputType::Unsigned(meta.avail_blocks()), - // total data blocks in file system - 'b' => OutputType::Unsigned(meta.total_blocks()), - // total file nodes in file system - 'c' => OutputType::Unsigned(meta.total_file_nodes()), - // free file nodes in file system - 'd' => OutputType::Unsigned(meta.free_file_nodes()), - // free blocks in file system - 'f' => OutputType::Unsigned(meta.free_blocks()), - // file system ID in hex - 'i' => OutputType::UnsignedHex(meta.fsid()), - // maximum length of filenames - 'l' => OutputType::Unsigned(meta.namelen()), - // file name - 'n' => OutputType::Str(display_name.to_string()), - // block size (for faster transfers) - 's' => OutputType::Unsigned(meta.io_size()), - // fundamental block size (for block counts) - 'S' => OutputType::Integer(meta.block_size()), - // file system type in hex - 't' => OutputType::UnsignedHex(meta.fs_type() as u64), - // file system type in human readable form - 'T' => OutputType::Str(pretty_fstype(meta.fs_type()).into()), - _ => OutputType::Unknown, - }; - - print_it(&output, flag, width, precision); - } - } - } - } - Err(e) => { - show_error!( - "cannot read file system information for {}: {}", - display_name.quote(), - e - ); - return 1; - } - } } 0 } diff --git a/src/uu/tail/src/chunks.rs b/src/uu/tail/src/chunks.rs index 4b934c1d7d..3aa380e20e 100644 --- a/src/uu/tail/src/chunks.rs +++ b/src/uu/tail/src/chunks.rs @@ -579,16 +579,16 @@ impl LinesChunkBuffer { } } - if !&self.chunks.is_empty() { + if self.chunks.is_empty() { + // chunks is empty when a file is empty so quitting early here + return Ok(()); + } else { let length = &self.chunks.len(); let last = &mut self.chunks[length - 1]; if !last.get_buffer().ends_with(&[self.delimiter]) { last.lines += 1; self.lines += 1; } - } else { - // chunks is empty when a file is empty so quitting early here - return Ok(()); } // skip unnecessary chunks and save the first chunk which may hold some lines we have to diff --git a/src/uu/tail/src/tail.rs b/src/uu/tail/src/tail.rs index 9e3273638b..e07616c6f5 100644 --- a/src/uu/tail/src/tail.rs +++ b/src/uu/tail/src/tail.rs @@ -125,10 +125,10 @@ fn tail_file( show_error!("error reading '{}': {}", input.display_name, err_msg); if settings.follow.is_some() { - let msg = if !settings.retry { - "; giving up on this name" - } else { + let msg = if settings.retry { "" + } else { + "; giving up on this name" }; show_error!( "{}: cannot follow end of this type of file{}", @@ -215,11 +215,7 @@ fn tail_stdin( // pipe None => { header_printer.print_input(input); - if !paths::stdin_is_bad_fd() { - let mut reader = BufReader::new(stdin()); - unbounded_tail(&mut reader, settings)?; - observer.add_stdin(input.display_name.as_str(), Some(Box::new(reader)), true)?; - } else { + if paths::stdin_is_bad_fd() { set_exit_code(1); show_error!( "cannot fstat {}: {}", @@ -233,6 +229,10 @@ fn tail_stdin( text::BAD_FD ); } + } else { + let mut reader = BufReader::new(stdin()); + unbounded_tail(&mut reader, settings)?; + observer.add_stdin(input.display_name.as_str(), Some(Box::new(reader)), true)?; } } }; diff --git a/src/uu/tee/src/tee.rs b/src/uu/tee/src/tee.rs index f8e6ebe419..5c388dd0ee 100644 --- a/src/uu/tee/src/tee.rs +++ b/src/uu/tee/src/tee.rs @@ -261,11 +261,11 @@ fn process_error( Err(f) } Some(OutputErrorMode::ExitNoPipe) => { - if f.kind() != ErrorKind::BrokenPipe { + if f.kind() == ErrorKind::BrokenPipe { + Ok(()) + } else { show_error!("{}: {}", writer.name.maybe_quote(), f); Err(f) - } else { - Ok(()) } } } diff --git a/src/uu/users/src/users.rs b/src/uu/users/src/users.rs index 05d656576a..6a5e54f99f 100644 --- a/src/uu/users/src/users.rs +++ b/src/uu/users/src/users.rs @@ -41,10 +41,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { .map(|v| v.map(AsRef::as_ref).collect()) .unwrap_or_default(); - let filename = if !files.is_empty() { - files[0] - } else { + let filename = if files.is_empty() { utmpx::DEFAULT_FILE.as_ref() + } else { + files[0] }; let mut users = Utmpx::iter_all_records_from(filename) diff --git a/src/uu/who/src/who.rs b/src/uu/who/src/who.rs index 26248b12b8..fbfff80d73 100644 --- a/src/uu/who/src/who.rs +++ b/src/uu/who/src/who.rs @@ -316,13 +316,13 @@ fn time_string(ut: &Utmpx) -> String { fn current_tty() -> String { unsafe { let res = ttyname(STDIN_FILENO); - if !res.is_null() { + if res.is_null() { + String::new() + } else { CStr::from_ptr(res as *const _) .to_string_lossy() .trim_start_matches("/dev/") .to_owned() - } else { - String::new() } } } @@ -402,7 +402,7 @@ impl Who { &time_string(ut), "", "", - if !last.is_control() { &comment } else { "" }, + if last.is_control() { "" } else { &comment }, "", ); } @@ -482,7 +482,7 @@ impl Who { let iwgrp = S_IWGRP; #[cfg(any(target_os = "android", target_os = "freebsd", target_vendor = "apple"))] let iwgrp = S_IWGRP as u32; - mesg = if meta.mode() & iwgrp != 0 { '+' } else { '-' }; + mesg = if meta.mode() & iwgrp == 0 { '-' } else { '+' }; last_change = meta.atime(); } _ => { @@ -491,10 +491,10 @@ impl Who { } } - let idle = if last_change != 0 { - idle_string(last_change, 0) - } else { + let idle = if last_change == 0 { " ?".into() + } else { + idle_string(last_change, 0) }; let s = if self.do_lookup { diff --git a/src/uucore/src/lib/features/encoding.rs b/src/uucore/src/lib/features/encoding.rs index db4c4c6358..a42044eea7 100644 --- a/src/uucore/src/lib/features/encoding.rs +++ b/src/uucore/src/lib/features/encoding.rs @@ -67,10 +67,10 @@ pub fn encode(f: Format, input: &[u8]) -> Result { Z85 => { // According to the spec we should not accept inputs whose len is not a multiple of 4. // However, the z85 crate implements a padded encoding and accepts such inputs. We have to manually check for them. - if input.len() % 4 != 0 { - return Err(EncodeError::Z85InputLenNotMultipleOf4); - } else { + if input.len() % 4 == 0 { z85::encode(input) + } else { + return Err(EncodeError::Z85InputLenNotMultipleOf4); } } }) diff --git a/src/uucore/src/lib/features/entries.rs b/src/uucore/src/lib/features/entries.rs index 561de888bd..1e8f2417ab 100644 --- a/src/uucore/src/lib/features/entries.rs +++ b/src/uucore/src/lib/features/entries.rs @@ -168,10 +168,10 @@ pub struct Passwd { /// SAFETY: ptr must point to a valid C string. /// Returns None if ptr is null. unsafe fn cstr2string(ptr: *const c_char) -> Option { - if !ptr.is_null() { - Some(CStr::from_ptr(ptr).to_string_lossy().into_owned()) - } else { + if ptr.is_null() { None + } else { + Some(CStr::from_ptr(ptr).to_string_lossy().into_owned()) } } diff --git a/src/uucore/src/lib/features/fs.rs b/src/uucore/src/lib/features/fs.rs index 43c21aa8d7..b82eba94a8 100644 --- a/src/uucore/src/lib/features/fs.rs +++ b/src/uucore/src/lib/features/fs.rs @@ -455,6 +455,8 @@ pub fn display_permissions(metadata: &fs::Metadata, display_file_type: bool) -> display_permissions_unix(mode, display_file_type) } +// The logic below is more readable written this way. +#[allow(clippy::if_not_else)] #[cfg(unix)] /// Display the permissions of a file on a unix like system pub fn display_permissions_unix(mode: mode_t, display_file_type: bool) -> String { diff --git a/src/uucore/src/lib/features/fsext.rs b/src/uucore/src/lib/features/fsext.rs index 927ae0f7ad..e7d5d66bf2 100644 --- a/src/uucore/src/lib/features/fsext.rs +++ b/src/uucore/src/lib/features/fsext.rs @@ -295,10 +295,10 @@ impl MountInfo { fs_type_buf.len() as u32, ) }; - let fs_type = if 0 != success { - Some(LPWSTR2String(&fs_type_buf)) - } else { + let fs_type = if 0 == success { None + } else { + Some(LPWSTR2String(&fs_type_buf)) }; let mut mn_info = Self { dev_id: volume_name, @@ -862,10 +862,10 @@ pub fn pretty_time(sec: i64, nsec: i64) -> String { pub fn pretty_filetype<'a>(mode: mode_t, size: u64) -> &'a str { match mode & S_IFMT { S_IFREG => { - if size != 0 { - "regular file" - } else { + if size == 0 { "regular empty file" + } else { + "regular file" } } S_IFDIR => "directory", diff --git a/src/uucore/src/lib/features/perms.rs b/src/uucore/src/lib/features/perms.rs index 07203a3181..1103136425 100644 --- a/src/uucore/src/lib/features/perms.rs +++ b/src/uucore/src/lib/features/perms.rs @@ -263,10 +263,10 @@ impl ChownExecutor { 0 }; - if !self.recursive { - ret - } else { + if self.recursive { ret | self.dive_into(&root) + } else { + ret } } diff --git a/src/uucore/src/lib/features/process.rs b/src/uucore/src/lib/features/process.rs index b8b2f178f1..4a52f0fc4f 100644 --- a/src/uucore/src/lib/features/process.rs +++ b/src/uucore/src/lib/features/process.rs @@ -58,10 +58,10 @@ pub trait ChildExt { impl ChildExt for Child { fn send_signal(&mut self, signal: usize) -> io::Result<()> { - if unsafe { libc::kill(self.id() as pid_t, signal as i32) } != 0 { - Err(io::Error::last_os_error()) - } else { + if unsafe { libc::kill(self.id() as pid_t, signal as i32) } == 0 { Ok(()) + } else { + Err(io::Error::last_os_error()) } } @@ -70,10 +70,10 @@ impl ChildExt for Child { if unsafe { libc::signal(signal as i32, libc::SIG_IGN) } != 0 { return Err(io::Error::last_os_error()); } - if unsafe { libc::kill(0, signal as i32) } != 0 { - Err(io::Error::last_os_error()) - } else { + if unsafe { libc::kill(0, signal as i32) } == 0 { Ok(()) + } else { + Err(io::Error::last_os_error()) } } diff --git a/src/uucore/src/lib/features/tokenize/sub.rs b/src/uucore/src/lib/features/tokenize/sub.rs index 9312040e32..af13fb83f8 100644 --- a/src/uucore/src/lib/features/tokenize/sub.rs +++ b/src/uucore/src/lib/features/tokenize/sub.rs @@ -197,22 +197,24 @@ impl SubParser { self.text_so_far.push(ch); match ch { '-' | '*' | '0'..='9' => { - if !self.past_decimal { - if self.min_width_is_asterisk || self.specifiers_found { + if self.past_decimal { + // second field should never have a + // negative value + if self.second_field_is_asterisk || ch == '-' || self.specifiers_found { return Err(SubError::InvalidSpec(self.text_so_far.clone()).into()); } - if self.min_width_tmp.is_none() { - self.min_width_tmp = Some(String::new()); + if self.second_field_tmp.is_none() { + self.second_field_tmp = Some(String::new()); } - match self.min_width_tmp.as_mut() { + match self.second_field_tmp.as_mut() { Some(x) => { - if (ch == '-' || ch == '*') && !x.is_empty() { + if ch == '*' && !x.is_empty() { return Err( SubError::InvalidSpec(self.text_so_far.clone()).into() ); } if ch == '*' { - self.min_width_is_asterisk = true; + self.second_field_is_asterisk = true; } x.push(ch); } @@ -221,23 +223,21 @@ impl SubParser { } } } else { - // second field should never have a - // negative value - if self.second_field_is_asterisk || ch == '-' || self.specifiers_found { + if self.min_width_is_asterisk || self.specifiers_found { return Err(SubError::InvalidSpec(self.text_so_far.clone()).into()); } - if self.second_field_tmp.is_none() { - self.second_field_tmp = Some(String::new()); + if self.min_width_tmp.is_none() { + self.min_width_tmp = Some(String::new()); } - match self.second_field_tmp.as_mut() { + match self.min_width_tmp.as_mut() { Some(x) => { - if ch == '*' && !x.is_empty() { + if (ch == '-' || ch == '*') && !x.is_empty() { return Err( SubError::InvalidSpec(self.text_so_far.clone()).into() ); } if ch == '*' { - self.second_field_is_asterisk = true; + self.min_width_is_asterisk = true; } x.push(ch); } @@ -248,10 +248,10 @@ impl SubParser { } } '.' => { - if !self.past_decimal { - self.past_decimal = true; - } else { + if self.past_decimal { return Err(SubError::InvalidSpec(self.text_so_far.clone()).into()); + } else { + self.past_decimal = true; } } x if legal_fields.binary_search(&x).is_ok() => { diff --git a/src/uucore/src/lib/features/tokenize/unescaped_text.rs b/src/uucore/src/lib/features/tokenize/unescaped_text.rs index e659b11b56..b4f632901e 100644 --- a/src/uucore/src/lib/features/tokenize/unescaped_text.rs +++ b/src/uucore/src/lib/features/tokenize/unescaped_text.rs @@ -135,13 +135,13 @@ impl UnescapedText { } _ => {} } - if !ignore { + if ignore { + byte_vec.push(ch as u8); + } else { let val = (Self::base_to_u32(min_len, max_len, base, it) % 256) as u8; byte_vec.push(val); let bvec = [val]; flush_bytes(writer, &bvec); - } else { - byte_vec.push(ch as u8); } } e => { diff --git a/src/uucore/src/lib/features/utmpx.rs b/src/uucore/src/lib/features/utmpx.rs index 599a027786..8ac41014b1 100644 --- a/src/uucore/src/lib/features/utmpx.rs +++ b/src/uucore/src/lib/features/utmpx.rs @@ -336,7 +336,9 @@ impl Iterator for UtmpxIter { fn next(&mut self) -> Option { unsafe { let res = getutxent(); - if !res.is_null() { + if res.is_null() { + None + } else { // The data behind this pointer will be replaced by the next // call to getutxent(), so we have to read it now. // All the strings live inline in the struct as arrays, which @@ -344,8 +346,6 @@ impl Iterator for UtmpxIter { Some(Utmpx { inner: ptr::read(res as *const _), }) - } else { - None } } } diff --git a/src/uucore/src/lib/mods/quoting_style.rs b/src/uucore/src/lib/mods/quoting_style.rs index 3c8bf686a8..a6efb2898c 100644 --- a/src/uucore/src/lib/mods/quoting_style.rs +++ b/src/uucore/src/lib/mods/quoting_style.rs @@ -259,13 +259,13 @@ fn shell_with_escape(name: &str, quotes: Quotes) -> (String, bool) { pub fn escape_name(name: &OsStr, style: &QuotingStyle) -> String { match style { QuotingStyle::Literal { show_control } => { - if !show_control { + if *show_control { + name.to_string_lossy().into_owned() + } else { name.to_string_lossy() .chars() .flat_map(|c| EscapedChar::new_literal(c).hide_control()) .collect() - } else { - name.to_string_lossy().into_owned() } } QuotingStyle::C { quotes } => { diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index d1e571e069..60209d8493 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -70,13 +70,13 @@ impl<'parser> Parser<'parser> { // Get the numeric part of the size argument. For example, if the // argument is "123K", then the numeric part is "123". let numeric_string: String = size.chars().take_while(|c| c.is_ascii_digit()).collect(); - let number: u64 = if !numeric_string.is_empty() { + let number: u64 = if numeric_string.is_empty() { + 1 + } else { match numeric_string.parse() { Ok(n) => n, Err(_) => return Err(ParseSizeError::parse_failure(size)), } - } else { - 1 }; // Get the alphabetic units part of the size argument and compute From b056e29b06e5f8934794bd6b328a627688734587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Sun, 26 Mar 2023 21:34:43 +0200 Subject: [PATCH 018/477] lint: Enable clippy::if_not_else rule --- .cargo/config | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.cargo/config b/.cargo/config index 7724c1b54d..a4dc4b423f 100644 --- a/.cargo/config +++ b/.cargo/config @@ -3,10 +3,11 @@ linker = "x86_64-unknown-redox-gcc" [target.'cfg(feature = "cargo-clippy")'] rustflags = [ - "-Wclippy::use_self", - "-Wclippy::needless_pass_by_value", - "-Wclippy::semicolon_if_nothing_returned", - "-Wclippy::single_char_pattern", - "-Wclippy::explicit_iter_loop", + "-Wclippy::use_self", + "-Wclippy::needless_pass_by_value", + "-Wclippy::semicolon_if_nothing_returned", + "-Wclippy::single_char_pattern", + "-Wclippy::explicit_iter_loop", + "-Wclippy::if_not_else", ] From 4ba6a3f06f8c667c7ce892cde207bd2f95f5cd1e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 05:18:34 +0000 Subject: [PATCH 019/477] chore(deps): update rust crate is-terminal to 0.4.5 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82f5ba6903..6ea4b24921 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1145,9 +1145,9 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", diff --git a/Cargo.toml b/Cargo.toml index 6690c8fe2e..1019601e99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -287,7 +287,7 @@ gcd = "2.2" glob = "0.3.0" half = "2.1" indicatif = "0.17" -is-terminal = "0.4.3" +is-terminal = "0.4.5" itertools = "0.10.0" libc = "0.2.139" lscolors = { version = "0.13.0", default-features=false, features = ["nu-ansi-term"] } From 44189524098639013277a52d0b1322b5fed85008 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 05:20:16 +0000 Subject: [PATCH 020/477] chore(deps): update rust crate nom to 7.1.3 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82f5ba6903..38f7ba5764 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1359,9 +1359,9 @@ dependencies = [ [[package]] name = "nom" -version = "7.1.1" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", diff --git a/Cargo.toml b/Cargo.toml index 6690c8fe2e..bf524c635c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -293,7 +293,7 @@ libc = "0.2.139" lscolors = { version = "0.13.0", default-features=false, features = ["nu-ansi-term"] } memchr = "2" nix = { version="0.26", default-features=false } -nom = "7.1.1" +nom = "7.1.3" notify = { version = "=5.0.0", features=["macos_kqueue"]} num_cpus = "1.14" num-bigint = "0.4.3" From bb939a3ba17eb9d8e0d5c190d8b3e69072083b8f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 05:25:50 +0000 Subject: [PATCH 021/477] chore(deps): update rust crate sha2 to 0.10.6 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 6690c8fe2e..ec76ae61e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -334,7 +334,7 @@ zip = { version = "0.6.3", default_features=false, features=["deflate"] } hex = "0.4.3" md-5 = "0.10.5" sha1 = "0.10.5" -sha2 = "0.10.2" +sha2 = "0.10.6" sha3 = "0.10.6" blake2b_simd = "1.0.1" blake3 = "1.3.3" From 00cef5680c0be0a6cb8038c548e77a4222d4c76e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 05:29:13 +0000 Subject: [PATCH 022/477] chore(deps): update rust crate unicode-width to 0.1.10 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 6690c8fe2e..628f182b7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -323,7 +323,7 @@ textwrap = { version="0.16.0", features=["terminal_size"] } thiserror = "1.0" time = { version="0.3" } unicode-segmentation = "1.9.0" -unicode-width = "0.1.8" +unicode-width = "0.1.10" utf-8 = "0.7.6" walkdir = "2.2" winapi-util = "0.1.5" From 515bd8f6422b360aa720dcf38b3ffbf411d8c87c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 05:32:38 +0000 Subject: [PATCH 023/477] fix(deps): update rust crate dns-lookup to 1.0.8 --- src/uucore/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 4ca3941db7..3e03f37455 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -20,7 +20,7 @@ path="src/lib/lib.rs" [dependencies] clap = { workspace=true } uucore_procs = { workspace=true } -dns-lookup = { version="1.0.5", optional=true } +dns-lookup = { version="1.0.8", optional=true } dunce = "1.0.3" wild = "2.0" glob = "0.3.0" From bf228385e8521bc008c24fa44d51a5324b5f5247 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 05:36:00 +0000 Subject: [PATCH 024/477] fix(deps): update rust crate glob to 0.3.1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82f5ba6903..9ad63e084c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1008,9 +1008,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "half" diff --git a/Cargo.toml b/Cargo.toml index 6690c8fe2e..89672152d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -284,7 +284,7 @@ fs_extra = "1.1.0" fts-sys = "0.2" fundu = "0.4.3" gcd = "2.2" -glob = "0.3.0" +glob = "0.3.1" half = "2.1" indicatif = "0.17" is-terminal = "0.4.3" diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 4ca3941db7..32a6f39060 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -23,7 +23,7 @@ uucore_procs = { workspace=true } dns-lookup = { version="1.0.5", optional=true } dunce = "1.0.3" wild = "2.0" -glob = "0.3.0" +glob = "0.3.1" # * optional itertools = { version="0.10.0", optional=true } thiserror = { workspace=true, optional=true } From 07c0d9cad98d7112c7c789207dcd23a5e9a29356 Mon Sep 17 00:00:00 2001 From: Piotr Kwiecinski Date: Mon, 27 Mar 2023 11:09:19 +0200 Subject: [PATCH 025/477] paste: move help strings to markdown file --- src/uu/paste/paste.md | 8 ++++++++ src/uu/paste/src/paste.rs | 6 ++++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 src/uu/paste/paste.md diff --git a/src/uu/paste/paste.md b/src/uu/paste/paste.md new file mode 100644 index 0000000000..26744cbfb7 --- /dev/null +++ b/src/uu/paste/paste.md @@ -0,0 +1,8 @@ +# paste + +``` +paste [OPTIONS] [FILE]... +``` + +Write lines consisting of the sequentially corresponding lines from each +`FILE`, separated by `TABs`, to standard output. diff --git a/src/uu/paste/src/paste.rs b/src/uu/paste/src/paste.rs index 3635ae967e..d7a4d325c6 100644 --- a/src/uu/paste/src/paste.rs +++ b/src/uu/paste/src/paste.rs @@ -13,9 +13,10 @@ use std::fs::File; use std::io::{stdin, stdout, BufRead, BufReader, Read, Write}; use std::path::Path; use uucore::error::{FromIo, UResult}; +use uucore::{format_usage, help_about, help_usage}; -static ABOUT: &str = "Write lines consisting of the sequentially corresponding lines from each -FILE, separated by TABs, to standard output."; +const ABOUT: &str = help_about!("paste.md"); +const USAGE: &str = help_usage!("paste.md"); mod options { pub const DELIMITER: &str = "delimiters"; @@ -76,6 +77,7 @@ pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(crate_version!()) .about(ABOUT) + .override_usage(format_usage(USAGE)) .infer_long_args(true) .arg( Arg::new(options::SERIAL) From d81ce37a4d50f0e0e7866b7f016b07ef151e325e Mon Sep 17 00:00:00 2001 From: Piotr Kwiecinski Date: Mon, 27 Mar 2023 11:41:08 +0200 Subject: [PATCH 026/477] paste: move backtick --- src/uu/paste/paste.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/paste/paste.md b/src/uu/paste/paste.md index 26744cbfb7..7416058889 100644 --- a/src/uu/paste/paste.md +++ b/src/uu/paste/paste.md @@ -5,4 +5,4 @@ paste [OPTIONS] [FILE]... ``` Write lines consisting of the sequentially corresponding lines from each -`FILE`, separated by `TABs`, to standard output. +`FILE`, separated by `TAB`s, to standard output. From 9b2974777bf927393c9ccfbf38a712d6a1777fa9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 15:20:31 +0000 Subject: [PATCH 027/477] chore(deps): update rust crate bstr to 1.4 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c742b50a2c..47d7c537ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.0.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca0852af221f458706eb0725c03e4ed6c46af9ac98e6a689d5e634215d594dd" +checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09" dependencies = [ "memchr", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index 08a0ef3bb8..c700a3d0da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -265,7 +265,7 @@ test = [ "uu_test" ] [workspace.dependencies] bigdecimal = "0.3" binary-heap-plus = "0.5.0" -bstr = "1.0" +bstr = "1.4" bytecount = "0.6.3" byteorder = "1.3.2" chrono = { version="^0.4.24", default-features=false, features=["std", "alloc", "clock"]} From 24ac85c32b04bb4f489f68b7907d61cbe8d1a15e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 05:30:55 +0000 Subject: [PATCH 028/477] chore(deps): update rust crate zip to 0.6.4 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eba2769e93..8fdf700259 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3557,9 +3557,9 @@ checksum = "2a599daf1b507819c1121f0bf87fa37eb19daac6aff3aefefd4e6e2e0f2020fc" [[package]] name = "zip" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080" +checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef" dependencies = [ "byteorder", "crc32fast", diff --git a/Cargo.toml b/Cargo.toml index 05e027b580..e29ef22337 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -329,7 +329,7 @@ walkdir = "2.2" winapi-util = "0.1.5" windows-sys = { version="0.42.0", default-features=false } xattr = "0.2.3" -zip = { version = "0.6.3", default_features=false, features=["deflate"] } +zip = { version = "0.6.4", default_features=false, features=["deflate"] } hex = "0.4.3" md-5 = "0.10.5" From f223629382f290d430cd329343347b70d5d42141 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 19:24:30 +0000 Subject: [PATCH 029/477] fix(deps): update rust crate itertools to 0.10.5 --- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ea64bb5ac7..4fe81bd0b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -288,7 +288,7 @@ glob = "0.3.0" half = "2.1" indicatif = "0.17" is-terminal = "0.4.5" -itertools = "0.10.0" +itertools = "0.10.5" libc = "0.2.139" lscolors = { version = "0.13.0", default-features=false, features = ["nu-ansi-term"] } memchr = "2" diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 4ca3941db7..917d432ff7 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -25,7 +25,7 @@ dunce = "1.0.3" wild = "2.0" glob = "0.3.0" # * optional -itertools = { version="0.10.0", optional=true } +itertools = { version="0.10.5", optional=true } thiserror = { workspace=true, optional=true } time = { workspace=true, optional=true, features = ["formatting", "local-offset", "macros"] } # * "problem" dependencies (pinned) From e433dabed42a4e87cdc80038fb0627c10d8423d5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 19:26:18 +0000 Subject: [PATCH 030/477] chore(deps): update rust crate byteorder to 1.4.3 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index ea64bb5ac7..c9ad7fb8f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -267,7 +267,7 @@ bigdecimal = "0.3" binary-heap-plus = "0.5.0" bstr = "1.0" bytecount = "0.6.3" -byteorder = "1.3.2" +byteorder = "1.4.3" chrono = { version="^0.4.24", default-features=false, features=["std", "alloc", "clock"]} clap = { version = "4.1", features = ["wrap_help", "cargo"] } clap_complete = "4.0" From 830f2b8eee16ca6341e0f08255387b2b902d8c93 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 19:28:39 +0000 Subject: [PATCH 031/477] chore(deps): update rust crate clap_complete to 4.1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eba2769e93..41c90b611f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -240,9 +240,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.0.6" +version = "4.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b3c9eae0de7bf8e3f904a5e40612b21fb2e2e566456d177809a48b892d24da" +checksum = "37686beaba5ac9f3ab01ee3172f792fc6ffdd685bfb9e63cfef02c0571a4e8e1" dependencies = [ "clap", ] diff --git a/Cargo.toml b/Cargo.toml index 05e027b580..4e7eb51862 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -270,7 +270,7 @@ bytecount = "0.6.3" byteorder = "1.3.2" chrono = { version="^0.4.24", default-features=false, features=["std", "alloc", "clock"]} clap = { version = "4.1", features = ["wrap_help", "cargo"] } -clap_complete = "4.0" +clap_complete = "4.1" clap_mangen = "0.2" compare = "0.1.0" coz = { version = "0.1.3" } From f7ff0d45b87d80f9d2b28b726a13b987f08fbb8c Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 27 Mar 2023 19:57:35 +0200 Subject: [PATCH 032/477] du: Update the GNU error message to our for tests/du/threshold.sh We are doing a better job. Make it FAIL => PASS --- util/build-gnu.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/build-gnu.sh b/util/build-gnu.sh index dad9708663..e7637ff942 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -224,3 +224,5 @@ sed -i -e "s/\$prog: multiple field specifications/error: The argument '--field # GNU doesn't support width > INT_MAX # disable these test cases sed -i -E "s|^([^#]*2_31.*)$|#\1|g" tests/misc/printf-cov.pl + +sed -i -e "s/du: invalid -t argument/du: invalid --threshold argument/" -e "s/du: option requires an argument/error: a value is required for '--threshold ' but none was supplied/" -e "/Try 'du --help' for more information./d" tests/du/threshold.sh From 9d83c06fd246869b96571fc6983be3ce2c6b8bf5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 21:24:21 +0000 Subject: [PATCH 033/477] chore(deps): update rust crate ctrlc to 3.2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 05e027b580..9b6403dbae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -275,7 +275,7 @@ clap_mangen = "0.2" compare = "0.1.0" coz = { version = "0.1.3" } crossterm = ">=0.19" -ctrlc = { version = "3.0", features = ["termination"] } +ctrlc = { version = "3.2", features = ["termination"] } exacl = "0.9.0" file_diff = "1.0.0" filetime = "0.2" From 44df670fa3dd695fa23918d1c0e289380fcc2e1c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 05:53:55 +0000 Subject: [PATCH 034/477] chore(deps): update rust crate fs_extra to 1.3.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5320e669aa..009870caaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -280,7 +280,7 @@ exacl = "0.9.0" file_diff = "1.0.0" filetime = "0.2" fnv = "1.0.7" -fs_extra = "1.1.0" +fs_extra = "1.3.0" fts-sys = "0.2" fundu = "0.4.3" gcd = "2.2" From 915c183ff80f50e8cbf2ab5f53d5ac2d16b5f49b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 06:02:04 +0000 Subject: [PATCH 035/477] fix(deps): update rust crate libc to 0.2.140 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f90100d8ae..d7599ffd38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1222,9 +1222,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "libloading" diff --git a/Cargo.toml b/Cargo.toml index 3c7f99c607..3d343efd9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -289,7 +289,7 @@ half = "2.1" indicatif = "0.17" is-terminal = "0.4.5" itertools = "0.10.5" -libc = "0.2.139" +libc = "0.2.140" lscolors = { version = "0.13.0", default-features=false, features = ["nu-ansi-term"] } memchr = "2" nix = { version="0.26", default-features=false } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 8c0f2a6f0e..1987bac538 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -32,7 +32,7 @@ time = { workspace=true, optional=true, features = ["formatting", "local-offset" data-encoding = { version="2.1", optional=true } data-encoding-macro = { version="0.1.12", optional=true } z85 = { version="3.0.5", optional=true } -libc = { version="0.2.137", optional=true } +libc = { version="0.2.140", optional=true } once_cell = { workspace=true } os_display = "0.1.3" From 67c482ea160cc84a4df390a8da6c5aedadcb94d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 06:07:57 +0000 Subject: [PATCH 036/477] chore(deps): update rust crate notify to v5.1.0 --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1e27eab1a..b58106bc21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1369,9 +1369,9 @@ dependencies = [ [[package]] name = "notify" -version = "5.0.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2c66da08abae1c024c01d635253e402341b4060a12e99b31c7594063bf490a" +checksum = "58ea850aa68a06e48fdb069c0ec44d0d64c8dbffa49bf3b6f7f0a901fdea1ba9" dependencies = [ "bitflags", "crossbeam-channel", @@ -1382,7 +1382,7 @@ dependencies = [ "libc", "mio", "walkdir", - "winapi", + "windows-sys 0.42.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a74f3d5978..5a6fb24833 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -294,7 +294,7 @@ lscolors = { version = "0.13.0", default-features=false, features = ["nu-ansi-te memchr = "2" nix = { version="0.26", default-features=false } nom = "7.1.3" -notify = { version = "=5.0.0", features=["macos_kqueue"]} +notify = { version = "=5.1.0", features=["macos_kqueue"]} num_cpus = "1.14" num-bigint = "0.4.3" num-traits = "0.2.15" From 5e3d9015927785a70f698feef9d82bd8c53cda6f Mon Sep 17 00:00:00 2001 From: Miles Liu Date: Tue, 28 Mar 2023 11:13:21 +0800 Subject: [PATCH 037/477] CI: linting and formatting checks for FreeBSD --- .github/workflows/freebsd.yml | 100 +++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 3 deletions(-) diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml index b8d9ba0263..2ff1674348 100644 --- a/.github/workflows/freebsd.yml +++ b/.github/workflows/freebsd.yml @@ -1,5 +1,11 @@ name: FreeBSD +# spell-checker:ignore sshfs usesh vmactions + +env: + # * style job configuration + STYLE_FAIL_ON_FAULT: true ## (bool) fail the build if a style job contains a fault (error or warning); may be overridden on a per-job basis + on: [push, pull_request] permissions: @@ -11,8 +17,97 @@ concurrency: cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} jobs: - test_freebsd: - name: Tests/FreeBSD test suite + style: + name: Style and Lint + runs-on: ${{ matrix.job.os }} + timeout-minutes: 90 + strategy: + fail-fast: false + matrix: + job: + - { os: macos-12 , features: unix } ## GHA MacOS-11.0 VM won't have VirtualBox; refs: , + env: + SCCACHE_GHA_ENABLED: "true" + RUSTC_WRAPPER: "sccache" + steps: + - uses: actions/checkout@v3 + - uses: Swatinem/rust-cache@v2 + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.3 + - name: Prepare, build and test + uses: vmactions/freebsd-vm@v0.3.0 + with: + usesh: true + # We need jq to run show-utils.sh and bash to use inline shell string replacement + prepare: pkg install -y curl sudo jq bash + run: | + ## Prepare, build, and test + # implementation modelled after ref: + # * NOTE: All steps need to be run in this block, otherwise, we are operating back on the mac host + set -e + # + TEST_USER=tester + REPO_NAME=${GITHUB_WORKSPACE##*/} + WORKSPACE_PARENT="/Users/runner/work/${REPO_NAME}" + WORKSPACE="${WORKSPACE_PARENT}/${REPO_NAME}" + # + pw adduser -n ${TEST_USER} -d /root/ -g wheel -c "Coreutils user to build" -w random + chown -R ${TEST_USER}:wheel /root/ "/Users/runner/work/${REPO_NAME}"/ + whoami + # + # Further work needs to be done in a sudo as we are changing users + sudo -i -u ${TEST_USER} bash << EOF + set -e + whoami + curl https://sh.rustup.rs -sSf --output rustup.sh + sh rustup.sh -y -c rustfmt,clippy --profile=minimal -t stable + . ${HOME}/.cargo/env + ## VARs setup + cd "${WORKSPACE}" + unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in + ''|0|f|false|n|no|off) FAULT_TYPE=warning ;; + *) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;; + esac; + FAULT_PREFIX=\$(echo "\${FAULT_TYPE}" | tr '[:lower:]' '[:upper:]') + # * determine sub-crate utility list + UTILITY_LIST="\$(./util/show-utils.sh --features ${{ matrix.job.features }})" + CARGO_UTILITY_LIST_OPTIONS="\$(for u in \${UTILITY_LIST}; do echo -n "-puu_\${u} "; done;)" + ## Info + # environment + echo "## environment" + echo "CI='${CI}'" + echo "REPO_NAME='${REPO_NAME}'" + echo "TEST_USER='${TEST_USER}'" + echo "WORKSPACE_PARENT='${WORKSPACE_PARENT}'" + echo "WORKSPACE='${WORKSPACE}'" + echo "FAULT_PREFIX='\${FAULT_PREFIX}'" + echo "UTILITY_LIST='\${UTILITY_LIST}'" + env | sort + # tooling info + echo "## tooling info" + cargo -V + rustc -V + # + # To ensure that files are cleaned up, we don't want to exit on error + set +e + unset FAULT + ## cargo fmt testing + echo "## cargo fmt testing" + # * convert any errors/warnings to GHA UI annotations; ref: + S=\$(cargo fmt -- --check) && printf "%s\n" "\$S" || { printf "%s\n" "\$S" ; printf "%s\n" "\$S" | sed -E -n -e "s/^Diff[[:space:]]+in[[:space:]]+\${PWD//\//\\\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*\$/::\${FAULT_TYPE} file=\1,line=\2::\${FAULT_PREFIX}: \\\`cargo fmt\\\`: style violation (file:'\1', line:\2; use \\\`cargo fmt -- \"\1\"\\\`)/p" ; FAULT=true ; } + ## cargo clippy lint testing + if [ -z "\${FAULT}" ]; then + echo "## cargo clippy lint testing" + # * convert any warnings to GHA UI annotations; ref: + S=\$(cargo clippy --all-targets \${CARGO_UTILITY_LIST_OPTIONS} -- -W clippy::manual_string_new -D warnings 2>&1) && printf "%s\n" "\$S" || { printf "%s\n" "\$S" ; printf "%s" "\$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*\$/::\${FAULT_TYPE} file=\2,line=\3,col=\4::\${FAULT_PREFIX}: \\\`cargo clippy\\\`: \1 (file:'\2', line:\3)/p;" -e '}' ; FAULT=true ; } + fi + # Clean to avoid to rsync back the files + cargo clean + if [ -n "\${FAIL_ON_FAULT}" ] && [ -n "\${FAULT}" ]; then exit 1 ; fi + EOF + + test: + name: Tests runs-on: ${{ matrix.job.os }} timeout-minutes: 90 strategy: @@ -30,7 +125,6 @@ jobs: - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - name: Prepare, build and test - ## spell-checker:ignore (ToDO) sshfs usesh vmactions uses: vmactions/freebsd-vm@v0.3.0 with: usesh: true From c2068f55938b80d83e9ce618934effd770c498c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 08:12:49 +0000 Subject: [PATCH 038/477] chore(deps): update rust crate crossterm to >=0.26.1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1e27eab1a..25ca1e044b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -579,9 +579,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" dependencies = [ "bitflags", "crossterm_winapi", diff --git a/Cargo.toml b/Cargo.toml index 9cf08533b7..09cea4255b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -274,7 +274,7 @@ clap_complete = "4.1" clap_mangen = "0.2" compare = "0.1.0" coz = { version = "0.1.3" } -crossterm = ">=0.19" +crossterm = ">=0.26.1" ctrlc = { version = "3.2", features = ["termination"] } exacl = "0.9.0" file_diff = "1.0.0" From 10be042bab4ed6ee8d9b68171fb5aa1bc82d82f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 08:14:38 +0000 Subject: [PATCH 039/477] chore(deps): update rust crate exacl to 0.10.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1e27eab1a..835f5970b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -800,9 +800,9 @@ dependencies = [ [[package]] name = "exacl" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129c7b60e19ea8393c47b2110f8e3cea800530fd962380ef110d1fef6591faee" +checksum = "1cfeb22a59deb24c3262c43ffcafd1eb807180f371f9fcc99098d181b5d639be" dependencies = [ "bitflags", "log", diff --git a/Cargo.toml b/Cargo.toml index 9cf08533b7..b044cc11ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -276,7 +276,7 @@ compare = "0.1.0" coz = { version = "0.1.3" } crossterm = ">=0.19" ctrlc = { version = "3.2", features = ["termination"] } -exacl = "0.9.0" +exacl = "0.10.0" file_diff = "1.0.0" filetime = "0.2" fnv = "1.0.7" From aa4043467570594c4f66b4dbc2dcadf13aac9f73 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 08:16:37 +0000 Subject: [PATCH 040/477] chore(deps): update rust crate once_cell to 1.17.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9cf08533b7..4ec1c0df5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -299,7 +299,7 @@ num_cpus = "1.14" num-bigint = "0.4.3" num-traits = "0.2.15" number_prefix = "0.4" -once_cell = "1.13.1" +once_cell = "1.17.1" onig = { version = "~6.4", default-features = false } ouroboros = "0.15.6" phf = "0.11.1" From e69e3ec16f6982be1c600b3e32161930da818521 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 12:50:30 +0000 Subject: [PATCH 041/477] chore(deps): update rust crate gcd to 2.3 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ddc64fd94..bc2e23411c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -981,9 +981,9 @@ dependencies = [ [[package]] name = "gcd" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1b088ad0a967aa29540456b82fc8903f854775d33f71e9709c4efb3dfbfd2" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" [[package]] name = "generic-array" diff --git a/Cargo.toml b/Cargo.toml index 3010ae078e..f5f4d6d288 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -283,7 +283,7 @@ fnv = "1.0.7" fs_extra = "1.1.0" fts-sys = "0.2" fundu = "0.4.3" -gcd = "2.2" +gcd = "2.3" glob = "0.3.1" half = "2.1" indicatif = "0.17" From 00e126b63e9859919350ef91c54683cb4f7fac6a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 12:52:17 +0000 Subject: [PATCH 042/477] chore(deps): update rust crate half to 2.2 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ddc64fd94..0e57f8b112 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1014,9 +1014,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "half" -version = "2.1.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554" +checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" dependencies = [ "crunchy", ] diff --git a/Cargo.toml b/Cargo.toml index 3010ae078e..4e34315c59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -285,7 +285,7 @@ fts-sys = "0.2" fundu = "0.4.3" gcd = "2.2" glob = "0.3.1" -half = "2.1" +half = "2.2" indicatif = "0.17" is-terminal = "0.4.5" itertools = "0.10.5" From 634fdcf9b1543f006f9e51b3d28533bb943c8a40 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 28 Mar 2023 21:23:51 +0200 Subject: [PATCH 043/477] Remove android from the job name (as it is now a workspace) --- .github/workflows/android.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index c5489919eb..059fe6d814 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -12,7 +12,7 @@ concurrency: jobs: test_android: - name: Test Android builds + name: Test builds runs-on: macos-latest timeout-minutes: 90 strategy: @@ -56,7 +56,7 @@ jobs: adb -s emulator-5554 emu avd snapshot save ${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }} echo "Emulator image created." pkill -9 qemu-system-x86_64 - - name: Build and Test on Android + - name: Build and Test uses: reactivecircus/android-emulator-runner@v2 with: api-level: ${{ matrix.api-level }} From d29f9f2e300fe768b635faec30b1758adb55f2bc Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 28 Mar 2023 22:46:59 +0200 Subject: [PATCH 044/477] dircolors: trigger an error when used on / --- src/uu/dircolors/src/dircolors.rs | 19 +++++++++++++++---- tests/by-util/test_dircolors.rs | 10 ++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index abab966afc..e960fdb138 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -12,6 +12,7 @@ use std::borrow::Borrow; use std::env; use std::fs::File; use std::io::{BufRead, BufReader}; +use std::path::Path; use clap::{crate_version, Arg, ArgAction, Command}; use uucore::display::Quotable; @@ -42,7 +43,6 @@ pub enum OutputFmt { } pub fn guess_syntax() -> OutputFmt { - use std::path::Path; match env::var("SHELL") { Ok(ref s) if !s.is_empty() => { let shell_path: &Path = s.as_ref(); @@ -138,15 +138,26 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let fin = BufReader::new(std::io::stdin()); result = parse(fin.lines().filter_map(Result::ok), &out_format, files[0]); } else { - match File::open(files[0]) { + let path = Path::new(files[0]); + if path.is_dir() { + return Err(USimpleError::new( + 2, + format!("expected file, got directory {}", path.quote()), + )); + } + match File::open(path) { Ok(f) => { let fin = BufReader::new(f); - result = parse(fin.lines().filter_map(Result::ok), &out_format, files[0]); + result = parse( + fin.lines().filter_map(Result::ok), + &out_format, + &path.to_string_lossy(), + ); } Err(e) => { return Err(USimpleError::new( 1, - format!("{}: {}", files[0].maybe_quote(), e), + format!("{}: {}", path.maybe_quote(), e), )); } } diff --git a/tests/by-util/test_dircolors.rs b/tests/by-util/test_dircolors.rs index 629a10912d..d2ec32f337 100644 --- a/tests/by-util/test_dircolors.rs +++ b/tests/by-util/test_dircolors.rs @@ -221,3 +221,13 @@ fn test_helper(file_name: &str, term: &str) { .run() .stdout_is_fixture(format!("{file_name}.sh.expected")); } + +#[test] +fn test_dircolors_for_dir_as_file() { + let result = new_ucmd!().args(&["-c", "/"]).fails(); + result.no_stdout(); + assert_eq!( + result.stderr_str().trim(), + "dircolors: expected file, got directory '/'", + ); +} From e7ef9dcd4676ca231bc4e5ce9c6afb684a78cf17 Mon Sep 17 00:00:00 2001 From: 0xMRTT <0xMRTT@proton.me> Date: Tue, 28 Mar 2023 23:26:11 +0200 Subject: [PATCH 045/477] `hashsum`: add `--zero` option (#4612) (#4632) * `hashsum`: add `--zero` option (#4612) --- src/uu/hashsum/src/hashsum.rs | 12 ++++++++++++ tests/by-util/test_hashsum.rs | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index d7e55e5673..460ab6f195 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -47,6 +47,7 @@ struct Options { strict: bool, warn: bool, output_bits: usize, + zero: bool, } #[allow(clippy::cognitive_complexity)] @@ -269,6 +270,7 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> { let quiet = matches.get_flag("quiet") || status; let strict = matches.get_flag("strict"); let warn = matches.get_flag("warn") && !status; + let zero = matches.get_flag("zero"); let opts = Options { algoname: name, @@ -282,6 +284,7 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> { quiet, strict, warn, + zero, }; match matches.get_many::("FILE") { @@ -359,6 +362,13 @@ pub fn uu_app_common() -> Command { .help("warn about improperly formatted checksum lines") .action(ArgAction::SetTrue), ) + .arg( + Arg::new("zero") + .short('z') + .long("zero") + .help("end each output line with NUL, not newline") + .action(ArgAction::SetTrue), + ) .arg( Arg::new("FILE") .index(1) @@ -613,6 +623,8 @@ where println!("{} ({}) = {}", options.algoname, filename.display(), sum); } else if options.nonames { println!("{sum}"); + } else if options.zero { + print!("{} {}{}\0", sum, binary_marker, filename.display()); } else { println!("{} {}{}", sum, binary_marker, filename.display()); } diff --git a/tests/by-util/test_hashsum.rs b/tests/by-util/test_hashsum.rs index 3d3d72c4ca..a227b9fc31 100644 --- a/tests/by-util/test_hashsum.rs +++ b/tests/by-util/test_hashsum.rs @@ -53,6 +53,14 @@ macro_rules! test_digest { .stdout_is("input.txt: OK\n"); } + #[test] + fn test_zero() { + let ts = TestScenario::new("hashsum"); + assert_eq!(ts.fixtures.read(EXPECTED_FILE), + get_hash!(ts.ucmd().arg(DIGEST_ARG).arg(BITS_ARG).arg("--zero").arg("input.txt").succeeds().no_stderr().stdout_str())); + } + + #[cfg(windows)] #[test] fn test_text_mode() { From 206e4144bb10923454becb23251e08f5caf96581 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 05:17:11 +0000 Subject: [PATCH 046/477] chore(deps): update rust crate is-terminal to 0.4.6 --- Cargo.lock | 47 +++++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 2 +- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d57d0ffeca..2f94303baa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -788,6 +788,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "errno" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.45.0", +] + [[package]] name = "errno-dragonfly" version = "0.1.2" @@ -1145,13 +1156,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" +checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", - "rustix", + "rustix 0.37.3", "windows-sys 0.45.0", ] @@ -1251,6 +1262,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +[[package]] +name = "linux-raw-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd550e73688e6d578f0ac2119e32b797a327631a42f9433e59d02e139c8df60d" + [[package]] name = "lock_api" version = "0.4.9" @@ -1703,7 +1720,7 @@ dependencies = [ "byteorder", "hex", "lazy_static", - "rustix", + "rustix 0.36.8", ] [[package]] @@ -1904,10 +1921,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" dependencies = [ "bitflags", - "errno", + "errno 0.2.8", + "io-lifetimes", + "libc", + "linux-raw-sys 0.1.4", + "windows-sys 0.45.0", +] + +[[package]] +name = "rustix" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" +dependencies = [ + "bitflags", + "errno 0.3.0", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.0", "windows-sys 0.45.0", ] @@ -2122,7 +2153,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall", - "rustix", + "rustix 0.36.8", "windows-sys 0.42.0", ] @@ -2150,7 +2181,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c9afddd2cec1c0909f06b00ef33f94ab2cc0578c4a610aa208ddfec8aa2b43a" dependencies = [ - "rustix", + "rustix 0.36.8", "windows-sys 0.45.0", ] diff --git a/Cargo.toml b/Cargo.toml index 029549ea55..ba39c264a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -287,7 +287,7 @@ gcd = "2.2" glob = "0.3.1" half = "2.1" indicatif = "0.17" -is-terminal = "0.4.5" +is-terminal = "0.4.6" itertools = "0.10.5" libc = "0.2.139" lscolors = { version = "0.13.0", default-features=false, features = ["nu-ansi-term"] } From 5786d78c5969e1c760c82f85d3407be631d09b2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 05:19:47 +0000 Subject: [PATCH 047/477] chore(deps): update rust crate clap to 4.2 --- Cargo.lock | 91 +++++++++++++++++++++++++++++++++++++++++++++--------- Cargo.toml | 2 +- 2 files changed, 77 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d784f7c581..a9586ad661 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,46 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-wincon", + "concolor-override", + "concolor-query", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" + +[[package]] +name = "anstyle-parse" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-wincon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +dependencies = [ + "anstyle", + "windows-sys 0.45.0", +] + [[package]] name = "arrayref" version = "0.3.6" @@ -225,16 +265,25 @@ dependencies = [ [[package]] name = "clap" -version = "4.1.13" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6efb5f0a41b5ef5b50c5da28c07609c20091df0c1fc33d418fa2a7e693c2b624" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c911b090850d79fc64fe9ea01e28e465f65e821e08813ced95bced72f7a8a9b" +checksum = "671fcaa5debda4b9a84aa7fde49c907c8986c0e6ab927e04217c9cb74e7c8bc9" dependencies = [ + "anstream", + "anstyle", "bitflags", "clap_lex", - "is-terminal", "once_cell", "strsim", - "termcolor", "terminal_size", ] @@ -249,12 +298,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" [[package]] name = "clap_mangen" @@ -282,6 +328,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "120133d4db2ec47efe2e26502ee984747630c67f51974fca0b6c1340cf2368d3" +[[package]] +name = "concolor-override" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" + +[[package]] +name = "concolor-query" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" +dependencies = [ + "windows-sys 0.45.0", +] + [[package]] name = "console" version = "0.15.5" @@ -1497,12 +1558,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "os_str_bytes" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - [[package]] name = "ouroboros" version = "0.15.6" @@ -2277,6 +2332,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "uu_arch" version = "0.0.17" diff --git a/Cargo.toml b/Cargo.toml index 8a5894752c..42ff2b8e15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -269,7 +269,7 @@ bstr = "1.4" bytecount = "0.6.3" byteorder = "1.4.3" chrono = { version="^0.4.24", default-features=false, features=["std", "alloc", "clock"]} -clap = { version = "4.1", features = ["wrap_help", "cargo"] } +clap = { version = "4.2", features = ["wrap_help", "cargo"] } clap_complete = "4.1" clap_mangen = "0.2" compare = "0.1.0" From b14d19770f84660e56753f8c37b11f3854357d90 Mon Sep 17 00:00:00 2001 From: Surya Teja K Date: Wed, 29 Mar 2023 11:19:14 +0530 Subject: [PATCH 048/477] date: show error when reading dirs for -f arg (#4572) Co-authored-by: Sylvestre Ledru --- src/uu/date/src/date.rs | 20 ++++++++++---------- tests/by-util/test_date.rs | 10 ++++++++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index 667eafe816..ab874cb32e 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -19,7 +19,7 @@ use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::PathBuf; use uucore::display::Quotable; -#[cfg(not(any(target_os = "macos", target_os = "redox")))] +#[cfg(not(any(target_os = "redox")))] use uucore::error::FromIo; use uucore::error::{UResult, USimpleError}; use uucore::{format_usage, help_about, help_usage, show}; @@ -219,19 +219,19 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let iter = std::iter::once(date); Box::new(iter) } - DateSource::File(ref path) => match File::open(path) { - Ok(file) => { - let lines = BufReader::new(file).lines(); - let iter = lines.filter_map(Result::ok).map(parse_date); - Box::new(iter) - } - Err(_err) => { + DateSource::File(ref path) => { + if path.is_dir() { return Err(USimpleError::new( 2, - format!("{}: No such file or directory", path.display()), + format!("expected file, got directory {}", path.quote()), )); } - }, + let file = File::open(path) + .map_err_context(|| path.as_os_str().to_string_lossy().to_string())?; + let lines = BufReader::new(file).lines(); + let iter = lines.map_while(Result::ok).map(parse_date); + Box::new(iter) + } DateSource::Now => { let iter = std::iter::once(Ok(now)); Box::new(iter) diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index 7e9c52af5c..d099671549 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -283,6 +283,16 @@ fn test_date_for_invalid_file() { ); } +#[test] +fn test_date_for_dir_as_file() { + let result = new_ucmd!().arg("--file").arg("/").fails(); + result.no_stdout(); + assert_eq!( + result.stderr_str().trim(), + "date: expected file, got directory '/'", + ); +} + #[test] fn test_date_for_file() { let (at, mut ucmd) = at_and_ucmd!(); From b0ebf590ff924db87c89db2a7d1c8d45c8c245e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 05:56:28 +0000 Subject: [PATCH 049/477] chore(deps): update rust crate num_cpus to 1.15 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d0a2c3ed94..0cf1bba0c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -295,7 +295,7 @@ memchr = "2" nix = { version="0.26", default-features=false } nom = "7.1.3" notify = { version = "=5.1.0", features=["macos_kqueue"]} -num_cpus = "1.14" +num_cpus = "1.15" num-bigint = "0.4.3" num-traits = "0.2.15" number_prefix = "0.4" From 74d4cf26374ba5f2c3bc1f5f7f5bbdc6d78929d3 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 27 Mar 2023 16:52:30 +0200 Subject: [PATCH 050/477] CICD: remove "continue-on-error" in fuzz_date step --- .github/workflows/CICD.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 0eeb948615..54ada97605 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -145,8 +145,6 @@ jobs: - name: Install `cargo-fuzz` run: cargo install cargo-fuzz - name: Run fuzz_date for XX seconds - # TODO: fix https://github.com/uutils/coreutils/issues/4494 - continue-on-error: true shell: bash run: | ## Run it From af0a2631911629d6d625d5159f628cdf4902730f Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 25 Mar 2023 20:26:03 +0100 Subject: [PATCH 051/477] 0.0.17 => 0.0.18 --- Cargo.lock | 214 ++++++++++++------------ Cargo.toml | 216 ++++++++++++------------- src/uu/arch/Cargo.toml | 2 +- src/uu/base32/Cargo.toml | 2 +- src/uu/base64/Cargo.toml | 2 +- src/uu/basename/Cargo.toml | 2 +- src/uu/basenc/Cargo.toml | 2 +- src/uu/cat/Cargo.toml | 2 +- src/uu/chcon/Cargo.toml | 2 +- src/uu/chgrp/Cargo.toml | 2 +- src/uu/chmod/Cargo.toml | 2 +- src/uu/chown/Cargo.toml | 2 +- src/uu/chroot/Cargo.toml | 2 +- src/uu/cksum/Cargo.toml | 2 +- src/uu/comm/Cargo.toml | 2 +- src/uu/cp/Cargo.toml | 2 +- src/uu/csplit/Cargo.toml | 2 +- src/uu/cut/Cargo.toml | 2 +- src/uu/date/Cargo.toml | 2 +- src/uu/dd/Cargo.toml | 2 +- src/uu/df/Cargo.toml | 2 +- src/uu/dir/Cargo.toml | 2 +- src/uu/dircolors/Cargo.toml | 2 +- src/uu/dirname/Cargo.toml | 2 +- src/uu/du/Cargo.toml | 2 +- src/uu/echo/Cargo.toml | 2 +- src/uu/env/Cargo.toml | 2 +- src/uu/expand/Cargo.toml | 2 +- src/uu/expr/Cargo.toml | 2 +- src/uu/factor/Cargo.toml | 2 +- src/uu/false/Cargo.toml | 2 +- src/uu/fmt/Cargo.toml | 2 +- src/uu/fold/Cargo.toml | 2 +- src/uu/groups/Cargo.toml | 2 +- src/uu/hashsum/Cargo.toml | 2 +- src/uu/head/Cargo.toml | 2 +- src/uu/hostid/Cargo.toml | 2 +- src/uu/hostname/Cargo.toml | 2 +- src/uu/id/Cargo.toml | 2 +- src/uu/install/Cargo.toml | 2 +- src/uu/join/Cargo.toml | 2 +- src/uu/kill/Cargo.toml | 2 +- src/uu/link/Cargo.toml | 2 +- src/uu/ln/Cargo.toml | 2 +- src/uu/logname/Cargo.toml | 2 +- src/uu/ls/Cargo.toml | 2 +- src/uu/mkdir/Cargo.toml | 2 +- src/uu/mkfifo/Cargo.toml | 2 +- src/uu/mknod/Cargo.toml | 2 +- src/uu/mktemp/Cargo.toml | 2 +- src/uu/more/Cargo.toml | 2 +- src/uu/mv/Cargo.toml | 2 +- src/uu/nice/Cargo.toml | 2 +- src/uu/nl/Cargo.toml | 2 +- src/uu/nohup/Cargo.toml | 2 +- src/uu/nproc/Cargo.toml | 2 +- src/uu/numfmt/Cargo.toml | 2 +- src/uu/od/Cargo.toml | 2 +- src/uu/paste/Cargo.toml | 2 +- src/uu/pathchk/Cargo.toml | 2 +- src/uu/pinky/Cargo.toml | 2 +- src/uu/pr/Cargo.toml | 2 +- src/uu/printenv/Cargo.toml | 2 +- src/uu/printf/Cargo.toml | 2 +- src/uu/ptx/Cargo.toml | 2 +- src/uu/pwd/Cargo.toml | 2 +- src/uu/readlink/Cargo.toml | 2 +- src/uu/realpath/Cargo.toml | 2 +- src/uu/relpath/Cargo.toml | 2 +- src/uu/rm/Cargo.toml | 2 +- src/uu/rmdir/Cargo.toml | 2 +- src/uu/runcon/Cargo.toml | 2 +- src/uu/seq/Cargo.toml | 2 +- src/uu/shred/Cargo.toml | 2 +- src/uu/shuf/Cargo.toml | 2 +- src/uu/sleep/Cargo.toml | 2 +- src/uu/sort/Cargo.toml | 2 +- src/uu/split/Cargo.toml | 2 +- src/uu/stat/Cargo.toml | 2 +- src/uu/stdbuf/Cargo.toml | 4 +- src/uu/stdbuf/src/libstdbuf/Cargo.toml | 4 +- src/uu/stty/Cargo.toml | 2 +- src/uu/sum/Cargo.toml | 2 +- src/uu/sync/Cargo.toml | 2 +- src/uu/tac/Cargo.toml | 2 +- src/uu/tail/Cargo.toml | 2 +- src/uu/tee/Cargo.toml | 2 +- src/uu/test/Cargo.toml | 2 +- src/uu/timeout/Cargo.toml | 2 +- src/uu/touch/Cargo.toml | 2 +- src/uu/tr/Cargo.toml | 2 +- src/uu/true/Cargo.toml | 2 +- src/uu/truncate/Cargo.toml | 2 +- src/uu/tsort/Cargo.toml | 2 +- src/uu/tty/Cargo.toml | 2 +- src/uu/uname/Cargo.toml | 2 +- src/uu/unexpand/Cargo.toml | 2 +- src/uu/uniq/Cargo.toml | 2 +- src/uu/unlink/Cargo.toml | 2 +- src/uu/uptime/Cargo.toml | 2 +- src/uu/users/Cargo.toml | 2 +- src/uu/vdir/Cargo.toml | 2 +- src/uu/wc/Cargo.toml | 2 +- src/uu/who/Cargo.toml | 2 +- src/uu/whoami/Cargo.toml | 2 +- src/uu/yes/Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- src/uucore_procs/Cargo.toml | 2 +- util/update-version.sh | 4 +- 109 files changed, 325 insertions(+), 325 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a54d02abe7..261f1b3e78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -318,7 +318,7 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "coreutils" -version = "0.0.17" +version = "0.0.18" dependencies = [ "chrono", "clap", @@ -2279,7 +2279,7 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uu_arch" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "platform-info", @@ -2288,7 +2288,7 @@ dependencies = [ [[package]] name = "uu_base32" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2296,7 +2296,7 @@ dependencies = [ [[package]] name = "uu_base64" -version = "0.0.17" +version = "0.0.18" dependencies = [ "uu_base32", "uucore", @@ -2304,7 +2304,7 @@ dependencies = [ [[package]] name = "uu_basename" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2312,7 +2312,7 @@ dependencies = [ [[package]] name = "uu_basenc" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uu_base32", @@ -2321,7 +2321,7 @@ dependencies = [ [[package]] name = "uu_cat" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "is-terminal", @@ -2332,7 +2332,7 @@ dependencies = [ [[package]] name = "uu_chcon" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "fts-sys", @@ -2344,7 +2344,7 @@ dependencies = [ [[package]] name = "uu_chgrp" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2352,7 +2352,7 @@ dependencies = [ [[package]] name = "uu_chmod" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2361,7 +2361,7 @@ dependencies = [ [[package]] name = "uu_chown" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2369,7 +2369,7 @@ dependencies = [ [[package]] name = "uu_chroot" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2377,7 +2377,7 @@ dependencies = [ [[package]] name = "uu_cksum" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "hex", @@ -2386,7 +2386,7 @@ dependencies = [ [[package]] name = "uu_comm" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2394,7 +2394,7 @@ dependencies = [ [[package]] name = "uu_cp" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "exacl", @@ -2410,7 +2410,7 @@ dependencies = [ [[package]] name = "uu_csplit" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "regex", @@ -2420,7 +2420,7 @@ dependencies = [ [[package]] name = "uu_cut" -version = "0.0.17" +version = "0.0.18" dependencies = [ "bstr", "clap", @@ -2431,7 +2431,7 @@ dependencies = [ [[package]] name = "uu_date" -version = "0.0.17" +version = "0.0.18" dependencies = [ "chrono", "clap", @@ -2442,7 +2442,7 @@ dependencies = [ [[package]] name = "uu_dd" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "gcd", @@ -2453,7 +2453,7 @@ dependencies = [ [[package]] name = "uu_df" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "unicode-width", @@ -2462,7 +2462,7 @@ dependencies = [ [[package]] name = "uu_dir" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uu_ls", @@ -2471,7 +2471,7 @@ dependencies = [ [[package]] name = "uu_dircolors" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2479,7 +2479,7 @@ dependencies = [ [[package]] name = "uu_dirname" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2487,7 +2487,7 @@ dependencies = [ [[package]] name = "uu_du" -version = "0.0.17" +version = "0.0.18" dependencies = [ "chrono", "clap", @@ -2498,7 +2498,7 @@ dependencies = [ [[package]] name = "uu_echo" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2506,7 +2506,7 @@ dependencies = [ [[package]] name = "uu_env" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "nix", @@ -2516,7 +2516,7 @@ dependencies = [ [[package]] name = "uu_expand" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "unicode-width", @@ -2525,7 +2525,7 @@ dependencies = [ [[package]] name = "uu_expr" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "num-bigint", @@ -2536,7 +2536,7 @@ dependencies = [ [[package]] name = "uu_factor" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "coz", @@ -2549,7 +2549,7 @@ dependencies = [ [[package]] name = "uu_false" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2557,7 +2557,7 @@ dependencies = [ [[package]] name = "uu_fmt" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "unicode-width", @@ -2566,7 +2566,7 @@ dependencies = [ [[package]] name = "uu_fold" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2574,7 +2574,7 @@ dependencies = [ [[package]] name = "uu_groups" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2582,7 +2582,7 @@ dependencies = [ [[package]] name = "uu_hashsum" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "hex", @@ -2593,7 +2593,7 @@ dependencies = [ [[package]] name = "uu_head" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "memchr", @@ -2602,7 +2602,7 @@ dependencies = [ [[package]] name = "uu_hostid" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2611,7 +2611,7 @@ dependencies = [ [[package]] name = "uu_hostname" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "hostname", @@ -2621,7 +2621,7 @@ dependencies = [ [[package]] name = "uu_id" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "selinux", @@ -2630,7 +2630,7 @@ dependencies = [ [[package]] name = "uu_install" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "file_diff", @@ -2642,7 +2642,7 @@ dependencies = [ [[package]] name = "uu_join" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "memchr", @@ -2651,7 +2651,7 @@ dependencies = [ [[package]] name = "uu_kill" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "nix", @@ -2660,7 +2660,7 @@ dependencies = [ [[package]] name = "uu_link" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2668,7 +2668,7 @@ dependencies = [ [[package]] name = "uu_ln" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2676,7 +2676,7 @@ dependencies = [ [[package]] name = "uu_logname" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2685,7 +2685,7 @@ dependencies = [ [[package]] name = "uu_ls" -version = "0.0.17" +version = "0.0.18" dependencies = [ "chrono", "clap", @@ -2703,7 +2703,7 @@ dependencies = [ [[package]] name = "uu_mkdir" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2711,7 +2711,7 @@ dependencies = [ [[package]] name = "uu_mkfifo" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2720,7 +2720,7 @@ dependencies = [ [[package]] name = "uu_mknod" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2729,7 +2729,7 @@ dependencies = [ [[package]] name = "uu_mktemp" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "rand", @@ -2739,7 +2739,7 @@ dependencies = [ [[package]] name = "uu_more" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "crossterm", @@ -2752,7 +2752,7 @@ dependencies = [ [[package]] name = "uu_mv" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "fs_extra", @@ -2762,7 +2762,7 @@ dependencies = [ [[package]] name = "uu_nice" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2772,7 +2772,7 @@ dependencies = [ [[package]] name = "uu_nl" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "regex", @@ -2781,7 +2781,7 @@ dependencies = [ [[package]] name = "uu_nohup" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "is-terminal", @@ -2791,7 +2791,7 @@ dependencies = [ [[package]] name = "uu_nproc" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2800,7 +2800,7 @@ dependencies = [ [[package]] name = "uu_numfmt" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2808,7 +2808,7 @@ dependencies = [ [[package]] name = "uu_od" -version = "0.0.17" +version = "0.0.18" dependencies = [ "byteorder", "clap", @@ -2818,7 +2818,7 @@ dependencies = [ [[package]] name = "uu_paste" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2826,7 +2826,7 @@ dependencies = [ [[package]] name = "uu_pathchk" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2835,7 +2835,7 @@ dependencies = [ [[package]] name = "uu_pinky" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2843,7 +2843,7 @@ dependencies = [ [[package]] name = "uu_pr" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "itertools", @@ -2855,7 +2855,7 @@ dependencies = [ [[package]] name = "uu_printenv" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2863,7 +2863,7 @@ dependencies = [ [[package]] name = "uu_printf" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2871,7 +2871,7 @@ dependencies = [ [[package]] name = "uu_ptx" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "regex", @@ -2880,7 +2880,7 @@ dependencies = [ [[package]] name = "uu_pwd" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2888,7 +2888,7 @@ dependencies = [ [[package]] name = "uu_readlink" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2896,7 +2896,7 @@ dependencies = [ [[package]] name = "uu_realpath" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2904,7 +2904,7 @@ dependencies = [ [[package]] name = "uu_relpath" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -2912,7 +2912,7 @@ dependencies = [ [[package]] name = "uu_rm" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2923,7 +2923,7 @@ dependencies = [ [[package]] name = "uu_rmdir" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2932,7 +2932,7 @@ dependencies = [ [[package]] name = "uu_runcon" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2943,7 +2943,7 @@ dependencies = [ [[package]] name = "uu_seq" -version = "0.0.17" +version = "0.0.18" dependencies = [ "bigdecimal", "clap", @@ -2954,7 +2954,7 @@ dependencies = [ [[package]] name = "uu_shred" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -2964,7 +2964,7 @@ dependencies = [ [[package]] name = "uu_shuf" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "memchr", @@ -2975,7 +2975,7 @@ dependencies = [ [[package]] name = "uu_sleep" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "fundu", @@ -2984,7 +2984,7 @@ dependencies = [ [[package]] name = "uu_sort" -version = "0.0.17" +version = "0.0.18" dependencies = [ "binary-heap-plus", "clap", @@ -3003,7 +3003,7 @@ dependencies = [ [[package]] name = "uu_split" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "memchr", @@ -3012,7 +3012,7 @@ dependencies = [ [[package]] name = "uu_stat" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -3020,7 +3020,7 @@ dependencies = [ [[package]] name = "uu_stdbuf" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "tempfile", @@ -3030,7 +3030,7 @@ dependencies = [ [[package]] name = "uu_stdbuf_libstdbuf" -version = "0.0.17" +version = "0.0.18" dependencies = [ "cpp", "cpp_build", @@ -3040,7 +3040,7 @@ dependencies = [ [[package]] name = "uu_stty" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "nix", @@ -3049,7 +3049,7 @@ dependencies = [ [[package]] name = "uu_sum" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -3057,7 +3057,7 @@ dependencies = [ [[package]] name = "uu_sync" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -3068,7 +3068,7 @@ dependencies = [ [[package]] name = "uu_tac" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "memchr", @@ -3079,7 +3079,7 @@ dependencies = [ [[package]] name = "uu_tail" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "fundu", @@ -3095,7 +3095,7 @@ dependencies = [ [[package]] name = "uu_tee" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -3104,7 +3104,7 @@ dependencies = [ [[package]] name = "uu_test" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -3114,7 +3114,7 @@ dependencies = [ [[package]] name = "uu_timeout" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -3124,7 +3124,7 @@ dependencies = [ [[package]] name = "uu_touch" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "filetime", @@ -3135,7 +3135,7 @@ dependencies = [ [[package]] name = "uu_tr" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "nom", @@ -3144,7 +3144,7 @@ dependencies = [ [[package]] name = "uu_true" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -3152,7 +3152,7 @@ dependencies = [ [[package]] name = "uu_truncate" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -3160,7 +3160,7 @@ dependencies = [ [[package]] name = "uu_tsort" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -3168,7 +3168,7 @@ dependencies = [ [[package]] name = "uu_tty" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "is-terminal", @@ -3178,7 +3178,7 @@ dependencies = [ [[package]] name = "uu_uname" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "platform-info", @@ -3187,7 +3187,7 @@ dependencies = [ [[package]] name = "uu_unexpand" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "unicode-width", @@ -3196,7 +3196,7 @@ dependencies = [ [[package]] name = "uu_uniq" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -3204,7 +3204,7 @@ dependencies = [ [[package]] name = "uu_unlink" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -3212,7 +3212,7 @@ dependencies = [ [[package]] name = "uu_uptime" -version = "0.0.17" +version = "0.0.18" dependencies = [ "chrono", "clap", @@ -3221,7 +3221,7 @@ dependencies = [ [[package]] name = "uu_users" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -3229,7 +3229,7 @@ dependencies = [ [[package]] name = "uu_vdir" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uu_ls", @@ -3238,7 +3238,7 @@ dependencies = [ [[package]] name = "uu_wc" -version = "0.0.17" +version = "0.0.18" dependencies = [ "bytecount", "clap", @@ -3251,7 +3251,7 @@ dependencies = [ [[package]] name = "uu_who" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "uucore", @@ -3259,7 +3259,7 @@ dependencies = [ [[package]] name = "uu_whoami" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "libc", @@ -3269,7 +3269,7 @@ dependencies = [ [[package]] name = "uu_yes" -version = "0.0.17" +version = "0.0.18" dependencies = [ "clap", "nix", @@ -3278,7 +3278,7 @@ dependencies = [ [[package]] name = "uucore" -version = "0.0.17" +version = "0.0.18" dependencies = [ "blake2b_simd", "blake3", @@ -3313,7 +3313,7 @@ dependencies = [ [[package]] name = "uucore_procs" -version = "0.0.17" +version = "0.0.18" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index d0a2c3ed94..bd344cb595 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ [package] name = "coreutils" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "coreutils ~ GNU coreutils (updated); implemented as universal (cross-platform) utils, written in Rust" @@ -341,10 +341,10 @@ blake3 = "1.3.3" sm3 = "0.4.1" digest = "0.10.6" -uucore = { version=">=0.0.17", package="uucore", path="src/uucore" } -uucore_procs = { version=">=0.0.17", package="uucore_procs", path="src/uucore_procs" } -uu_ls = { version=">=0.0.17", path="src/uu/ls" } -uu_base32 = { version=">=0.0.17", path="src/uu/base32"} +uucore = { version=">=0.0.18", package="uucore", path="src/uucore" } +uucore_procs = { version=">=0.0.18", package="uucore_procs", path="src/uucore_procs" } +uu_ls = { version=">=0.0.18", path="src/uu/ls" } +uu_base32 = { version=">=0.0.18", path="src/uu/base32"} [dependencies] clap = { workspace=true } @@ -358,110 +358,110 @@ textwrap = { workspace=true } zip = { workspace=true, optional = true } # * uutils -uu_test = { optional=true, version="0.0.17", package="uu_test", path="src/uu/test" } +uu_test = { optional=true, version="0.0.18", package="uu_test", path="src/uu/test" } # -arch = { optional=true, version="0.0.17", package="uu_arch", path="src/uu/arch" } -base32 = { optional=true, version="0.0.17", package="uu_base32", path="src/uu/base32" } -base64 = { optional=true, version="0.0.17", package="uu_base64", path="src/uu/base64" } -basename = { optional=true, version="0.0.17", package="uu_basename", path="src/uu/basename" } -basenc = { optional=true, version="0.0.17", package="uu_basenc", path="src/uu/basenc" } -cat = { optional=true, version="0.0.17", package="uu_cat", path="src/uu/cat" } -chcon = { optional=true, version="0.0.17", package="uu_chcon", path="src/uu/chcon" } -chgrp = { optional=true, version="0.0.17", package="uu_chgrp", path="src/uu/chgrp" } -chmod = { optional=true, version="0.0.17", package="uu_chmod", path="src/uu/chmod" } -chown = { optional=true, version="0.0.17", package="uu_chown", path="src/uu/chown" } -chroot = { optional=true, version="0.0.17", package="uu_chroot", path="src/uu/chroot" } -cksum = { optional=true, version="0.0.17", package="uu_cksum", path="src/uu/cksum" } -comm = { optional=true, version="0.0.17", package="uu_comm", path="src/uu/comm" } -cp = { optional=true, version="0.0.17", package="uu_cp", path="src/uu/cp" } -csplit = { optional=true, version="0.0.17", package="uu_csplit", path="src/uu/csplit" } -cut = { optional=true, version="0.0.17", package="uu_cut", path="src/uu/cut" } -date = { optional=true, version="0.0.17", package="uu_date", path="src/uu/date" } -dd = { optional=true, version="0.0.17", package="uu_dd", path="src/uu/dd" } -df = { optional=true, version="0.0.17", package="uu_df", path="src/uu/df" } -dir = { optional=true, version="0.0.17", package="uu_dir", path="src/uu/dir" } -dircolors= { optional=true, version="0.0.17", package="uu_dircolors", path="src/uu/dircolors" } -dirname = { optional=true, version="0.0.17", package="uu_dirname", path="src/uu/dirname" } -du = { optional=true, version="0.0.17", package="uu_du", path="src/uu/du" } -echo = { optional=true, version="0.0.17", package="uu_echo", path="src/uu/echo" } -env = { optional=true, version="0.0.17", package="uu_env", path="src/uu/env" } -expand = { optional=true, version="0.0.17", package="uu_expand", path="src/uu/expand" } -expr = { optional=true, version="0.0.17", package="uu_expr", path="src/uu/expr" } -factor = { optional=true, version="0.0.17", package="uu_factor", path="src/uu/factor" } -false = { optional=true, version="0.0.17", package="uu_false", path="src/uu/false" } -fmt = { optional=true, version="0.0.17", package="uu_fmt", path="src/uu/fmt" } -fold = { optional=true, version="0.0.17", package="uu_fold", path="src/uu/fold" } -groups = { optional=true, version="0.0.17", package="uu_groups", path="src/uu/groups" } -hashsum = { optional=true, version="0.0.17", package="uu_hashsum", path="src/uu/hashsum" } -head = { optional=true, version="0.0.17", package="uu_head", path="src/uu/head" } -hostid = { optional=true, version="0.0.17", package="uu_hostid", path="src/uu/hostid" } -hostname = { optional=true, version="0.0.17", package="uu_hostname", path="src/uu/hostname" } -id = { optional=true, version="0.0.17", package="uu_id", path="src/uu/id" } -install = { optional=true, version="0.0.17", package="uu_install", path="src/uu/install" } -join = { optional=true, version="0.0.17", package="uu_join", path="src/uu/join" } -kill = { optional=true, version="0.0.17", package="uu_kill", path="src/uu/kill" } -link = { optional=true, version="0.0.17", package="uu_link", path="src/uu/link" } -ln = { optional=true, version="0.0.17", package="uu_ln", path="src/uu/ln" } -ls = { optional=true, version="0.0.17", package="uu_ls", path="src/uu/ls" } -logname = { optional=true, version="0.0.17", package="uu_logname", path="src/uu/logname" } -mkdir = { optional=true, version="0.0.17", package="uu_mkdir", path="src/uu/mkdir" } -mkfifo = { optional=true, version="0.0.17", package="uu_mkfifo", path="src/uu/mkfifo" } -mknod = { optional=true, version="0.0.17", package="uu_mknod", path="src/uu/mknod" } -mktemp = { optional=true, version="0.0.17", package="uu_mktemp", path="src/uu/mktemp" } -more = { optional=true, version="0.0.17", package="uu_more", path="src/uu/more" } -mv = { optional=true, version="0.0.17", package="uu_mv", path="src/uu/mv" } -nice = { optional=true, version="0.0.17", package="uu_nice", path="src/uu/nice" } -nl = { optional=true, version="0.0.17", package="uu_nl", path="src/uu/nl" } -nohup = { optional=true, version="0.0.17", package="uu_nohup", path="src/uu/nohup" } -nproc = { optional=true, version="0.0.17", package="uu_nproc", path="src/uu/nproc" } -numfmt = { optional=true, version="0.0.17", package="uu_numfmt", path="src/uu/numfmt" } -od = { optional=true, version="0.0.17", package="uu_od", path="src/uu/od" } -paste = { optional=true, version="0.0.17", package="uu_paste", path="src/uu/paste" } -pathchk = { optional=true, version="0.0.17", package="uu_pathchk", path="src/uu/pathchk" } -pinky = { optional=true, version="0.0.17", package="uu_pinky", path="src/uu/pinky" } -pr = { optional=true, version="0.0.17", package="uu_pr", path="src/uu/pr" } -printenv = { optional=true, version="0.0.17", package="uu_printenv", path="src/uu/printenv" } -printf = { optional=true, version="0.0.17", package="uu_printf", path="src/uu/printf" } -ptx = { optional=true, version="0.0.17", package="uu_ptx", path="src/uu/ptx" } -pwd = { optional=true, version="0.0.17", package="uu_pwd", path="src/uu/pwd" } -readlink = { optional=true, version="0.0.17", package="uu_readlink", path="src/uu/readlink" } -realpath = { optional=true, version="0.0.17", package="uu_realpath", path="src/uu/realpath" } -relpath = { optional=true, version="0.0.17", package="uu_relpath", path="src/uu/relpath" } -rm = { optional=true, version="0.0.17", package="uu_rm", path="src/uu/rm" } -rmdir = { optional=true, version="0.0.17", package="uu_rmdir", path="src/uu/rmdir" } -runcon = { optional=true, version="0.0.17", package="uu_runcon", path="src/uu/runcon" } -seq = { optional=true, version="0.0.17", package="uu_seq", path="src/uu/seq" } -shred = { optional=true, version="0.0.17", package="uu_shred", path="src/uu/shred" } -shuf = { optional=true, version="0.0.17", package="uu_shuf", path="src/uu/shuf" } -sleep = { optional=true, version="0.0.17", package="uu_sleep", path="src/uu/sleep" } -sort = { optional=true, version="0.0.17", package="uu_sort", path="src/uu/sort" } -split = { optional=true, version="0.0.17", package="uu_split", path="src/uu/split" } -stat = { optional=true, version="0.0.17", package="uu_stat", path="src/uu/stat" } -stdbuf = { optional=true, version="0.0.17", package="uu_stdbuf", path="src/uu/stdbuf" } -stty = { optional=true, version="0.0.17", package="uu_stty", path="src/uu/stty" } -sum = { optional=true, version="0.0.17", package="uu_sum", path="src/uu/sum" } -sync = { optional=true, version="0.0.17", package="uu_sync", path="src/uu/sync" } -tac = { optional=true, version="0.0.17", package="uu_tac", path="src/uu/tac" } -tail = { optional=true, version="0.0.17", package="uu_tail", path="src/uu/tail" } -tee = { optional=true, version="0.0.17", package="uu_tee", path="src/uu/tee" } -timeout = { optional=true, version="0.0.17", package="uu_timeout", path="src/uu/timeout" } -touch = { optional=true, version="0.0.17", package="uu_touch", path="src/uu/touch" } -tr = { optional=true, version="0.0.17", package="uu_tr", path="src/uu/tr" } -true = { optional=true, version="0.0.17", package="uu_true", path="src/uu/true" } -truncate = { optional=true, version="0.0.17", package="uu_truncate", path="src/uu/truncate" } -tsort = { optional=true, version="0.0.17", package="uu_tsort", path="src/uu/tsort" } -tty = { optional=true, version="0.0.17", package="uu_tty", path="src/uu/tty" } -uname = { optional=true, version="0.0.17", package="uu_uname", path="src/uu/uname" } -unexpand = { optional=true, version="0.0.17", package="uu_unexpand", path="src/uu/unexpand" } -uniq = { optional=true, version="0.0.17", package="uu_uniq", path="src/uu/uniq" } -unlink = { optional=true, version="0.0.17", package="uu_unlink", path="src/uu/unlink" } -uptime = { optional=true, version="0.0.17", package="uu_uptime", path="src/uu/uptime" } -users = { optional=true, version="0.0.17", package="uu_users", path="src/uu/users" } -vdir = { optional=true, version="0.0.17", package="uu_vdir", path="src/uu/vdir" } -wc = { optional=true, version="0.0.17", package="uu_wc", path="src/uu/wc" } -who = { optional=true, version="0.0.17", package="uu_who", path="src/uu/who" } -whoami = { optional=true, version="0.0.17", package="uu_whoami", path="src/uu/whoami" } -yes = { optional=true, version="0.0.17", package="uu_yes", path="src/uu/yes" } +arch = { optional=true, version="0.0.18", package="uu_arch", path="src/uu/arch" } +base32 = { optional=true, version="0.0.18", package="uu_base32", path="src/uu/base32" } +base64 = { optional=true, version="0.0.18", package="uu_base64", path="src/uu/base64" } +basename = { optional=true, version="0.0.18", package="uu_basename", path="src/uu/basename" } +basenc = { optional=true, version="0.0.18", package="uu_basenc", path="src/uu/basenc" } +cat = { optional=true, version="0.0.18", package="uu_cat", path="src/uu/cat" } +chcon = { optional=true, version="0.0.18", package="uu_chcon", path="src/uu/chcon" } +chgrp = { optional=true, version="0.0.18", package="uu_chgrp", path="src/uu/chgrp" } +chmod = { optional=true, version="0.0.18", package="uu_chmod", path="src/uu/chmod" } +chown = { optional=true, version="0.0.18", package="uu_chown", path="src/uu/chown" } +chroot = { optional=true, version="0.0.18", package="uu_chroot", path="src/uu/chroot" } +cksum = { optional=true, version="0.0.18", package="uu_cksum", path="src/uu/cksum" } +comm = { optional=true, version="0.0.18", package="uu_comm", path="src/uu/comm" } +cp = { optional=true, version="0.0.18", package="uu_cp", path="src/uu/cp" } +csplit = { optional=true, version="0.0.18", package="uu_csplit", path="src/uu/csplit" } +cut = { optional=true, version="0.0.18", package="uu_cut", path="src/uu/cut" } +date = { optional=true, version="0.0.18", package="uu_date", path="src/uu/date" } +dd = { optional=true, version="0.0.18", package="uu_dd", path="src/uu/dd" } +df = { optional=true, version="0.0.18", package="uu_df", path="src/uu/df" } +dir = { optional=true, version="0.0.18", package="uu_dir", path="src/uu/dir" } +dircolors= { optional=true, version="0.0.18", package="uu_dircolors", path="src/uu/dircolors" } +dirname = { optional=true, version="0.0.18", package="uu_dirname", path="src/uu/dirname" } +du = { optional=true, version="0.0.18", package="uu_du", path="src/uu/du" } +echo = { optional=true, version="0.0.18", package="uu_echo", path="src/uu/echo" } +env = { optional=true, version="0.0.18", package="uu_env", path="src/uu/env" } +expand = { optional=true, version="0.0.18", package="uu_expand", path="src/uu/expand" } +expr = { optional=true, version="0.0.18", package="uu_expr", path="src/uu/expr" } +factor = { optional=true, version="0.0.18", package="uu_factor", path="src/uu/factor" } +false = { optional=true, version="0.0.18", package="uu_false", path="src/uu/false" } +fmt = { optional=true, version="0.0.18", package="uu_fmt", path="src/uu/fmt" } +fold = { optional=true, version="0.0.18", package="uu_fold", path="src/uu/fold" } +groups = { optional=true, version="0.0.18", package="uu_groups", path="src/uu/groups" } +hashsum = { optional=true, version="0.0.18", package="uu_hashsum", path="src/uu/hashsum" } +head = { optional=true, version="0.0.18", package="uu_head", path="src/uu/head" } +hostid = { optional=true, version="0.0.18", package="uu_hostid", path="src/uu/hostid" } +hostname = { optional=true, version="0.0.18", package="uu_hostname", path="src/uu/hostname" } +id = { optional=true, version="0.0.18", package="uu_id", path="src/uu/id" } +install = { optional=true, version="0.0.18", package="uu_install", path="src/uu/install" } +join = { optional=true, version="0.0.18", package="uu_join", path="src/uu/join" } +kill = { optional=true, version="0.0.18", package="uu_kill", path="src/uu/kill" } +link = { optional=true, version="0.0.18", package="uu_link", path="src/uu/link" } +ln = { optional=true, version="0.0.18", package="uu_ln", path="src/uu/ln" } +ls = { optional=true, version="0.0.18", package="uu_ls", path="src/uu/ls" } +logname = { optional=true, version="0.0.18", package="uu_logname", path="src/uu/logname" } +mkdir = { optional=true, version="0.0.18", package="uu_mkdir", path="src/uu/mkdir" } +mkfifo = { optional=true, version="0.0.18", package="uu_mkfifo", path="src/uu/mkfifo" } +mknod = { optional=true, version="0.0.18", package="uu_mknod", path="src/uu/mknod" } +mktemp = { optional=true, version="0.0.18", package="uu_mktemp", path="src/uu/mktemp" } +more = { optional=true, version="0.0.18", package="uu_more", path="src/uu/more" } +mv = { optional=true, version="0.0.18", package="uu_mv", path="src/uu/mv" } +nice = { optional=true, version="0.0.18", package="uu_nice", path="src/uu/nice" } +nl = { optional=true, version="0.0.18", package="uu_nl", path="src/uu/nl" } +nohup = { optional=true, version="0.0.18", package="uu_nohup", path="src/uu/nohup" } +nproc = { optional=true, version="0.0.18", package="uu_nproc", path="src/uu/nproc" } +numfmt = { optional=true, version="0.0.18", package="uu_numfmt", path="src/uu/numfmt" } +od = { optional=true, version="0.0.18", package="uu_od", path="src/uu/od" } +paste = { optional=true, version="0.0.18", package="uu_paste", path="src/uu/paste" } +pathchk = { optional=true, version="0.0.18", package="uu_pathchk", path="src/uu/pathchk" } +pinky = { optional=true, version="0.0.18", package="uu_pinky", path="src/uu/pinky" } +pr = { optional=true, version="0.0.18", package="uu_pr", path="src/uu/pr" } +printenv = { optional=true, version="0.0.18", package="uu_printenv", path="src/uu/printenv" } +printf = { optional=true, version="0.0.18", package="uu_printf", path="src/uu/printf" } +ptx = { optional=true, version="0.0.18", package="uu_ptx", path="src/uu/ptx" } +pwd = { optional=true, version="0.0.18", package="uu_pwd", path="src/uu/pwd" } +readlink = { optional=true, version="0.0.18", package="uu_readlink", path="src/uu/readlink" } +realpath = { optional=true, version="0.0.18", package="uu_realpath", path="src/uu/realpath" } +relpath = { optional=true, version="0.0.18", package="uu_relpath", path="src/uu/relpath" } +rm = { optional=true, version="0.0.18", package="uu_rm", path="src/uu/rm" } +rmdir = { optional=true, version="0.0.18", package="uu_rmdir", path="src/uu/rmdir" } +runcon = { optional=true, version="0.0.18", package="uu_runcon", path="src/uu/runcon" } +seq = { optional=true, version="0.0.18", package="uu_seq", path="src/uu/seq" } +shred = { optional=true, version="0.0.18", package="uu_shred", path="src/uu/shred" } +shuf = { optional=true, version="0.0.18", package="uu_shuf", path="src/uu/shuf" } +sleep = { optional=true, version="0.0.18", package="uu_sleep", path="src/uu/sleep" } +sort = { optional=true, version="0.0.18", package="uu_sort", path="src/uu/sort" } +split = { optional=true, version="0.0.18", package="uu_split", path="src/uu/split" } +stat = { optional=true, version="0.0.18", package="uu_stat", path="src/uu/stat" } +stdbuf = { optional=true, version="0.0.18", package="uu_stdbuf", path="src/uu/stdbuf" } +stty = { optional=true, version="0.0.18", package="uu_stty", path="src/uu/stty" } +sum = { optional=true, version="0.0.18", package="uu_sum", path="src/uu/sum" } +sync = { optional=true, version="0.0.18", package="uu_sync", path="src/uu/sync" } +tac = { optional=true, version="0.0.18", package="uu_tac", path="src/uu/tac" } +tail = { optional=true, version="0.0.18", package="uu_tail", path="src/uu/tail" } +tee = { optional=true, version="0.0.18", package="uu_tee", path="src/uu/tee" } +timeout = { optional=true, version="0.0.18", package="uu_timeout", path="src/uu/timeout" } +touch = { optional=true, version="0.0.18", package="uu_touch", path="src/uu/touch" } +tr = { optional=true, version="0.0.18", package="uu_tr", path="src/uu/tr" } +true = { optional=true, version="0.0.18", package="uu_true", path="src/uu/true" } +truncate = { optional=true, version="0.0.18", package="uu_truncate", path="src/uu/truncate" } +tsort = { optional=true, version="0.0.18", package="uu_tsort", path="src/uu/tsort" } +tty = { optional=true, version="0.0.18", package="uu_tty", path="src/uu/tty" } +uname = { optional=true, version="0.0.18", package="uu_uname", path="src/uu/uname" } +unexpand = { optional=true, version="0.0.18", package="uu_unexpand", path="src/uu/unexpand" } +uniq = { optional=true, version="0.0.18", package="uu_uniq", path="src/uu/uniq" } +unlink = { optional=true, version="0.0.18", package="uu_unlink", path="src/uu/unlink" } +uptime = { optional=true, version="0.0.18", package="uu_uptime", path="src/uu/uptime" } +users = { optional=true, version="0.0.18", package="uu_users", path="src/uu/users" } +vdir = { optional=true, version="0.0.18", package="uu_vdir", path="src/uu/vdir" } +wc = { optional=true, version="0.0.18", package="uu_wc", path="src/uu/wc" } +who = { optional=true, version="0.0.18", package="uu_who", path="src/uu/who" } +whoami = { optional=true, version="0.0.18", package="uu_whoami", path="src/uu/whoami" } +yes = { optional=true, version="0.0.18", package="uu_yes", path="src/uu/yes" } # this breaks clippy linting with: "tests/by-util/test_factor_benches.rs: No such file or directory (os error 2)" # factor_benches = { optional = true, version = "0.0.0", package = "uu_factor_benches", path = "tests/benches/factor" } diff --git a/src/uu/arch/Cargo.toml b/src/uu/arch/Cargo.toml index 8e87123386..b2cdfdc17a 100644 --- a/src/uu/arch/Cargo.toml +++ b/src/uu/arch/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_arch" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "arch ~ (uutils) display machine architecture" diff --git a/src/uu/base32/Cargo.toml b/src/uu/base32/Cargo.toml index d71e71f952..e4a8464d95 100644 --- a/src/uu/base32/Cargo.toml +++ b/src/uu/base32/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_base32" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "base32 ~ (uutils) decode/encode input (base32-encoding)" diff --git a/src/uu/base64/Cargo.toml b/src/uu/base64/Cargo.toml index af92c70c2d..e5ea4cf149 100644 --- a/src/uu/base64/Cargo.toml +++ b/src/uu/base64/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_base64" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "base64 ~ (uutils) decode/encode input (base64-encoding)" diff --git a/src/uu/basename/Cargo.toml b/src/uu/basename/Cargo.toml index 7d8377de5e..f234d1021f 100644 --- a/src/uu/basename/Cargo.toml +++ b/src/uu/basename/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_basename" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "basename ~ (uutils) display PATHNAME with leading directory components removed" diff --git a/src/uu/basenc/Cargo.toml b/src/uu/basenc/Cargo.toml index e6babef761..cc4264b519 100644 --- a/src/uu/basenc/Cargo.toml +++ b/src/uu/basenc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_basenc" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "basenc ~ (uutils) decode/encode input" diff --git a/src/uu/cat/Cargo.toml b/src/uu/cat/Cargo.toml index fbf91c2492..941637514f 100644 --- a/src/uu/cat/Cargo.toml +++ b/src/uu/cat/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cat" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "cat ~ (uutils) concatenate and display input" diff --git a/src/uu/chcon/Cargo.toml b/src/uu/chcon/Cargo.toml index 2e28aa29ef..e5dc6b93cd 100644 --- a/src/uu/chcon/Cargo.toml +++ b/src/uu/chcon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chcon" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "chcon ~ (uutils) change file security context" diff --git a/src/uu/chgrp/Cargo.toml b/src/uu/chgrp/Cargo.toml index 164a30e209..13b8c7e4d5 100644 --- a/src/uu/chgrp/Cargo.toml +++ b/src/uu/chgrp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chgrp" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "chgrp ~ (uutils) change the group ownership of FILE" diff --git a/src/uu/chmod/Cargo.toml b/src/uu/chmod/Cargo.toml index 833067208d..8b7d09e920 100644 --- a/src/uu/chmod/Cargo.toml +++ b/src/uu/chmod/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chmod" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "chmod ~ (uutils) change mode of FILE" diff --git a/src/uu/chown/Cargo.toml b/src/uu/chown/Cargo.toml index 9ff43b0064..bc28d86403 100644 --- a/src/uu/chown/Cargo.toml +++ b/src/uu/chown/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chown" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "chown ~ (uutils) change the ownership of FILE" diff --git a/src/uu/chroot/Cargo.toml b/src/uu/chroot/Cargo.toml index 0cae53110b..ca083753d6 100644 --- a/src/uu/chroot/Cargo.toml +++ b/src/uu/chroot/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chroot" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "chroot ~ (uutils) run COMMAND under a new root directory" diff --git a/src/uu/cksum/Cargo.toml b/src/uu/cksum/Cargo.toml index 9b7f70f8f8..61c66e7048 100644 --- a/src/uu/cksum/Cargo.toml +++ b/src/uu/cksum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cksum" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "cksum ~ (uutils) display CRC and size of input" diff --git a/src/uu/comm/Cargo.toml b/src/uu/comm/Cargo.toml index fbe28903f0..0371d46c17 100644 --- a/src/uu/comm/Cargo.toml +++ b/src/uu/comm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_comm" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "comm ~ (uutils) compare sorted inputs" diff --git a/src/uu/cp/Cargo.toml b/src/uu/cp/Cargo.toml index 4aa871185f..32d34112ba 100644 --- a/src/uu/cp/Cargo.toml +++ b/src/uu/cp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cp" -version = "0.0.17" +version = "0.0.18" authors = [ "Jordy Dickinson ", "Joshua S. Miller ", diff --git a/src/uu/csplit/Cargo.toml b/src/uu/csplit/Cargo.toml index 62b43c10e3..560ddf6e83 100644 --- a/src/uu/csplit/Cargo.toml +++ b/src/uu/csplit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_csplit" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "csplit ~ (uutils) Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output" diff --git a/src/uu/cut/Cargo.toml b/src/uu/cut/Cargo.toml index 8a5e8f1d23..6e49ce4d41 100644 --- a/src/uu/cut/Cargo.toml +++ b/src/uu/cut/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cut" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "cut ~ (uutils) display byte/field columns of input lines" diff --git a/src/uu/date/Cargo.toml b/src/uu/date/Cargo.toml index cd7c505138..fab98f20d9 100644 --- a/src/uu/date/Cargo.toml +++ b/src/uu/date/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_date" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "date ~ (uutils) display or set the current time" diff --git a/src/uu/dd/Cargo.toml b/src/uu/dd/Cargo.toml index e7feaaeddf..b81ef1a8ef 100644 --- a/src/uu/dd/Cargo.toml +++ b/src/uu/dd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dd" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "dd ~ (uutils) copy and convert files" diff --git a/src/uu/df/Cargo.toml b/src/uu/df/Cargo.toml index 83ae2ae146..9cca407bb4 100644 --- a/src/uu/df/Cargo.toml +++ b/src/uu/df/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_df" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "df ~ (uutils) display file system information" diff --git a/src/uu/dir/Cargo.toml b/src/uu/dir/Cargo.toml index 03235fdfcb..c8cb861f96 100644 --- a/src/uu/dir/Cargo.toml +++ b/src/uu/dir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dir" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "shortcut to ls -C -b" diff --git a/src/uu/dircolors/Cargo.toml b/src/uu/dircolors/Cargo.toml index 9a3479426b..7d729f3965 100644 --- a/src/uu/dircolors/Cargo.toml +++ b/src/uu/dircolors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dircolors" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "dircolors ~ (uutils) display commands to set LS_COLORS" diff --git a/src/uu/dirname/Cargo.toml b/src/uu/dirname/Cargo.toml index 1186a4697f..f002bf15af 100644 --- a/src/uu/dirname/Cargo.toml +++ b/src/uu/dirname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dirname" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "dirname ~ (uutils) display parent directory of PATHNAME" diff --git a/src/uu/du/Cargo.toml b/src/uu/du/Cargo.toml index a8e8aead51..22659bc0ee 100644 --- a/src/uu/du/Cargo.toml +++ b/src/uu/du/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_du" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "du ~ (uutils) display disk usage" diff --git a/src/uu/echo/Cargo.toml b/src/uu/echo/Cargo.toml index 0ae385cbec..276fdaf850 100644 --- a/src/uu/echo/Cargo.toml +++ b/src/uu/echo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_echo" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "echo ~ (uutils) display TEXT" diff --git a/src/uu/env/Cargo.toml b/src/uu/env/Cargo.toml index b2224c405b..689bb12a40 100644 --- a/src/uu/env/Cargo.toml +++ b/src/uu/env/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_env" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "env ~ (uutils) set each NAME to VALUE in the environment and run COMMAND" diff --git a/src/uu/expand/Cargo.toml b/src/uu/expand/Cargo.toml index 362ed5a3a8..f30fcbce51 100644 --- a/src/uu/expand/Cargo.toml +++ b/src/uu/expand/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_expand" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "expand ~ (uutils) convert input tabs to spaces" diff --git a/src/uu/expr/Cargo.toml b/src/uu/expr/Cargo.toml index 4ee2b5b1a4..26c9d67245 100644 --- a/src/uu/expr/Cargo.toml +++ b/src/uu/expr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_expr" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "expr ~ (uutils) display the value of EXPRESSION" diff --git a/src/uu/factor/Cargo.toml b/src/uu/factor/Cargo.toml index f2e6245d50..8de973503c 100644 --- a/src/uu/factor/Cargo.toml +++ b/src/uu/factor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_factor" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "factor ~ (uutils) display the prime factors of each NUMBER" diff --git a/src/uu/false/Cargo.toml b/src/uu/false/Cargo.toml index 1bd0bc2604..44d9837881 100644 --- a/src/uu/false/Cargo.toml +++ b/src/uu/false/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_false" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "false ~ (uutils) do nothing and fail" diff --git a/src/uu/fmt/Cargo.toml b/src/uu/fmt/Cargo.toml index f37e9468af..1446e8ba55 100644 --- a/src/uu/fmt/Cargo.toml +++ b/src/uu/fmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_fmt" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "fmt ~ (uutils) reformat each paragraph of input" diff --git a/src/uu/fold/Cargo.toml b/src/uu/fold/Cargo.toml index d3e4417e1a..3358fb7cc7 100644 --- a/src/uu/fold/Cargo.toml +++ b/src/uu/fold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_fold" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "fold ~ (uutils) wrap each line of input" diff --git a/src/uu/groups/Cargo.toml b/src/uu/groups/Cargo.toml index 49034a4b37..940661bc40 100644 --- a/src/uu/groups/Cargo.toml +++ b/src/uu/groups/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_groups" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "groups ~ (uutils) display group memberships for USERNAME" diff --git a/src/uu/hashsum/Cargo.toml b/src/uu/hashsum/Cargo.toml index f335211b86..a75141e93f 100644 --- a/src/uu/hashsum/Cargo.toml +++ b/src/uu/hashsum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hashsum" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "hashsum ~ (uutils) display or check input digests" diff --git a/src/uu/head/Cargo.toml b/src/uu/head/Cargo.toml index c631cf3310..a826782859 100644 --- a/src/uu/head/Cargo.toml +++ b/src/uu/head/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_head" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "head ~ (uutils) display the first lines of input" diff --git a/src/uu/hostid/Cargo.toml b/src/uu/hostid/Cargo.toml index 7aa28328aa..a31286bbdc 100644 --- a/src/uu/hostid/Cargo.toml +++ b/src/uu/hostid/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hostid" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "hostid ~ (uutils) display the numeric identifier of the current host" diff --git a/src/uu/hostname/Cargo.toml b/src/uu/hostname/Cargo.toml index e57e5c364f..c39f8fdaec 100644 --- a/src/uu/hostname/Cargo.toml +++ b/src/uu/hostname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hostname" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "hostname ~ (uutils) display or set the host name of the current host" diff --git a/src/uu/id/Cargo.toml b/src/uu/id/Cargo.toml index 3a157ada4c..dd363340b2 100644 --- a/src/uu/id/Cargo.toml +++ b/src/uu/id/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_id" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "id ~ (uutils) display user and group information for USER" diff --git a/src/uu/install/Cargo.toml b/src/uu/install/Cargo.toml index 0890fe8c97..789f84de33 100644 --- a/src/uu/install/Cargo.toml +++ b/src/uu/install/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_install" -version = "0.0.17" +version = "0.0.18" authors = [ "Ben Eills ", "uutils developers", diff --git a/src/uu/join/Cargo.toml b/src/uu/join/Cargo.toml index 5be4af1a72..d92c032aad 100644 --- a/src/uu/join/Cargo.toml +++ b/src/uu/join/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_join" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "join ~ (uutils) merge lines from inputs with matching join fields" diff --git a/src/uu/kill/Cargo.toml b/src/uu/kill/Cargo.toml index 8171900832..21010160cf 100644 --- a/src/uu/kill/Cargo.toml +++ b/src/uu/kill/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_kill" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "kill ~ (uutils) send a signal to a process" diff --git a/src/uu/link/Cargo.toml b/src/uu/link/Cargo.toml index e35e23cfc4..2d81883a62 100644 --- a/src/uu/link/Cargo.toml +++ b/src/uu/link/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_link" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "link ~ (uutils) create a hard (file system) link to FILE" diff --git a/src/uu/ln/Cargo.toml b/src/uu/ln/Cargo.toml index f08f04e416..c06218fb74 100644 --- a/src/uu/ln/Cargo.toml +++ b/src/uu/ln/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ln" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "ln ~ (uutils) create a (file system) link to TARGET" diff --git a/src/uu/logname/Cargo.toml b/src/uu/logname/Cargo.toml index 18ecdc9ab4..e75571e0fc 100644 --- a/src/uu/logname/Cargo.toml +++ b/src/uu/logname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_logname" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "logname ~ (uutils) display the login name of the current user" diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index 7c7add2941..251268c2b4 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ls" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "ls ~ (uutils) display directory contents" diff --git a/src/uu/mkdir/Cargo.toml b/src/uu/mkdir/Cargo.toml index b8bc1dddf2..e2b65c0309 100644 --- a/src/uu/mkdir/Cargo.toml +++ b/src/uu/mkdir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mkdir" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "mkdir ~ (uutils) create DIRECTORY" diff --git a/src/uu/mkfifo/Cargo.toml b/src/uu/mkfifo/Cargo.toml index 9ffe3c765b..8fd154a3f6 100644 --- a/src/uu/mkfifo/Cargo.toml +++ b/src/uu/mkfifo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mkfifo" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "mkfifo ~ (uutils) create FIFOs (named pipes)" diff --git a/src/uu/mknod/Cargo.toml b/src/uu/mknod/Cargo.toml index b74ed3b463..ee272dbf7b 100644 --- a/src/uu/mknod/Cargo.toml +++ b/src/uu/mknod/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mknod" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "mknod ~ (uutils) create special file NAME of TYPE" diff --git a/src/uu/mktemp/Cargo.toml b/src/uu/mktemp/Cargo.toml index 029e89bc94..7f1ac62eef 100644 --- a/src/uu/mktemp/Cargo.toml +++ b/src/uu/mktemp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mktemp" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "mktemp ~ (uutils) create and display a temporary file or directory from TEMPLATE" diff --git a/src/uu/more/Cargo.toml b/src/uu/more/Cargo.toml index 01bb961839..573eafc437 100644 --- a/src/uu/more/Cargo.toml +++ b/src/uu/more/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_more" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "more ~ (uutils) input perusal filter" diff --git a/src/uu/mv/Cargo.toml b/src/uu/mv/Cargo.toml index 87ce36c5fd..d1f82bf885 100644 --- a/src/uu/mv/Cargo.toml +++ b/src/uu/mv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mv" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "mv ~ (uutils) move (rename) SOURCE to DESTINATION" diff --git a/src/uu/nice/Cargo.toml b/src/uu/nice/Cargo.toml index 054daf2737..3c5d763dad 100644 --- a/src/uu/nice/Cargo.toml +++ b/src/uu/nice/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nice" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "nice ~ (uutils) run PROGRAM with modified scheduling priority" diff --git a/src/uu/nl/Cargo.toml b/src/uu/nl/Cargo.toml index 5dd539db84..efa3f3e0ba 100644 --- a/src/uu/nl/Cargo.toml +++ b/src/uu/nl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nl" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "nl ~ (uutils) display input with added line numbers" diff --git a/src/uu/nohup/Cargo.toml b/src/uu/nohup/Cargo.toml index f358695065..7067e51e82 100644 --- a/src/uu/nohup/Cargo.toml +++ b/src/uu/nohup/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nohup" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "nohup ~ (uutils) run COMMAND, ignoring hangup signals" diff --git a/src/uu/nproc/Cargo.toml b/src/uu/nproc/Cargo.toml index c2c224a409..13202b739a 100644 --- a/src/uu/nproc/Cargo.toml +++ b/src/uu/nproc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nproc" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "nproc ~ (uutils) display the number of processing units available" diff --git a/src/uu/numfmt/Cargo.toml b/src/uu/numfmt/Cargo.toml index 2e68cbab2d..2f3a2e69a2 100644 --- a/src/uu/numfmt/Cargo.toml +++ b/src/uu/numfmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_numfmt" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "numfmt ~ (uutils) reformat NUMBER" diff --git a/src/uu/od/Cargo.toml b/src/uu/od/Cargo.toml index c2bc937311..28abbfce22 100644 --- a/src/uu/od/Cargo.toml +++ b/src/uu/od/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_od" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "od ~ (uutils) display formatted representation of input" diff --git a/src/uu/paste/Cargo.toml b/src/uu/paste/Cargo.toml index aa1f5fe90c..36765594e3 100644 --- a/src/uu/paste/Cargo.toml +++ b/src/uu/paste/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_paste" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "paste ~ (uutils) merge lines from inputs" diff --git a/src/uu/pathchk/Cargo.toml b/src/uu/pathchk/Cargo.toml index 134f5bb5d2..01a626042c 100644 --- a/src/uu/pathchk/Cargo.toml +++ b/src/uu/pathchk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pathchk" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "pathchk ~ (uutils) diagnose invalid or non-portable PATHNAME" diff --git a/src/uu/pinky/Cargo.toml b/src/uu/pinky/Cargo.toml index a9abee40b9..f2c930831e 100644 --- a/src/uu/pinky/Cargo.toml +++ b/src/uu/pinky/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pinky" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "pinky ~ (uutils) display user information" diff --git a/src/uu/pr/Cargo.toml b/src/uu/pr/Cargo.toml index 773a71b7fb..414168c64d 100644 --- a/src/uu/pr/Cargo.toml +++ b/src/uu/pr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pr" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "pr ~ (uutils) convert text files for printing" diff --git a/src/uu/printenv/Cargo.toml b/src/uu/printenv/Cargo.toml index 7f179e4114..007348a95a 100644 --- a/src/uu/printenv/Cargo.toml +++ b/src/uu/printenv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_printenv" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "printenv ~ (uutils) display value of environment VAR" diff --git a/src/uu/printf/Cargo.toml b/src/uu/printf/Cargo.toml index ffb266f188..aa64a24ef6 100644 --- a/src/uu/printf/Cargo.toml +++ b/src/uu/printf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_printf" -version = "0.0.17" +version = "0.0.18" authors = [ "Nathan Ross", "uutils developers", diff --git a/src/uu/ptx/Cargo.toml b/src/uu/ptx/Cargo.toml index 1cb2857d3b..8f2cda9389 100644 --- a/src/uu/ptx/Cargo.toml +++ b/src/uu/ptx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ptx" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "ptx ~ (uutils) display a permuted index of input" diff --git a/src/uu/pwd/Cargo.toml b/src/uu/pwd/Cargo.toml index 2be2046081..af1451564c 100644 --- a/src/uu/pwd/Cargo.toml +++ b/src/uu/pwd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pwd" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "pwd ~ (uutils) display current working directory" diff --git a/src/uu/readlink/Cargo.toml b/src/uu/readlink/Cargo.toml index 59acd7731c..aed0652070 100644 --- a/src/uu/readlink/Cargo.toml +++ b/src/uu/readlink/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_readlink" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "readlink ~ (uutils) display resolved path of PATHNAME" diff --git a/src/uu/realpath/Cargo.toml b/src/uu/realpath/Cargo.toml index cf23d60af7..17af009c6a 100644 --- a/src/uu/realpath/Cargo.toml +++ b/src/uu/realpath/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_realpath" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "realpath ~ (uutils) display resolved absolute path of PATHNAME" diff --git a/src/uu/relpath/Cargo.toml b/src/uu/relpath/Cargo.toml index 99e37f5f88..7046aafee2 100644 --- a/src/uu/relpath/Cargo.toml +++ b/src/uu/relpath/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_relpath" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "relpath ~ (uutils) display relative path of PATHNAME_TO from PATHNAME_FROM" diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index af63aee784..5151beb93b 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_rm" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "rm ~ (uutils) remove PATHNAME" diff --git a/src/uu/rmdir/Cargo.toml b/src/uu/rmdir/Cargo.toml index 6e6bbcb154..f35817c6cf 100644 --- a/src/uu/rmdir/Cargo.toml +++ b/src/uu/rmdir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_rmdir" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "rmdir ~ (uutils) remove empty DIRECTORY" diff --git a/src/uu/runcon/Cargo.toml b/src/uu/runcon/Cargo.toml index 46d5652233..5373658e4c 100644 --- a/src/uu/runcon/Cargo.toml +++ b/src/uu/runcon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_runcon" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "runcon ~ (uutils) run command with specified security context" diff --git a/src/uu/seq/Cargo.toml b/src/uu/seq/Cargo.toml index d8c861aaeb..c217d067fa 100644 --- a/src/uu/seq/Cargo.toml +++ b/src/uu/seq/Cargo.toml @@ -1,7 +1,7 @@ # spell-checker:ignore bigdecimal [package] name = "uu_seq" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "seq ~ (uutils) display a sequence of numbers" diff --git a/src/uu/shred/Cargo.toml b/src/uu/shred/Cargo.toml index ee129122a8..e085041c33 100644 --- a/src/uu/shred/Cargo.toml +++ b/src/uu/shred/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_shred" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "shred ~ (uutils) hide former FILE contents with repeated overwrites" diff --git a/src/uu/shuf/Cargo.toml b/src/uu/shuf/Cargo.toml index eed9065c7e..8c7dd72784 100644 --- a/src/uu/shuf/Cargo.toml +++ b/src/uu/shuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_shuf" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "shuf ~ (uutils) display random permutations of input lines" diff --git a/src/uu/sleep/Cargo.toml b/src/uu/sleep/Cargo.toml index aa4bf0664b..6091ac1da7 100644 --- a/src/uu/sleep/Cargo.toml +++ b/src/uu/sleep/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sleep" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "sleep ~ (uutils) pause for DURATION" diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index e940d08e5f..41d6bd66f8 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sort" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "sort ~ (uutils) sort input lines" diff --git a/src/uu/split/Cargo.toml b/src/uu/split/Cargo.toml index 2d379a3734..cae21b1635 100644 --- a/src/uu/split/Cargo.toml +++ b/src/uu/split/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_split" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "split ~ (uutils) split input into output files" diff --git a/src/uu/stat/Cargo.toml b/src/uu/stat/Cargo.toml index 1c84eaf1ec..bd873404e8 100644 --- a/src/uu/stat/Cargo.toml +++ b/src/uu/stat/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stat" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "stat ~ (uutils) display FILE status" diff --git a/src/uu/stdbuf/Cargo.toml b/src/uu/stdbuf/Cargo.toml index 164188f9f2..224af033ee 100644 --- a/src/uu/stdbuf/Cargo.toml +++ b/src/uu/stdbuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stdbuf" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "stdbuf ~ (uutils) run COMMAND with modified standard stream buffering" @@ -20,7 +20,7 @@ tempfile = { workspace=true } uucore = { workspace=true } [build-dependencies] -libstdbuf = { version="0.0.17", package="uu_stdbuf_libstdbuf", path="src/libstdbuf" } +libstdbuf = { version="0.0.18", package="uu_stdbuf_libstdbuf", path="src/libstdbuf" } [[bin]] name = "stdbuf" diff --git a/src/uu/stdbuf/src/libstdbuf/Cargo.toml b/src/uu/stdbuf/src/libstdbuf/Cargo.toml index 2498f7671a..d9d94cd578 100644 --- a/src/uu/stdbuf/src/libstdbuf/Cargo.toml +++ b/src/uu/stdbuf/src/libstdbuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stdbuf_libstdbuf" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "stdbuf/libstdbuf ~ (uutils); dynamic library required for stdbuf" @@ -19,7 +19,7 @@ crate-type = ["cdylib", "rlib"] # XXX: note: the rlib is just to prevent Cargo f [dependencies] cpp = "0.5" libc = { workspace=true } -uucore = { version=">=0.0.17", package="uucore", path="../../../../uucore" } +uucore = { version=">=0.0.18", package="uucore", path="../../../../uucore" } [build-dependencies] cpp_build = "0.5" diff --git a/src/uu/stty/Cargo.toml b/src/uu/stty/Cargo.toml index 9c94f8cb16..f6ea290d9e 100644 --- a/src/uu/stty/Cargo.toml +++ b/src/uu/stty/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stty" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "stty ~ (uutils) print or change terminal characteristics" diff --git a/src/uu/sum/Cargo.toml b/src/uu/sum/Cargo.toml index 0997f22fc9..37a997224c 100644 --- a/src/uu/sum/Cargo.toml +++ b/src/uu/sum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sum" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "sum ~ (uutils) display checksum and block counts for input" diff --git a/src/uu/sync/Cargo.toml b/src/uu/sync/Cargo.toml index 19696d881a..49cfbf1b54 100644 --- a/src/uu/sync/Cargo.toml +++ b/src/uu/sync/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sync" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "sync ~ (uutils) synchronize cache writes to storage" diff --git a/src/uu/tac/Cargo.toml b/src/uu/tac/Cargo.toml index 3df365bad1..50d83a67cb 100644 --- a/src/uu/tac/Cargo.toml +++ b/src/uu/tac/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "uu_tac" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "tac ~ (uutils) concatenate and display input lines in reverse order" diff --git a/src/uu/tail/Cargo.toml b/src/uu/tail/Cargo.toml index 88b82a8e6f..f58adf8aba 100644 --- a/src/uu/tail/Cargo.toml +++ b/src/uu/tail/Cargo.toml @@ -1,7 +1,7 @@ # spell-checker:ignore (libs) kqueue fundu [package] name = "uu_tail" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "tail ~ (uutils) display the last lines of input" diff --git a/src/uu/tee/Cargo.toml b/src/uu/tee/Cargo.toml index 52a2acceac..36e4f0dd45 100644 --- a/src/uu/tee/Cargo.toml +++ b/src/uu/tee/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tee" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "tee ~ (uutils) display input and copy to FILE" diff --git a/src/uu/test/Cargo.toml b/src/uu/test/Cargo.toml index 5e7d2e23a1..b3229f5063 100644 --- a/src/uu/test/Cargo.toml +++ b/src/uu/test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_test" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "test ~ (uutils) evaluate comparison and file type expressions" diff --git a/src/uu/timeout/Cargo.toml b/src/uu/timeout/Cargo.toml index b19a2e9996..8b92f9d8b1 100644 --- a/src/uu/timeout/Cargo.toml +++ b/src/uu/timeout/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_timeout" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "timeout ~ (uutils) run COMMAND with a DURATION time limit" diff --git a/src/uu/touch/Cargo.toml b/src/uu/touch/Cargo.toml index 1fad22c028..794273bba7 100644 --- a/src/uu/touch/Cargo.toml +++ b/src/uu/touch/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_touch" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "touch ~ (uutils) change FILE timestamps" diff --git a/src/uu/tr/Cargo.toml b/src/uu/tr/Cargo.toml index eee6c7cd62..559546efd6 100644 --- a/src/uu/tr/Cargo.toml +++ b/src/uu/tr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tr" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "tr ~ (uutils) translate characters within input and display" diff --git a/src/uu/true/Cargo.toml b/src/uu/true/Cargo.toml index 9954c29063..bab8161d87 100644 --- a/src/uu/true/Cargo.toml +++ b/src/uu/true/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_true" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "true ~ (uutils) do nothing and succeed" diff --git a/src/uu/truncate/Cargo.toml b/src/uu/truncate/Cargo.toml index e93751e89e..0d5615eead 100644 --- a/src/uu/truncate/Cargo.toml +++ b/src/uu/truncate/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_truncate" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "truncate ~ (uutils) truncate (or extend) FILE to SIZE" diff --git a/src/uu/tsort/Cargo.toml b/src/uu/tsort/Cargo.toml index 2737454eb5..08a035eacb 100644 --- a/src/uu/tsort/Cargo.toml +++ b/src/uu/tsort/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tsort" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "tsort ~ (uutils) topologically sort input (partially ordered) pairs" diff --git a/src/uu/tty/Cargo.toml b/src/uu/tty/Cargo.toml index ee7fe559b0..ed4f2ba53b 100644 --- a/src/uu/tty/Cargo.toml +++ b/src/uu/tty/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tty" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "tty ~ (uutils) display the name of the terminal connected to standard input" diff --git a/src/uu/uname/Cargo.toml b/src/uu/uname/Cargo.toml index 818e6dd06d..a24113cb7b 100644 --- a/src/uu/uname/Cargo.toml +++ b/src/uu/uname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uname" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "uname ~ (uutils) display system information" diff --git a/src/uu/unexpand/Cargo.toml b/src/uu/unexpand/Cargo.toml index a80bcdaf5d..5e4d486cb5 100644 --- a/src/uu/unexpand/Cargo.toml +++ b/src/uu/unexpand/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_unexpand" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "unexpand ~ (uutils) convert input spaces to tabs" diff --git a/src/uu/uniq/Cargo.toml b/src/uu/uniq/Cargo.toml index 272cc5a1b5..1491f81f2b 100644 --- a/src/uu/uniq/Cargo.toml +++ b/src/uu/uniq/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uniq" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "uniq ~ (uutils) filter identical adjacent lines from input" diff --git a/src/uu/unlink/Cargo.toml b/src/uu/unlink/Cargo.toml index 6b300dab06..99efdbaeea 100644 --- a/src/uu/unlink/Cargo.toml +++ b/src/uu/unlink/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_unlink" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "unlink ~ (uutils) remove a (file system) link to FILE" diff --git a/src/uu/uptime/Cargo.toml b/src/uu/uptime/Cargo.toml index a38a030e8b..fdd49cb841 100644 --- a/src/uu/uptime/Cargo.toml +++ b/src/uu/uptime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uptime" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "uptime ~ (uutils) display dynamic system information" diff --git a/src/uu/users/Cargo.toml b/src/uu/users/Cargo.toml index 32abd15819..023b34a3e2 100644 --- a/src/uu/users/Cargo.toml +++ b/src/uu/users/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_users" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "users ~ (uutils) display names of currently logged-in users" diff --git a/src/uu/vdir/Cargo.toml b/src/uu/vdir/Cargo.toml index 569807af6c..281e7158e0 100644 --- a/src/uu/vdir/Cargo.toml +++ b/src/uu/vdir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_vdir" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "shortcut to ls -l -b" diff --git a/src/uu/wc/Cargo.toml b/src/uu/wc/Cargo.toml index 40e0fd03b4..ca0eec9bc9 100644 --- a/src/uu/wc/Cargo.toml +++ b/src/uu/wc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_wc" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "wc ~ (uutils) display newline, word, and byte counts for input" diff --git a/src/uu/who/Cargo.toml b/src/uu/who/Cargo.toml index 31c5575085..5b5b57bf10 100644 --- a/src/uu/who/Cargo.toml +++ b/src/uu/who/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_who" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "who ~ (uutils) display information about currently logged-in users" diff --git a/src/uu/whoami/Cargo.toml b/src/uu/whoami/Cargo.toml index 15a7ad4ce4..7e13c14f3d 100644 --- a/src/uu/whoami/Cargo.toml +++ b/src/uu/whoami/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_whoami" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "whoami ~ (uutils) display user name of current effective user ID" diff --git a/src/uu/yes/Cargo.toml b/src/uu/yes/Cargo.toml index fd2aca5b49..fd3d9ddc0b 100644 --- a/src/uu/yes/Cargo.toml +++ b/src/uu/yes/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_yes" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "yes ~ (uutils) repeatedly display a line with STRING (or 'y')" diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 6eb852cdc1..1f10214895 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "uucore" -version = "0.0.17" +version = "0.0.18" authors = ["uutils developers"] license = "MIT" description = "uutils ~ 'core' uutils code library (cross-platform)" diff --git a/src/uucore_procs/Cargo.toml b/src/uucore_procs/Cargo.toml index c61d636734..6a44eacd42 100644 --- a/src/uucore_procs/Cargo.toml +++ b/src/uucore_procs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uucore_procs" -version = "0.0.17" +version = "0.0.18" authors = ["Roy Ivy III "] license = "MIT" description = "uutils ~ 'uucore' proc-macros" diff --git a/util/update-version.sh b/util/update-version.sh index 4b7b6d554e..2e2dca9030 100755 --- a/util/update-version.sh +++ b/util/update-version.sh @@ -11,8 +11,8 @@ # 6) Run util/publish.sh --do-it # 7) In some cases, you might have to fix dependencies and run import -FROM="0.0.16" -TO="0.0.17" +FROM="0.0.17" +TO="0.0.18" PROGS=$(ls -1d src/uu/*/Cargo.toml src/uu/stdbuf/src/libstdbuf/Cargo.toml src/uucore/Cargo.toml Cargo.toml) From 3c962fd627761d3cab5d4c013296e87d2ceafd06 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 08:11:09 +0000 Subject: [PATCH 052/477] chore(deps): update rust crate rstest to 0.17.0 --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d285d511a..5ba3fb4e86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1865,9 +1865,9 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] name = "rstest" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07f2d176c472198ec1e6551dc7da28f1c089652f66a7b722676c2238ebc0edf" +checksum = "de1bb486a691878cd320c2f0d319ba91eeaa2e894066d8b5f8f117c000e9d962" dependencies = [ "futures", "futures-timer", @@ -1877,9 +1877,9 @@ dependencies = [ [[package]] name = "rstest_macros" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7229b505ae0706e64f37ffc54a9c163e11022a6636d58fe1f3f52018257ff9f7" +checksum = "290ca1a1c8ca7edb7c3283bd44dc35dd54fdec6253a3912e201ba1072018fca8" dependencies = [ "cfg-if", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index e4575d5a5a..bb90be2c83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -488,7 +488,7 @@ uucore = { workspace=true, features=["entries", "process", "signals"] } walkdir = { workspace=true } is-terminal = { workspace=true } hex-literal = "0.3.4" -rstest = "0.16.0" +rstest = "0.17.0" [target.'cfg(any(target_os = "linux", target_os = "android"))'.dev-dependencies] procfs = { version = "0.15", default-features = false } From d8ee1833a454f616b9822b5ac9a43d9d9ea2ff1c Mon Sep 17 00:00:00 2001 From: Piotr Kwiecinski Date: Wed, 29 Mar 2023 10:59:24 +0200 Subject: [PATCH 053/477] pr: move help strings to markdown file --- src/uu/pr/pr.md | 33 +++++++++++++++++++++++++++++++++ src/uu/pr/src/pr.rs | 31 +++++-------------------------- 2 files changed, 38 insertions(+), 26 deletions(-) create mode 100644 src/uu/pr/pr.md diff --git a/src/uu/pr/pr.md b/src/uu/pr/pr.md new file mode 100644 index 0000000000..af38ef734e --- /dev/null +++ b/src/uu/pr/pr.md @@ -0,0 +1,33 @@ +# pr + +``` +pr [OPTIONS] [files]... +``` + +Write content of given file or standard input to standard output with pagination filter + +## After help + +`+PAGE` Begin output at page number page of the formatted input. +`-COLUMN` Produce multi-column output. See `--column` + +The pr utility is a printing and pagination filter +for text files. When multiple input files are specified, +each is read, formatted, and written to standard +output. By default, the input is separated +into 66-line pages, each with + +o A 5-line header with the page number, date, +time, and the pathname of the file. + +o A 5-line trailer consisting of blank lines. + +If standard output is associated with a terminal, +diagnostic messages are suppressed until the pr +utility has completed processing. + +When multiple column output is specified, text columns +are of equal width. By default, text columns +are separated by at least one ``. Input lines +that do not fit into a text column are truncated. +Lines are not truncated under single column output. diff --git a/src/uu/pr/src/pr.rs b/src/uu/pr/src/pr.rs index 9f1b644837..63df207daf 100644 --- a/src/uu/pr/src/pr.rs +++ b/src/uu/pr/src/pr.rs @@ -21,33 +21,11 @@ use time::OffsetDateTime; use quick_error::quick_error; use uucore::display::Quotable; use uucore::error::UResult; +use uucore::{format_usage, help_about, help_section, help_usage}; -const ABOUT: &str = - "Write content of given file or standard input to standard output with pagination filter"; -const AFTER_HELP: &str = - " +PAGE\n Begin output at page number page of the formatted input. - -COLUMN\n Produce multi-column output. See --column - -The pr utility is a printing and pagination filter -for text files. When multiple input files are specified, -each is read, formatted, and written to standard -output. By default, the input is separated -into 66-line pages, each with - -o A 5-line header with the page number, date, - time, and the pathname of the file. - -o A 5-line trailer consisting of blank lines. - -If standard output is associated with a terminal, -diagnostic messages are suppressed until the pr -utility has completed processing. - -When multiple column output is specified, text columns -are of equal width. By default text columns -are separated by at least one . Input lines -that do not fit into a text column are truncated. -Lines are not truncated under single column output."; +const ABOUT: &str = help_about!("pr.md"); +const USAGE: &str = help_usage!("pr.md"); +const AFTER_HELP: &str = help_section!("after help", "pr.md"); const TAB: char = '\t'; const LINES_PER_PAGE: usize = 66; const LINES_PER_PAGE_FOR_FORM_FEED: usize = 63; @@ -195,6 +173,7 @@ pub fn uu_app() -> Command { .version(crate_version!()) .about(ABOUT) .after_help(AFTER_HELP) + .override_usage(format_usage(USAGE)) .infer_long_args(true) .args_override_self(true) .disable_help_flag(true) From 8f7ddf2818c9fd955b5b91efd042506a98ec14e1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 09:37:24 +0000 Subject: [PATCH 054/477] chore(deps): update rust crate clap_complete to 4.2 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18db41c3d5..b40f534a54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -289,9 +289,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.1.5" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37686beaba5ac9f3ab01ee3172f792fc6ffdd685bfb9e63cfef02c0571a4e8e1" +checksum = "01c22dcfb410883764b29953103d9ef7bb8fe21b3fa1158bc99986c2067294bd" dependencies = [ "clap", ] diff --git a/Cargo.toml b/Cargo.toml index dad0615136..eac70f50a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -270,7 +270,7 @@ bytecount = "0.6.3" byteorder = "1.4.3" chrono = { version="^0.4.24", default-features=false, features=["std", "alloc", "clock"]} clap = { version = "4.2", features = ["wrap_help", "cargo"] } -clap_complete = "4.1" +clap_complete = "4.2" clap_mangen = "0.2" compare = "0.1.0" coz = { version = "0.1.3" } From 012c5eaa1f7b6989644f0a9e27475f2ff82761be Mon Sep 17 00:00:00 2001 From: Miles Liu Date: Wed, 29 Mar 2023 15:05:49 +0800 Subject: [PATCH 055/477] unlink: move help strings to markdown file --- src/uu/unlink/src/unlink.rs | 5 ++++- src/uu/unlink/unlink.md | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/uu/unlink/unlink.md diff --git a/src/uu/unlink/src/unlink.rs b/src/uu/unlink/src/unlink.rs index 99dd557918..5d1594a05c 100644 --- a/src/uu/unlink/src/unlink.rs +++ b/src/uu/unlink/src/unlink.rs @@ -16,8 +16,10 @@ use clap::{crate_version, Arg, Command}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult}; +use uucore::{format_usage, help_about, help_usage}; -static ABOUT: &str = "Unlink the file at FILE."; +const ABOUT: &str = help_about!("unlink.md"); +const USAGE: &str = help_usage!("unlink.md"); static OPT_PATH: &str = "FILE"; #[uucore::main] @@ -33,6 +35,7 @@ pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(crate_version!()) .about(ABOUT) + .override_usage(format_usage(USAGE)) .infer_long_args(true) .arg( Arg::new(OPT_PATH) diff --git a/src/uu/unlink/unlink.md b/src/uu/unlink/unlink.md new file mode 100644 index 0000000000..4468fb2045 --- /dev/null +++ b/src/uu/unlink/unlink.md @@ -0,0 +1,7 @@ +# unlink + +``` +unlink [FILE] +``` + +Unlink the file at `FILE`. From 1d3efa841fd5388a3d287da875e5ce31e2137db5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 14:28:04 +0000 Subject: [PATCH 056/477] chore(deps): update rust crate fundu to 0.5.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea6e09d518..cc8b45e3a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -952,9 +952,9 @@ dependencies = [ [[package]] name = "fundu" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46d94380e064d45b7067806001781761c861c9c4785bca7baf98361fa2149b32" +checksum = "bd020eeb034c9fc682e8fe6b9a28e1c0eda92eeb347c38776c09a0b227cdf9e5" [[package]] name = "futures" diff --git a/Cargo.toml b/Cargo.toml index b1d8f8f9e1..9ed732a5fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -282,7 +282,7 @@ filetime = "0.2" fnv = "1.0.7" fs_extra = "1.3.0" fts-sys = "0.2" -fundu = "0.4.3" +fundu = "0.5.0" gcd = "2.3" glob = "0.3.1" half = "2.2" From c71735bf50b38fb685935b8cc0a1289de7dea2a1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 14:32:56 +0000 Subject: [PATCH 057/477] chore(deps): update rust crate unicode-segmentation to 1.10.1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea6e09d518..d7bc4add08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2325,9 +2325,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" diff --git a/Cargo.toml b/Cargo.toml index b1d8f8f9e1..bfa866c36a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -322,7 +322,7 @@ terminal_size = "0.2.5" textwrap = { version="0.16.0", features=["terminal_size"] } thiserror = "1.0" time = { version="0.3" } -unicode-segmentation = "1.9.0" +unicode-segmentation = "1.10.1" unicode-width = "0.1.10" utf-8 = "0.7.6" walkdir = "2.2" From 889df29cba951df33ce7cb589aacfe11052502cb Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 29 Mar 2023 21:15:24 +0200 Subject: [PATCH 058/477] dircolors : replace filter_map by map_while --- src/uu/dircolors/src/dircolors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index e960fdb138..6b2bd9a98b 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -149,7 +149,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Ok(f) => { let fin = BufReader::new(f); result = parse( - fin.lines().filter_map(Result::ok), + fin.lines().map_while(Result::ok), &out_format, &path.to_string_lossy(), ); From a886db4ae19fbfa4c9c241cd62ecba65137d45e3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:18:11 +0000 Subject: [PATCH 059/477] chore(deps): update rust crate unindent to 0.2 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88736c7baf..6da49d56a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2343,9 +2343,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "unindent" -version = "0.1.10" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ee9362deb4a96cef4d437d1ad49cffc9b9e92d202b6995674e928ce684f112" +checksum = "5aa30f5ea51ff7edfc797c6d3f9ec8cbd8cfedef5371766b7181d33977f4814f" [[package]] name = "users" diff --git a/Cargo.toml b/Cargo.toml index 9abe7f11ef..08f8a48f1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -483,7 +483,7 @@ regex = { workspace=true } sha1 = { version="0.10", features=["std"] } tempfile = { workspace=true } time = { workspace=true, features=["local-offset"] } -unindent = "0.1" +unindent = "0.2" uucore = { workspace=true, features=["entries", "process", "signals"] } walkdir = { workspace=true } is-terminal = { workspace=true } From 59c210d0f9c69282f25691d15354a4b8f43fd11f Mon Sep 17 00:00:00 2001 From: Miles Liu Date: Wed, 29 Mar 2023 18:07:33 +0800 Subject: [PATCH 060/477] uniq: move help strings to markdown file --- src/uu/uniq/src/uniq.rs | 14 +++++--------- src/uu/uniq/uniq.md | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 src/uu/uniq/uniq.md diff --git a/src/uu/uniq/src/uniq.rs b/src/uu/uniq/src/uniq.rs index cd4d728d9a..16b4ab2c49 100644 --- a/src/uu/uniq/src/uniq.rs +++ b/src/uu/uniq/src/uniq.rs @@ -12,15 +12,11 @@ use std::path::Path; use std::str::FromStr; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; -use uucore::format_usage; +use uucore::{format_usage, help_about, help_section, help_usage}; -const ABOUT: &str = "Report or omit repeated lines."; -const USAGE: &str = "{} [OPTION]... [INPUT [OUTPUT]]..."; -const LONG_USAGE: &str = "\ - Filter adjacent matching lines from INPUT (or standard input),\n\ - writing to OUTPUT (or standard output).\n\n\ - Note: 'uniq' does not detect repeated lines unless they are adjacent.\n\ - You may want to sort the input first, or use 'sort -u' without 'uniq'."; +const ABOUT: &str = help_about!("uniq.md"); +const USAGE: &str = help_usage!("uniq.md"); +const AFTER_HELP: &str = help_section!("after help", "uniq.md"); pub mod options { pub static ALL_REPEATED: &str = "all-repeated"; @@ -247,7 +243,7 @@ fn opt_parsed(opt_name: &str, matches: &ArgMatches) -> UResult UResult<()> { - let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; + let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; let files: Vec = matches .get_many::(ARG_FILES) diff --git a/src/uu/uniq/uniq.md b/src/uu/uniq/uniq.md new file mode 100644 index 0000000000..dea57081b7 --- /dev/null +++ b/src/uu/uniq/uniq.md @@ -0,0 +1,15 @@ +# uniq + +``` +uniq [OPTION]... [INPUT [OUTPUT]]... +``` + +Report or omit repeated lines. + +## After help + +Filter adjacent matching lines from `INPUT` (or standard input), +writing to `OUTPUT` (or standard output). + +Note: `uniq` does not detect repeated lines unless they are adjacent. +You may want to sort the input first, or use `sort -u` without `uniq`. From c29b52a381ce518eb6110cfcb4354e5c41678c07 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 05:56:43 +0000 Subject: [PATCH 061/477] chore(deps): update rust crate walkdir to 2.3 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 062e74e934..94b10cce93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -325,7 +325,7 @@ time = { version="0.3" } unicode-segmentation = "1.10.1" unicode-width = "0.1.10" utf-8 = "0.7.6" -walkdir = "2.2" +walkdir = "2.3" winapi-util = "0.1.5" windows-sys = { version="0.42.0", default-features=false } xattr = "0.2.3" From 4a89f4ab968c7d82063477a2bfb9ba7b1c7a66d4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 05:59:08 +0000 Subject: [PATCH 062/477] fix(deps): update rust crate data-encoding to 2.3 --- src/uucore/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 6eb852cdc1..482c638102 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -29,7 +29,7 @@ itertools = { version="0.10.5", optional=true } thiserror = { workspace=true, optional=true } time = { workspace=true, optional=true, features = ["formatting", "local-offset", "macros"] } # * "problem" dependencies (pinned) -data-encoding = { version="2.1", optional=true } +data-encoding = { version="2.3", optional=true } data-encoding-macro = { version="0.1.12", optional=true } z85 = { version="3.0.5", optional=true } libc = { version="0.2.140", optional=true } From 2945d6b6b975fdc1c2826f70e0ede340a9022584 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 06:11:01 +0000 Subject: [PATCH 063/477] fix(deps): update rust crate wild to 2.1 --- src/uucore/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 6eb852cdc1..1641d99f80 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -22,7 +22,7 @@ clap = { workspace=true } uucore_procs = { workspace=true } dns-lookup = { version="1.0.8", optional=true } dunce = "1.0.3" -wild = "2.0" +wild = "2.1" glob = "0.3.1" # * optional itertools = { version="0.10.5", optional=true } From 5398449267df327ba040845e2c6c6331bb2b94f2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 08:05:55 +0000 Subject: [PATCH 064/477] chore(deps): update rust crate xattr to v1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1e8dc1ff3..56c5761487 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3628,9 +3628,9 @@ checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "xattr" -version = "0.2.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +checksum = "ea263437ca03c1522846a4ddafbca2542d0ad5ed9b784909d4b27b76f62bc34a" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index 1bdf0cb1d1..b0eebac74a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -328,7 +328,7 @@ utf-8 = "0.7.6" walkdir = "2.2" winapi-util = "0.1.5" windows-sys = { version="0.42.0", default-features=false } -xattr = "0.2.3" +xattr = "1.0.0" zip = { version = "0.6.4", default_features=false, features=["deflate"] } hex = "0.4.3" From f6485e07cbec3b24fe3510b79540f11365569baa Mon Sep 17 00:00:00 2001 From: Piotr Kwiecinski Date: Thu, 30 Mar 2023 10:59:43 +0200 Subject: [PATCH 065/477] pr: use paragraphs wider in markdown file --- src/uu/pr/pr.md | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/uu/pr/pr.md b/src/uu/pr/pr.md index af38ef734e..2c246b25f1 100644 --- a/src/uu/pr/pr.md +++ b/src/uu/pr/pr.md @@ -11,23 +11,17 @@ Write content of given file or standard input to standard output with pagination `+PAGE` Begin output at page number page of the formatted input. `-COLUMN` Produce multi-column output. See `--column` -The pr utility is a printing and pagination filter -for text files. When multiple input files are specified, -each is read, formatted, and written to standard -output. By default, the input is separated -into 66-line pages, each with +The pr utility is a printing and pagination filter for text files. +When multiple input files are specified, each is read, formatted, and written to standard output. +By default, the input is separated into 66-line pages, each with -o A 5-line header with the page number, date, -time, and the pathname of the file. +* A 5-line header with the page number, date, time, and the pathname of the file. +* A 5-line trailer consisting of blank lines. -o A 5-line trailer consisting of blank lines. - -If standard output is associated with a terminal, -diagnostic messages are suppressed until the pr +If standard output is associated with a terminal, diagnostic messages are suppressed until the pr utility has completed processing. -When multiple column output is specified, text columns -are of equal width. By default, text columns -are separated by at least one ``. Input lines -that do not fit into a text column are truncated. +When multiple column output is specified, text columns are of equal width. +By default, text columns are separated by at least one ``. +Input lines that do not fit into a text column are truncated. Lines are not truncated under single column output. From ce6bacd87a327d4e7a25bffad1d83b85959246fe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Mar 2023 13:44:57 +0000 Subject: [PATCH 066/477] fix(deps): update rust crate windows-sys to 0.45.0 --- Cargo.lock | 18 +++++++++--------- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56c5761487..79432cfcab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2529,7 +2529,7 @@ dependencies = [ "clap", "libc", "uucore", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -2585,7 +2585,7 @@ dependencies = [ "clap", "glob", "uucore", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -2708,7 +2708,7 @@ dependencies = [ "clap", "hostname", "uucore", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3010,7 +3010,7 @@ dependencies = [ "libc", "uucore", "walkdir", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3155,7 +3155,7 @@ dependencies = [ "libc", "nix", "uucore", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3182,7 +3182,7 @@ dependencies = [ "same-file", "uucore", "winapi-util", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3222,7 +3222,7 @@ dependencies = [ "filetime", "time", "uucore", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3356,7 +3356,7 @@ dependencies = [ "clap", "libc", "uucore", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3399,7 +3399,7 @@ dependencies = [ "walkdir", "wild", "winapi-util", - "windows-sys 0.42.0", + "windows-sys 0.45.0", "z85", ] diff --git a/Cargo.toml b/Cargo.toml index 6c1e33b4d1..72f947ed35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -327,7 +327,7 @@ unicode-width = "0.1.10" utf-8 = "0.7.6" walkdir = "2.3" winapi-util = "0.1.5" -windows-sys = { version="0.42.0", default-features=false } +windows-sys = { version="0.45.0", default-features=false } xattr = "1.0.0" zip = { version = "0.6.4", default_features=false, features=["deflate"] } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 1641d99f80..03b256f460 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -57,7 +57,7 @@ once_cell = { workspace=true } [target.'cfg(target_os = "windows")'.dependencies] winapi-util = { version= "0.1.5", optional=true } -windows-sys = { version = "0.42.0", optional = true, default-features = false, features = ["Win32_Storage_FileSystem", "Win32_Foundation", "Win32_System_WindowsProgramming"] } +windows-sys = { version = "0.45.0", optional = true, default-features = false, features = ["Win32_Storage_FileSystem", "Win32_Foundation", "Win32_System_WindowsProgramming"] } [features] default = [] From 0fa08757fa6953a1aa7734e20917b88ef46c8391 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 31 Mar 2023 08:16:46 +0200 Subject: [PATCH 067/477] wc: implement --total --- src/uu/wc/src/wc.rs | 83 +++++++++++++++++++++++++++++++++------- tests/by-util/test_wc.rs | 56 +++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 14 deletions(-) diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 0b7b164a81..984722dd1f 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -42,6 +42,7 @@ struct Settings { show_max_line_length: bool, files0_from_stdin_mode: bool, title_quoting_style: QuotingStyle, + total_when: TotalWhen, } impl Settings { @@ -65,6 +66,7 @@ impl Settings { show_max_line_length: matches.get_flag(options::MAX_LINE_LENGTH), files0_from_stdin_mode, title_quoting_style, + total_when: matches.get_one::(options::TOTAL).unwrap().into(), }; if settings.show_bytes @@ -84,6 +86,7 @@ impl Settings { show_max_line_length: false, files0_from_stdin_mode, title_quoting_style: settings.title_quoting_style, + total_when: settings.total_when, } } @@ -107,6 +110,7 @@ pub mod options { pub static FILES0_FROM: &str = "files0-from"; pub static LINES: &str = "lines"; pub static MAX_LINE_LENGTH: &str = "max-line-length"; + pub static TOTAL: &str = "total"; pub static WORDS: &str = "words"; } @@ -160,6 +164,37 @@ impl Input { } } +/// When to show the "total" line +#[derive(PartialEq)] +enum TotalWhen { + Auto, + Always, + Only, + Never, +} + +impl From<&String> for TotalWhen { + fn from(s: &String) -> Self { + match s.as_ref() { + "auto" => Self::Auto, + "always" => Self::Always, + "only" => Self::Only, + "never" => Self::Never, + _ => unreachable!("Should have been caught by clap"), + } + } +} + +impl TotalWhen { + fn is_total_row_visible(&self, num_inputs: usize) -> bool { + match self { + Self::Auto => num_inputs > 1, + Self::Always | Self::Only => true, + Self::Never => false, + } + } +} + #[derive(Debug)] enum WcError { FilesDisabled(String), @@ -246,6 +281,15 @@ pub fn uu_app() -> Command { .help("print the length of the longest line") .action(ArgAction::SetTrue), ) + .arg( + Arg::new(options::TOTAL) + .long(options::TOTAL) + .value_parser(["auto", "always", "only", "never"]) + .default_value("auto") + .hide_default_value(true) + .value_name("WHEN") + .help("when to print a line with total counts"), + ) .arg( Arg::new(options::WORDS) .short('w') @@ -561,11 +605,19 @@ fn compute_number_width(inputs: &[Input], settings: &Settings) -> usize { } fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> { - let number_width = compute_number_width(inputs, settings); - let mut total_word_count = WordCount::default(); - let num_inputs = inputs.len(); + let (number_width, are_stats_visible, total_row_title) = + if settings.total_when == TotalWhen::Only { + (1, false, None) + } else { + let number_width = compute_number_width(inputs, settings); + let title = Some(String::from("total")); + + (number_width, true, title) + }; + + let is_total_row_visible = settings.total_when.is_total_row_visible(inputs.len()); for input in inputs { let word_count = match word_count_from_input(input, settings) { @@ -595,20 +647,23 @@ fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> { }; total_word_count += word_count; let result = word_count.with_title(input.to_title(&settings.title_quoting_style)); - if let Err(err) = print_stats(settings, &result, number_width) { - show!(USimpleError::new( - 1, - format!( - "failed to print result for {}: {}", - &result.title.unwrap_or_else(|| String::from("")), - err, - ), - )); + + if are_stats_visible { + if let Err(err) = print_stats(settings, &result, number_width) { + show!(USimpleError::new( + 1, + format!( + "failed to print result for {}: {}", + &result.title.unwrap_or_else(|| String::from("")), + err, + ), + )); + } } } - if num_inputs > 1 { - let total_result = total_word_count.with_title(Some(String::from("total"))); + if is_total_row_visible { + let total_result = total_word_count.with_title(total_row_title); if let Err(err) = print_stats(settings, &total_result, number_width) { show!(USimpleError::new( 1, diff --git a/tests/by-util/test_wc.rs b/tests/by-util/test_wc.rs index 3cda99270f..4516f770fd 100644 --- a/tests/by-util/test_wc.rs +++ b/tests/by-util/test_wc.rs @@ -464,3 +464,59 @@ fn test_files0_from_with_stdin_try_read_from_stdin() { .stderr_contains(MSG) .stdout_is(""); } + +#[test] +fn test_total_auto() { + new_ucmd!() + .args(&["lorem_ipsum.txt", "--total=auto"]) + .run() + .stdout_is(" 13 109 772 lorem_ipsum.txt\n"); + + new_ucmd!() + .args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=auto"]) + .run() + .stdout_is( + " 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 31 313 1887 total\n", + ); +} + +#[test] +fn test_total_always() { + new_ucmd!() + .args(&["lorem_ipsum.txt", "--total=always"]) + .run() + .stdout_is(" 13 109 772 lorem_ipsum.txt\n 13 109 772 total\n"); + + new_ucmd!() + .args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=always"]) + .run() + .stdout_is( + " 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 31 313 1887 total\n", + ); +} + +#[test] +fn test_total_never() { + new_ucmd!() + .args(&["lorem_ipsum.txt", "--total=never"]) + .run() + .stdout_is(" 13 109 772 lorem_ipsum.txt\n"); + + new_ucmd!() + .args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=never"]) + .run() + .stdout_is(" 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n"); +} + +#[test] +fn test_total_only() { + new_ucmd!() + .args(&["lorem_ipsum.txt", "--total=only"]) + .run() + .stdout_is("13 109 772\n"); + + new_ucmd!() + .args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=only"]) + .run() + .stdout_is("31 313 1887\n"); +} From cf9c75d364d91ac9b5fd207c29baa67bd96f0ac3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 2 Apr 2023 06:17:07 +0000 Subject: [PATCH 068/477] chore(deps): update rust crate hex-literal to 0.4.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 994e9ebc27..039232ff9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1125,9 +1125,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "4bcb5b3e439c92a7191df2f9bbe733de8de55c3f86368cdb1c63f8be7e9e328e" [[package]] name = "hostname" diff --git a/Cargo.toml b/Cargo.toml index 0ca4b5906f..8e6ad2026d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -487,7 +487,7 @@ unindent = "0.2" uucore = { workspace=true, features=["entries", "process", "signals"] } walkdir = { workspace=true } is-terminal = { workspace=true } -hex-literal = "0.3.4" +hex-literal = "0.4.0" rstest = "0.17.0" [target.'cfg(any(target_os = "linux", target_os = "android"))'.dev-dependencies] From 0161775af35e9dc32ea4483a93d41e09c1db9ef9 Mon Sep 17 00:00:00 2001 From: m11o Date: Mon, 3 Apr 2023 00:37:14 +0900 Subject: [PATCH 069/477] pinky: move help strings to markdown file --- src/uu/pinky/pinky.md | 7 +++++++ src/uu/pinky/src/pinky.rs | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 src/uu/pinky/pinky.md diff --git a/src/uu/pinky/pinky.md b/src/uu/pinky/pinky.md new file mode 100644 index 0000000000..9eadd3c44b --- /dev/null +++ b/src/uu/pinky/pinky.md @@ -0,0 +1,7 @@ +# pinky + +``` +pinky [OPTION]... [USER]... +``` + +Lightweight finger diff --git a/src/uu/pinky/src/pinky.rs b/src/uu/pinky/src/pinky.rs index 18f72638be..5aa14ac639 100644 --- a/src/uu/pinky/src/pinky.rs +++ b/src/uu/pinky/src/pinky.rs @@ -20,10 +20,10 @@ use std::os::unix::fs::MetadataExt; use clap::{crate_version, Arg, ArgAction, Command}; use std::path::PathBuf; -use uucore::format_usage; +use uucore::{format_usage, help_about, help_usage}; -static ABOUT: &str = "Lightweight finger"; -const USAGE: &str = "{} [OPTION]... [USER]..."; +static ABOUT: &str = help_about!("pinky.md"); +const USAGE: &str = help_usage!("pinky.md"); mod options { pub const LONG_FORMAT: &str = "long_format"; From 0a6f1758b913b8bd9a7190f1e0654ede054a1ac4 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 2 Apr 2023 20:59:02 +0200 Subject: [PATCH 070/477] add missing feature --- src/uu/hashsum/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/hashsum/Cargo.toml b/src/uu/hashsum/Cargo.toml index a75141e93f..638b3b60f5 100644 --- a/src/uu/hashsum/Cargo.toml +++ b/src/uu/hashsum/Cargo.toml @@ -16,7 +16,7 @@ path = "src/hashsum.rs" [dependencies] clap = { workspace=true } -uucore = { workspace=true } +uucore = { workspace=true, features=["sum"] } memchr = { workspace=true } regex = { workspace=true } hex = { workspace=true } From eb11c4006f3286efee5226e546f119a20998266b Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 2 Apr 2023 21:00:08 +0200 Subject: [PATCH 071/477] tee: add missing feature --- src/uu/tee/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/tee/Cargo.toml b/src/uu/tee/Cargo.toml index 36e4f0dd45..b0cf0e916a 100644 --- a/src/uu/tee/Cargo.toml +++ b/src/uu/tee/Cargo.toml @@ -17,7 +17,7 @@ path = "src/tee.rs" [dependencies] clap = { workspace=true } libc = { workspace=true } -uucore = { workspace=true, features=["libc"] } +uucore = { workspace=true, features=["libc", "signals"] } [[bin]] name = "tee" From 087767769709e58104833063084e3ecf343e4108 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Mon, 3 Apr 2023 07:26:34 +0900 Subject: [PATCH 072/477] Update src/uu/pinky/pinky.md Co-authored-by: Sylvestre Ledru --- src/uu/pinky/pinky.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/pinky/pinky.md b/src/uu/pinky/pinky.md index 9eadd3c44b..965ae4cd09 100644 --- a/src/uu/pinky/pinky.md +++ b/src/uu/pinky/pinky.md @@ -4,4 +4,4 @@ pinky [OPTION]... [USER]... ``` -Lightweight finger +Displays brief user information on Unix-based systems From cae3e6d13f4f459bf87ab6222cce8fe27f91d1b3 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:57:01 +0900 Subject: [PATCH 073/477] Update src/uu/pinky/src/pinky.rs Co-authored-by: Daniel Hofstetter --- src/uu/pinky/src/pinky.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/pinky/src/pinky.rs b/src/uu/pinky/src/pinky.rs index 5aa14ac639..172a9e1380 100644 --- a/src/uu/pinky/src/pinky.rs +++ b/src/uu/pinky/src/pinky.rs @@ -22,7 +22,7 @@ use clap::{crate_version, Arg, ArgAction, Command}; use std::path::PathBuf; use uucore::{format_usage, help_about, help_usage}; -static ABOUT: &str = help_about!("pinky.md"); +const ABOUT: &str = help_about!("pinky.md"); const USAGE: &str = help_usage!("pinky.md"); mod options { From 1c9b49025b90120d666382138e38d6e4adbbd4fe Mon Sep 17 00:00:00 2001 From: Piotr Kwiecinski Date: Mon, 3 Apr 2023 16:54:37 +0200 Subject: [PATCH 074/477] true: move help strings to markdown file --- src/uu/true/src/true.rs | 9 ++------- src/uu/true/true.md | 11 +++++++++++ 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 src/uu/true/true.md diff --git a/src/uu/true/src/true.rs b/src/uu/true/src/true.rs index 7c373fb7ab..334652ce8d 100644 --- a/src/uu/true/src/true.rs +++ b/src/uu/true/src/true.rs @@ -7,14 +7,9 @@ use clap::{Arg, ArgAction, Command}; use std::{ffi::OsString, io::Write}; use uucore::error::{set_exit_code, UResult}; +use uucore::help_about; -static ABOUT: &str = "\ -Returns true, a successful exit status. - -Immediately returns with the exit status `0`, except when invoked with one of the recognized -options. In those cases it will try to write the help or version text. Any IO error during this -operation causes the program to return `1` instead. -"; +const ABOUT: &str = help_about!("true.md"); #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { diff --git a/src/uu/true/true.md b/src/uu/true/true.md new file mode 100644 index 0000000000..b21c9616e1 --- /dev/null +++ b/src/uu/true/true.md @@ -0,0 +1,11 @@ +# true + +``` +true +``` + +Returns true, a successful exit status. + +Immediately returns with the exit status `0`, except when invoked with one of the recognized +options. In those cases it will try to write the help or version text. Any IO error during this +operation causes the program to return `1` instead. From f920d44e62de3060f9f338d24e78c2738a442918 Mon Sep 17 00:00:00 2001 From: Piotr Kwiecinski Date: Mon, 3 Apr 2023 17:06:58 +0200 Subject: [PATCH 075/477] unexpand: move help strings to markdown file --- src/uu/unexpand/src/unexpand.rs | 7 +++---- src/uu/unexpand/unexpand.md | 8 ++++++++ 2 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 src/uu/unexpand/unexpand.md diff --git a/src/uu/unexpand/src/unexpand.rs b/src/uu/unexpand/src/unexpand.rs index df2348a8c9..da60aa1c2b 100644 --- a/src/uu/unexpand/src/unexpand.rs +++ b/src/uu/unexpand/src/unexpand.rs @@ -19,11 +19,10 @@ use std::str::from_utf8; use unicode_width::UnicodeWidthChar; use uucore::display::Quotable; use uucore::error::{FromIo, UError, UResult}; -use uucore::{crash, crash_if_err, format_usage}; +use uucore::{crash, crash_if_err, format_usage, help_about, help_usage}; -static USAGE: &str = "{} [OPTION]... [FILE]..."; -static ABOUT: &str = "Convert blanks in each FILE to tabs, writing to standard output.\n\n\ - With no FILE, or when FILE is -, read standard input."; +const USAGE: &str = help_usage!("unexpand.md"); +const ABOUT: &str = help_about!("unexpand.md"); const DEFAULT_TABSTOP: usize = 8; diff --git a/src/uu/unexpand/unexpand.md b/src/uu/unexpand/unexpand.md new file mode 100644 index 0000000000..6fc69b93a3 --- /dev/null +++ b/src/uu/unexpand/unexpand.md @@ -0,0 +1,8 @@ +# unexpand + +``` +unexpand [OPTION]... [FILE]... +``` + +Convert blanks in each `FILE` to tabs, writing to standard output. +With no `FILE`, or when `FILE` is `-`, read standard input. From f5f96d9bcee78d517869f64d6f3b9bed5af3b3aa Mon Sep 17 00:00:00 2001 From: m11o Date: Tue, 4 Apr 2023 00:44:41 +0900 Subject: [PATCH 076/477] printf: move help strings to markdown file --- src/uu/printf/printf.md | 259 ++++++++++++++++++++++++++++++++++++ src/uu/printf/src/printf.rs | 259 +----------------------------------- 2 files changed, 263 insertions(+), 255 deletions(-) create mode 100644 src/uu/printf/printf.md diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md new file mode 100644 index 0000000000..703a25fdb2 --- /dev/null +++ b/src/uu/printf/printf.md @@ -0,0 +1,259 @@ +# printf + +``` +printf FORMATSTRING [ARGUMENT]... +``` + +Print output based off of the format string and proceeding arguments. + +## After Help + +basic anonymous string templating: + +prints format string at least once, repeating as long as there are remaining arguments +output prints escaped literals in the format string as character literals +output replaces anonymous fields with the next unused argument, formatted according to the field. + +Prints the , replacing escaped character sequences with character literals +and substitution field sequences with passed arguments + +literally, with the exception of the below +escaped character sequences, and the substitution sequences described further down. + +ESCAPE SEQUENCES + +The following escape sequences, organized here in alphabetical order, +will print the corresponding character literal: + +\" double quote + +\\\\ backslash + +\\a alert (BEL) + +\\b backspace + +\\c End-of-Input + +\\e escape + +\\f form feed + +\\n new line + +\\r carriage return + +\\t horizontal tab + +\\v vertical tab + +\\NNN byte with value expressed in octal value NNN (1 to 3 digits) +values greater than 256 will be treated + +\\xHH byte with value expressed in hexadecimal value NN (1 to 2 digits) + +\\uHHHH Unicode (IEC 10646) character with value expressed in hexadecimal value HHHH (4 digits) + +\\uHHHH Unicode character with value expressed in hexadecimal value HHHH (8 digits) + +%% a single % + +SUBSTITUTIONS + +SUBSTITUTION QUICK REFERENCE + +Fields + +%s - string +%b - string parsed for literals +second parameter is max length + +%c - char +no second parameter + +%i or %d - 64-bit integer +%u - 64 bit unsigned integer +%x or %X - 64-bit unsigned integer as hex +%o - 64-bit unsigned integer as octal +second parameter is min-width, integer +output below that width is padded with leading zeroes + +%f or %F - decimal floating point value +%e or %E - scientific notation floating point value +%g or %G - shorter of specially interpreted decimal or SciNote floating point value. +second parameter is +-max places after decimal point for floating point output +-max number of significant digits for scientific notation output + +parameterizing fields + +examples: + +printf '%4.3i' 7 +has a first parameter of 4 +and a second parameter of 3 +will result in ' 007' + +printf '%.1s' abcde +has no first parameter +and a second parameter of 1 +will result in 'a' + +printf '%4c' q +has a first parameter of 4 +and no second parameter +will result in ' q' + +The first parameter of a field is the minimum width to pad the output to +if the output is less than this absolute value of this width, +it will be padded with leading spaces, or, if the argument is negative, +with trailing spaces. the default is zero. + +The second parameter of a field is particular to the output field type. +defaults can be found in the full substitution help below + +special prefixes to numeric arguments +0 (e.g. 010) - interpret argument as octal (integer output fields only) +0x (e.g. 0xABC) - interpret argument as hex (numeric output fields only) +\' (e.g. \'a) - interpret argument as a character constant + +HOW TO USE SUBSTITUTIONS + +Substitutions are used to pass additional argument(s) into the FORMAT string, to be formatted a +particular way. E.g. + + printf 'the letter %X comes before the letter %X' 10 11 + +will print + +'the letter A comes before the letter B' + +because the substitution field %X means +'take an integer argument and write it as a hexadecimal number' + +Passing more arguments than are in the format string will cause the format string to be +repeated for the remaining substitutions + +printf 'it is %i F in %s \n' 22 Portland 25 Boston 27 New York + +will print + +'it is 22 F in Portland +it is 25 F in Boston +it is 27 F in Boston +' +If a format string is printed but there are less arguments remaining +than there are substitution fields, substitution fields without +an argument will default to empty strings, or for numeric fields +the value 0 + +AVAILABLE SUBSTITUTIONS + +This program, like GNU coreutils printf, +interprets a modified subset of the POSIX C printf spec, +a quick reference to substitutions is below. + +STRING SUBSTITUTIONS +All string fields have a 'max width' parameter +%.3s means 'print no more than three characters of the original input' + +%s - string + +%b - escaped string - the string will be checked for any escaped literals from +the escaped literal list above, and translate them to literal characters. +e.g. \\n will be transformed into a newline character. + + One special rule about %b mode is that octal literals are interpreted differently + In arguments passed by %b, pass octal-interpreted literals must be in the form of \\0NNN + instead of \\NNN. (Although, for legacy reasons, octal literals in the form of \\NNN will + still be interpreted and not throw a warning, you will have problems if you use this for a + literal whose code begins with zero, as it will be viewed as in \\0NNN form.) + +CHAR SUBSTITUTIONS +The character field does not have a secondary parameter. + +%c - a single character + +INTEGER SUBSTITUTIONS +All integer fields have a 'pad with zero' parameter +%.4i means an integer which if it is less than 4 digits in length, +is padded with leading zeros until it is 4 digits in length. + +%d or %i - 64-bit integer + +%u - 64 bit unsigned integer + +%x or %X - 64 bit unsigned integer printed in Hexadecimal (base 16) +%X instead of %x means to use uppercase letters for 'a' through 'f' + +%o - 64 bit unsigned integer printed in octal (base 8) + +FLOATING POINT SUBSTITUTIONS + +All floating point fields have a 'max decimal places / max significant digits' parameter +%.10f means a decimal floating point with 7 decimal places past 0 +%.10e means a scientific notation number with 10 significant digits +%.10g means the same behavior for decimal and Sci. Note, respectively, and provides the shorter +of each's output. + +Like with GNU coreutils, the value after the decimal point is these outputs is parsed as a +double first before being rendered to text. For both implementations do not expect meaningful +precision past the 18th decimal place. When using a number of decimal places that is 18 or +higher, you can expect variation in output between GNU coreutils printf and this printf at the +18th decimal place of +/- 1 + +%f - floating point value presented in decimal, truncated and displayed to 6 decimal places by +default. There is not past-double behavior parity with Coreutils printf, values are not +estimated or adjusted beyond input values. + +%e or %E - floating point value presented in scientific notation +7 significant digits by default +%E means use to use uppercase E for the mantissa. + +%g or %G - floating point value presented in the shorter of decimal and scientific notation +behaves differently from %f and %E, please see posix printf spec for full details, +some examples of different behavior: + + Sci Note has 6 significant digits by default + Trailing zeroes are removed + Instead of being truncated, digit after last is rounded + +Like other behavior in this utility, the design choices of floating point +behavior in this utility is selected to reproduce in exact +the behavior of GNU coreutils' printf from an inputs and outputs standpoint. + +USING PARAMETERS +Most substitution fields can be parameterized using up to 2 numbers that can +be passed to the field, between the % sign and the field letter. + +The 1st parameter always indicates the minimum width of output, it is useful for creating +columnar output. Any output that would be less than this minimum width is padded with +leading spaces +The 2nd parameter is proceeded by a dot. +You do not have to use parameters + +SPECIAL FORMS OF INPUT +For numeric input, the following additional forms of input are accepted besides decimal: + +Octal (only with integer): if the argument begins with a 0 the proceeding characters +will be interpreted as octal (base 8) for integer fields + +Hexadecimal: if the argument begins with 0x the proceeding characters will be interpreted +will be interpreted as hex (base 16) for any numeric fields +for float fields, hexadecimal input results in a precision +limit (in converting input past the decimal point) of 10^-15 + +Character Constant: if the argument begins with a single quote character, the first byte +of the next character will be interpreted as an 8-bit unsigned integer. If there are +additional bytes, they will throw an error (unless the environment variable POSIXLY_CORRECT +is set) + +WRITTEN BY : +Nathan E. Ross, et al. for the uutils project + +MORE INFO : +https://github.com/uutils/coreutils + +COPYRIGHT : +Copyright 2015 uutils project. +Licensed under the MIT License, please see LICENSE file for details diff --git a/src/uu/printf/src/printf.rs b/src/uu/printf/src/printf.rs index 2592f212d1..487f06ac10 100644 --- a/src/uu/printf/src/printf.rs +++ b/src/uu/printf/src/printf.rs @@ -4,265 +4,14 @@ use clap::{crate_version, Arg, ArgAction, Command}; use uucore::error::{UResult, UUsageError}; -use uucore::format_usage; +use uucore::{format_usage, help_about, help_usage, help_section}; use uucore::memo::printf; const VERSION: &str = "version"; const HELP: &str = "help"; -const USAGE: &str = "{} FORMATSTRING [ARGUMENT]..."; -const ABOUT: &str = "Print output based off of the format string and proceeding arguments."; -const AFTER_HELP: &str = " -basic anonymous string templating: - -prints format string at least once, repeating as long as there are remaining arguments -output prints escaped literals in the format string as character literals -output replaces anonymous fields with the next unused argument, formatted according to the field. - -Prints the , replacing escaped character sequences with character literals - and substitution field sequences with passed arguments - -literally, with the exception of the below - escaped character sequences, and the substitution sequences described further down. - -ESCAPE SEQUENCES - -The following escape sequences, organized here in alphabetical order, -will print the corresponding character literal: - -\" double quote - -\\\\ backslash - -\\a alert (BEL) - -\\b backspace - -\\c End-of-Input - -\\e escape - -\\f form feed - -\\n new line - -\\r carriage return - -\\t horizontal tab - -\\v vertical tab - -\\NNN byte with value expressed in octal value NNN (1 to 3 digits) - values greater than 256 will be treated - -\\xHH byte with value expressed in hexadecimal value NN (1 to 2 digits) - -\\uHHHH Unicode (IEC 10646) character with value expressed in hexadecimal value HHHH (4 digits) - -\\uHHHH Unicode character with value expressed in hexadecimal value HHHH (8 digits) - -%% a single % - -SUBSTITUTIONS - -SUBSTITUTION QUICK REFERENCE - -Fields - -%s - string -%b - string parsed for literals - second parameter is max length - -%c - char - no second parameter - -%i or %d - 64-bit integer -%u - 64 bit unsigned integer -%x or %X - 64-bit unsigned integer as hex -%o - 64-bit unsigned integer as octal - second parameter is min-width, integer - output below that width is padded with leading zeroes - -%f or %F - decimal floating point value -%e or %E - scientific notation floating point value -%g or %G - shorter of specially interpreted decimal or SciNote floating point value. - second parameter is - -max places after decimal point for floating point output - -max number of significant digits for scientific notation output - -parameterizing fields - -examples: - -printf '%4.3i' 7 -has a first parameter of 4 - and a second parameter of 3 -will result in ' 007' - -printf '%.1s' abcde -has no first parameter - and a second parameter of 1 -will result in 'a' - -printf '%4c' q -has a first parameter of 4 - and no second parameter -will result in ' q' - -The first parameter of a field is the minimum width to pad the output to - if the output is less than this absolute value of this width, - it will be padded with leading spaces, or, if the argument is negative, - with trailing spaces. the default is zero. - -The second parameter of a field is particular to the output field type. - defaults can be found in the full substitution help below - -special prefixes to numeric arguments - 0 (e.g. 010) - interpret argument as octal (integer output fields only) - 0x (e.g. 0xABC) - interpret argument as hex (numeric output fields only) - \' (e.g. \'a) - interpret argument as a character constant - -HOW TO USE SUBSTITUTIONS - -Substitutions are used to pass additional argument(s) into the FORMAT string, to be formatted a -particular way. E.g. - - printf 'the letter %X comes before the letter %X' 10 11 - -will print - - 'the letter A comes before the letter B' - -because the substitution field %X means -'take an integer argument and write it as a hexadecimal number' - -Passing more arguments than are in the format string will cause the format string to be - repeated for the remaining substitutions - - printf 'it is %i F in %s \n' 22 Portland 25 Boston 27 New York - -will print - - 'it is 22 F in Portland - it is 25 F in Boston - it is 27 F in Boston - ' -If a format string is printed but there are less arguments remaining - than there are substitution fields, substitution fields without - an argument will default to empty strings, or for numeric fields - the value 0 - -AVAILABLE SUBSTITUTIONS - -This program, like GNU coreutils printf, -interprets a modified subset of the POSIX C printf spec, -a quick reference to substitutions is below. - - STRING SUBSTITUTIONS - All string fields have a 'max width' parameter - %.3s means 'print no more than three characters of the original input' - - %s - string - - %b - escaped string - the string will be checked for any escaped literals from - the escaped literal list above, and translate them to literal characters. - e.g. \\n will be transformed into a newline character. - - One special rule about %b mode is that octal literals are interpreted differently - In arguments passed by %b, pass octal-interpreted literals must be in the form of \\0NNN - instead of \\NNN. (Although, for legacy reasons, octal literals in the form of \\NNN will - still be interpreted and not throw a warning, you will have problems if you use this for a - literal whose code begins with zero, as it will be viewed as in \\0NNN form.) - - CHAR SUBSTITUTIONS - The character field does not have a secondary parameter. - - %c - a single character - - INTEGER SUBSTITUTIONS - All integer fields have a 'pad with zero' parameter - %.4i means an integer which if it is less than 4 digits in length, - is padded with leading zeros until it is 4 digits in length. - - %d or %i - 64-bit integer - - %u - 64 bit unsigned integer - - %x or %X - 64 bit unsigned integer printed in Hexadecimal (base 16) - %X instead of %x means to use uppercase letters for 'a' through 'f' - - %o - 64 bit unsigned integer printed in octal (base 8) - - FLOATING POINT SUBSTITUTIONS - - All floating point fields have a 'max decimal places / max significant digits' parameter - %.10f means a decimal floating point with 7 decimal places past 0 - %.10e means a scientific notation number with 10 significant digits - %.10g means the same behavior for decimal and Sci. Note, respectively, and provides the shorter - of each's output. - - Like with GNU coreutils, the value after the decimal point is these outputs is parsed as a - double first before being rendered to text. For both implementations do not expect meaningful - precision past the 18th decimal place. When using a number of decimal places that is 18 or - higher, you can expect variation in output between GNU coreutils printf and this printf at the - 18th decimal place of +/- 1 - - %f - floating point value presented in decimal, truncated and displayed to 6 decimal places by - default. There is not past-double behavior parity with Coreutils printf, values are not - estimated or adjusted beyond input values. - - %e or %E - floating point value presented in scientific notation - 7 significant digits by default - %E means use to use uppercase E for the mantissa. - - %g or %G - floating point value presented in the shorter of decimal and scientific notation - behaves differently from %f and %E, please see posix printf spec for full details, - some examples of different behavior: - - Sci Note has 6 significant digits by default - Trailing zeroes are removed - Instead of being truncated, digit after last is rounded - - Like other behavior in this utility, the design choices of floating point - behavior in this utility is selected to reproduce in exact - the behavior of GNU coreutils' printf from an inputs and outputs standpoint. - -USING PARAMETERS - Most substitution fields can be parameterized using up to 2 numbers that can - be passed to the field, between the % sign and the field letter. - - The 1st parameter always indicates the minimum width of output, it is useful for creating - columnar output. Any output that would be less than this minimum width is padded with - leading spaces - The 2nd parameter is proceeded by a dot. - You do not have to use parameters - -SPECIAL FORMS OF INPUT - For numeric input, the following additional forms of input are accepted besides decimal: - - Octal (only with integer): if the argument begins with a 0 the proceeding characters - will be interpreted as octal (base 8) for integer fields - - Hexadecimal: if the argument begins with 0x the proceeding characters will be interpreted - will be interpreted as hex (base 16) for any numeric fields - for float fields, hexadecimal input results in a precision - limit (in converting input past the decimal point) of 10^-15 - - Character Constant: if the argument begins with a single quote character, the first byte - of the next character will be interpreted as an 8-bit unsigned integer. If there are - additional bytes, they will throw an error (unless the environment variable POSIXLY_CORRECT - is set) - -WRITTEN BY : - Nathan E. Ross, et al. for the uutils project - -MORE INFO : - https://github.com/uutils/coreutils - -COPYRIGHT : - Copyright 2015 uutils project. - Licensed under the MIT License, please see LICENSE file for details - -"; +const USAGE: &str = help_usage!("printf.md"); +const ABOUT: &str = help_about!("printf.md"); +const AFTER_HELP: &str = help_section!("after help", "printf.md"); mod options { pub const FORMATSTRING: &str = "FORMATSTRING"; From 57a70eb2000d91ec401e6d124243428c431d1c6e Mon Sep 17 00:00:00 2001 From: m11o Date: Tue, 4 Apr 2023 00:51:24 +0900 Subject: [PATCH 077/477] fix to align indents --- src/uu/printf/printf.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index 703a25fdb2..ceb1f01241 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -163,11 +163,11 @@ All string fields have a 'max width' parameter the escaped literal list above, and translate them to literal characters. e.g. \\n will be transformed into a newline character. - One special rule about %b mode is that octal literals are interpreted differently - In arguments passed by %b, pass octal-interpreted literals must be in the form of \\0NNN - instead of \\NNN. (Although, for legacy reasons, octal literals in the form of \\NNN will - still be interpreted and not throw a warning, you will have problems if you use this for a - literal whose code begins with zero, as it will be viewed as in \\0NNN form.) + One special rule about %b mode is that octal literals are interpreted differently + In arguments passed by %b, pass octal-interpreted literals must be in the form of \\0NNN + instead of \\NNN. (Although, for legacy reasons, octal literals in the form of \\NNN will + still be interpreted and not throw a warning, you will have problems if you use this for a + literal whose code begins with zero, as it will be viewed as in \\0NNN form.) CHAR SUBSTITUTIONS The character field does not have a secondary parameter. @@ -214,9 +214,9 @@ estimated or adjusted beyond input values. behaves differently from %f and %E, please see posix printf spec for full details, some examples of different behavior: - Sci Note has 6 significant digits by default - Trailing zeroes are removed - Instead of being truncated, digit after last is rounded + Sci Note has 6 significant digits by default + Trailing zeroes are removed + Instead of being truncated, digit after last is rounded Like other behavior in this utility, the design choices of floating point behavior in this utility is selected to reproduce in exact From 120a5f6d76ed3cce51ec3480ad38a8c544e08555 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 10:22:35 +0000 Subject: [PATCH 078/477] fix(deps): update rust crate libc to 0.2.141 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 838fa0b8fe..54a080c9c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1294,9 +1294,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.140" +version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "libloading" diff --git a/Cargo.toml b/Cargo.toml index a50aae9b82..980860749f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -289,7 +289,7 @@ half = "2.2" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" -libc = "0.2.140" +libc = "0.2.141" lscolors = { version = "0.13.0", default-features=false, features = ["nu-ansi-term"] } memchr = "2" nix = { version="0.26", default-features=false } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 5caf55c66b..69c23b3cf7 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -32,7 +32,7 @@ time = { workspace=true, optional=true, features = ["formatting", "local-offset" data-encoding = { version="2.3", optional=true } data-encoding-macro = { version="0.1.12", optional=true } z85 = { version="3.0.5", optional=true } -libc = { version="0.2.140", optional=true } +libc = { version="0.2.141", optional=true } once_cell = { workspace=true } os_display = "0.1.3" From e5d88082c4777d311d1091d231876b082fdabfca Mon Sep 17 00:00:00 2001 From: m11o Date: Tue, 4 Apr 2023 21:50:30 +0900 Subject: [PATCH 079/477] Fix style violation in src/uu/printf/src/printf.rs --- src/uu/printf/src/printf.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/src/printf.rs b/src/uu/printf/src/printf.rs index 487f06ac10..bf79369cca 100644 --- a/src/uu/printf/src/printf.rs +++ b/src/uu/printf/src/printf.rs @@ -4,8 +4,8 @@ use clap::{crate_version, Arg, ArgAction, Command}; use uucore::error::{UResult, UUsageError}; -use uucore::{format_usage, help_about, help_usage, help_section}; use uucore::memo::printf; +use uucore::{format_usage, help_about, help_section, help_usage}; const VERSION: &str = "version"; const HELP: &str = "help"; From 23f7434530138f6b3672e3d12f7145a0aade5bb6 Mon Sep 17 00:00:00 2001 From: m11o Date: Tue, 4 Apr 2023 22:09:06 +0900 Subject: [PATCH 080/477] Ignore spells for spell-checker --- src/uu/printf/printf.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index ceb1f01241..b81c9f0f14 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -1,3 +1,5 @@ + + # printf ``` From feef6f4e24aa38346b7c611ffbd3a8a0eaf58d74 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Tue, 4 Apr 2023 22:32:07 +0900 Subject: [PATCH 081/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index ceb1f01241..65593b4425 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -14,7 +14,7 @@ prints format string at least once, repeating as long as there are remaining arg output prints escaped literals in the format string as character literals output replaces anonymous fields with the next unused argument, formatted according to the field. -Prints the , replacing escaped character sequences with character literals +Prints the `,` replacing escaped character sequences with character literals and substitution field sequences with passed arguments literally, with the exception of the below From b8eb9d35522869e49a155eaee2af780838d71053 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 4 Apr 2023 16:36:49 +0200 Subject: [PATCH 082/477] wc: use concat! to improve readability of tests --- tests/by-util/test_wc.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/tests/by-util/test_wc.rs b/tests/by-util/test_wc.rs index 4516f770fd..64e3b70da8 100644 --- a/tests/by-util/test_wc.rs +++ b/tests/by-util/test_wc.rs @@ -475,9 +475,11 @@ fn test_total_auto() { new_ucmd!() .args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=auto"]) .run() - .stdout_is( - " 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 31 313 1887 total\n", - ); + .stdout_is(concat!( + " 13 109 772 lorem_ipsum.txt\n", + " 18 204 1115 moby_dick.txt\n", + " 31 313 1887 total\n", + )); } #[test] @@ -485,14 +487,19 @@ fn test_total_always() { new_ucmd!() .args(&["lorem_ipsum.txt", "--total=always"]) .run() - .stdout_is(" 13 109 772 lorem_ipsum.txt\n 13 109 772 total\n"); + .stdout_is(concat!( + " 13 109 772 lorem_ipsum.txt\n", + " 13 109 772 total\n", + )); new_ucmd!() .args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=always"]) .run() - .stdout_is( - " 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 31 313 1887 total\n", - ); + .stdout_is(concat!( + " 13 109 772 lorem_ipsum.txt\n", + " 18 204 1115 moby_dick.txt\n", + " 31 313 1887 total\n", + )); } #[test] @@ -505,7 +512,10 @@ fn test_total_never() { new_ucmd!() .args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=never"]) .run() - .stdout_is(" 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n"); + .stdout_is(concat!( + " 13 109 772 lorem_ipsum.txt\n", + " 18 204 1115 moby_dick.txt\n", + )); } #[test] From 76e15d049bf346ad75dc925a1576c0f0c484e3c4 Mon Sep 17 00:00:00 2001 From: m11o Date: Wed, 5 Apr 2023 01:36:30 +0900 Subject: [PATCH 083/477] Fix markdown --- src/uu/printf/printf.md | 205 ++++++++++++++++++++-------------------- 1 file changed, 101 insertions(+), 104 deletions(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index b75971544a..ad6ad0d50b 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -1,4 +1,4 @@ - + # printf @@ -22,89 +22,90 @@ and substitution field sequences with passed arguments literally, with the exception of the below escaped character sequences, and the substitution sequences described further down. -ESCAPE SEQUENCES +### ESCAPE SEQUENCES The following escape sequences, organized here in alphabetical order, will print the corresponding character literal: -\" double quote +* `\"` double quote -\\\\ backslash +* `\\\\` backslash -\\a alert (BEL) +* `\\a` alert (BEL) -\\b backspace +* `\\b` backspace -\\c End-of-Input +* `\\c` End-of-Input -\\e escape +* `\\e` escape -\\f form feed +* `\\f` form feed -\\n new line +* `\\n` new line -\\r carriage return +* `\\r` carriage return -\\t horizontal tab +* `\\t` horizontal tab -\\v vertical tab +* `\\v` vertical tab -\\NNN byte with value expressed in octal value NNN (1 to 3 digits) -values greater than 256 will be treated +* `\\NNN` byte with value expressed in octal value NNN (1 to 3 digits) + values greater than 256 will be treated -\\xHH byte with value expressed in hexadecimal value NN (1 to 2 digits) +* `\\xHH` byte with value expressed in hexadecimal value NN (1 to 2 digits) -\\uHHHH Unicode (IEC 10646) character with value expressed in hexadecimal value HHHH (4 digits) +* `\\uHHHH` Unicode (IEC 10646) character with value expressed in hexadecimal value HHHH (4 digits) -\\uHHHH Unicode character with value expressed in hexadecimal value HHHH (8 digits) +* `\\uHHHH` Unicode character with value expressed in hexadecimal value HHHH (8 digits) -%% a single % +* `%%` a single % -SUBSTITUTIONS +### SUBSTITUTIONS -SUBSTITUTION QUICK REFERENCE +#### SUBSTITUTION QUICK REFERENCE Fields -%s - string -%b - string parsed for literals -second parameter is max length +* `%s`: string +* `%b`: string parsed for literals second parameter is max length -%c - char -no second parameter +* `%c`: char no second parameter -%i or %d - 64-bit integer -%u - 64 bit unsigned integer -%x or %X - 64-bit unsigned integer as hex -%o - 64-bit unsigned integer as octal -second parameter is min-width, integer -output below that width is padded with leading zeroes +* `%i or %d`: 64-bit integer +* `%u`: 64 bit unsigned integer +* `%x or %X`: 64-bit unsigned integer as hex +* `%o`: 64-bit unsigned integer as octal + second parameter is min-width, integer + output below that width is padded with leading zeroes -%f or %F - decimal floating point value -%e or %E - scientific notation floating point value -%g or %G - shorter of specially interpreted decimal or SciNote floating point value. -second parameter is --max places after decimal point for floating point output --max number of significant digits for scientific notation output +* `%f or %F`: decimal floating point value +* `%e or %E`: scientific notation floating point value +* `%g or %G`: shorter of specially interpreted decimal or SciNote floating point value. + second parameter is + -max places after decimal point for floating point output + -max number of significant digits for scientific notation output parameterizing fields examples: +``` printf '%4.3i' 7 -has a first parameter of 4 -and a second parameter of 3 -will result in ' 007' +``` + +It has a first parameter of 4 and a second parameter of 3 and will result in ' 007' +``` printf '%.1s' abcde -has no first parameter -and a second parameter of 1 -will result in 'a' +``` + +It has no first parameter and a second parameter of 1 and will result in 'a' +``` printf '%4c' q -has a first parameter of 4 -and no second parameter -will result in ' q' +``` + +It has a first parameter of 4 and no second parameter and will result in ' q' The first parameter of a field is the minimum width to pad the output to if the output is less than this absolute value of this width, @@ -115,19 +116,21 @@ The second parameter of a field is particular to the output field type. defaults can be found in the full substitution help below special prefixes to numeric arguments -0 (e.g. 010) - interpret argument as octal (integer output fields only) -0x (e.g. 0xABC) - interpret argument as hex (numeric output fields only) -\' (e.g. \'a) - interpret argument as a character constant -HOW TO USE SUBSTITUTIONS +* `0 (e.g. 010)`: interpret argument as octal (integer output fields only) +* `0x (e.g. 0xABC)`: interpret argument as hex (numeric output fields only) +* `\' (e.g. \'a)`: interpret argument as a character constant + +#### HOW TO USE SUBSTITUTIONS Substitutions are used to pass additional argument(s) into the FORMAT string, to be formatted a particular way. E.g. - printf 'the letter %X comes before the letter %X' 10 11 +``` +printf 'the letter %X comes before the letter %X' 10 11 +``` will print - 'the letter A comes before the letter B' because the substitution field %X means @@ -136,10 +139,11 @@ because the substitution field %X means Passing more arguments than are in the format string will cause the format string to be repeated for the remaining substitutions +``` printf 'it is %i F in %s \n' 22 Portland 25 Boston 27 New York +``` will print - 'it is 22 F in Portland it is 25 F in Boston it is 27 F in Boston @@ -149,53 +153,55 @@ than there are substitution fields, substitution fields without an argument will default to empty strings, or for numeric fields the value 0 -AVAILABLE SUBSTITUTIONS +#### AVAILABLE SUBSTITUTIONS This program, like GNU coreutils printf, interprets a modified subset of the POSIX C printf spec, a quick reference to substitutions is below. -STRING SUBSTITUTIONS +#### STRING SUBSTITUTIONS + All string fields have a 'max width' parameter -%.3s means 'print no more than three characters of the original input' +`%.3s` means 'print no more than three characters of the original input' -%s - string +* `%s`: string -%b - escaped string - the string will be checked for any escaped literals from -the escaped literal list above, and translate them to literal characters. -e.g. \\n will be transformed into a newline character. +* `%b`: escaped string - the string will be checked for any escaped literals from + the escaped literal list above, and translate them to literal characters. + e.g. `\\n` will be transformed into a newline character. + One special rule about `%b` mode is that octal literals are interpreted differently + In arguments passed by `%b`, pass octal-interpreted literals must be in the form of `\\0NNN` + instead of `\\NNN`. (Although, for legacy reasons, octal literals in the form of `\\NNN` will + still be interpreted and not throw a warning, you will have problems if you use this for a + literal whose code begins with zero, as it will be viewed as in `\\0NNN` form.) - One special rule about %b mode is that octal literals are interpreted differently - In arguments passed by %b, pass octal-interpreted literals must be in the form of \\0NNN - instead of \\NNN. (Although, for legacy reasons, octal literals in the form of \\NNN will - still be interpreted and not throw a warning, you will have problems if you use this for a - literal whose code begins with zero, as it will be viewed as in \\0NNN form.) +#### CHAR SUBSTITUTIONS -CHAR SUBSTITUTIONS The character field does not have a secondary parameter. -%c - a single character +* `%c`: a single character + +#### INTEGER SUBSTITUTIONS -INTEGER SUBSTITUTIONS All integer fields have a 'pad with zero' parameter -%.4i means an integer which if it is less than 4 digits in length, +`%.4i` means an integer which if it is less than 4 digits in length, is padded with leading zeros until it is 4 digits in length. -%d or %i - 64-bit integer +* `%d or %i`: 64-bit integer -%u - 64 bit unsigned integer +* `%u`: 64-bit unsigned integer -%x or %X - 64 bit unsigned integer printed in Hexadecimal (base 16) -%X instead of %x means to use uppercase letters for 'a' through 'f' +* `%x or %X`: 64-bit unsigned integer printed in Hexadecimal (base 16) + `%X` instead of `%x` means to use uppercase letters for 'a' through 'f' -%o - 64 bit unsigned integer printed in octal (base 8) +* `%o`: 64-bit unsigned integer printed in octal (base 8) -FLOATING POINT SUBSTITUTIONS +#### FLOATING POINT SUBSTITUTIONS All floating point fields have a 'max decimal places / max significant digits' parameter -%.10f means a decimal floating point with 7 decimal places past 0 -%.10e means a scientific notation number with 10 significant digits -%.10g means the same behavior for decimal and Sci. Note, respectively, and provides the shorter +`%.10f` means a decimal floating point with 7 decimal places past 0 +`%.10e` means a scientific notation number with 10 significant digits +`%.10g` means the same behavior for decimal and Sci. Note, respectively, and provides the shortest of each's output. Like with GNU coreutils, the value after the decimal point is these outputs is parsed as a @@ -204,27 +210,27 @@ precision past the 18th decimal place. When using a number of decimal places tha higher, you can expect variation in output between GNU coreutils printf and this printf at the 18th decimal place of +/- 1 -%f - floating point value presented in decimal, truncated and displayed to 6 decimal places by -default. There is not past-double behavior parity with Coreutils printf, values are not -estimated or adjusted beyond input values. +* `%f`: floating point value presented in decimal, truncated and displayed to 6 decimal places by + default. There is not past-double behavior parity with Coreutils printf, values are not + estimated or adjusted beyond input values. -%e or %E - floating point value presented in scientific notation -7 significant digits by default -%E means use to use uppercase E for the mantissa. +* `%e or %E`: floating point value presented in scientific notation + 7 significant digits by default + `%E` means use to use uppercase E for the mantissa. -%g or %G - floating point value presented in the shorter of decimal and scientific notation -behaves differently from %f and %E, please see posix printf spec for full details, -some examples of different behavior: - - Sci Note has 6 significant digits by default - Trailing zeroes are removed - Instead of being truncated, digit after last is rounded +* `%g or %G`: floating point value presented in the shortest of decimal and scientific notation + behaves differently from `%f` and `%E`, please see posix printf spec for full details, + some examples of different behavior: + Sci Note has 6 significant digits by default + Trailing zeroes are removed + Instead of being truncated, digit after last is rounded Like other behavior in this utility, the design choices of floating point behavior in this utility is selected to reproduce in exact the behavior of GNU coreutils' printf from an inputs and outputs standpoint. -USING PARAMETERS +### USING PARAMETERS + Most substitution fields can be parameterized using up to 2 numbers that can be passed to the field, between the % sign and the field letter. @@ -234,7 +240,8 @@ leading spaces The 2nd parameter is proceeded by a dot. You do not have to use parameters -SPECIAL FORMS OF INPUT +### SPECIAL FORMS OF INPUT + For numeric input, the following additional forms of input are accepted besides decimal: Octal (only with integer): if the argument begins with a 0 the proceeding characters @@ -249,13 +256,3 @@ Character Constant: if the argument begins with a single quote character, the fi of the next character will be interpreted as an 8-bit unsigned integer. If there are additional bytes, they will throw an error (unless the environment variable POSIXLY_CORRECT is set) - -WRITTEN BY : -Nathan E. Ross, et al. for the uutils project - -MORE INFO : -https://github.com/uutils/coreutils - -COPYRIGHT : -Copyright 2015 uutils project. -Licensed under the MIT License, please see LICENSE file for details From b8a3f14fb3f1a35e54029b520925fdeca11f2a3a Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:19:57 +0900 Subject: [PATCH 084/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index ad6ad0d50b..9dadba4335 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -71,7 +71,7 @@ Fields * `%c`: char no second parameter -* `%i or %d`: 64-bit integer +* `%i` or `%d`: 64-bit integer * `%u`: 64 bit unsigned integer * `%x or %X`: 64-bit unsigned integer as hex * `%o`: 64-bit unsigned integer as octal From 75bb1661687998a58672d0734708efb8be7028f3 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:20:37 +0900 Subject: [PATCH 085/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index 9dadba4335..d5c7d4f145 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -73,7 +73,7 @@ Fields * `%i` or `%d`: 64-bit integer * `%u`: 64 bit unsigned integer -* `%x or %X`: 64-bit unsigned integer as hex +* `%x` or `%X`: 64-bit unsigned integer as hex * `%o`: 64-bit unsigned integer as octal second parameter is min-width, integer output below that width is padded with leading zeroes From 46f11737e1defa5e67850023eb6b024ae9daf5e2 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:20:46 +0900 Subject: [PATCH 086/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index d5c7d4f145..d8f57b26cb 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -78,7 +78,7 @@ Fields second parameter is min-width, integer output below that width is padded with leading zeroes -* `%f or %F`: decimal floating point value +* `%f` or `%F`: decimal floating point value * `%e or %E`: scientific notation floating point value * `%g or %G`: shorter of specially interpreted decimal or SciNote floating point value. second parameter is From 13bb755e6035992365a9976f88f1fb56b0f0b27d Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:21:33 +0900 Subject: [PATCH 087/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index d8f57b26cb..6387b856ba 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -79,7 +79,7 @@ Fields output below that width is padded with leading zeroes * `%f` or `%F`: decimal floating point value -* `%e or %E`: scientific notation floating point value +* `%e` or `%E`: scientific notation floating point value * `%g or %G`: shorter of specially interpreted decimal or SciNote floating point value. second parameter is -max places after decimal point for floating point output From f688a7ec8d45a800d842407a5f9946fb4b90beff Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:21:44 +0900 Subject: [PATCH 088/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index 6387b856ba..ae6f362805 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -80,7 +80,7 @@ Fields * `%f` or `%F`: decimal floating point value * `%e` or `%E`: scientific notation floating point value -* `%g or %G`: shorter of specially interpreted decimal or SciNote floating point value. +* `%g` or `%G`: shorter of specially interpreted decimal or SciNote floating point value. second parameter is -max places after decimal point for floating point output -max number of significant digits for scientific notation output From 097002bdaf7ce23772b9513a472bda5d8d3a4689 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:21:57 +0900 Subject: [PATCH 089/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index ae6f362805..0151e14c0c 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -82,7 +82,7 @@ Fields * `%e` or `%E`: scientific notation floating point value * `%g` or `%G`: shorter of specially interpreted decimal or SciNote floating point value. second parameter is - -max places after decimal point for floating point output + `-max` places after decimal point for floating point output -max number of significant digits for scientific notation output parameterizing fields From ade823c16301d39459adbf121ab18032a272855d Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:22:08 +0900 Subject: [PATCH 090/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index 0151e14c0c..8bff53edc2 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -83,7 +83,7 @@ Fields * `%g` or `%G`: shorter of specially interpreted decimal or SciNote floating point value. second parameter is `-max` places after decimal point for floating point output - -max number of significant digits for scientific notation output + `-max` number of significant digits for scientific notation output parameterizing fields From a838c31978331012149b52d186d15e8bf1c1f159 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:22:26 +0900 Subject: [PATCH 091/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index 8bff53edc2..097eeb8efa 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -214,7 +214,7 @@ higher, you can expect variation in output between GNU coreutils printf and this default. There is not past-double behavior parity with Coreutils printf, values are not estimated or adjusted beyond input values. -* `%e or %E`: floating point value presented in scientific notation +* `%e` or `%E`: floating point value presented in scientific notation 7 significant digits by default `%E` means use to use uppercase E for the mantissa. From 109aa925c43f71336ffa20584f1e43484f264b3e Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:23:27 +0900 Subject: [PATCH 092/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index 097eeb8efa..5acc99bf32 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -187,7 +187,7 @@ All integer fields have a 'pad with zero' parameter `%.4i` means an integer which if it is less than 4 digits in length, is padded with leading zeros until it is 4 digits in length. -* `%d or %i`: 64-bit integer +* `%d` or `%i`: 64-bit integer * `%u`: 64-bit unsigned integer From 11f3976e352fb3e2d5f4ed33524b3c9136b3239d Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:24:06 +0900 Subject: [PATCH 093/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index 5acc99bf32..e596c08310 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -191,7 +191,7 @@ is padded with leading zeros until it is 4 digits in length. * `%u`: 64-bit unsigned integer -* `%x or %X`: 64-bit unsigned integer printed in Hexadecimal (base 16) +* `%x` or `%X`: 64-bit unsigned integer printed in Hexadecimal (base 16) `%X` instead of `%x` means to use uppercase letters for 'a' through 'f' * `%o`: 64-bit unsigned integer printed in octal (base 8) From cbc0ff67718d606ed1e73957fad3c3ef047a75e3 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:24:19 +0900 Subject: [PATCH 094/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index e596c08310..4aeeae3f71 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -218,7 +218,7 @@ higher, you can expect variation in output between GNU coreutils printf and this 7 significant digits by default `%E` means use to use uppercase E for the mantissa. -* `%g or %G`: floating point value presented in the shortest of decimal and scientific notation +* `%g` or `%G`: floating point value presented in the shortest of decimal and scientific notation behaves differently from `%f` and `%E`, please see posix printf spec for full details, some examples of different behavior: Sci Note has 6 significant digits by default From 5633eb9cd7e411f03707bd01fa4998fe5a5921cd Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:25:28 +0900 Subject: [PATCH 095/477] Update src/uu/printf/printf.md Co-authored-by: Sylvestre Ledru --- src/uu/printf/printf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index 4aeeae3f71..1d25a0e59f 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -133,7 +133,7 @@ printf 'the letter %X comes before the letter %X' 10 11 will print 'the letter A comes before the letter B' -because the substitution field %X means +because the substitution field `%X` means 'take an integer argument and write it as a hexadecimal number' Passing more arguments than are in the format string will cause the format string to be From bedb0d14a6ddd1fecee4b149a2f81e78b3ddee60 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 15:30:31 +0000 Subject: [PATCH 096/477] chore(deps): update rust crate hex-literal to 0.4.1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54a080c9c0..0fbba8f987 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1125,9 +1125,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcb5b3e439c92a7191df2f9bbe733de8de55c3f86368cdb1c63f8be7e9e328e" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "hostname" diff --git a/Cargo.toml b/Cargo.toml index 980860749f..5b6b71edf9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -487,7 +487,7 @@ unindent = "0.2" uucore = { workspace=true, features=["entries", "process", "signals"] } walkdir = { workspace=true } is-terminal = { workspace=true } -hex-literal = "0.4.0" +hex-literal = "0.4.1" rstest = "0.17.0" [target.'cfg(any(target_os = "linux", target_os = "android"))'.dev-dependencies] From 45ce14c85bec0b6a8625d7833382c3dfcb8cc9d5 Mon Sep 17 00:00:00 2001 From: m11o Date: Thu, 6 Apr 2023 00:44:26 +0900 Subject: [PATCH 097/477] fix review to use code block --- src/uu/printf/printf.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index 1d25a0e59f..e64321edef 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -131,7 +131,10 @@ printf 'the letter %X comes before the letter %X' 10 11 ``` will print -'the letter A comes before the letter B' + +``` +the letter A comes before the letter B +``` because the substitution field `%X` means 'take an integer argument and write it as a hexadecimal number' @@ -144,10 +147,13 @@ printf 'it is %i F in %s \n' 22 Portland 25 Boston 27 New York ``` will print -'it is 22 F in Portland + +``` +it is 22 F in Portland it is 25 F in Boston it is 27 F in Boston -' +``` + If a format string is printed but there are less arguments remaining than there are substitution fields, substitution fields without an argument will default to empty strings, or for numeric fields From 1c5f068886b1a0fbaee563b31593b970961b2e9a Mon Sep 17 00:00:00 2001 From: m11o Date: Thu, 6 Apr 2023 00:50:02 +0900 Subject: [PATCH 098/477] use ` for keyword --- src/uu/printf/printf.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uu/printf/printf.md b/src/uu/printf/printf.md index e64321edef..60b50354c6 100644 --- a/src/uu/printf/printf.md +++ b/src/uu/printf/printf.md @@ -117,9 +117,9 @@ defaults can be found in the full substitution help below special prefixes to numeric arguments -* `0 (e.g. 010)`: interpret argument as octal (integer output fields only) -* `0x (e.g. 0xABC)`: interpret argument as hex (numeric output fields only) -* `\' (e.g. \'a)`: interpret argument as a character constant +* `0`: (e.g. 010) interpret argument as octal (integer output fields only) +* `0x`: (e.g. 0xABC) interpret argument as hex (numeric output fields only) +* `\'`: (e.g. \'a) interpret argument as a character constant #### HOW TO USE SUBSTITUTIONS From 20a8b5ac9eb1f90dbcefa187c4e5ccaf111fa0fb Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 6 Apr 2023 09:45:13 +0200 Subject: [PATCH 099/477] factor: fix "unused import" warning in test --- tests/by-util/test_factor.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_factor.rs b/tests/by-util/test_factor.rs index 23da2ea69f..64eb2a6408 100644 --- a/tests/by-util/test_factor.rs +++ b/tests/by-util/test_factor.rs @@ -8,7 +8,7 @@ // spell-checker:ignore (methods) hexdigest -use crate::common::util::{AtPath, TestScenario}; +use crate::common::util::TestScenario; use std::time::{Duration, SystemTime}; @@ -33,6 +33,7 @@ fn test_invalid_arg() { #[test] #[cfg(feature = "sort")] fn test_parallel() { + use crate::common::util::AtPath; use hex_literal::hex; use sha1::{Digest, Sha1}; use std::{fs::OpenOptions, time::Duration}; From 74a95bc7a585b65305ac5f9609f8b013e7efced8 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 6 Apr 2023 09:47:21 +0200 Subject: [PATCH 100/477] factor: expand glob import in test --- tests/by-util/test_factor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_factor.rs b/tests/by-util/test_factor.rs index 64eb2a6408..9c818df249 100644 --- a/tests/by-util/test_factor.rs +++ b/tests/by-util/test_factor.rs @@ -118,7 +118,7 @@ fn test_cli_args() { #[test] fn test_random() { - use conv::prelude::*; + use conv::prelude::ValueFrom; let log_num_primes = f64::value_from(NUM_PRIMES).unwrap().log2().ceil(); let primes = Sieve::primes().take(NUM_PRIMES).collect::>(); From 305087f8e2e23e2ca9715ad9a5281238a90f5f61 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 6 Apr 2023 14:52:54 +0200 Subject: [PATCH 101/477] factor: remove unnecessary "extern crate" in test --- tests/by-util/test_factor.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/by-util/test_factor.rs b/tests/by-util/test_factor.rs index 9c818df249..25ac718ae5 100644 --- a/tests/by-util/test_factor.rs +++ b/tests/by-util/test_factor.rs @@ -15,12 +15,9 @@ use std::time::{Duration, SystemTime}; #[path = "../../src/uu/factor/sieve.rs"] mod sieve; -extern crate conv; -extern crate rand; - -use self::rand::distributions::{Distribution, Uniform}; -use self::rand::{rngs::SmallRng, Rng, SeedableRng}; use self::sieve::Sieve; +use rand::distributions::{Distribution, Uniform}; +use rand::{rngs::SmallRng, Rng, SeedableRng}; const NUM_PRIMES: usize = 10000; const NUM_TESTS: usize = 100; @@ -81,7 +78,6 @@ fn test_parallel() { #[test] fn test_first_1000_integers() { - extern crate sha1; use hex_literal::hex; use sha1::{Digest, Sha1}; From 19e456fe2ab22fefeeb20347c540e54500fe2bee Mon Sep 17 00:00:00 2001 From: xalfer Date: Fri, 7 Apr 2023 21:36:26 +0200 Subject: [PATCH 102/477] touch: add support for --ref and --date together This commit resolves issue #4608. To make it relatively straightforward to implement I have taken some code from parse_date and put it inside a function parse_relative_time. This commit changes and adds some test as well to work with the new functionality. --- src/uu/touch/src/touch.rs | 119 ++++++++++++++++++++++-------------- tests/by-util/test_touch.rs | 29 ++++++++- 2 files changed, 101 insertions(+), 47 deletions(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index ec88586c64..230f55625d 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -77,19 +77,57 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { ), ) })?; - let (mut atime, mut mtime) = - if let Some(reference) = matches.get_one::(options::sources::REFERENCE) { - stat(Path::new(reference), !matches.get_flag(options::NO_DEREF))? - } else { - let timestamp = if let Some(date) = matches.get_one::(options::sources::DATE) { - parse_date(date)? - } else if let Some(current) = matches.get_one::(options::sources::CURRENT) { - parse_timestamp(current)? + let (mut atime, mut mtime) = match ( + matches.get_one::(options::sources::REFERENCE), + matches.get_one::(options::sources::DATE), + ) { + (Some(reference), Some(date)) => { + let (atime, mtime) = stat(Path::new(reference), !matches.get_flag(options::NO_DEREF))?; + if let Some(offset) = parse_relative_time(date) { + let mut seconds = offset.whole_seconds(); + let mut nanos = offset.subsec_nanoseconds(); + if nanos < 0 { + nanos = 1_000_000_000 + nanos; + seconds -= 1; + } + + let ref_atime_secs = atime.unix_seconds(); + let ref_atime_nanos = atime.nanoseconds(); + let atime = FileTime::from_unix_time( + ref_atime_secs + seconds, + ref_atime_nanos + nanos as u32, + ); + + let ref_mtime_secs = mtime.unix_seconds(); + let ref_mtime_nanos = mtime.nanoseconds(); + let mtime = FileTime::from_unix_time( + ref_mtime_secs + seconds, + ref_mtime_nanos + nanos as u32, + ); + + (atime, mtime) } else { - local_dt_to_filetime(time::OffsetDateTime::now_local().unwrap()) - }; + let timestamp = parse_date(date)?; + (timestamp, timestamp) + } + } + (Some(reference), None) => { + stat(Path::new(reference), !matches.get_flag(options::NO_DEREF))? + } + (None, Some(date)) => { + let timestamp = parse_date(date)?; (timestamp, timestamp) - }; + } + (None, None) => { + let timestamp = + if let Some(current) = matches.get_one::(options::sources::CURRENT) { + parse_timestamp(current)? + } else { + local_dt_to_filetime(time::OffsetDateTime::now_local().unwrap()) + }; + (timestamp, timestamp) + } + }; for filename in files { // FIXME: find a way to avoid having to clone the path @@ -202,7 +240,8 @@ pub fn uu_app() -> Command { .long(options::sources::DATE) .allow_hyphen_values(true) .help("parse argument and use it instead of current time") - .value_name("STRING"), + .value_name("STRING") + .conflicts_with(options::sources::CURRENT), ) .arg( Arg::new(options::MODIFICATION) @@ -234,7 +273,8 @@ pub fn uu_app() -> Command { .help("use this file's times instead of the current time") .value_name("FILE") .value_parser(ValueParser::os_string()) - .value_hint(clap::ValueHint::AnyPath), + .value_hint(clap::ValueHint::AnyPath) + .conflicts_with(options::sources::CURRENT), ) .arg( Arg::new(options::TIME) @@ -254,11 +294,15 @@ pub fn uu_app() -> Command { .value_parser(ValueParser::os_string()) .value_hint(clap::ValueHint::AnyPath), ) - .group(ArgGroup::new(options::SOURCES).args([ - options::sources::CURRENT, - options::sources::DATE, - options::sources::REFERENCE, - ])) + .group( + ArgGroup::new(options::SOURCES) + .args([ + options::sources::CURRENT, + options::sources::DATE, + options::sources::REFERENCE, + ]) + .multiple(true), + ) } fn stat(path: &Path, follow: bool) -> UResult<(FileTime, FileTime)> { @@ -384,33 +428,22 @@ fn parse_date(s: &str) -> UResult { } } - // Relative day, like "today", "tomorrow", or "yesterday". - match s { - "now" | "today" => { - let now_local = time::OffsetDateTime::now_local().unwrap(); - return Ok(local_dt_to_filetime(now_local)); - } - "tomorrow" => { - let duration = time::Duration::days(1); - let now_local = time::OffsetDateTime::now_local().unwrap(); - let diff = now_local.checked_add(duration).unwrap(); - return Ok(local_dt_to_filetime(diff)); - } - "yesterday" => { - let duration = time::Duration::days(1); - let now_local = time::OffsetDateTime::now_local().unwrap(); - let diff = now_local.checked_sub(duration).unwrap(); - return Ok(local_dt_to_filetime(diff)); - } - _ => {} + if let Some(duration) = parse_relative_time(s) { + let now_local = time::OffsetDateTime::now_local().unwrap(); + let diff = now_local.checked_add(duration).unwrap(); + return Ok(local_dt_to_filetime(diff)); } + Err(USimpleError::new(1, format!("Unable to parse date: {s}"))) +} + +fn parse_relative_time(s: &str) -> Option { // Relative time, like "-1 hour" or "+3 days". // // TODO Add support for "year" and "month". // TODO Add support for times without spaces like "-1hour". let tokens: Vec<&str> = s.split_whitespace().collect(); - let maybe_duration = match &tokens[..] { + match &tokens[..] { [num_str, "fortnight" | "fortnights"] => num_str .parse::() .ok() @@ -430,15 +463,11 @@ fn parse_date(s: &str) -> UResult { num_str.parse::().ok().map(time::Duration::seconds) } ["second" | "seconds" | "sec" | "secs"] => Some(time::Duration::seconds(1)), + ["now" | "today"] => Some(time::Duration::ZERO), + ["yesterday"] => Some(time::Duration::days(-1)), + ["tomorrow"] => Some(time::Duration::days(1)), _ => None, - }; - if let Some(duration) = maybe_duration { - let now_local = time::OffsetDateTime::now_local().unwrap(); - let diff = now_local.checked_add(duration).unwrap(); - return Ok(local_dt_to_filetime(diff)); } - - Err(USimpleError::new(1, format!("Unable to parse date: {s}"))) } fn parse_timestamp(s: &str) -> UResult { diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index 80fb267108..b21f95645c 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -251,14 +251,39 @@ fn test_touch_set_both_date_and_reference() { let ref_file = "test_touch_reference"; let file = "test_touch_set_both_date_and_reference"; - let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000"); + let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501011234"); at.touch(ref_file); set_file_times(&at, ref_file, start_of_year, start_of_year); assert!(at.file_exists(ref_file)); ucmd.args(&["-d", "Thu Jan 01 12:34:00 2015", "-r", ref_file, file]) - .fails(); + .succeeds() + .no_stderr(); + let (atime, mtime) = get_file_times(&at, file); + assert_eq!(atime, start_of_year); + assert_eq!(mtime, start_of_year); +} + +#[test] +fn test_touch_set_both_offset_date_and_reference() { + let (at, mut ucmd) = at_and_ucmd!(); + let ref_file = "test_touch_reference"; + let file = "test_touch_set_both_date_and_reference"; + + let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501011234"); + let five_days_later = str_to_filetime("%Y%m%d%H%M", "201501061234"); + + at.touch(ref_file); + set_file_times(&at, ref_file, start_of_year, start_of_year); + assert!(at.file_exists(ref_file)); + + ucmd.args(&["-d", "+5 days", "-r", ref_file, file]) + .succeeds() + .no_stderr(); + let (atime, mtime) = get_file_times(&at, file); + assert_eq!(atime, five_days_later); + assert_eq!(mtime, five_days_later); } #[test] From 9badfcd7d277520de5c88cb64158f630b5208372 Mon Sep 17 00:00:00 2001 From: xalfer Date: Sat, 8 Apr 2023 12:23:24 +0200 Subject: [PATCH 103/477] touch: fix clippy lints --- src/uu/touch/src/touch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index 230f55625d..5b30ba400b 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -87,7 +87,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let mut seconds = offset.whole_seconds(); let mut nanos = offset.subsec_nanoseconds(); if nanos < 0 { - nanos = 1_000_000_000 + nanos; + nanos += 1_000_000_000; seconds -= 1; } From 81b1bc1fa7b5c8c8bf7da3b324bf36115683634c Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 8 Apr 2023 16:34:29 +0200 Subject: [PATCH 104/477] touch: remove unnecessary "extern crate"s --- src/uu/touch/src/touch.rs | 4 ++-- tests/by-util/test_touch.rs | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index 5b30ba400b..eeb1dd13ab 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -7,11 +7,10 @@ // that was distributed with this source code. // spell-checker:ignore (ToDO) filetime strptime utcoff strs datetime MMDDhhmm clapv PWSTR lpszfilepath hresult mktime YYYYMMDDHHMM YYMMDDHHMM DATETIME YYYYMMDDHHMMS subsecond -pub extern crate filetime; use clap::builder::ValueParser; use clap::{crate_version, Arg, ArgAction, ArgGroup, Command}; -use filetime::*; +use filetime::{set_symlink_file_times, FileTime}; use std::ffi::OsString; use std::fs::{self, File}; use std::path::{Path, PathBuf}; @@ -23,6 +22,7 @@ use uucore::{format_usage, help_about, help_usage, show}; const ABOUT: &str = help_about!("touch.md"); const USAGE: &str = help_usage!("touch.md"); + pub mod options { // Both SOURCES and sources are needed as we need to be able to refer to the ArgGroup. pub static SOURCES: &str = "sources"; diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index b21f95645c..ae3a28e49f 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -6,10 +6,8 @@ // See https://github.com/time-rs/time/issues/293#issuecomment-946382614= // Defined in .cargo/config -extern crate touch; -use self::touch::filetime::{self, FileTime}; +use filetime::FileTime; -extern crate time; use time::macros::format_description; use crate::common::util::{AtPath, TestScenario}; From dfea103bc48b697da08184c4e4085d58d107f186 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 9 Apr 2023 14:53:15 +0200 Subject: [PATCH 105/477] uucore: remove commented out imports --- src/uucore/src/lib/features/utmpx.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/uucore/src/lib/features/utmpx.rs b/src/uucore/src/lib/features/utmpx.rs index 8ac41014b1..27519f2883 100644 --- a/src/uucore/src/lib/features/utmpx.rs +++ b/src/uucore/src/lib/features/utmpx.rs @@ -42,13 +42,10 @@ use std::ptr; use std::sync::{Mutex, MutexGuard}; pub use self::ut::*; -use libc::utmpx; -// pub use libc::getutxid; -// pub use libc::getutxline; -// pub use libc::pututxline; pub use libc::endutxent; pub use libc::getutxent; pub use libc::setutxent; +use libc::utmpx; #[cfg(any(target_vendor = "apple", target_os = "linux", target_os = "netbsd"))] pub use libc::utmpxname; From 4355fb7f781a37942a4917c95c351452ed0e188e Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 9 Apr 2023 14:46:11 +0200 Subject: [PATCH 106/477] Remove some unnecessary "extern crate" statements --- src/uu/sync/src/sync.rs | 3 --- src/uucore/src/lib/features/fsext.rs | 1 - src/uucore/src/lib/features/utmpx.rs | 1 - src/uucore/src/lib/mods/backup_control.rs | 2 -- src/uucore_procs/src/lib.rs | 1 - 5 files changed, 8 deletions(-) diff --git a/src/uu/sync/src/sync.rs b/src/uu/sync/src/sync.rs index d4bc1604d9..120e31dfee 100644 --- a/src/uu/sync/src/sync.rs +++ b/src/uu/sync/src/sync.rs @@ -7,8 +7,6 @@ /* Last synced with: sync (GNU coreutils) 8.13 */ -extern crate libc; - use clap::{crate_version, Arg, ArgAction, Command}; #[cfg(any(target_os = "linux", target_os = "android"))] use nix::errno::Errno; @@ -34,7 +32,6 @@ static ARG_FILES: &str = "files"; #[cfg(unix)] mod platform { - use super::libc; #[cfg(any(target_os = "linux", target_os = "android"))] use std::fs::File; #[cfg(any(target_os = "linux", target_os = "android"))] diff --git a/src/uucore/src/lib/features/fsext.rs b/src/uucore/src/lib/features/fsext.rs index e7d5d66bf2..1e7f84e6a9 100644 --- a/src/uucore/src/lib/features/fsext.rs +++ b/src/uucore/src/lib/features/fsext.rs @@ -11,7 +11,6 @@ // spell-checker:ignore DATETIME subsecond (arch) bitrig ; (fs) cifs smbfs -extern crate time; use time::macros::format_description; use time::UtcOffset; diff --git a/src/uucore/src/lib/features/utmpx.rs b/src/uucore/src/lib/features/utmpx.rs index 27519f2883..35c5ac5b02 100644 --- a/src/uucore/src/lib/features/utmpx.rs +++ b/src/uucore/src/lib/features/utmpx.rs @@ -227,7 +227,6 @@ impl Utmpx { let (hostname, display) = host.split_once(':').unwrap_or((&host, "")); if !hostname.is_empty() { - extern crate dns_lookup; use dns_lookup::{getaddrinfo, AddrInfoHints}; const AI_CANONNAME: i32 = 0x2; diff --git a/src/uucore/src/lib/mods/backup_control.rs b/src/uucore/src/lib/mods/backup_control.rs index 52b2771c6a..2d161c43fa 100644 --- a/src/uucore/src/lib/mods/backup_control.rs +++ b/src/uucore/src/lib/mods/backup_control.rs @@ -200,8 +200,6 @@ impl Display for BackupError { pub mod arguments { use clap::ArgAction; - extern crate clap; - pub static OPT_BACKUP: &str = "backupopt_backup"; pub static OPT_BACKUP_NO_ARG: &str = "backupopt_b"; pub static OPT_SUFFIX: &str = "backupopt_suffix"; diff --git a/src/uucore_procs/src/lib.rs b/src/uucore_procs/src/lib.rs index ab2458cebb..124978f936 100644 --- a/src/uucore_procs/src/lib.rs +++ b/src/uucore_procs/src/lib.rs @@ -1,7 +1,6 @@ // Copyright (C) ~ Roy Ivy III ; MIT license // spell-checker:ignore backticks -extern crate proc_macro; use std::{fs::File, io::Read, path::PathBuf}; use proc_macro::{Literal, TokenStream, TokenTree}; From 7a888da409af5cb8fa9ff66205695b25015c2f03 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 10 Apr 2023 08:31:31 +0200 Subject: [PATCH 107/477] tests: remove all "extern crate" statements --- tests/by-util/test_chmod.rs | 4 +--- tests/by-util/test_chown.rs | 4 +--- tests/by-util/test_date.rs | 4 +--- tests/by-util/test_dir.rs | 8 +------- tests/by-util/test_dircolors.rs | 3 +-- tests/by-util/test_hostid.rs | 5 ++--- tests/by-util/test_ls.rs | 8 +------- tests/by-util/test_mkdir.rs | 6 ++---- tests/by-util/test_mv.rs | 5 +---- tests/by-util/test_od.rs | 4 +--- tests/by-util/test_pinky.rs | 9 ++------- tests/by-util/test_pr.rs | 1 - tests/by-util/test_split.rs | 7 ++----- tests/by-util/test_stat.rs | 2 -- tests/by-util/test_sync.rs | 1 - tests/by-util/test_tail.rs | 2 -- tests/by-util/test_uptime.rs | 3 +-- tests/by-util/test_vdir.rs | 8 +------- tests/tests.rs | 3 --- 19 files changed, 18 insertions(+), 69 deletions(-) diff --git a/tests/by-util/test_chmod.rs b/tests/by-util/test_chmod.rs index 379df49441..acba00854f 100644 --- a/tests/by-util/test_chmod.rs +++ b/tests/by-util/test_chmod.rs @@ -4,9 +4,7 @@ use std::fs::{metadata, set_permissions, OpenOptions, Permissions}; use std::os::unix::fs::{OpenOptionsExt, PermissionsExt}; use std::sync::Mutex; -extern crate chmod; -extern crate libc; -use self::libc::umask; +use libc::umask; static TEST_FILE: &str = "file"; static REFERENCE_FILE: &str = "reference"; diff --git a/tests/by-util/test_chown.rs b/tests/by-util/test_chown.rs index 9bd6382a69..fce4fa6359 100644 --- a/tests/by-util/test_chown.rs +++ b/tests/by-util/test_chown.rs @@ -4,8 +4,6 @@ use crate::common::util::{is_ci, run_ucmd_as_root, CmdResult, TestScenario}; #[cfg(any(target_os = "linux", target_os = "android"))] use rust_users::get_effective_uid; -extern crate chown; - // Apparently some CI environments have configuration issues, e.g. with 'whoami' and 'id'. // If we are running inside the CI and "needle" is in "stderr" skipping this test is // considered okay. If we are not inside the CI this calls assert!(result.success). @@ -36,7 +34,7 @@ fn skipping_test_is_okay(result: &CmdResult, needle: &str) -> bool { #[cfg(test)] mod test_passgrp { - use super::chown::entries::{gid2grp, grp2gid, uid2usr, usr2uid}; + use chown::entries::{gid2grp, grp2gid, uid2usr, usr2uid}; #[test] fn test_usr2uid() { diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index d099671549..a1bdda6518 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -1,7 +1,5 @@ -extern crate regex; - -use self::regex::Regex; use crate::common::util::TestScenario; +use regex::Regex; #[cfg(all(unix, not(target_os = "macos")))] use rust_users::get_effective_uid; diff --git a/tests/by-util/test_dir.rs b/tests/by-util/test_dir.rs index 5905edff18..fd94f3a8f5 100644 --- a/tests/by-util/test_dir.rs +++ b/tests/by-util/test_dir.rs @@ -1,11 +1,5 @@ -#[cfg(not(windows))] -extern crate libc; -extern crate regex; -#[cfg(not(windows))] -extern crate tempfile; - -use self::regex::Regex; use crate::common::util::TestScenario; +use regex::Regex; /* * As dir use the same functions than ls, we don't have to retest them here. diff --git a/tests/by-util/test_dircolors.rs b/tests/by-util/test_dircolors.rs index d2ec32f337..2d83c76b53 100644 --- a/tests/by-util/test_dircolors.rs +++ b/tests/by-util/test_dircolors.rs @@ -1,8 +1,7 @@ // spell-checker:ignore overridable use crate::common::util::TestScenario; -extern crate dircolors; -use self::dircolors::{guess_syntax, OutputFmt, StrUtils}; +use dircolors::{guess_syntax, OutputFmt, StrUtils}; #[test] fn test_invalid_arg() { diff --git a/tests/by-util/test_hostid.rs b/tests/by-util/test_hostid.rs index 3ea818480b..b42ec211d0 100644 --- a/tests/by-util/test_hostid.rs +++ b/tests/by-util/test_hostid.rs @@ -1,6 +1,5 @@ -use crate::common::util::*; -extern crate regex; -use self::regex::Regex; +use crate::common::util::TestScenario; +use regex::Regex; #[test] fn test_normal() { diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index ba328d8957..1a189a25ad 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1,17 +1,11 @@ // spell-checker:ignore (words) READMECAREFULLY birthtime doesntexist oneline somebackup lrwx somefile somegroup somehiddenbackup somehiddenfile tabsize aaaaaaaa bbbb cccc dddddddd ncccc -#[cfg(not(windows))] -extern crate libc; -extern crate regex; -#[cfg(not(windows))] -extern crate tempfile; - -use self::regex::Regex; #[cfg(feature = "feat_selinux")] use crate::common::util::expected_result; use crate::common::util::TestScenario; #[cfg(all(unix, feature = "chmod"))] use nix::unistd::{close, dup}; +use regex::Regex; use std::collections::HashMap; #[cfg(all(unix, feature = "chmod"))] use std::os::unix::io::IntoRawFd; diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index 2f09be6c20..e2ac763b44 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -1,10 +1,8 @@ use crate::common::util::TestScenario; #[cfg(not(windows))] -use std::os::unix::fs::PermissionsExt; -#[cfg(not(windows))] -extern crate libc; +use libc::{mode_t, umask}; #[cfg(not(windows))] -use self::libc::{mode_t, umask}; +use std::os::unix::fs::PermissionsExt; static TEST_DIR1: &str = "mkdir_test1"; static TEST_DIR2: &str = "mkdir_test2"; diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 54bf53002c..f9b0c59ea8 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -1,8 +1,5 @@ -extern crate filetime; -extern crate time; - -use self::filetime::FileTime; use crate::common::util::TestScenario; +use filetime::FileTime; #[test] fn test_invalid_arg() { diff --git a/tests/by-util/test_od.rs b/tests/by-util/test_od.rs index da30a5d971..24626cd767 100644 --- a/tests/by-util/test_od.rs +++ b/tests/by-util/test_od.rs @@ -4,15 +4,13 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -extern crate unindent; - -use self::unindent::unindent; use crate::common::util::TestScenario; use std::env; use std::fs::remove_file; use std::fs::File; use std::io::Write; use std::path::Path; +use unindent::unindent; // octal dump of 'abcdefghijklmnopqrstuvwxyz\n' // spell-checker:disable-line static ALPHA_OUT: &str = " diff --git a/tests/by-util/test_pinky.rs b/tests/by-util/test_pinky.rs index ba142c905c..f266175f52 100644 --- a/tests/by-util/test_pinky.rs +++ b/tests/by-util/test_pinky.rs @@ -3,14 +3,9 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -extern crate uucore; - use crate::common::util::{expected_result, TestScenario}; - -use self::uucore::entries::{Locate, Passwd}; - -extern crate pinky; -pub use self::pinky::*; +use pinky::Capitalize; +use uucore::entries::{Locate, Passwd}; #[test] fn test_invalid_arg() { diff --git a/tests/by-util/test_pr.rs b/tests/by-util/test_pr.rs index 66f4f13092..b62fa4a968 100644 --- a/tests/by-util/test_pr.rs +++ b/tests/by-util/test_pr.rs @@ -1,5 +1,4 @@ // spell-checker:ignore (ToDO) Sdivide -extern crate time; use crate::common::util::{TestScenario, UCommand}; use std::fs::metadata; diff --git a/tests/by-util/test_split.rs b/tests/by-util/test_split.rs index 5ed96ed351..1395a4fa28 100644 --- a/tests/by-util/test_split.rs +++ b/tests/by-util/test_split.rs @@ -3,13 +3,10 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. // spell-checker:ignore xzaaa sixhundredfiftyonebytes ninetyonebytes threebytes asciilowercase fghij klmno pqrst uvwxyz fivelines twohundredfortyonebytes onehundredlines nbbbb -extern crate rand; -extern crate regex; -use self::rand::{thread_rng, Rng}; -use self::regex::Regex; use crate::common::util::{AtPath, TestScenario}; -use rand::SeedableRng; +use rand::{thread_rng, Rng, SeedableRng}; +use regex::Regex; #[cfg(not(windows))] use std::env; use std::path::Path; diff --git a/tests/by-util/test_stat.rs b/tests/by-util/test_stat.rs index 6dbe940f83..2527dc7cdd 100644 --- a/tests/by-util/test_stat.rs +++ b/tests/by-util/test_stat.rs @@ -3,8 +3,6 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -extern crate regex; - use crate::common::util::{expected_result, TestScenario}; #[test] diff --git a/tests/by-util/test_sync.rs b/tests/by-util/test_sync.rs index 961b2d2163..d55a874ba8 100644 --- a/tests/by-util/test_sync.rs +++ b/tests/by-util/test_sync.rs @@ -1,5 +1,4 @@ use crate::common::util::TestScenario; -extern crate tempfile; use std::fs; use tempfile::tempdir; diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index a8039cef66..2f83f303bc 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -7,8 +7,6 @@ // spell-checker:ignore (libs) kqueue // spell-checker:ignore (jargon) tailable untailable datasame runneradmin tmpi -extern crate tail; - use crate::common::random::{AlphanumericNewline, RandomString}; #[cfg(unix)] use crate::common::util::expected_result; diff --git a/tests/by-util/test_uptime.rs b/tests/by-util/test_uptime.rs index 46613ef565..628f4cead6 100644 --- a/tests/by-util/test_uptime.rs +++ b/tests/by-util/test_uptime.rs @@ -1,6 +1,5 @@ -extern crate regex; -use self::regex::Regex; use crate::common::util::TestScenario; +use regex::Regex; #[test] fn test_invalid_arg() { diff --git a/tests/by-util/test_vdir.rs b/tests/by-util/test_vdir.rs index d80247450c..f6498567fb 100644 --- a/tests/by-util/test_vdir.rs +++ b/tests/by-util/test_vdir.rs @@ -1,11 +1,5 @@ -#[cfg(not(windows))] -extern crate libc; -extern crate regex; -#[cfg(not(windows))] -extern crate tempfile; - -use self::regex::Regex; use crate::common::util::TestScenario; +use regex::Regex; /* * As vdir use the same functions than ls, we don't have to retest them here. diff --git a/tests/tests.rs b/tests/tests.rs index 17581799dd..02c3bfdaba 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,9 +1,6 @@ #[macro_use] mod common; -#[cfg(unix)] -extern crate rust_users; - #[cfg(feature = "arch")] #[path = "by-util/test_arch.rs"] mod test_arch; From ae1113d7dc849c4cb0d2230f952e330a1e1a5743 Mon Sep 17 00:00:00 2001 From: Marras Antoine Date: Mon, 10 Apr 2023 18:31:18 +0200 Subject: [PATCH 108/477] b2sum: add support to -l option --- src/uu/hashsum/src/hashsum.rs | 36 ++++++++++++++++++++++++++++-- src/uucore/src/lib/features/sum.rs | 23 +++++++++++++++---- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index 460ab6f195..67431fe9f1 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -65,7 +65,23 @@ fn detect_algo( "sha256sum" => ("SHA256", Box::new(Sha256::new()) as Box, 256), "sha384sum" => ("SHA384", Box::new(Sha384::new()) as Box, 384), "sha512sum" => ("SHA512", Box::new(Sha512::new()) as Box, 512), - "b2sum" => ("BLAKE2", Box::new(Blake2b::new()) as Box, 512), + "b2sum" => match matches.get_one::("length") { + Some(length_in_bits) => { + // blake2 output size must be a multiple of 8 bits + if length_in_bits % 8 == 0 { + let length_in_bytes = length_in_bits / 8; + ( + "BLAKE2", + Box::new(Blake2b::with_output_bytes(length_in_bytes)), + *length_in_bits, + ) + } else { + crash!(1, "Invalid length (expected a multiple of 8)") + } + } + // by default, blake2 uses 64bytes (512 bits) + None => ("BLAKE2", Box::new(Blake2b::new()) as Box, 512), + }, "b3sum" => ("BLAKE3", Box::new(Blake3::new()) as Box, 256), "sha3sum" => match matches.get_one::("bits") { Some(224) => ( @@ -379,6 +395,22 @@ pub fn uu_app_common() -> Command { ) } +pub fn uu_app_length() -> Command { + uu_app_opt_length(uu_app_common()) +} + +fn uu_app_opt_length(command: Command) -> Command { + // Needed for variable-length output sums (e.g. SHAKE) + command.arg( + Arg::new("length") + .short('l') + .long("length") + .help("digest length in bits; must not exceed the max for the blake2 algorithm (512) and must be a multiple of 8") + .value_name("BITS") + .value_parser(parse_bit_num), + ) +} + pub fn uu_app_b3sum() -> Command { uu_app_b3sum_opts(uu_app_common()) } @@ -454,7 +486,7 @@ fn uu_app(binary_name: &str) -> Command { uu_app_common() } // b2sum supports the md5sum options plus -l/--length. - "b2sum" => uu_app_common(), // TODO: Implement -l/--length + "b2sum" => uu_app_length(), // These have never been part of GNU Coreutils, but can function with the same // options as md5sum. "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" => uu_app_common(), diff --git a/src/uucore/src/lib/features/sum.rs b/src/uucore/src/lib/features/sum.rs index 3394146308..c1cfaf5f84 100644 --- a/src/uucore/src/lib/features/sum.rs +++ b/src/uucore/src/lib/features/sum.rs @@ -38,10 +38,25 @@ pub trait Digest { } } -pub struct Blake2b(blake2b_simd::State); +/// first element of the tuple is the blake2b state +/// second is the number of output bits +pub struct Blake2b(blake2b_simd::State, usize); + +impl Blake2b { + /// Return a new Blake2b instance with a custom output bytes length + pub fn with_output_bytes(output_bytes: usize) -> Self { + let mut params = blake2b_simd::Params::new(); + params.hash_length(output_bytes); + + let state = params.to_state(); + Self(state, output_bytes * 8) + } +} + impl Digest for Blake2b { fn new() -> Self { - Self(blake2b_simd::State::new()) + // by default, Blake2b output is 512 bits long (= 64B) + Self::with_output_bytes(64) } fn hash_update(&mut self, input: &[u8]) { @@ -54,11 +69,11 @@ impl Digest for Blake2b { } fn reset(&mut self) { - *self = Self::new(); + *self = Self::with_output_bytes(self.output_bytes()); } fn output_bits(&self) -> usize { - 512 + self.1 } } From 0a559ab3def2500cacb43da374b52ebd3c48e493 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 10 Apr 2023 19:24:25 +0200 Subject: [PATCH 109/477] Use the full path for the ignore list --- .github/workflows/GnuTests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 3e78be910d..3926349094 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -203,7 +203,7 @@ jobs: REPO_DEFAULT_BRANCH='${{ steps.vars.outputs.repo_default_branch }}' # https://github.com/uutils/coreutils/issues/4294 # https://github.com/uutils/coreutils/issues/4295 - IGNORE_INTERMITTENT='.github/workflows/ignore-intermittent.txt' + IGNORE_INTERMITTENT='${path_UUTILS}/.github/workflows/ignore-intermittent.txt' mkdir -p ${{ steps.vars.outputs.path_reference }} From 0798cfe155419c827194b0cf940ed0b5f3fa3191 Mon Sep 17 00:00:00 2001 From: Marras Antoine Date: Mon, 10 Apr 2023 20:27:49 +0200 Subject: [PATCH 110/477] b2sum: added test for length option --- tests/by-util/test_hashsum.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/by-util/test_hashsum.rs b/tests/by-util/test_hashsum.rs index a227b9fc31..55bef37920 100644 --- a/tests/by-util/test_hashsum.rs +++ b/tests/by-util/test_hashsum.rs @@ -125,6 +125,23 @@ fn test_check_sha1() { .stderr_is(""); } +#[test] +fn test_check_b2sum_length_option() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + at.write("testf", "foobar\n"); + at.write("testf.b2sum", "6a testf\n"); + + scene + .ccmd("b2sum") + .arg("--length=8") + .arg("-c") + .arg(at.subdir.join("testf.b2sum")) + .succeeds() + .stdout_only("testf: OK\n"); +} + #[test] fn test_check_file_not_found_warning() { let scene = TestScenario::new(util_name!()); From a9e65e881c3dd6999ffc7dbfaafdf983c7bf63e1 Mon Sep 17 00:00:00 2001 From: Marras Antoine Date: Mon, 10 Apr 2023 21:20:54 +0200 Subject: [PATCH 111/477] b2sum: handled 0 length case and greater than 512 case --- src/uu/hashsum/src/hashsum.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index 67431fe9f1..30c794e07f 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -67,6 +67,15 @@ fn detect_algo( "sha512sum" => ("SHA512", Box::new(Sha512::new()) as Box, 512), "b2sum" => match matches.get_one::("length") { Some(length_in_bits) => { + if *length_in_bits > 512 { + crash!(1, "Invalid length (maximum digest length is 512 bits)") + } + + // --length=0 falls back to default behaviour + if *length_in_bits == 0 { + return ("BLAKE2", Box::new(Blake2b::new()) as Box, 512); + } + // blake2 output size must be a multiple of 8 bits if length_in_bits % 8 == 0 { let length_in_bytes = length_in_bits / 8; @@ -400,7 +409,6 @@ pub fn uu_app_length() -> Command { } fn uu_app_opt_length(command: Command) -> Command { - // Needed for variable-length output sums (e.g. SHAKE) command.arg( Arg::new("length") .short('l') From c4d637125c31341501539c3616a3fa2c9699b16e Mon Sep 17 00:00:00 2001 From: Marras Antoine Date: Tue, 11 Apr 2023 09:28:41 +0200 Subject: [PATCH 112/477] b2sum: changed british spelling for american spelling --- src/uu/hashsum/src/hashsum.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index 30c794e07f..3c3fdd2f95 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -71,7 +71,7 @@ fn detect_algo( crash!(1, "Invalid length (maximum digest length is 512 bits)") } - // --length=0 falls back to default behaviour + // --length=0 falls back to default behavior if *length_in_bits == 0 { return ("BLAKE2", Box::new(Blake2b::new()) as Box, 512); } @@ -88,7 +88,7 @@ fn detect_algo( crash!(1, "Invalid length (expected a multiple of 8)") } } - // by default, blake2 uses 64bytes (512 bits) + // by default, blake2 uses 64 bytes (512 bits) None => ("BLAKE2", Box::new(Blake2b::new()) as Box, 512), }, "b3sum" => ("BLAKE3", Box::new(Blake3::new()) as Box, 256), From b005b0e0ed691f6e0596585ec68810363fb3e370 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 11 Apr 2023 15:22:44 +0200 Subject: [PATCH 113/477] CICD: fix full path for the ignore list --- .github/workflows/GnuTests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 3926349094..b723d0a024 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -201,6 +201,7 @@ jobs: REF_LOG_FILE='${{ steps.vars.outputs.path_reference }}/test-logs/test-suite.log' REF_SUMMARY_FILE='${{ steps.vars.outputs.path_reference }}/test-summary/gnu-result.json' REPO_DEFAULT_BRANCH='${{ steps.vars.outputs.repo_default_branch }}' + path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}' # https://github.com/uutils/coreutils/issues/4294 # https://github.com/uutils/coreutils/issues/4295 IGNORE_INTERMITTENT='${path_UUTILS}/.github/workflows/ignore-intermittent.txt' From 33d4ab82ba4d1c5252410d5413fabc7e6a7ec397 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 11 Apr 2023 23:02:15 +0200 Subject: [PATCH 114/477] ls: extract most of the content into functions --- src/uu/ls/src/ls.rs | 354 +++++++++++++++++++++++--------------------- 1 file changed, 189 insertions(+), 165 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 309ae1a769..c1c0637d06 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -426,36 +426,194 @@ struct PaddingCollection { block_size: usize, } +fn extract_format(options: &clap::ArgMatches) -> (Format, Option<&'static str>) { + if let Some(format_) = options.get_one::(options::FORMAT) { + ( + match format_.as_str() { + "long" | "verbose" => Format::Long, + "single-column" => Format::OneLine, + "columns" | "vertical" => Format::Columns, + "across" | "horizontal" => Format::Across, + "commas" => Format::Commas, + // below should never happen as clap already restricts the values. + _ => unreachable!("Invalid field for --format"), + }, + Some(options::FORMAT), + ) + } else if options.get_flag(options::format::LONG) { + (Format::Long, Some(options::format::LONG)) + } else if options.get_flag(options::format::ACROSS) { + (Format::Across, Some(options::format::ACROSS)) + } else if options.get_flag(options::format::COMMAS) { + (Format::Commas, Some(options::format::COMMAS)) + } else if options.get_flag(options::format::COLUMNS) { + (Format::Columns, Some(options::format::COLUMNS)) + } else if std::io::stdout().is_terminal() { + (Format::Columns, None) + } else { + (Format::OneLine, None) + } +} + +fn extract_files(options: &clap::ArgMatches) -> Files { + if options.get_flag(options::files::ALL) { + Files::All + } else if options.get_flag(options::files::ALMOST_ALL) { + Files::AlmostAll + } else { + Files::Normal + } +} + +fn extract_sort(options: &clap::ArgMatches) -> Sort { + if let Some(field) = options.get_one::(options::SORT) { + match field.as_str() { + "none" => Sort::None, + "name" => Sort::Name, + "time" => Sort::Time, + "size" => Sort::Size, + "version" => Sort::Version, + "extension" => Sort::Extension, + // below should never happen as clap already restricts the values. + _ => unreachable!("Invalid field for --sort"), + } + } else if options.get_flag(options::sort::TIME) { + Sort::Time + } else if options.get_flag(options::sort::SIZE) { + Sort::Size + } else if options.get_flag(options::sort::NONE) { + Sort::None + } else if options.get_flag(options::sort::VERSION) { + Sort::Version + } else if options.get_flag(options::sort::EXTENSION) { + Sort::Extension + } else { + Sort::Name + } +} + +fn extract_time(options: &clap::ArgMatches) -> Time { + if let Some(field) = options.get_one::(options::TIME) { + match field.as_str() { + "ctime" | "status" => Time::Change, + "access" | "atime" | "use" => Time::Access, + "birth" | "creation" => Time::Birth, + // below should never happen as clap already restricts the values. + _ => unreachable!("Invalid field for --time"), + } + } else if options.get_flag(options::time::ACCESS) { + Time::Access + } else if options.get_flag(options::time::CHANGE) { + Time::Change + } else { + Time::Modification + } +} + +fn extract_color(options: &clap::ArgMatches) -> bool { + match options.get_one::(options::COLOR) { + None => options.contains_id(options::COLOR), + Some(val) => match val.as_str() { + "" | "always" | "yes" | "force" => true, + "auto" | "tty" | "if-tty" => std::io::stdout().is_terminal(), + /* "never" | "no" | "none" | */ _ => false, + }, + } +} + +fn extract_quoting_style(options: &clap::ArgMatches, show_control: bool) -> QuotingStyle { + let opt_quoting_style = options + .get_one::(options::QUOTING_STYLE) + .map(|cmd_line_qs| cmd_line_qs.to_owned()); + + if let Some(style) = opt_quoting_style { + match style.as_str() { + "literal" => QuotingStyle::Literal { show_control }, + "shell" => QuotingStyle::Shell { + escape: false, + always_quote: false, + show_control, + }, + "shell-always" => QuotingStyle::Shell { + escape: false, + always_quote: true, + show_control, + }, + "shell-escape" => QuotingStyle::Shell { + escape: true, + always_quote: false, + show_control, + }, + "shell-escape-always" => QuotingStyle::Shell { + escape: true, + always_quote: true, + show_control, + }, + "c" => QuotingStyle::C { + quotes: quoting_style::Quotes::Double, + }, + "escape" => QuotingStyle::C { + quotes: quoting_style::Quotes::None, + }, + _ => unreachable!("Should have been caught by Clap"), + } + } else if options.get_flag(options::quoting::LITERAL) { + QuotingStyle::Literal { show_control } + } else if options.get_flag(options::quoting::ESCAPE) { + QuotingStyle::C { + quotes: quoting_style::Quotes::None, + } + } else if options.get_flag(options::quoting::C) { + QuotingStyle::C { + quotes: quoting_style::Quotes::Double, + } + } else { + // TODO: use environment variable if available + QuotingStyle::Shell { + escape: true, + always_quote: false, + show_control, + } + } +} + +fn extract_indicator_style(options: &clap::ArgMatches) -> IndicatorStyle { + if let Some(field) = options.get_one::(options::INDICATOR_STYLE) { + match field.as_str() { + "none" => IndicatorStyle::None, + "file-type" => IndicatorStyle::FileType, + "classify" => IndicatorStyle::Classify, + "slash" => IndicatorStyle::Slash, + &_ => IndicatorStyle::None, + } + } else if let Some(field) = options.get_one::(options::indicator_style::CLASSIFY) { + match field.as_str() { + "never" | "no" | "none" => IndicatorStyle::None, + "always" | "yes" | "force" => IndicatorStyle::Classify, + "auto" | "tty" | "if-tty" => { + if std::io::stdout().is_terminal() { + IndicatorStyle::Classify + } else { + IndicatorStyle::None + } + } + &_ => IndicatorStyle::None, + } + } else if options.get_flag(options::indicator_style::SLASH) { + IndicatorStyle::Slash + } else if options.get_flag(options::indicator_style::FILE_TYPE) { + IndicatorStyle::FileType + } else { + IndicatorStyle::None + } +} + impl Config { #[allow(clippy::cognitive_complexity)] pub fn from(options: &clap::ArgMatches) -> UResult { let context = options.get_flag(options::CONTEXT); - let (mut format, opt) = if let Some(format_) = options.get_one::(options::FORMAT) { - ( - match format_.as_str() { - "long" | "verbose" => Format::Long, - "single-column" => Format::OneLine, - "columns" | "vertical" => Format::Columns, - "across" | "horizontal" => Format::Across, - "commas" => Format::Commas, - // below should never happen as clap already restricts the values. - _ => unreachable!("Invalid field for --format"), - }, - Some(options::FORMAT), - ) - } else if options.get_flag(options::format::LONG) { - (Format::Long, Some(options::format::LONG)) - } else if options.get_flag(options::format::ACROSS) { - (Format::Across, Some(options::format::ACROSS)) - } else if options.get_flag(options::format::COMMAS) { - (Format::Commas, Some(options::format::COMMAS)) - } else if options.get_flag(options::format::COLUMNS) { - (Format::Columns, Some(options::format::COLUMNS)) - } else if std::io::stdout().is_terminal() { - (Format::Columns, None) - } else { - (Format::OneLine, None) - }; + let (mut format, opt) = extract_format(options); + let files = extract_files(options); // The -o, -n and -g options are tricky. They cannot override with each // other because it's possible to combine them. For example, the option @@ -504,63 +662,11 @@ impl Config { } } - let files = if options.get_flag(options::files::ALL) { - Files::All - } else if options.get_flag(options::files::ALMOST_ALL) { - Files::AlmostAll - } else { - Files::Normal - }; + let sort = extract_sort(options); - let sort = if let Some(field) = options.get_one::(options::SORT) { - match field.as_str() { - "none" => Sort::None, - "name" => Sort::Name, - "time" => Sort::Time, - "size" => Sort::Size, - "version" => Sort::Version, - "extension" => Sort::Extension, - // below should never happen as clap already restricts the values. - _ => unreachable!("Invalid field for --sort"), - } - } else if options.get_flag(options::sort::TIME) { - Sort::Time - } else if options.get_flag(options::sort::SIZE) { - Sort::Size - } else if options.get_flag(options::sort::NONE) { - Sort::None - } else if options.get_flag(options::sort::VERSION) { - Sort::Version - } else if options.get_flag(options::sort::EXTENSION) { - Sort::Extension - } else { - Sort::Name - }; + let time = extract_time(options); - let time = if let Some(field) = options.get_one::(options::TIME) { - match field.as_str() { - "ctime" | "status" => Time::Change, - "access" | "atime" | "use" => Time::Access, - "birth" | "creation" => Time::Birth, - // below should never happen as clap already restricts the values. - _ => unreachable!("Invalid field for --time"), - } - } else if options.get_flag(options::time::ACCESS) { - Time::Access - } else if options.get_flag(options::time::CHANGE) { - Time::Change - } else { - Time::Modification - }; - - let mut needs_color = match options.get_one::(options::COLOR) { - None => options.contains_id(options::COLOR), - Some(val) => match val.as_str() { - "" | "always" | "yes" | "force" => true, - "auto" | "tty" | "if-tty" => std::io::stdout().is_terminal(), - /* "never" | "no" | "none" | */ _ => false, - }, - }; + let mut needs_color = extract_color(options); let cmd_line_bs = options.get_one::(options::size::BLOCK_SIZE); let opt_si = cmd_line_bs.is_some() @@ -681,90 +787,8 @@ impl Config { !std::io::stdout().is_terminal() }; - let opt_quoting_style = options - .get_one::(options::QUOTING_STYLE) - .map(|cmd_line_qs| cmd_line_qs.to_owned()); - - let mut quoting_style = if let Some(style) = opt_quoting_style { - match style.as_str() { - "literal" => QuotingStyle::Literal { show_control }, - "shell" => QuotingStyle::Shell { - escape: false, - always_quote: false, - show_control, - }, - "shell-always" => QuotingStyle::Shell { - escape: false, - always_quote: true, - show_control, - }, - "shell-escape" => QuotingStyle::Shell { - escape: true, - always_quote: false, - show_control, - }, - "shell-escape-always" => QuotingStyle::Shell { - escape: true, - always_quote: true, - show_control, - }, - "c" => QuotingStyle::C { - quotes: quoting_style::Quotes::Double, - }, - "escape" => QuotingStyle::C { - quotes: quoting_style::Quotes::None, - }, - _ => unreachable!("Should have been caught by Clap"), - } - } else if options.get_flag(options::quoting::LITERAL) { - QuotingStyle::Literal { show_control } - } else if options.get_flag(options::quoting::ESCAPE) { - QuotingStyle::C { - quotes: quoting_style::Quotes::None, - } - } else if options.get_flag(options::quoting::C) { - QuotingStyle::C { - quotes: quoting_style::Quotes::Double, - } - } else { - // TODO: use environment variable if available - QuotingStyle::Shell { - escape: true, - always_quote: false, - show_control, - } - }; - - let indicator_style = if let Some(field) = - options.get_one::(options::INDICATOR_STYLE) - { - match field.as_str() { - "none" => IndicatorStyle::None, - "file-type" => IndicatorStyle::FileType, - "classify" => IndicatorStyle::Classify, - "slash" => IndicatorStyle::Slash, - &_ => IndicatorStyle::None, - } - } else if let Some(field) = options.get_one::(options::indicator_style::CLASSIFY) { - match field.as_str() { - "never" | "no" | "none" => IndicatorStyle::None, - "always" | "yes" | "force" => IndicatorStyle::Classify, - "auto" | "tty" | "if-tty" => { - if std::io::stdout().is_terminal() { - IndicatorStyle::Classify - } else { - IndicatorStyle::None - } - } - &_ => IndicatorStyle::None, - } - } else if options.get_flag(options::indicator_style::SLASH) { - IndicatorStyle::Slash - } else if options.get_flag(options::indicator_style::FILE_TYPE) { - IndicatorStyle::FileType - } else { - IndicatorStyle::None - }; + let mut quoting_style = extract_quoting_style(options, show_control); + let indicator_style = extract_indicator_style(options); let time_style = parse_time_style(options)?; let mut ignore_patterns: Vec = Vec::new(); From ee0fc86ce84d949786a52c31073a7a6aab75a804 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 11 Apr 2023 23:03:41 +0200 Subject: [PATCH 115/477] ls: remove cognitive_complexity clippy allow --- src/uu/ls/src/ls.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index c1c0637d06..b6c8677d6f 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -609,7 +609,6 @@ fn extract_indicator_style(options: &clap::ArgMatches) -> IndicatorStyle { } impl Config { - #[allow(clippy::cognitive_complexity)] pub fn from(options: &clap::ArgMatches) -> UResult { let context = options.get_flag(options::CONTEXT); let (mut format, opt) = extract_format(options); From c8d2a9ad0e3132237f8debf0486b91d2365978b0 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 11 Apr 2023 23:13:04 +0200 Subject: [PATCH 116/477] ls: document the new functions --- src/uu/ls/src/ls.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index b6c8677d6f..9be9b19d45 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -426,6 +426,12 @@ struct PaddingCollection { block_size: usize, } +/// Extracts the format to display the information based on the options provided. +/// +/// # Returns +/// +/// A tuple containing the Format variant and an Option containing a &'static str +/// which corresponds to the option used to define the format. fn extract_format(options: &clap::ArgMatches) -> (Format, Option<&'static str>) { if let Some(format_) = options.get_one::(options::FORMAT) { ( @@ -455,6 +461,11 @@ fn extract_format(options: &clap::ArgMatches) -> (Format, Option<&'static str>) } } +/// Extracts the type of files to display +/// +/// # Returns +/// +/// A Files variant representing the type of files to display. fn extract_files(options: &clap::ArgMatches) -> Files { if options.get_flag(options::files::ALL) { Files::All @@ -465,6 +476,11 @@ fn extract_files(options: &clap::ArgMatches) -> Files { } } +/// Extracts the sorting method to use based on the options provided. +/// +/// # Returns +/// +/// A Sort variant representing the sorting method to use. fn extract_sort(options: &clap::ArgMatches) -> Sort { if let Some(field) = options.get_one::(options::SORT) { match field.as_str() { @@ -492,6 +508,11 @@ fn extract_sort(options: &clap::ArgMatches) -> Sort { } } +/// Extracts the time to use based on the options provided. +/// +/// # Returns +/// +/// A Time variant representing the time to use. fn extract_time(options: &clap::ArgMatches) -> Time { if let Some(field) = options.get_one::(options::TIME) { match field.as_str() { @@ -510,6 +531,11 @@ fn extract_time(options: &clap::ArgMatches) -> Time { } } +/// Extracts the color option to use based on the options provided. +/// +/// # Returns +/// +/// A boolean representing whether or not to use color. fn extract_color(options: &clap::ArgMatches) -> bool { match options.get_one::(options::COLOR) { None => options.contains_id(options::COLOR), @@ -521,6 +547,16 @@ fn extract_color(options: &clap::ArgMatches) -> bool { } } +/// Extracts the quoting style to use based on the options provided. +/// +/// # Arguments +/// +/// * `options` - A reference to a clap::ArgMatches object containing command line arguments. +/// * `show_control` - A boolean value representing whether or not to show control characters. +/// +/// # Returns +/// +/// A QuotingStyle variant representing the quoting style to use. fn extract_quoting_style(options: &clap::ArgMatches, show_control: bool) -> QuotingStyle { let opt_quoting_style = options .get_one::(options::QUOTING_STYLE) @@ -577,6 +613,11 @@ fn extract_quoting_style(options: &clap::ArgMatches, show_control: bool) -> Quot } } +/// Extracts the indicator style to use based on the options provided. +/// +/// # Returns +/// +/// An IndicatorStyle variant representing the indicator style to use. fn extract_indicator_style(options: &clap::ArgMatches) -> IndicatorStyle { if let Some(field) = options.get_one::(options::INDICATOR_STYLE) { match field.as_str() { From 692af0957dbd9433f5a83401a8ba24da95b49b2e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:07:14 +0000 Subject: [PATCH 117/477] chore(deps): update rust crate sha3 to 0.10.7 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fbba8f987..db4e2035ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2080,9 +2080,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" dependencies = [ "digest", "keccak", diff --git a/Cargo.toml b/Cargo.toml index 5b6b71edf9..98c899b98f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -335,7 +335,7 @@ hex = "0.4.3" md-5 = "0.10.5" sha1 = "0.10.5" sha2 = "0.10.6" -sha3 = "0.10.6" +sha3 = "0.10.7" blake2b_simd = "1.0.1" blake3 = "1.3.3" sm3 = "0.4.1" From fdbebfad9da500c72b0a9c127f59c95e06b248f6 Mon Sep 17 00:00:00 2001 From: Marras Antoine Date: Wed, 12 Apr 2023 09:49:20 +0200 Subject: [PATCH 118/477] b2sum: moved 0 case into None arm --- src/uu/hashsum/src/hashsum.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index 3c3fdd2f95..5678a58b35 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -66,16 +66,14 @@ fn detect_algo( "sha384sum" => ("SHA384", Box::new(Sha384::new()) as Box, 384), "sha512sum" => ("SHA512", Box::new(Sha512::new()) as Box, 512), "b2sum" => match matches.get_one::("length") { + // by default, blake2 uses 64 bytes (512 bits) + // --length=0 falls back to default behavior + Some(0) | None => ("BLAKE2", Box::new(Blake2b::new()) as Box, 512), Some(length_in_bits) => { if *length_in_bits > 512 { crash!(1, "Invalid length (maximum digest length is 512 bits)") } - // --length=0 falls back to default behavior - if *length_in_bits == 0 { - return ("BLAKE2", Box::new(Blake2b::new()) as Box, 512); - } - // blake2 output size must be a multiple of 8 bits if length_in_bits % 8 == 0 { let length_in_bytes = length_in_bits / 8; @@ -88,8 +86,6 @@ fn detect_algo( crash!(1, "Invalid length (expected a multiple of 8)") } } - // by default, blake2 uses 64 bytes (512 bits) - None => ("BLAKE2", Box::new(Blake2b::new()) as Box, 512), }, "b3sum" => ("BLAKE3", Box::new(Blake3::new()) as Box, 256), "sha3sum" => match matches.get_one::("bits") { From 756293a9c47ec9fc6eaef7b7c87e5c7e3be41bea Mon Sep 17 00:00:00 2001 From: Marras Antoine Date: Wed, 12 Apr 2023 21:05:11 +0200 Subject: [PATCH 119/477] b2sum: added tests to handle 0, non multiple of 8 and and more than 512 cases --- tests/by-util/test_hashsum.rs | 49 ++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_hashsum.rs b/tests/by-util/test_hashsum.rs index 55bef37920..645f11ef2c 100644 --- a/tests/by-util/test_hashsum.rs +++ b/tests/by-util/test_hashsum.rs @@ -126,7 +126,24 @@ fn test_check_sha1() { } #[test] -fn test_check_b2sum_length_option() { +fn test_check_b2sum_length_option_0() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + at.write("testf", "foobar\n"); + at.write("testf.b2sum", "9e2bf63e933e610efee4a8d6cd4a9387e80860edee97e27db3b37a828d226ab1eb92a9cdd8ca9ca67a753edaf8bd89a0558496f67a30af6f766943839acf0110 testf\n"); + + scene + .ccmd("b2sum") + .arg("--length=0") + .arg("-c") + .arg(at.subdir.join("testf.b2sum")) + .succeeds() + .stdout_only("testf: OK\n"); +} + +#[test] +fn test_check_b2sum_length_option_8() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; @@ -142,6 +159,36 @@ fn test_check_b2sum_length_option() { .stdout_only("testf: OK\n"); } +#[test] +fn test_invalid_b2sum_length_option_not_multiple_of_8() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + at.write("testf", "foobar\n"); + + scene + .ccmd("b2sum") + .arg("--length=9") + .arg(at.subdir.join("testf")) + .fails() + .code_is(1); +} + +#[test] +fn test_invalid_b2sum_length_option_too_large() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + at.write("testf", "foobar\n"); + + scene + .ccmd("b2sum") + .arg("--length=513") + .arg(at.subdir.join("testf")) + .fails() + .code_is(1); +} + #[test] fn test_check_file_not_found_warning() { let scene = TestScenario::new(util_name!()); From d3406b0c662a5eada2bfc77c3c3b35a8ddb6613b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Apr 2023 20:30:46 +0000 Subject: [PATCH 120/477] chore(deps): update rust crate lscolors to 0.14.0 --- Cargo.lock | 17 +++++------------ Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db4e2035ab..1123224777 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1350,9 +1350,9 @@ dependencies = [ [[package]] name = "lscolors" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dedc85d67baf5327114fad78ab9418f8893b1121c17d5538dd11005ad1ddf2" +checksum = "18a9df1d1fb6d9e92fa043e9eb9a3ecf6892c7b542bae5137cd1e419e40aa8bf" dependencies = [ "nu-ansi-term", ] @@ -1465,12 +1465,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "1df031e117bca634c262e9bd3173776844b6c17a90b3741c9163663b4385af76" dependencies = [ - "overload", - "winapi", + "windows-sys 0.45.0", ] [[package]] @@ -1607,12 +1606,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "parking_lot" version = "0.12.1" diff --git a/Cargo.toml b/Cargo.toml index 98c899b98f..24bea229ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -290,7 +290,7 @@ indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" libc = "0.2.141" -lscolors = { version = "0.13.0", default-features=false, features = ["nu-ansi-term"] } +lscolors = { version = "0.14.0", default-features=false, features = ["nu-ansi-term"] } memchr = "2" nix = { version="0.26", default-features=false } nom = "7.1.3" From 5a1d9cec7ec2b82fc7460f4d2b011b58dd3f83da Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 9 Apr 2023 21:10:31 +0200 Subject: [PATCH 121/477] du: an error code when done on a non existing file --- src/uu/du/src/du.rs | 3 ++- tests/by-util/test_du.rs | 25 ++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index cab9da2275..fb490888a9 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -33,7 +33,7 @@ use std::time::{Duration, UNIX_EPOCH}; use std::{error::Error, fmt::Display}; use uucore::display::{print_verbatim, Quotable}; use uucore::error::FromIo; -use uucore::error::{UError, UResult}; +use uucore::error::{set_exit_code, UError, UResult}; use uucore::parse_glob; use uucore::parse_size::{parse_size, ParseSizeError}; use uucore::{ @@ -655,6 +655,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { path_string.maybe_quote(), "No such file or directory" ); + set_exit_code(1); } } diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index d69eaaf991..73be82bf9f 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -6,7 +6,6 @@ // spell-checker:ignore (paths) sublink subwords azerty azeaze xcwww azeaz amaz azea qzerty tazerty #[cfg(not(windows))] use regex::Regex; -#[cfg(not(windows))] use std::io::Write; #[cfg(any(target_os = "linux", target_os = "android"))] @@ -851,3 +850,27 @@ fn test_du_exclude_invalid_syntax() { .fails() .stderr_contains("du: Invalid exclude syntax"); } + +#[test] +fn test_du_symlink_fail() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + + at.symlink_file("non-existing.txt", "target.txt"); + + ts.ucmd().arg("-L").arg("target.txt").fails().code_is(1); +} + +#[test] +fn test_du_symlink_multiple_fail() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + + at.symlink_file("non-existing.txt", "target.txt"); + let mut file1 = at.make_file("file1"); + file1.write_all(b"azeaze").unwrap(); + + let result = ts.ucmd().arg("-L").arg("target.txt").arg("file1").fails(); + assert_eq!(result.code(), 1); + result.stdout_contains("4\tfile1\n"); +} From eea8d40e781f667fb66856d62cb7827df998deac Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 9 Apr 2023 21:12:39 +0200 Subject: [PATCH 122/477] du: add support of --dereference-args Should fix tests/du/deref.sh --- src/uu/du/src/du.rs | 36 ++++++++++++++++++++++++++---------- tests/by-util/test_du.rs | 28 +++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index fb490888a9..74d86219b3 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -68,6 +68,7 @@ mod options { pub const TIME_STYLE: &str = "time-style"; pub const ONE_FILE_SYSTEM: &str = "one-file-system"; pub const DEREFERENCE: &str = "dereference"; + pub const DEREFERENCE_ARGS: &str = "dereference-args"; pub const INODES: &str = "inodes"; pub const EXCLUDE: &str = "exclude"; pub const EXCLUDE_FROM: &str = "exclude-from"; @@ -89,6 +90,7 @@ struct Options { separate_dirs: bool, one_file_system: bool, dereference: bool, + dereference_args: Vec, inodes: bool, verbose: bool, } @@ -113,7 +115,7 @@ struct Stat { impl Stat { fn new(path: PathBuf, options: &Options) -> Result { - let metadata = if options.dereference { + let metadata = if options.dereference || options.dereference_args.contains(&path) { fs::metadata(&path)? } else { fs::symlink_metadata(&path)? @@ -505,6 +507,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { summarize, )?; + let files = match matches.get_one::(options::FILE) { + Some(_) => matches + .get_many::(options::FILE) + .unwrap() + .map(|s| s.as_str()) + .collect(), + None => vec!["."], + }; + let options = Options { all: matches.get_flag(options::ALL), max_depth, @@ -512,19 +523,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { separate_dirs: matches.get_flag(options::SEPARATE_DIRS), one_file_system: matches.get_flag(options::ONE_FILE_SYSTEM), dereference: matches.get_flag(options::DEREFERENCE), + dereference_args: if matches.get_flag(options::DEREFERENCE_ARGS) { + // Convert into a pathbuf as we will use it in a function using Pathbuf + // We don't care about the cost as it is rarely used + files.iter().map(PathBuf::from).collect() + } else { + vec![] + }, inodes: matches.get_flag(options::INODES), verbose: matches.get_flag(options::VERBOSE), }; - let files = match matches.get_one::(options::FILE) { - Some(_) => matches - .get_many::(options::FILE) - .unwrap() - .map(|s| s.as_str()) - .collect(), - None => vec!["."], - }; - if options.inodes && (matches.get_flag(options::APPARENT_SIZE) || matches.get_flag(options::BYTES)) { @@ -789,6 +798,13 @@ pub fn uu_app() -> Command { .help("dereference all symbolic links") .action(ArgAction::SetTrue) ) + .arg( + Arg::new(options::DEREFERENCE_ARGS) + .short('D') + .long(options::DEREFERENCE_ARGS) + .help("dereference only symlinks that are listed on the command line") + .action(ArgAction::SetTrue) + ) // .arg( // Arg::new("no-dereference") // .short('P') diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index 73be82bf9f..992f7f1621 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -3,7 +3,7 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -// spell-checker:ignore (paths) sublink subwords azerty azeaze xcwww azeaz amaz azea qzerty tazerty +// spell-checker:ignore (paths) sublink subwords azerty azeaze xcwww azeaz amaz azea qzerty tazerty tsublink #[cfg(not(windows))] use regex::Regex; use std::io::Write; @@ -285,6 +285,30 @@ fn test_du_dereference() { _du_dereference(result.stdout_str()); } +#[cfg(not(windows))] +#[test] +fn test_du_dereference_args() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + + at.mkdir_all("subdir"); + let mut file1 = at.make_file("subdir/file-ignore1"); + file1.write_all(b"azeaze").unwrap(); + let mut file2 = at.make_file("subdir/file-ignore1"); + file2.write_all(b"amaz?ng").unwrap(); + at.symlink_dir("subdir", "sublink"); + + let result = ts.ucmd().arg("-D").arg("-s").arg("sublink").succeeds(); + let stdout = result.stdout_str(); + + assert!(!stdout.starts_with("0")); + assert!(stdout.contains("sublink")); + + // Without the option + let result = ts.ucmd().arg("-s").arg("sublink").succeeds(); + result.stdout_contains("0\tsublink\n"); +} + #[cfg(target_vendor = "apple")] fn _du_dereference(s: &str) { assert_eq!(s, "4\tsubdir/links/deeper_dir\n16\tsubdir/links\n"); @@ -851,6 +875,7 @@ fn test_du_exclude_invalid_syntax() { .stderr_contains("du: Invalid exclude syntax"); } +#[cfg(not(windows))] #[test] fn test_du_symlink_fail() { let ts = TestScenario::new(util_name!()); @@ -861,6 +886,7 @@ fn test_du_symlink_fail() { ts.ucmd().arg("-L").arg("target.txt").fails().code_is(1); } +#[cfg(not(windows))] #[test] fn test_du_symlink_multiple_fail() { let ts = TestScenario::new(util_name!()); From 47cb40c020605c62df85f8edc9ad26b0c799deee Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 9 Apr 2023 21:24:09 +0200 Subject: [PATCH 123/477] du: adjust test_du_basics_bad_name as we made it work --- tests/by-util/test_du.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index 992f7f1621..a965d3fc69 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -121,7 +121,7 @@ fn test_du_invalid_size() { fn test_du_basics_bad_name() { new_ucmd!() .arg("bad_name") - .succeeds() // TODO: replace with ".fails()" once `du` is fixed + .fails() .stderr_only("du: bad_name: No such file or directory\n"); } From f08b8dab235604e2d79d3bdb4e0a76bb1ea61e81 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 11 Apr 2023 17:54:19 +0200 Subject: [PATCH 124/477] du: directly get a vec of pathbuf to avoid several type changes --- src/uu/du/src/du.rs | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 74d86219b3..2dcfbf2acd 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -114,12 +114,13 @@ struct Stat { } impl Stat { - fn new(path: PathBuf, options: &Options) -> Result { - let metadata = if options.dereference || options.dereference_args.contains(&path) { - fs::metadata(&path)? - } else { - fs::symlink_metadata(&path)? - }; + fn new(path: &Path, options: &Options) -> Result { + let metadata = + if options.dereference || options.dereference_args.contains(&path.to_path_buf()) { + fs::metadata(path)? + } else { + fs::symlink_metadata(path)? + }; #[cfg(not(windows))] let file_info = FileInfo { @@ -128,7 +129,7 @@ impl Stat { }; #[cfg(not(windows))] return Ok(Self { - path, + path: path.to_path_buf(), is_dir: metadata.is_dir(), size: metadata.len(), blocks: metadata.blocks(), @@ -140,12 +141,12 @@ impl Stat { }); #[cfg(windows)] - let size_on_disk = get_size_on_disk(&path); + let size_on_disk = get_size_on_disk(path); #[cfg(windows)] - let file_info = get_file_info(&path); + let file_info = get_file_info(path); #[cfg(windows)] Ok(Self { - path, + path: path.to_path_buf(), is_dir: metadata.is_dir(), size: metadata.len(), blocks: size_on_disk / 1024 * 2, @@ -298,7 +299,7 @@ fn du( 'file_loop: for f in read { match f { Ok(entry) => { - match Stat::new(entry.path(), options) { + match Stat::new(&entry.path(), options) { Ok(this_stat) => { // We have an exclude list for pattern in exclude { @@ -511,9 +512,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Some(_) => matches .get_many::(options::FILE) .unwrap() - .map(|s| s.as_str()) + .map(PathBuf::from) .collect(), - None => vec!["."], + None => vec![PathBuf::from(".")], }; let options = Options { @@ -524,9 +525,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { one_file_system: matches.get_flag(options::ONE_FILE_SYSTEM), dereference: matches.get_flag(options::DEREFERENCE), dereference_args: if matches.get_flag(options::DEREFERENCE_ARGS) { - // Convert into a pathbuf as we will use it in a function using Pathbuf - // We don't care about the cost as it is rarely used - files.iter().map(PathBuf::from).collect() + // We don't care about the cost of cloning as it is rarely used + files.clone() } else { vec![] }, @@ -589,11 +589,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let excludes = build_exclude_patterns(&matches)?; let mut grand_total = 0; - 'loop_file: for path_string in files { + 'loop_file: for path in files { // Skip if we don't want to ignore anything if !&excludes.is_empty() { + let path_string = path.to_string_lossy(); for pattern in &excludes { - if pattern.matches(path_string) { + if pattern.matches(&path_string) { // if the directory is ignored, leave early if options.verbose { println!("{} ignored", path_string.quote()); @@ -603,9 +604,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } - let path = PathBuf::from(&path_string); // Check existence of path provided in argument - if let Ok(stat) = Stat::new(path, &options) { + if let Ok(stat) = Stat::new(&path, &options) { // Kick off the computation of disk usage from the initial path let mut inodes: HashSet = HashSet::new(); if let Some(inode) = stat.inode { @@ -661,7 +661,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } else { show_error!( "{}: {}", - path_string.maybe_quote(), + path.to_string_lossy().maybe_quote(), "No such file or directory" ); set_exit_code(1); From f475a362042301319665f68c5869d5145cd38da4 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 11 Apr 2023 20:41:57 +0200 Subject: [PATCH 125/477] du: reduce the complexity by moving the time option mgmt into a function --- src/uu/du/src/du.rs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 2dcfbf2acd..c5aafb44e2 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -625,20 +625,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if matches.contains_id(options::TIME) { let tm = { - let secs = { - match matches.get_one::(options::TIME) { - Some(s) => match s.as_str() { - "ctime" | "status" => stat.modified, - "access" | "atime" | "use" => stat.accessed, - "birth" | "creation" => stat - .created - .ok_or_else(|| DuError::InvalidTimeArg(s.into()))?, - // below should never happen as clap already restricts the values. - _ => unreachable!("Invalid field for --time"), - }, - None => stat.modified, - } - }; + let secs = matches + .get_one::(options::TIME) + .map(|s| get_time_secs(s, &stat)) + .transpose()? + .unwrap_or(stat.modified); DateTime::::from(UNIX_EPOCH + Duration::from_secs(secs)) }; if !summarize || index == len - 1 { @@ -676,6 +667,19 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Ok(()) } +fn get_time_secs(s: &str, stat: &Stat) -> std::result::Result { + let secs = match s { + "ctime" | "status" => stat.modified, + "access" | "atime" | "use" => stat.accessed, + "birth" | "creation" => stat + .created + .ok_or_else(|| DuError::InvalidTimeArg(s.into()))?, + // below should never happen as clap already restricts the values. + _ => unreachable!("Invalid field for --time"), + }; + Ok(secs) +} + fn parse_time_style(s: Option<&str>) -> UResult<&str> { match s { Some(s) => match s { From b2fd72878ee97f8b8f13e6dcb190df6cf4e50d2d Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 11 Apr 2023 21:03:24 +0200 Subject: [PATCH 126/477] du: reduce the complexity by moving get_convert_size_fn option mgmt into a function --- src/uu/du/src/du.rs | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index c5aafb44e2..d7618d3e09 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -400,6 +400,20 @@ fn convert_size_other(size: u64, _multiplier: u64, block_size: u64) -> String { format!("{}", ((size as f64) / (block_size as f64)).ceil()) } +fn get_convert_size_fn(matches: &ArgMatches) -> Box String> { + if matches.get_flag(options::HUMAN_READABLE) || matches.get_flag(options::SI) { + Box::new(convert_size_human) + } else if matches.get_flag(options::BYTES) { + Box::new(convert_size_b) + } else if matches.get_flag(options::BLOCK_SIZE_1K) { + Box::new(convert_size_k) + } else if matches.get_flag(options::BLOCK_SIZE_1M) { + Box::new(convert_size_m) + } else { + Box::new(convert_size_other) + } +} + #[derive(Debug)] enum DuError { InvalidMaxDepthArg(String), @@ -556,19 +570,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } else { 1024 }; - let convert_size_fn = { - if matches.get_flag(options::HUMAN_READABLE) || matches.get_flag(options::SI) { - convert_size_human - } else if matches.get_flag(options::BYTES) { - convert_size_b - } else if matches.get_flag(options::BLOCK_SIZE_1K) { - convert_size_k - } else if matches.get_flag(options::BLOCK_SIZE_1M) { - convert_size_m - } else { - convert_size_other - } - }; + + let convert_size_fn = get_convert_size_fn(&matches); + let convert_size = |size: u64| { if options.inodes { size.to_string() From e82e6a3e4c075f1c30ef0cd3d26d87cb053d75f8 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 11 Apr 2023 22:33:34 +0200 Subject: [PATCH 127/477] du: remove cognitive_complexity clippy allow --- src/uu/du/src/du.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index d7618d3e09..4b1aa5a0e7 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -507,7 +507,6 @@ fn build_exclude_patterns(matches: &ArgMatches) -> UResult> { } #[uucore::main] -#[allow(clippy::cognitive_complexity)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let args = args.collect_ignore(); From 00a866e1281e62c830038f829de0c98829a9b9f3 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 12 Apr 2023 21:25:42 +0200 Subject: [PATCH 128/477] du: move to use an enum --- src/uu/du/src/du.rs | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 4b1aa5a0e7..f78e0d4ae9 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -89,12 +89,18 @@ struct Options { total: bool, separate_dirs: bool, one_file_system: bool, - dereference: bool, - dereference_args: Vec, + dereference: Deref, inodes: bool, verbose: bool, } +#[derive(PartialEq)] +enum Deref { + All, + Args(Vec), + None, +} + #[derive(PartialEq, Eq, Hash, Clone, Copy)] struct FileInfo { file_id: u128, @@ -115,12 +121,20 @@ struct Stat { impl Stat { fn new(path: &Path, options: &Options) -> Result { - let metadata = - if options.dereference || options.dereference_args.contains(&path.to_path_buf()) { - fs::metadata(path)? - } else { - fs::symlink_metadata(path)? - }; + // Determine whether to dereference (follow) the symbolic link + let should_dereference = match &options.dereference { + Deref::All => true, + Deref::Args(paths) => paths.contains(&path.to_path_buf()), + Deref::None => false, + }; + + let metadata = if should_dereference { + // Get metadata, following symbolic links if necessary + fs::metadata(path) + } else { + // Get metadata without following symbolic links + fs::symlink_metadata(path) + }?; #[cfg(not(windows))] let file_info = FileInfo { @@ -536,12 +550,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { total: matches.get_flag(options::TOTAL), separate_dirs: matches.get_flag(options::SEPARATE_DIRS), one_file_system: matches.get_flag(options::ONE_FILE_SYSTEM), - dereference: matches.get_flag(options::DEREFERENCE), - dereference_args: if matches.get_flag(options::DEREFERENCE_ARGS) { + dereference: if matches.get_flag(options::DEREFERENCE) { + Deref::All + } else if matches.get_flag(options::DEREFERENCE_ARGS) { // We don't care about the cost of cloning as it is rarely used - files.clone() + Deref::Args(files.clone()) } else { - vec![] + Deref::None }, inodes: matches.get_flag(options::INODES), verbose: matches.get_flag(options::VERBOSE), From 40fef4981723aee59279cb300973230a6dc5bc00 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 13 Apr 2023 16:47:05 +0200 Subject: [PATCH 129/477] Fix incorrect comment & remove irrelevant comment --- util/build-gnu.sh | 2 +- util/run-gnu-test.sh | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/util/build-gnu.sh b/util/build-gnu.sh index e7637ff942..9035fa69b3 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -1,7 +1,7 @@ #!/bin/bash # `build-gnu.bash` ~ builds GNU coreutils (from supplied sources) # -# UU_MAKE_PROFILE == 'debug' | 'release' ## build profile for *uutils* build; may be supplied by caller, defaults to 'debug' +# UU_MAKE_PROFILE == 'debug' | 'release' ## build profile for *uutils* build; may be supplied by caller, defaults to 'release' # spell-checker:ignore (paths) abmon deref discrim eacces getlimits getopt ginstall inacc infloop inotify reflink ; (misc) INT_OFLOW OFLOW baddecode submodules ; (vars/env) SRCDIR vdir rcexp xpart diff --git a/util/run-gnu-test.sh b/util/run-gnu-test.sh index f5c47e6450..ac736abe19 100755 --- a/util/run-gnu-test.sh +++ b/util/run-gnu-test.sh @@ -1,8 +1,6 @@ #!/bin/sh # `run-gnu-test.bash [TEST]` # run GNU test (or all tests if TEST is missing/null) -# -# UU_MAKE_PROFILE == 'debug' | 'release' ## build profile used for *uutils* build; may be supplied by caller, defaults to 'release' # spell-checker:ignore (env/vars) GNULIB SRCDIR SUBDIRS ; (utils) shellcheck @@ -62,4 +60,4 @@ else sudo make -j "$(nproc)" check-root SUBDIRS=. RUN_EXPENSIVE_TESTS=yes RUN_VERY_EXPENSIVE_TESTS=yes VERBOSE=no gl_public_submodule_commit="" srcdir="${path_GNU}" TEST_SUITE_LOG="tests/test-suite-root.log" || : fi fi -fi \ No newline at end of file +fi From fcc1ebf078324ea54d7ca3bc00538dfac3fdc34f Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 13 Apr 2023 19:28:50 +0200 Subject: [PATCH 130/477] be more consistent in the help. use follow for deference options --- src/uu/du/src/du.rs | 4 ++-- src/uu/ln/src/ln.rs | 2 +- src/uu/ls/src/ls.rs | 4 ++-- src/uu/stat/stat.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index f78e0d4ae9..f6a631d205 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -817,14 +817,14 @@ pub fn uu_app() -> Command { Arg::new(options::DEREFERENCE) .short('L') .long(options::DEREFERENCE) - .help("dereference all symbolic links") + .help("follow all symbolic links") .action(ArgAction::SetTrue) ) .arg( Arg::new(options::DEREFERENCE_ARGS) .short('D') .long(options::DEREFERENCE_ARGS) - .help("dereference only symlinks that are listed on the command line") + .help("follow only symlinks that are listed on the command line") .action(ArgAction::SetTrue) ) // .arg( diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index bfff8d3ebc..d98f3afb15 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -199,7 +199,7 @@ pub fn uu_app() -> Command { Arg::new(options::LOGICAL) .short('L') .long(options::LOGICAL) - .help("dereference TARGETs that are symbolic links") + .help("follow TARGETs that are symbolic links") .overrides_with(options::PHYSICAL) .action(ArgAction::SetTrue), ) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 9be9b19d45..52ac489ef2 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -1422,7 +1422,7 @@ pub fn uu_app() -> Command { Arg::new(options::dereference::DIR_ARGS) .long(options::dereference::DIR_ARGS) .help( - "Do not dereference symlinks except when they link to directories and are \ + "Do not follow symlinks except when they link to directories and are \ given as command line arguments.", ) .overrides_with_all([ @@ -1436,7 +1436,7 @@ pub fn uu_app() -> Command { Arg::new(options::dereference::ARGS) .short('H') .long(options::dereference::ARGS) - .help("Do not dereference symlinks except when given as command line arguments.") + .help("Do not follow symlinks except when given as command line arguments.") .overrides_with_all([ options::dereference::ALL, options::dereference::DIR_ARGS, diff --git a/src/uu/stat/stat.md b/src/uu/stat/stat.md index d91f2b01f0..ac63edd18d 100644 --- a/src/uu/stat/stat.md +++ b/src/uu/stat/stat.md @@ -25,7 +25,7 @@ Valid format sequences for files (without `--file-system`): - `%i`: inode number - `%m`: mount point - `%n`: file name -- `%N`: quoted file name with dereference if symbolic link +- `%N`: quoted file name with dereference (follow) if symbolic link - `%o`: optimal I/O transfer size hint - `%s`: total size, in bytes - `%t`: major device type in hex, for character/block device special files From 6a54d820ac9e6fed5e40cb257be82076d816672a Mon Sep 17 00:00:00 2001 From: Ideflop <94184575+Ideflop@users.noreply.github.com> Date: Fri, 14 Apr 2023 21:20:19 +0200 Subject: [PATCH 131/477] factor: add -h/--exponents option (#4710) * factor: add -h/--exponents option * Factor: Rebase, add -h/--exponents options --- src/uu/factor/factor.md | 2 +- src/uu/factor/src/cli.rs | 36 ++++++++++++++-- src/uu/factor/src/factor.rs | 9 +++- tests/benches/factor/Cargo.toml | 4 +- tests/benches/factor/benches/gcd.rs | 4 +- tests/benches/factor/benches/table.rs | 33 ++++++-------- tests/by-util/test_factor.rs | 62 +++++++++++++++++++++++++++ 7 files changed, 121 insertions(+), 29 deletions(-) diff --git a/src/uu/factor/factor.md b/src/uu/factor/factor.md index b5bec6039b..ccce4f2529 100644 --- a/src/uu/factor/factor.md +++ b/src/uu/factor/factor.md @@ -1,7 +1,7 @@ # factor ``` -factor [NUMBER]... +factor [OPTION]... [NUMBER]... ``` Print the prime factors of the given NUMBER(s). diff --git a/src/uu/factor/src/cli.rs b/src/uu/factor/src/cli.rs index 956b6aa9f0..9f3d55db9f 100644 --- a/src/uu/factor/src/cli.rs +++ b/src/uu/factor/src/cli.rs @@ -27,6 +27,8 @@ const ABOUT: &str = help_about!("factor.md"); const USAGE: &str = help_usage!("factor.md"); mod options { + pub static EXPONENTS: &str = "exponents"; + pub static HELP: &str = "help"; pub static NUMBER: &str = "NUMBER"; } @@ -34,6 +36,7 @@ fn print_factors_str( num_str: &str, w: &mut io::BufWriter, factors_buffer: &mut String, + print_exponents: bool, ) -> Result<(), Box> { num_str .trim() @@ -41,7 +44,13 @@ fn print_factors_str( .map_err(|e| e.into()) .and_then(|x| { factors_buffer.clear(); - writeln!(factors_buffer, "{}:{}", x, factor(x))?; + // If print_exponents is true, use the alternate format specifier {:#} from fmt to print the factors + // of x in the form of p^e. + if print_exponents { + writeln!(factors_buffer, "{}:{:#}", x, factor(x))?; + } else { + writeln!(factors_buffer, "{}:{}", x, factor(x))?; + } w.write_all(factors_buffer.as_bytes())?; Ok(()) }) @@ -50,6 +59,10 @@ fn print_factors_str( #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args)?; + + // If matches find --exponents flag than variable print_exponents is true and p^e output format will be used. + let print_exponents = matches.get_flag(options::EXPONENTS); + let stdout = stdout(); // We use a smaller buffer here to pass a gnu test. 4KiB appears to be the default pipe size for bash. let mut w = io::BufWriter::with_capacity(4 * 1024, stdout.lock()); @@ -57,7 +70,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if let Some(values) = matches.get_many::(options::NUMBER) { for number in values { - if let Err(e) = print_factors_str(number, &mut w, &mut factors_buffer) { + if let Err(e) = print_factors_str(number, &mut w, &mut factors_buffer, print_exponents) + { show_warning!("{}: {}", number.maybe_quote(), e); } } @@ -66,7 +80,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let lines = stdin.lock().lines(); for line in lines { for number in line.unwrap().split_whitespace() { - if let Err(e) = print_factors_str(number, &mut w, &mut factors_buffer) { + if let Err(e) = + print_factors_str(number, &mut w, &mut factors_buffer, print_exponents) + { show_warning!("{}: {}", number.maybe_quote(), e); } } @@ -86,5 +102,19 @@ pub fn uu_app() -> Command { .about(ABOUT) .override_usage(format_usage(USAGE)) .infer_long_args(true) + .disable_help_flag(true) .arg(Arg::new(options::NUMBER).action(ArgAction::Append)) + .arg( + Arg::new(options::EXPONENTS) + .short('h') + .long(options::EXPONENTS) + .help("Print factors in the form p^e") + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new(options::HELP) + .long(options::HELP) + .help("Print help information.") + .action(ArgAction::Help), + ) } diff --git a/src/uu/factor/src/factor.rs b/src/uu/factor/src/factor.rs index 5d16153423..a87f4219e7 100644 --- a/src/uu/factor/src/factor.rs +++ b/src/uu/factor/src/factor.rs @@ -97,9 +97,14 @@ impl fmt::Display for Factors { let v = &mut (self.0).borrow_mut().0; v.sort_unstable(); + let include_exponents = f.alternate(); for (p, exp) in v.iter() { - for _ in 0..*exp { - write!(f, " {p}")?; + if include_exponents && *exp > 1 { + write!(f, " {p}^{exp}")?; + } else { + for _ in 0..*exp { + write!(f, " {p}")?; + } } } diff --git a/tests/benches/factor/Cargo.toml b/tests/benches/factor/Cargo.toml index efada4b00e..26900e78a9 100644 --- a/tests/benches/factor/Cargo.toml +++ b/tests/benches/factor/Cargo.toml @@ -7,6 +7,8 @@ description = "Benchmarks for the uu_factor integer factorization tool" homepage = "https://github.com/uutils/coreutils" edition = "2021" +[workspace] + [dependencies] uu_factor = { path = "../../../src/uu/factor" } @@ -14,7 +16,7 @@ uu_factor = { path = "../../../src/uu/factor" } array-init = "2.0.0" criterion = "0.3" rand = "0.8" -rand_chacha = "0.2.2" +rand_chacha = "0.3.1" [[bench]] name = "gcd" diff --git a/tests/benches/factor/benches/gcd.rs b/tests/benches/factor/benches/gcd.rs index f2bae51c74..a9d2a8c55e 100644 --- a/tests/benches/factor/benches/gcd.rs +++ b/tests/benches/factor/benches/gcd.rs @@ -6,7 +6,7 @@ fn gcd(c: &mut Criterion) { // Deterministic RNG; use an explicitly-named RNG to guarantee stability use rand::{RngCore, SeedableRng}; use rand_chacha::ChaCha8Rng; - const SEED: u64 = 0xa_b4d_1dea_dead_cafe; + const SEED: u64 = 0xab4d_1dea_dead_cafe; let mut rng = ChaCha8Rng::seed_from_u64(SEED); std::iter::repeat_with(move || (rng.next_u64(), rng.next_u64())) @@ -22,7 +22,7 @@ fn gcd(c: &mut Criterion) { }, ); } - group.finish() + group.finish(); } criterion_group!(benches, gcd); diff --git a/tests/benches/factor/benches/table.rs b/tests/benches/factor/benches/table.rs index 7f749a10ff..59e8db1f3b 100644 --- a/tests/benches/factor/benches/table.rs +++ b/tests/benches/factor/benches/table.rs @@ -7,12 +7,7 @@ fn table(c: &mut Criterion) { check_personality(); const INPUT_SIZE: usize = 128; - assert!( - INPUT_SIZE % CHUNK_SIZE == 0, - "INPUT_SIZE ({}) is not divisible by CHUNK_SIZE ({})", - INPUT_SIZE, - CHUNK_SIZE - ); + let inputs = { // Deterministic RNG; use an explicitly-named RNG to guarantee stability use rand::{RngCore, SeedableRng}; @@ -29,42 +24,40 @@ fn table(c: &mut Criterion) { let a_str = format!("{:?}", a); group.bench_with_input(BenchmarkId::new("factor_chunk", &a_str), &a, |b, &a| { b.iter(|| { - let mut n_s = a.clone(); + let mut n_s = a; let mut f_s: [_; INPUT_SIZE] = array_init(|_| Factors::one()); for (n_s, f_s) in n_s.chunks_mut(CHUNK_SIZE).zip(f_s.chunks_mut(CHUNK_SIZE)) { - factor_chunk(n_s.try_into().unwrap(), f_s.try_into().unwrap()) + factor_chunk(n_s.try_into().unwrap(), f_s.try_into().unwrap()); } - }) + }); }); group.bench_with_input(BenchmarkId::new("factor", &a_str), &a, |b, &a| { b.iter(|| { - let mut n_s = a.clone(); + let mut n_s = a; let mut f_s: [_; INPUT_SIZE] = array_init(|_| Factors::one()); for (n, f) in n_s.iter_mut().zip(f_s.iter_mut()) { - factor(n, f) + factor(n, f); } - }) + }); }); } - group.finish() + group.finish(); } #[cfg(target_os = "linux")] fn check_personality() { use std::fs; const ADDR_NO_RANDOMIZE: u64 = 0x0040000; - const PERSONALITY_PATH: &'static str = "/proc/self/personality"; + const PERSONALITY_PATH: &str = "/proc/self/personality"; let p_string = fs::read_to_string(PERSONALITY_PATH) - .expect(&format!("Couldn't read '{}'", PERSONALITY_PATH)) - .strip_suffix("\n") + .unwrap_or_else(|_| panic!("Couldn't read '{}'", PERSONALITY_PATH)) + .strip_suffix('\n') .unwrap() .to_owned(); - let personality = u64::from_str_radix(&p_string, 16).expect(&format!( - "Expected a hex value for personality, got '{:?}'", - p_string - )); + let personality = u64::from_str_radix(&p_string, 16) + .unwrap_or_else(|_| panic!("Expected a hex value for personality, got '{:?}'", p_string)); if personality & ADDR_NO_RANDOMIZE == 0 { eprintln!( "WARNING: Benchmarking with ASLR enabled (personality is {:x}), results might not be reproducible.", diff --git a/tests/by-util/test_factor.rs b/tests/by-util/test_factor.rs index 25ac718ae5..59940e2e3a 100644 --- a/tests/by-util/test_factor.rs +++ b/tests/by-util/test_factor.rs @@ -27,6 +27,12 @@ fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails().code_is(1); } +#[test] +fn test_valid_arg_exponents() { + new_ucmd!().arg("-h").succeeds().code_is(0); + new_ucmd!().arg("--exponents").succeeds().code_is(0); +} + #[test] #[cfg(feature = "sort")] fn test_parallel() { @@ -100,6 +106,33 @@ fn test_first_1000_integers() { ); } +#[test] +fn test_first_1000_integers_with_exponents() { + use hex_literal::hex; + use sha1::{Digest, Sha1}; + + let n_integers = 1000; + let mut input_string = String::new(); + for i in 0..=n_integers { + input_string.push_str(&(format!("{i} "))[..]); + } + + println!("STDIN='{input_string}'"); + let result = new_ucmd!() + .arg("-h") + .pipe_in(input_string.as_bytes()) + .succeeds(); + + // Using factor from GNU Coreutils 9.2 + // `seq 0 1000 | factor -h | sha1sum` => "45f5f758a9319870770bd1fec2de23d54331944d" + let mut hasher = Sha1::new(); + hasher.update(result.stdout()); + let hash_check = hasher.finalize(); + assert_eq!( + hash_check[..], + hex!("45f5f758a9319870770bd1fec2de23d54331944d") + ); +} #[test] fn test_cli_args() { // Make sure that factor works with CLI arguments as well. @@ -279,6 +312,35 @@ fn run(input_string: &[u8], output_string: &[u8]) { .stdout_is(String::from_utf8(output_string.to_owned()).unwrap()); } +#[test] +fn test_primes_with_exponents() { + let mut input_string = String::new(); + let mut output_string = String::new(); + for primes in PRIMES_BY_BITS.iter() { + for &prime in *primes { + input_string.push_str(&(format!("{prime} "))[..]); + output_string.push_str(&(format!("{prime}: {prime}\n"))[..]); + } + } + + println!( + "STDIN='{}'", + String::from_utf8_lossy(input_string.as_bytes()) + ); + println!( + "STDOUT(expected)='{}'", + String::from_utf8_lossy(output_string.as_bytes()) + ); + + // run factor with --exponents + new_ucmd!() + .timeout(Duration::from_secs(240)) + .arg("--exponents") + .pipe_in(input_string) + .run() + .stdout_is(String::from_utf8(output_string.as_bytes().to_owned()).unwrap()); +} + const PRIMES_BY_BITS: &[&[u64]] = &[ PRIMES14, PRIMES15, PRIMES16, PRIMES17, PRIMES18, PRIMES19, PRIMES20, PRIMES21, PRIMES22, PRIMES23, PRIMES24, PRIMES25, PRIMES26, PRIMES27, PRIMES28, PRIMES29, PRIMES30, PRIMES31, From 084510e499ce8a8d9e7da96731e33f671070baab Mon Sep 17 00:00:00 2001 From: publicmatt <52261150+publicmatt@users.noreply.github.com> Date: Fri, 14 Apr 2023 12:31:11 -0700 Subject: [PATCH 132/477] Copy the UTF8 crate in the tree and remove utf8 dependency. (#4460) --- Cargo.lock | 7 -- src/uu/wc/Cargo.toml | 1 - src/uu/wc/src/utf8/LICENSE | 26 +++++++ src/uu/wc/src/utf8/mod.rs | 93 +++++++++++++++++++++++++ src/uu/wc/src/utf8/read.rs | 137 +++++++++++++++++++++++++++++++++++++ src/uu/wc/src/wc.rs | 1 + 6 files changed, 257 insertions(+), 8 deletions(-) create mode 100644 src/uu/wc/src/utf8/LICENSE create mode 100644 src/uu/wc/src/utf8/mod.rs create mode 100644 src/uu/wc/src/utf8/read.rs diff --git a/Cargo.lock b/Cargo.lock index 1123224777..33e33d31a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2350,12 +2350,6 @@ dependencies = [ "log", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "utf8parse" version = "0.2.1" @@ -3330,7 +3324,6 @@ dependencies = [ "libc", "nix", "unicode-width", - "utf-8", "uucore", ] diff --git a/src/uu/wc/Cargo.toml b/src/uu/wc/Cargo.toml index ca0eec9bc9..1b1bd41d31 100644 --- a/src/uu/wc/Cargo.toml +++ b/src/uu/wc/Cargo.toml @@ -18,7 +18,6 @@ path = "src/wc.rs" clap = { workspace=true } uucore = { workspace=true, features=["pipes"] } bytecount = { workspace=true } -utf-8 = { workspace=true } unicode-width = { workspace=true } [target.'cfg(unix)'.dependencies] diff --git a/src/uu/wc/src/utf8/LICENSE b/src/uu/wc/src/utf8/LICENSE new file mode 100644 index 0000000000..6f3c83e687 --- /dev/null +++ b/src/uu/wc/src/utf8/LICENSE @@ -0,0 +1,26 @@ +// spell-checker:ignore Sapin +Copyright (c) Simon Sapin and many others + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/uu/wc/src/utf8/mod.rs b/src/uu/wc/src/utf8/mod.rs new file mode 100644 index 0000000000..31638e7589 --- /dev/null +++ b/src/uu/wc/src/utf8/mod.rs @@ -0,0 +1,93 @@ +// spell-checker:ignore Sapin +mod read; + +pub use read::{BufReadDecoder, BufReadDecoderError}; + +use std::cmp; +use std::str; + +/// +/// Incremental, zero-copy UTF-8 decoding with error handling +/// +/// The original implementation was written by Simon Sapin in the utf-8 crate . +/// uu_wc used to depend on that crate. +/// The author archived the repository . +/// They suggested incorporating the source directly into uu_wc . +/// + +#[derive(Debug, Copy, Clone)] +pub struct Incomplete { + pub buffer: [u8; 4], + pub buffer_len: u8, +} + +impl Incomplete { + pub fn empty() -> Self { + Self { + buffer: [0, 0, 0, 0], + buffer_len: 0, + } + } + + pub fn is_empty(&self) -> bool { + self.buffer_len == 0 + } + + pub fn new(bytes: &[u8]) -> Self { + let mut buffer = [0, 0, 0, 0]; + let len = bytes.len(); + buffer[..len].copy_from_slice(bytes); + Self { + buffer, + buffer_len: len as u8, + } + } + + fn take_buffer(&mut self) -> &[u8] { + let len = self.buffer_len as usize; + self.buffer_len = 0; + &self.buffer[..len] + } + + /// (consumed_from_input, None): not enough input + /// (consumed_from_input, Some(Err(()))): error bytes in buffer + /// (consumed_from_input, Some(Ok(()))): UTF-8 string in buffer + fn try_complete_offsets(&mut self, input: &[u8]) -> (usize, Option>) { + let initial_buffer_len = self.buffer_len as usize; + let copied_from_input; + { + let unwritten = &mut self.buffer[initial_buffer_len..]; + copied_from_input = cmp::min(unwritten.len(), input.len()); + unwritten[..copied_from_input].copy_from_slice(&input[..copied_from_input]); + } + let spliced = &self.buffer[..initial_buffer_len + copied_from_input]; + match str::from_utf8(spliced) { + Ok(_) => { + self.buffer_len = spliced.len() as u8; + (copied_from_input, Some(Ok(()))) + } + Err(error) => { + let valid_up_to = error.valid_up_to(); + if valid_up_to > 0 { + let consumed = valid_up_to.checked_sub(initial_buffer_len).unwrap(); + self.buffer_len = valid_up_to as u8; + (consumed, Some(Ok(()))) + } else { + match error.error_len() { + Some(invalid_sequence_length) => { + let consumed = invalid_sequence_length + .checked_sub(initial_buffer_len) + .unwrap(); + self.buffer_len = invalid_sequence_length as u8; + (consumed, Some(Err(()))) + } + None => { + self.buffer_len = spliced.len() as u8; + (copied_from_input, None) + } + } + } + } + } + } +} diff --git a/src/uu/wc/src/utf8/read.rs b/src/uu/wc/src/utf8/read.rs new file mode 100644 index 0000000000..79b8ad8aeb --- /dev/null +++ b/src/uu/wc/src/utf8/read.rs @@ -0,0 +1,137 @@ +// spell-checker:ignore bytestream +use super::*; +use std::error::Error; +use std::fmt; +use std::io::{self, BufRead}; +use std::str; + +/// Wraps a `std::io::BufRead` buffered byte stream and decode it as UTF-8. +pub struct BufReadDecoder { + buf_read: B, + bytes_consumed: usize, + incomplete: Incomplete, +} + +#[derive(Debug)] +pub enum BufReadDecoderError<'a> { + /// Represents one UTF-8 error in the byte stream. + /// + /// In lossy decoding, each such error should be replaced with U+FFFD. + /// (See `BufReadDecoder::next_lossy` and `BufReadDecoderError::lossy`.) + InvalidByteSequence(&'a [u8]), + + /// An I/O error from the underlying byte stream + Io(io::Error), +} + +impl<'a> fmt::Display for BufReadDecoderError<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + BufReadDecoderError::InvalidByteSequence(bytes) => { + write!(f, "invalid byte sequence: {:02x?}", bytes) + } + BufReadDecoderError::Io(ref err) => write!(f, "underlying bytestream error: {}", err), + } + } +} + +impl<'a> Error for BufReadDecoderError<'a> { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match *self { + BufReadDecoderError::InvalidByteSequence(_) => None, + BufReadDecoderError::Io(ref err) => Some(err), + } + } +} + +impl BufReadDecoder { + pub fn new(buf_read: B) -> Self { + Self { + buf_read, + bytes_consumed: 0, + incomplete: Incomplete::empty(), + } + } + + /// Decode and consume the next chunk of UTF-8 input. + /// + /// This method is intended to be called repeatedly until it returns `None`, + /// which represents EOF from the underlying byte stream. + /// This is similar to `Iterator::next`, + /// except that decoded chunks borrow the decoder (~iterator) + /// so they need to be handled or copied before the next chunk can start decoding. + pub fn next_strict(&mut self) -> Option> { + enum BytesSource { + BufRead(usize), + Incomplete, + } + macro_rules! try_io { + ($io_result: expr) => { + match $io_result { + Ok(value) => value, + Err(error) => return Some(Err(BufReadDecoderError::Io(error))), + } + }; + } + let (source, result) = loop { + if self.bytes_consumed > 0 { + self.buf_read.consume(self.bytes_consumed); + self.bytes_consumed = 0; + } + let buf = try_io!(self.buf_read.fill_buf()); + + // Force loop iteration to go through an explicit `continue` + enum Unreachable {} + let _: Unreachable = if self.incomplete.is_empty() { + if buf.is_empty() { + return None; // EOF + } + match str::from_utf8(buf) { + Ok(_) => break (BytesSource::BufRead(buf.len()), Ok(())), + Err(error) => { + let valid_up_to = error.valid_up_to(); + if valid_up_to > 0 { + break (BytesSource::BufRead(valid_up_to), Ok(())); + } + match error.error_len() { + Some(invalid_sequence_length) => { + break (BytesSource::BufRead(invalid_sequence_length), Err(())) + } + None => { + self.bytes_consumed = buf.len(); + self.incomplete = Incomplete::new(buf); + // need more input bytes + continue; + } + } + } + } + } else { + if buf.is_empty() { + break (BytesSource::Incomplete, Err(())); // EOF with incomplete code point + } + let (consumed, opt_result) = self.incomplete.try_complete_offsets(buf); + self.bytes_consumed = consumed; + match opt_result { + None => { + // need more input bytes + continue; + } + Some(result) => break (BytesSource::Incomplete, result), + } + }; + }; + let bytes = match source { + BytesSource::BufRead(byte_count) => { + self.bytes_consumed = byte_count; + let buf = try_io!(self.buf_read.fill_buf()); + &buf[..byte_count] + } + BytesSource::Incomplete => self.incomplete.take_buffer(), + }; + match result { + Ok(()) => Some(Ok(unsafe { str::from_utf8_unchecked(bytes) })), + Err(()) => Some(Err(BufReadDecoderError::InvalidByteSequence(bytes))), + } + } +} diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 984722dd1f..949f05d653 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -9,6 +9,7 @@ mod count_fast; mod countable; +mod utf8; mod word_count; use clap::builder::ValueParser; use count_fast::{count_bytes_chars_and_lines_fast, count_bytes_fast}; From 699c1d5aa1348acb1c703bfd44e2b019e4689b99 Mon Sep 17 00:00:00 2001 From: Miles Liu Date: Fri, 31 Mar 2023 13:46:29 +0800 Subject: [PATCH 133/477] CI: compute individual binary sizes --- .github/workflows/CICD.yml | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 54ada97605..add337f661 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -572,15 +572,32 @@ jobs: shell: bash run: | ## Compute uutil release sizes - SIZE=$(du -s target/size-release/usr/local/bin/|awk '{print $1}') - SIZE_MULTI=$(du -s target/size-multi-release/usr/local/bin/|awk '{print $1}') + DATE=$(date --rfc-email) + find target/size-release/usr/local/bin -type f -printf '%f\0' | sort -z | + while IFS= read -r -d '' name; do + size=$(du -s target/size-release/usr/local/bin/$name | awk '{print $1}') + echo "\"$name\"" + echo "$size" + done | \ + jq -n \ + --arg date "$DATE" \ + --arg sha "$GITHUB_SHA" \ + 'reduce inputs as $name ({}; . + { ($name): input }) | { ($date): {sha: $sha, sizes: map_values(.)} }' > individual-size-result.json + SIZE=$(cat individual-size-result.json | jq '[.[] | .sizes | .[]] | reduce .[] as $num (0; . + $num)') + SIZE_MULTI=$(du -s target/size-multi-release/usr/local/bin/coreutils | awk '{print $1}') jq -n \ - --arg date "$(date --rfc-email)" \ + --arg date "$DATE" \ --arg sha "$GITHUB_SHA" \ --arg size "$SIZE" \ --arg multisize "$SIZE_MULTI" \ '{($date): { sha: $sha, size: $size, multisize: $multisize, }}' > size-result.json - - uses: actions/upload-artifact@v3 + - name: Upload the individual size result + uses: actions/upload-artifact@v3 + with: + name: individual-size-result + path: individual-size-result.json + - name: Upload the size result + uses: actions/upload-artifact@v3 with: name: size-result path: size-result.json From 163a75c9e3b5bcbeacf266ea7fce51bbadce0b71 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 15 Apr 2023 11:55:40 +0200 Subject: [PATCH 134/477] ci: Fix usages of rust-cache to produce more cache hits --- .github/workflows/CICD.yml | 115 +++++++++++++++++---------------- .github/workflows/GnuTests.yml | 18 +++--- 2 files changed, 70 insertions(+), 63 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 54ada97605..62cfa08cb8 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -48,6 +48,11 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 + - name: Install `rust` toolchain + run: | + rustup toolchain install nightly --no-self-update --profile minimal + rustup default nightly + - uses: Swatinem/rust-cache@v2 - name: Initialize workflow variables id: vars shell: bash @@ -67,10 +72,6 @@ jobs: outputs CARGO_FEATURES_OPTION ## note: requires 'nightly' toolchain b/c `cargo-udeps` uses the `rustc` '-Z save-analysis' option ## * ... ref: - - name: Install `rust` toolchain - run: | - rustup toolchain install nightly --no-self-update --profile minimal - rustup default nightly - name: Install `cargo-udeps` run: cargo install cargo-udeps env: @@ -97,6 +98,12 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 + - name: Install `rust` toolchain + run: | + ## Install `rust` toolchain + rustup toolchain install stable --no-self-update -c rustfmt --profile minimal + rustup default stable + - uses: Swatinem/rust-cache@v2 - name: Initialize workflow variables id: vars shell: bash @@ -114,11 +121,6 @@ jobs: CARGO_FEATURES_OPTION='' ; if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi outputs CARGO_FEATURES_OPTION - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update -c rustfmt --profile minimal - rustup default stable - name: "`cargo fmt` testing" shell: bash run: | @@ -137,13 +139,13 @@ jobs: RUN_FOR: 60 steps: - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@v2 - name: Install `rust` toolchain run: | rustup toolchain install nightly --no-self-update --profile minimal rustup default nightly - name: Install `cargo-fuzz` run: cargo install cargo-fuzz + - uses: Swatinem/rust-cache@v2 - name: Run fuzz_date for XX seconds shell: bash run: | @@ -184,6 +186,11 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 + - name: Install `rust` toolchain + run: | + ## Install `rust` toolchain + rustup toolchain install stable --no-self-update -c clippy --profile minimal + rustup default stable - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -216,11 +223,6 @@ jobs: case '${{ matrix.job.os }}' in macos-latest) brew install coreutils ;; # needed for show-utils.sh esac - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update -c clippy --profile minimal - rustup default stable - name: "`cargo clippy` lint testing" shell: bash run: | @@ -295,6 +297,11 @@ jobs: # - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 + - name: Install `rust` toolchain + run: | + ## Install `rust` toolchain + rustup toolchain install stable --no-self-update -c clippy --profile minimal + rustup default stable - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -320,11 +327,6 @@ jobs: echo UTILITY_LIST=${UTILITY_LIST} CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo -n "-puu_${u} "; done;)" outputs CARGO_UTILITY_LIST_OPTIONS - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update -c clippy --profile minimal - rustup default stable - name: "`cargo doc` with warnings" shell: bash run: | @@ -349,6 +351,11 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 + - name: Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) + run: | + ## Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) + rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} --profile minimal + rustup default ${{ env.RUST_MIN_SRV }} - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -363,11 +370,6 @@ jobs: unset CARGO_FEATURES_OPTION if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi outputs CARGO_FEATURES_OPTION - - name: Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) - run: | - ## Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) - rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} --profile minimal - rustup default ${{ env.RUST_MIN_SRV }} - name: Confirm MinSRV compatible 'Cargo.lock' shell: bash run: | @@ -422,6 +424,7 @@ jobs: ## Install `rust` toolchain rustup toolchain install stable --no-self-update --profile minimal rustup default stable + - uses: Swatinem/rust-cache@v2 - name: "`cargo update` testing" shell: bash run: | @@ -443,14 +446,14 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@v2 - - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 - name: Install `rust` toolchain run: | ## Install `rust` toolchain rustup toolchain install stable --no-self-update --profile minimal rustup default stable + - uses: Swatinem/rust-cache@v2 + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.3 - name: "`make build`" shell: bash run: | @@ -489,14 +492,14 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@v2 - - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 - name: Install `rust` toolchain run: | ## Install `rust` toolchain rustup toolchain install stable --no-self-update --profile minimal rustup default stable + - uses: Swatinem/rust-cache@v2 + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.3 - name: Test run: cargo test ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: @@ -519,14 +522,14 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@v2 - - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 - name: Install `rust` toolchain run: | ## Install `rust` toolchain rustup toolchain install nightly --no-self-update --profile minimal rustup default nightly + - uses: Swatinem/rust-cache@v2 + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.3 - name: Test run: cargo test ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: @@ -546,6 +549,11 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 + - name: Install `rust` toolchain + run: | + ## Install `rust` toolchain + rustup toolchain install stable --no-self-update --profile minimal + rustup default stable - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -555,11 +563,6 @@ jobs: ## Install dependencies sudo apt-get update sudo apt-get install jq - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update --profile minimal - rustup default stable - name: "`make install`" shell: bash run: | @@ -615,7 +618,14 @@ jobs: - { os: windows-latest , target: x86_64-pc-windows-msvc , features: feat_os_windows } steps: - uses: actions/checkout@v3 + - name: rust toolchain ~ install + run: | + ## rust toolchain ~ install + rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} -t ${{ matrix.job.target }} --profile minimal + rustup default ${{ env.RUST_MIN_SRV }} - uses: Swatinem/rust-cache@v2 + with: + key: "${{ matrix.job.os }}_${{ matrix.job.target }}" - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - name: Initialize workflow variables @@ -740,11 +750,6 @@ jobs: echo "foo" > /home/runner/.plan ;; esac - - name: rust toolchain ~ install - run: | - ## rust toolchain ~ install - rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} -t ${{ matrix.job.target }} --profile minimal - rustup default ${{ env.RUST_MIN_SRV }} - name: Initialize toolchain-dependent workflow variables id: dep_vars shell: bash @@ -950,14 +955,14 @@ jobs: TEST_SUMMARY_FILE="toybox-result.json" outputs TEST_SUMMARY_FILE - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@v2 - - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 - name: rust toolchain ~ install run: | ## rust toolchain ~ install rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} --profile minimal rustup default ${{ env.RUST_MIN_SRV }} + - uses: Swatinem/rust-cache@v2 + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.3 - name: Build coreutils as multiple binaries shell: bash run: | @@ -1028,11 +1033,16 @@ jobs: fail-fast: false matrix: job: - - { os: ubuntu-latest , features: unix } - - { os: macos-latest , features: macos } - - { os: windows-latest , features: windows } + - { os: ubuntu-latest , features: unix, toolchain: nightly } + - { os: macos-latest , features: macos, toolchain: nightly } + - { os: windows-latest , features: windows, toolchain: nightly-x86_64-pc-windows-gnu } steps: - uses: actions/checkout@v3 + - name: rust toolchain ~ install + run: | + ## rust toolchain ~ install + rustup toolchain install ${{ matrix.job.toolchain }} --no-self-update --profile minimal + rustup default ${{ matrix.job.toolchain }} - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -1084,11 +1094,6 @@ jobs: echo "foo" > /home/runner/.plan ;; esac - - name: rust toolchain ~ install - run: | - ## rust toolchain ~ install - rustup toolchain install ${{ steps.vars.outputs.TOOLCHAIN }} --no-self-update --profile minimal - rustup default ${{ steps.vars.outputs.TOOLCHAIN }} - name: Initialize toolchain-dependent workflow variables id: dep_vars shell: bash diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index b723d0a024..790bcce3ff 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -1,8 +1,8 @@ name: GnuTests -# spell-checker:ignore (abbrev/names) CodeCov gnulib GnuTests +# spell-checker:ignore (abbrev/names) CodeCov gnulib GnuTests Swatinem # spell-checker:ignore (jargon) submodules -# spell-checker:ignore (libs/utils) autopoint chksum gperf lcov libexpect pyinotify shopt texinfo valgrind +# spell-checker:ignore (libs/utils) autopoint chksum gperf lcov libexpect pyinotify shopt texinfo valgrind libattr libcap # spell-checker:ignore (options) Ccodegen Coverflow Cpanic Zpanic # spell-checker:ignore (people) Dawid Dziurla * dawidd # spell-checker:ignore (vars) FILESET SUBDIRS XPASS @@ -58,6 +58,13 @@ jobs: uses: actions/checkout@v3 with: path: '${{ steps.vars.outputs.path_UUTILS }}' + - name: Install `rust` toolchain + run: | + ## Install `rust` toolchain + rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} + rustup toolchain install stable -c rustfmt --profile minimal + rustup default stable + - uses: Swatinem/rust-cache@v2 - name: Checkout code (GNU coreutils) uses: actions/checkout@v3 with: @@ -75,12 +82,6 @@ jobs: # workflow_conclusion: success ## (default); * but, if commit with failed GnuTests is merged into the default branch, future commits will all show regression errors in GnuTests CI until o/w fixed workflow_conclusion: completed ## continually recalibrates to last commit of default branch with a successful GnuTests (ie, "self-heals" from GnuTest regressions, but needs more supervision for/of regressions) path: "${{ steps.vars.outputs.path_reference }}" - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} - rustup toolchain install stable -c rustfmt --profile minimal - rustup default stable - name: Install dependencies shell: bash run: | @@ -322,6 +323,7 @@ jobs: rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} rustup toolchain install nightly -c rustfmt --profile minimal rustup default nightly + - uses: Swatinem/rust-cache@v2 - name: Install dependencies run: | ## Install dependencies From 658323184dda473434d3cbba779027f8e507031c Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 17 Mar 2023 08:55:08 +0100 Subject: [PATCH 135/477] uudoc,uucore_procs: move md parsing to help_parser --- Cargo.lock | 6 + Cargo.toml | 4 +- src/bin/uudoc.rs | 82 +++---------- src/help_parser/Cargo.toml | 5 + src/help_parser/src/lib.rs | 236 ++++++++++++++++++++++++++++++++++++ src/uucore_procs/Cargo.toml | 1 + src/uucore_procs/src/lib.rs | 229 ++-------------------------------- 7 files changed, 280 insertions(+), 283 deletions(-) create mode 100644 src/help_parser/Cargo.toml create mode 100644 src/help_parser/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 33e33d31a7..5002551fd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -388,6 +388,7 @@ dependencies = [ "conv", "filetime", "glob", + "help_parser", "hex-literal", "is-terminal", "libc", @@ -1102,6 +1103,10 @@ dependencies = [ "ahash", ] +[[package]] +name = "help_parser" +version = "0.0.18" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -3393,6 +3398,7 @@ dependencies = [ name = "uucore_procs" version = "0.0.18" dependencies = [ + "help_parser", "proc-macro2", "quote", ] diff --git a/Cargo.toml b/Cargo.toml index 24bea229ce..ff21ff97e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ windows = [ "feat_os_windows" ] nightly = [] test_unimplemented = [] # * only build `uudoc` when `--feature uudoc` is activated -uudoc = ["zip"] +uudoc = ["zip", "dep:help_parser"] ## features # "feat_acl" == enable support for ACLs (access control lists; by using`--features feat_acl`) # NOTE: @@ -357,6 +357,8 @@ selinux = { workspace=true, optional = true } textwrap = { workspace=true } zip = { workspace=true, optional = true } +help_parser = { path="src/help_parser", optional = true } + # * uutils uu_test = { optional=true, version="0.0.18", package="uu_test", path="src/uu/test" } # diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index 8276d2ae12..7d1a9cff55 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -133,7 +133,7 @@ impl<'a, 'b> MDWriter<'a, 'b> { write!(self.w, "# {}\n\n", self.name)?; self.additional()?; self.usage()?; - self.description()?; + self.about()?; self.options()?; self.after_help()?; self.examples() @@ -177,54 +177,34 @@ impl<'a, 'b> MDWriter<'a, 'b> { } fn usage(&mut self) -> io::Result<()> { - writeln!(self.w, "\n```")?; - let mut usage: String = self - .command - .render_usage() - .to_string() - .lines() - .map(|l| l.strip_prefix("Usage:").unwrap_or(l)) - .map(|l| l.trim()) - .filter(|l| !l.is_empty()) - .collect::>() - .join("\n"); - usage = usage - .to_string() - .replace(uucore::execution_phrase(), self.name); - writeln!(self.w, "{}", usage)?; - writeln!(self.w, "```") - } + if let Some(markdown) = &self.markdown { + let usage = help_parser::parse_usage(&markdown); + let usage = usage.replace("{}", self.name); - fn description(&mut self) -> io::Result<()> { - if let Some(after_help) = self.markdown_section("about") { - return writeln!(self.w, "\n\n{}", after_help); + writeln!(self.w, "\n```")?; + writeln!(self.w, "{}", usage)?; + writeln!(self.w, "```") + } else { + Ok(()) } + } - if let Some(about) = self - .command - .get_long_about() - .or_else(|| self.command.get_about()) - { - writeln!(self.w, "{}", about) + fn about(&mut self) -> io::Result<()> { + if let Some(markdown) = &self.markdown { + writeln!(self.w, "{}", help_parser::parse_about(&markdown)) } else { Ok(()) } } fn after_help(&mut self) -> io::Result<()> { - if let Some(after_help) = self.markdown_section("after help") { - return writeln!(self.w, "\n\n{}", after_help); + if let Some(markdown) = &self.markdown { + if let Some(after_help) = help_parser::parse_section("after help", &markdown) { + return writeln!(self.w, "\n\n{after_help}"); + } } - if let Some(after_help) = self - .command - .get_after_long_help() - .or_else(|| self.command.get_after_help()) - { - writeln!(self.w, "\n\n{}", after_help) - } else { - Ok(()) - } + Ok(()) } fn examples(&mut self) -> io::Result<()> { @@ -327,32 +307,6 @@ impl<'a, 'b> MDWriter<'a, 'b> { } writeln!(self.w, "\n") } - - fn markdown_section(&self, section: &str) -> Option { - let md = self.markdown.as_ref()?; - let section = section.to_lowercase(); - - fn is_section_header(line: &str, section: &str) -> bool { - line.strip_prefix("##") - .map_or(false, |l| l.trim().to_lowercase() == section) - } - - let result = md - .lines() - .skip_while(|&l| !is_section_header(l, §ion)) - .skip(1) - .take_while(|l| !l.starts_with("##")) - .collect::>() - .join("\n") - .trim() - .to_string(); - - if !result.is_empty() { - Some(result) - } else { - None - } - } } fn get_zip_content(archive: &mut ZipArchive, name: &str) -> Option { diff --git a/src/help_parser/Cargo.toml b/src/help_parser/Cargo.toml new file mode 100644 index 0000000000..d3a8a0f543 --- /dev/null +++ b/src/help_parser/Cargo.toml @@ -0,0 +1,5 @@ +[package] +name = "help_parser" +version = "0.0.18" +edition = "2021" +license = "MIT" diff --git a/src/help_parser/src/lib.rs b/src/help_parser/src/lib.rs new file mode 100644 index 0000000000..8faa4e6ce4 --- /dev/null +++ b/src/help_parser/src/lib.rs @@ -0,0 +1,236 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +//! A collection of functions to parse the markdown code of help files. +//! +//! The structure of the markdown code is assumed to be: +//! +//! # util name +//! +//! ```text +//! usage info +//! ``` +//! +//! About text +//! +//! ## Section 1 +//! +//! Some content +//! +//! ## Section 2 +//! +//! Some content + +const MARKDOWN_CODE_FENCES: &str = "```"; + +/// Parses the text between the first markdown code block and the next header, if any, +/// into an about string. +pub fn parse_about(content: &str) -> String { + content + .lines() + .skip_while(|l| !l.starts_with(MARKDOWN_CODE_FENCES)) + .skip(1) + .skip_while(|l| !l.starts_with(MARKDOWN_CODE_FENCES)) + .skip(1) + .take_while(|l| !l.starts_with('#')) + .collect::>() + .join("\n") + .trim() + .to_string() +} + +/// Parses the first markdown code block into a usage string +/// +/// The code fences are removed and the name of the util is replaced +/// with `{}` so that it can be replaced with the appropriate name +/// at runtime. +pub fn parse_usage(content: &str) -> String { + content + .lines() + .skip_while(|l| !l.starts_with(MARKDOWN_CODE_FENCES)) + .skip(1) + .take_while(|l| !l.starts_with(MARKDOWN_CODE_FENCES)) + .map(|l| { + // Replace the util name (assumed to be the first word) with "{}" + // to be replaced with the runtime value later. + if let Some((_util, args)) = l.split_once(' ') { + format!("{{}} {args}\n") + } else { + "{}\n".to_string() + } + }) + .collect::>() + .join("") + .trim() + .to_string() +} + +/// Get a single section from content +/// +/// The section must be a second level section (i.e. start with `##`). +pub fn parse_section(section: &str, content: &str) -> Option { + fn is_section_header(line: &str, section: &str) -> bool { + line.strip_prefix("##") + .map_or(false, |l| l.trim().to_lowercase() == section) + } + + let section = §ion.to_lowercase(); + + // We cannot distinguish between an empty or non-existing section below, + // so we do a quick test to check whether the section exists + if content.lines().all(|l| !is_section_header(l, section)) { + return None; + } + + // Prefix includes space to allow processing of section with level 3-6 headers + let section_header_prefix = "## "; + + Some( + content + .lines() + .skip_while(|&l| !is_section_header(l, section)) + .skip(1) + .take_while(|l| !l.starts_with(section_header_prefix)) + .collect::>() + .join("\n") + .trim() + .to_string(), + ) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_section() { + let input = "\ + # ls\n\ + ## some section\n\ + This is some section\n\ + \n\ + ## ANOTHER SECTION + This is the other section\n\ + with multiple lines\n"; + + assert_eq!( + parse_section("some section", input).unwrap(), + "This is some section" + ); + assert_eq!( + parse_section("SOME SECTION", input).unwrap(), + "This is some section" + ); + assert_eq!( + parse_section("another section", input).unwrap(), + "This is the other section\nwith multiple lines" + ); + } + + #[test] + fn test_parse_section_with_sub_headers() { + let input = "\ + # ls\n\ + ## after section\n\ + This is some section\n\ + \n\ + ### level 3 header\n\ + \n\ + Additional text under the section.\n\ + \n\ + #### level 4 header\n\ + \n\ + Yet another paragraph\n"; + + assert_eq!( + parse_section("after section", input).unwrap(), + "This is some section\n\n\ + ### level 3 header\n\n\ + Additional text under the section.\n\n\ + #### level 4 header\n\n\ + Yet another paragraph" + ); + } + + #[test] + fn test_parse_non_existing_section() { + let input = "\ + # ls\n\ + ## some section\n\ + This is some section\n\ + \n\ + ## ANOTHER SECTION + This is the other section\n\ + with multiple lines\n"; + + assert!(parse_section("non-existing section", input).is_none()); + } + + #[test] + fn test_parse_usage() { + let input = "\ + # ls\n\ + ```\n\ + ls -l\n\ + ```\n\ + ## some section\n\ + This is some section\n\ + \n\ + ## ANOTHER SECTION + This is the other section\n\ + with multiple lines\n"; + + assert_eq!(parse_usage(input), "{} -l"); + } + + #[test] + fn test_parse_multi_line_usage() { + let input = "\ + # ls\n\ + ```\n\ + ls -a\n\ + ls -b\n\ + ls -c\n\ + ```\n\ + ## some section\n\ + This is some section\n"; + + assert_eq!(parse_usage(input), "{} -a\n{} -b\n{} -c"); + } + + #[test] + fn test_parse_about() { + let input = "\ + # ls\n\ + ```\n\ + ls -l\n\ + ```\n\ + \n\ + This is the about section\n\ + \n\ + ## some section\n\ + This is some section\n"; + + assert_eq!(parse_about(input), "This is the about section"); + } + + #[test] + fn test_parse_multi_line_about() { + let input = "\ + # ls\n\ + ```\n\ + ls -l\n\ + ```\n\ + \n\ + about a\n\ + \n\ + about b\n\ + \n\ + ## some section\n\ + This is some section\n"; + + assert_eq!(parse_about(input), "about a\n\nabout b"); + } +} diff --git a/src/uucore_procs/Cargo.toml b/src/uucore_procs/Cargo.toml index 6a44eacd42..bb41a82a67 100644 --- a/src/uucore_procs/Cargo.toml +++ b/src/uucore_procs/Cargo.toml @@ -18,3 +18,4 @@ proc-macro = true [dependencies] proc-macro2 = "1.0" quote = "1.0" +help_parser = { path="../help_parser", version="0.0.18" } diff --git a/src/uucore_procs/src/lib.rs b/src/uucore_procs/src/lib.rs index 124978f936..4bc2521b87 100644 --- a/src/uucore_procs/src/lib.rs +++ b/src/uucore_procs/src/lib.rs @@ -6,8 +6,6 @@ use std::{fs::File, io::Read, path::PathBuf}; use proc_macro::{Literal, TokenStream, TokenTree}; use quote::quote; -const MARKDOWN_CODE_FENCES: &str = "```"; - //## rust proc-macro background info //* ref: @@ //* ref: [path construction from LitStr](https://oschwald.github.io/maxminddb-rust/syn/struct.LitStr.html) @@ @@ -60,7 +58,7 @@ fn render_markdown(s: &str) -> String { pub fn help_about(input: TokenStream) -> TokenStream { let input: Vec = input.into_iter().collect(); let filename = get_argument(&input, 0, "filename"); - let text: String = parse_about(&read_help(&filename)); + let text: String = help_parser::parse_about(&read_help(&filename)); TokenTree::Literal(Literal::string(&text)).into() } @@ -74,7 +72,7 @@ pub fn help_about(input: TokenStream) -> TokenStream { pub fn help_usage(input: TokenStream) -> TokenStream { let input: Vec = input.into_iter().collect(); let filename = get_argument(&input, 0, "filename"); - let text: String = parse_usage(&read_help(&filename)); + let text: String = help_parser::parse_usage(&read_help(&filename)); TokenTree::Literal(Literal::string(&text)).into() } @@ -107,9 +105,15 @@ pub fn help_section(input: TokenStream) -> TokenStream { let input: Vec = input.into_iter().collect(); let section = get_argument(&input, 0, "section"); let filename = get_argument(&input, 1, "filename"); - let text = parse_help_section(§ion, &read_help(&filename)); - let rendered = render_markdown(&text); - TokenTree::Literal(Literal::string(&rendered)).into() + + if let Some(text) = help_parser::parse_section(§ion, &read_help(&filename)) { + let rendered = render_markdown(&text); + TokenTree::Literal(Literal::string(&rendered)).into() + } else { + panic!( + "The section '{section}' could not be found in the help file. Maybe it is spelled wrong?" + ) + } } /// Get an argument from the input vector of `TokenTree`. @@ -148,214 +152,3 @@ fn read_help(filename: &str) -> String { content } - -/// Get a single section from content -/// -/// The section must be a second level section (i.e. start with `##`). -fn parse_help_section(section: &str, content: &str) -> String { - fn is_section_header(line: &str, section: &str) -> bool { - line.strip_prefix("##") - .map_or(false, |l| l.trim().to_lowercase() == section) - } - - let section = §ion.to_lowercase(); - - // We cannot distinguish between an empty or non-existing section below, - // so we do a quick test to check whether the section exists to provide - // a nice error message. - if content.lines().all(|l| !is_section_header(l, section)) { - panic!( - "The section '{section}' could not be found in the help file. Maybe it is spelled wrong?" - ) - } - - // Prefix includes space to allow processing of section with level 3-6 headers - let section_header_prefix = "## "; - - content - .lines() - .skip_while(|&l| !is_section_header(l, section)) - .skip(1) - .take_while(|l| !l.starts_with(section_header_prefix)) - .collect::>() - .join("\n") - .trim() - .to_string() -} - -/// Parses the first markdown code block into a usage string -/// -/// The code fences are removed and the name of the util is replaced -/// with `{}` so that it can be replaced with the appropriate name -/// at runtime. -fn parse_usage(content: &str) -> String { - content - .lines() - .skip_while(|l| !l.starts_with(MARKDOWN_CODE_FENCES)) - .skip(1) - .take_while(|l| !l.starts_with(MARKDOWN_CODE_FENCES)) - .map(|l| { - // Replace the util name (assumed to be the first word) with "{}" - // to be replaced with the runtime value later. - if let Some((_util, args)) = l.split_once(' ') { - format!("{{}} {args}\n") - } else { - "{}\n".to_string() - } - }) - .collect::>() - .join("") - .trim() - .to_string() -} - -/// Parses the text between the first markdown code block and the next header, if any, -/// into an about string. -fn parse_about(content: &str) -> String { - content - .lines() - .skip_while(|l| !l.starts_with(MARKDOWN_CODE_FENCES)) - .skip(1) - .skip_while(|l| !l.starts_with(MARKDOWN_CODE_FENCES)) - .skip(1) - .take_while(|l| !l.starts_with('#')) - .collect::>() - .join("\n") - .trim() - .to_string() -} - -#[cfg(test)] -mod tests { - use super::{parse_about, parse_help_section, parse_usage}; - - #[test] - fn section_parsing() { - let input = "\ - # ls\n\ - ## some section\n\ - This is some section\n\ - \n\ - ## ANOTHER SECTION - This is the other section\n\ - with multiple lines\n"; - - assert_eq!( - parse_help_section("some section", input), - "This is some section" - ); - assert_eq!( - parse_help_section("SOME SECTION", input), - "This is some section" - ); - assert_eq!( - parse_help_section("another section", input), - "This is the other section\nwith multiple lines" - ); - } - - #[test] - fn section_parsing_with_additional_headers() { - let input = "\ - # ls\n\ - ## after section\n\ - This is some section\n\ - \n\ - ### level 3 header\n\ - \n\ - Additional text under the section.\n\ - \n\ - #### level 4 header\n\ - \n\ - Yet another paragraph\n"; - - assert_eq!( - parse_help_section("after section", input), - "This is some section\n\n\ - ### level 3 header\n\n\ - Additional text under the section.\n\n\ - #### level 4 header\n\n\ - Yet another paragraph" - ); - } - - #[test] - #[should_panic] - fn section_parsing_panic() { - let input = "\ - # ls\n\ - ## some section\n\ - This is some section\n\ - \n\ - ## ANOTHER SECTION - This is the other section\n\ - with multiple lines\n"; - parse_help_section("non-existent section", input); - } - - #[test] - fn usage_parsing() { - let input = "\ - # ls\n\ - ```\n\ - ls -l\n\ - ```\n\ - ## some section\n\ - This is some section\n\ - \n\ - ## ANOTHER SECTION - This is the other section\n\ - with multiple lines\n"; - - assert_eq!(parse_usage(input), "{} -l"); - } - - #[test] - fn multi_line_usage_parsing() { - let input = "\ - # ls\n\ - ```\n\ - ls -a\n\ - ls -b\n\ - ls -c\n\ - ```\n\ - ## some section\n\ - This is some section\n"; - - assert_eq!(parse_usage(input), "{} -a\n{} -b\n{} -c"); - } - - #[test] - fn about_parsing() { - let input = "\ - # ls\n\ - ```\n\ - ls -l\n\ - ```\n\ - \n\ - This is the about section\n\ - \n\ - ## some section\n\ - This is some section\n"; - - assert_eq!(parse_about(input), "This is the about section"); - } - - #[test] - fn multi_line_about_parsing() { - let input = "\ - # ls\n\ - ```\n\ - ls -l\n\ - ```\n\ - \n\ - about a\n\ - \n\ - about b\n\ - \n\ - ## some section\n\ - This is some section\n"; - - assert_eq!(parse_about(input), "about a\n\nabout b"); - } -} From 1e43cb1c1ec634173ca9ad6fb195939096ed19f8 Mon Sep 17 00:00:00 2001 From: Miles Liu Date: Mon, 17 Apr 2023 14:24:57 +0800 Subject: [PATCH 136/477] CI: warn if the size of the binary increases by more than 5% --- .github/workflows/CICD.yml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index add337f661..e13f1774a2 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -591,6 +591,44 @@ jobs: --arg size "$SIZE" \ --arg multisize "$SIZE_MULTI" \ '{($date): { sha: $sha, size: $size, multisize: $multisize, }}' > size-result.json + - name: Download the previous individual size result + uses: dawidd6/action-download-artifact@v2 + with: + workflow: CICD.yml + name: individual-size-result + repo: uutils/coreutils + path: dl + - name: Download the previous size result + uses: dawidd6/action-download-artifact@v2 + with: + workflow: CICD.yml + name: size-result + repo: uutils/coreutils + path: dl + - name: Check uutil release sizes + shell: bash + run: | + check() { + # Warn if the size increases by more than 5% + threshold='1.05' + ratio=$(jq -n "$2 / $3") + echo "$1: size=$2, previous_size=$3, ratio=$ratio, threshold=$threshold" + if [[ "$(jq -n "$ratio > $threshold")" == 'true' ]]; then + echo "::warning file=$4::Size of $1 increases by more than 5%" + fi + } + ## Check individual size result + while read -r name previous_size; do + size=$(cat individual-size-result.json | jq -r ".[] | .sizes | .\"$name\"") + check "\`$name\` binary" "$size" "$previous_size" 'individual-size-result.json' + done < <(cat dl/individual-size-result.json | jq -r '.[] | .sizes | to_entries[] | "\(.key) \(.value)"') + ## Check size result + size=$(cat size-result.json | jq -r '.[] | .size') + previous_size=$(cat dl/size-result.json | jq -r '.[] | .size') + check 'multiple binaries' "$size" "$previous_size" 'size-result.json' + multisize=$(cat size-result.json | jq -r '.[] | .multisize') + previous_multisize=$(cat dl/size-result.json | jq -r '.[] | .multisize') + check 'multicall binary' "$multisize" "$previous_multisize" 'size-result.json' - name: Upload the individual size result uses: actions/upload-artifact@v3 with: From 59c0f51208da8442ecec2a8a21a9f7f13c0b0916 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 14 Apr 2023 22:58:22 +0200 Subject: [PATCH 137/477] hashsum: split/doc detect_algo into smaller functions --- src/uu/hashsum/src/hashsum.rs | 365 +++++++++++++++++++--------------- 1 file changed, 207 insertions(+), 158 deletions(-) diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index 5678a58b35..44e0cbcd80 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -50,71 +50,140 @@ struct Options { zero: bool, } -#[allow(clippy::cognitive_complexity)] +/// Creates a Blake2b hasher instance based on the specified length argument. +/// +/// # Returns +/// +/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. +/// +/// # Panics +/// +/// Panics if the length is not a multiple of 8 or if it is greater than 512. +fn create_blake2b(matches: &ArgMatches) -> (&'static str, Box, usize) { + match matches.get_one::("length") { + Some(0) | None => ("BLAKE2", Box::new(Blake2b::new()) as Box, 512), + Some(length_in_bits) => { + if *length_in_bits > 512 { + crash!(1, "Invalid length (maximum digest length is 512 bits)") + } + + if length_in_bits % 8 == 0 { + let length_in_bytes = length_in_bits / 8; + ( + "BLAKE2", + Box::new(Blake2b::with_output_bytes(length_in_bytes)), + *length_in_bits, + ) + } else { + crash!(1, "Invalid length (expected a multiple of 8)") + } + } + } +} + +/// Creates a SHA3 hasher instance based on the specified bits argument. +/// +/// # Returns +/// +/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. +/// +/// # Panics +/// +/// Panics if an unsupported output size is provided, or if the `--bits` flag is missing. +fn create_sha3(matches: &ArgMatches) -> (&'static str, Box, usize) { + match matches.get_one::("bits") { + Some(224) => ( + "SHA3-224", + Box::new(Sha3_224::new()) as Box, + 224, + ), + Some(256) => ( + "SHA3-256", + Box::new(Sha3_256::new()) as Box, + 256, + ), + Some(384) => ( + "SHA3-384", + Box::new(Sha3_384::new()) as Box, + 384, + ), + Some(512) => ( + "SHA3-512", + Box::new(Sha3_512::new()) as Box, + 512, + ), + Some(_) => crash!( + 1, + "Invalid output size for SHA3 (expected 224, 256, 384, or 512)" + ), + None => crash!(1, "--bits required for SHA3"), + } +} + +/// Creates a SHAKE-128 hasher instance based on the specified bits argument. +/// +/// # Returns +/// +/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. +/// +/// # Panics +/// +/// Panics if the `--bits` flag is missing. +fn create_shake128(matches: &ArgMatches) -> (&'static str, Box, usize) { + match matches.get_one::("bits") { + Some(bits) => ( + "SHAKE128", + Box::new(Shake128::new()) as Box, + *bits, + ), + None => crash!(1, "--bits required for SHAKE-128"), + } +} + +/// Creates a SHAKE-256 hasher instance based on the specified bits argument. +/// +/// # Returns +/// +/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. +/// +/// # Panics +/// +/// Panics if the `--bits` flag is missing. +fn create_shake256(matches: &ArgMatches) -> (&'static str, Box, usize) { + match matches.get_one::("bits") { + Some(bits) => ( + "SHAKE256", + Box::new(Shake256::new()) as Box, + *bits, + ), + None => crash!(1, "--bits required for SHAKE-256"), + } +} + +/// Detects the hash algorithm from the program name or command-line arguments. +/// +/// # Arguments +/// +/// * `program` - A string slice containing the program name. +/// * `matches` - A reference to the `ArgMatches` object containing the command-line arguments. +/// +/// # Returns +/// +/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. fn detect_algo( program: &str, matches: &ArgMatches, ) -> (&'static str, Box, usize) { - let mut alg: Option> = None; - let mut name: &'static str = ""; - let mut output_bits = 0; - match program { + let (name, alg, output_bits) = match program { "md5sum" => ("MD5", Box::new(Md5::new()) as Box, 128), "sha1sum" => ("SHA1", Box::new(Sha1::new()) as Box, 160), "sha224sum" => ("SHA224", Box::new(Sha224::new()) as Box, 224), "sha256sum" => ("SHA256", Box::new(Sha256::new()) as Box, 256), "sha384sum" => ("SHA384", Box::new(Sha384::new()) as Box, 384), "sha512sum" => ("SHA512", Box::new(Sha512::new()) as Box, 512), - "b2sum" => match matches.get_one::("length") { - // by default, blake2 uses 64 bytes (512 bits) - // --length=0 falls back to default behavior - Some(0) | None => ("BLAKE2", Box::new(Blake2b::new()) as Box, 512), - Some(length_in_bits) => { - if *length_in_bits > 512 { - crash!(1, "Invalid length (maximum digest length is 512 bits)") - } - - // blake2 output size must be a multiple of 8 bits - if length_in_bits % 8 == 0 { - let length_in_bytes = length_in_bits / 8; - ( - "BLAKE2", - Box::new(Blake2b::with_output_bytes(length_in_bytes)), - *length_in_bits, - ) - } else { - crash!(1, "Invalid length (expected a multiple of 8)") - } - } - }, + "b2sum" => create_blake2b(matches), "b3sum" => ("BLAKE3", Box::new(Blake3::new()) as Box, 256), - "sha3sum" => match matches.get_one::("bits") { - Some(224) => ( - "SHA3-224", - Box::new(Sha3_224::new()) as Box, - 224, - ), - Some(256) => ( - "SHA3-256", - Box::new(Sha3_256::new()) as Box, - 256, - ), - Some(384) => ( - "SHA3-384", - Box::new(Sha3_384::new()) as Box, - 384, - ), - Some(512) => ( - "SHA3-512", - Box::new(Sha3_512::new()) as Box, - 512, - ), - Some(_) => crash!( - 1, - "Invalid output size for SHA3 (expected 224, 256, 384, or 512)" - ), - None => crash!(1, "--bits required for SHA3"), - }, + "sha3sum" => create_sha3(matches), "sha3-224sum" => ( "SHA3-224", Box::new(Sha3_224::new()) as Box, @@ -135,114 +204,94 @@ fn detect_algo( Box::new(Sha3_512::new()) as Box, 512, ), - "shake128sum" => match matches.get_one::("bits") { - Some(bits) => ( - "SHAKE128", - Box::new(Shake128::new()) as Box, - *bits, - ), + "shake128sum" => create_shake128(matches), + "shake256sum" => create_shake256(matches), + _ => create_algorithm_from_flags(matches), + }; + (name, alg, output_bits) +} + +/// Creates a hasher instance based on the command-line flags. +/// +/// # Arguments +/// +/// * `matches` - A reference to the `ArgMatches` object containing the command-line arguments. +/// +/// # Returns +/// +/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits. +/// +/// # Panics +/// +/// Panics if multiple hash algorithms are specified or if a required flag is missing. +fn create_algorithm_from_flags(matches: &ArgMatches) -> (&'static str, Box, usize) { + let mut alg: Option> = None; + let mut name: &'static str = ""; + let mut output_bits = 0; + let mut set_or_crash = |n, val, bits| { + if alg.is_some() { + crash!(1, "You cannot combine multiple hash algorithms!"); + }; + name = n; + alg = Some(val); + output_bits = bits; + }; + + if matches.get_flag("md5") { + set_or_crash("MD5", Box::new(Md5::new()), 128); + } + if matches.get_flag("sha1") { + set_or_crash("SHA1", Box::new(Sha1::new()), 160); + } + if matches.get_flag("sha224") { + set_or_crash("SHA224", Box::new(Sha224::new()), 224); + } + if matches.get_flag("sha256") { + set_or_crash("SHA256", Box::new(Sha256::new()), 256); + } + if matches.get_flag("sha384") { + set_or_crash("SHA384", Box::new(Sha384::new()), 384); + } + if matches.get_flag("sha512") { + set_or_crash("SHA512", Box::new(Sha512::new()), 512); + } + if matches.get_flag("b2sum") { + set_or_crash("BLAKE2", Box::new(Blake2b::new()), 512); + } + if matches.get_flag("b3sum") { + set_or_crash("BLAKE3", Box::new(Blake3::new()), 256); + } + if matches.get_flag("sha3") { + let (n, val, bits) = create_sha3(matches); + set_or_crash(n, val, bits); + } + if matches.get_flag("sha3-224") { + set_or_crash("SHA3-224", Box::new(Sha3_224::new()), 224); + } + if matches.get_flag("sha3-256") { + set_or_crash("SHA3-256", Box::new(Sha3_256::new()), 256); + } + if matches.get_flag("sha3-384") { + set_or_crash("SHA3-384", Box::new(Sha3_384::new()), 384); + } + if matches.get_flag("sha3-512") { + set_or_crash("SHA3-512", Box::new(Sha3_512::new()), 512); + } + if matches.get_flag("shake128") { + match matches.get_one::("bits") { + Some(bits) => set_or_crash("SHAKE128", Box::new(Shake128::new()), *bits), None => crash!(1, "--bits required for SHAKE-128"), - }, - "shake256sum" => match matches.get_one::("bits") { - Some(bits) => ( - "SHAKE256", - Box::new(Shake256::new()) as Box, - *bits, - ), + } + } + if matches.get_flag("shake256") { + match matches.get_one::("bits") { + Some(bits) => set_or_crash("SHAKE256", Box::new(Shake256::new()), *bits), None => crash!(1, "--bits required for SHAKE-256"), - }, - _ => { - { - let mut set_or_crash = |n, val, bits| { - if alg.is_some() { - crash!(1, "You cannot combine multiple hash algorithms!") - }; - name = n; - alg = Some(val); - output_bits = bits; - }; - if matches.get_flag("md5") { - set_or_crash("MD5", Box::new(Md5::new()), 128); - } - if matches.get_flag("sha1") { - set_or_crash("SHA1", Box::new(Sha1::new()), 160); - } - if matches.get_flag("sha224") { - set_or_crash("SHA224", Box::new(Sha224::new()), 224); - } - if matches.get_flag("sha256") { - set_or_crash("SHA256", Box::new(Sha256::new()), 256); - } - if matches.get_flag("sha384") { - set_or_crash("SHA384", Box::new(Sha384::new()), 384); - } - if matches.get_flag("sha512") { - set_or_crash("SHA512", Box::new(Sha512::new()), 512); - } - if matches.get_flag("b2sum") { - set_or_crash("BLAKE2", Box::new(Blake2b::new()), 512); - } - if matches.get_flag("b3sum") { - set_or_crash("BLAKE3", Box::new(Blake3::new()), 256); - } - if matches.get_flag("sha3") { - match matches.get_one::("bits") { - Some(224) => set_or_crash( - "SHA3-224", - Box::new(Sha3_224::new()) as Box, - 224, - ), - Some(256) => set_or_crash( - "SHA3-256", - Box::new(Sha3_256::new()) as Box, - 256, - ), - Some(384) => set_or_crash( - "SHA3-384", - Box::new(Sha3_384::new()) as Box, - 384, - ), - Some(512) => set_or_crash( - "SHA3-512", - Box::new(Sha3_512::new()) as Box, - 512, - ), - Some(_) => crash!( - 1, - "Invalid output size for SHA3 (expected 224, 256, 384, or 512)" - ), - None => crash!(1, "--bits required for SHA3"), - } - } - if matches.get_flag("sha3-224") { - set_or_crash("SHA3-224", Box::new(Sha3_224::new()), 224); - } - if matches.get_flag("sha3-256") { - set_or_crash("SHA3-256", Box::new(Sha3_256::new()), 256); - } - if matches.get_flag("sha3-384") { - set_or_crash("SHA3-384", Box::new(Sha3_384::new()), 384); - } - if matches.get_flag("sha3-512") { - set_or_crash("SHA3-512", Box::new(Sha3_512::new()), 512); - } - if matches.get_flag("shake128") { - match matches.get_one::("bits") { - Some(bits) => set_or_crash("SHAKE128", Box::new(Shake128::new()), *bits), - None => crash!(1, "--bits required for SHAKE-128"), - } - } - if matches.get_flag("shake256") { - match matches.get_one::("bits") { - Some(bits) => set_or_crash("SHAKE256", Box::new(Shake256::new()), *bits), - None => crash!(1, "--bits required for SHAKE-256"), - } - } - } - let alg = alg.unwrap_or_else(|| crash!(1, "You must specify hash algorithm!")); - (name, alg, output_bits) } } + + let alg = alg.unwrap_or_else(|| crash!(1, "You must specify hash algorithm!")); + (name, alg, output_bits) } // TODO: return custom error type From fb72738db4c06162648993cd5c2a5cde1f4b8f66 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 14 Apr 2023 22:58:40 +0200 Subject: [PATCH 138/477] stat: split/doc print_it into smaller functions --- src/uu/stat/src/stat.rs | 216 +++++++++++++++++++++++++++++----------- 1 file changed, 160 insertions(+), 56 deletions(-) diff --git a/src/uu/stat/src/stat.rs b/src/uu/stat/src/stat.rs index 586803db4a..69f3c27608 100644 --- a/src/uu/stat/src/stat.rs +++ b/src/uu/stat/src/stat.rs @@ -205,7 +205,16 @@ struct Stater { default_dev_tokens: Vec, } -#[allow(clippy::cognitive_complexity)] +/// Prints a formatted output based on the provided output type, flags, width, and precision. +/// +/// # Arguments +/// +/// * `output` - A reference to the OutputType enum containing the value to be printed. +/// * `flags` - A Flags struct containing formatting flags. +/// * `width` - The width of the field for the printed output. +/// * `precision` - An Option containing the precision value. +/// +/// This function delegates the printing process to more specialized functions depending on the output type. fn print_it(output: &OutputType, flags: Flags, width: usize, precision: Option) { // If the precision is given as just '.', the precision is taken to be zero. // A negative precision is taken as if the precision were omitted. @@ -236,71 +245,166 @@ fn print_it(output: &OutputType, flags: Flags, width: usize, precision: Option { - let s = match precision { - Some(p) if p < s.len() => &s[..p], - _ => s, - }; - pad_and_print(s, flags.left, width, Padding::Space); - } - OutputType::Integer(num) => { - let num = num.to_string(); - let arg = if flags.group { - group_num(&num) - } else { - Cow::Borrowed(num.as_str()) - }; - let prefix = if flags.sign { - "+" - } else if flags.space { - " " - } else { - "" - }; - let extended = format!( - "{prefix}{arg:0>precision$}", - precision = precision.unwrap_or(0) - ); - pad_and_print(&extended, flags.left, width, padding_char); - } - OutputType::Unsigned(num) => { - let num = num.to_string(); - let s = if flags.group { - group_num(&num) - } else { - Cow::Borrowed(num.as_str()) - }; - let s = format!("{s:0>precision$}", precision = precision.unwrap_or(0)); - pad_and_print(&s, flags.left, width, padding_char); - } + OutputType::Str(s) => print_str(s, &flags, width, precision), + OutputType::Integer(num) => print_integer(*num, &flags, width, precision, padding_char), + OutputType::Unsigned(num) => print_unsigned(*num, &flags, width, precision, padding_char), OutputType::UnsignedOct(num) => { - let prefix = if flags.alter { "0" } else { "" }; - let s = format!( - "{prefix}{num:0>precision$o}", - precision = precision.unwrap_or(0) - ); - pad_and_print(&s, flags.left, width, padding_char); + print_unsigned_oct(*num, &flags, width, precision, padding_char); } OutputType::UnsignedHex(num) => { - let prefix = if flags.alter { "0x" } else { "" }; - let s = format!( - "{prefix}{num:0>precision$x}", - precision = precision.unwrap_or(0) - ); - pad_and_print(&s, flags.left, width, padding_char); + print_unsigned_hex(*num, &flags, width, precision, padding_char); } OutputType::Unknown => print!("?"), } } +/// Determines the padding character based on the provided flags and precision. +/// +/// # Arguments +/// +/// * `flags` - A reference to the Flags struct containing formatting flags. +/// * `precision` - An Option containing the precision value. +/// +/// # Returns +/// +/// * Padding - An instance of the Padding enum representing the padding character. +fn determine_padding_char(flags: &Flags, precision: &Option) -> Padding { + if flags.zero && !flags.left && precision.is_none() { + Padding::Zero + } else { + Padding::Space + } +} + +/// Prints a string value based on the provided flags, width, and precision. +/// +/// # Arguments +/// +/// * `s` - The string to be printed. +/// * `flags` - A reference to the Flags struct containing formatting flags. +/// * `width` - The width of the field for the printed string. +/// * `precision` - An Option containing the precision value. +fn print_str(s: &str, flags: &Flags, width: usize, precision: Option) { + let s = match precision { + Some(p) if p < s.len() => &s[..p], + _ => s, + }; + pad_and_print(s, flags.left, width, Padding::Space); +} + +/// Prints an integer value based on the provided flags, width, and precision. +/// +/// # Arguments +/// +/// * `num` - The integer value to be printed. +/// * `flags` - A reference to the Flags struct containing formatting flags. +/// * `width` - The width of the field for the printed integer. +/// * `precision` - An Option containing the precision value. +/// * `padding_char` - The padding character as determined by `determine_padding_char`. +fn print_integer( + num: i64, + flags: &Flags, + width: usize, + precision: Option, + padding_char: Padding, +) { + let num = num.to_string(); + let arg = if flags.group { + group_num(&num) + } else { + Cow::Borrowed(num.as_str()) + }; + let prefix = if flags.sign { + "+" + } else if flags.space { + " " + } else { + "" + }; + let extended = format!( + "{prefix}{arg:0>precision$}", + precision = precision.unwrap_or(0) + ); + pad_and_print(&extended, flags.left, width, padding_char); +} + +/// Prints an unsigned integer value based on the provided flags, width, and precision. +/// +/// # Arguments +/// +/// * `num` - The unsigned integer value to be printed. +/// * `flags` - A reference to the Flags struct containing formatting flags. +/// * `width` - The width of the field for the printed unsigned integer. +/// * `precision` - An Option containing the precision value. +/// * `padding_char` - The padding character as determined by `determine_padding_char`. +fn print_unsigned( + num: u64, + flags: &Flags, + width: usize, + precision: Option, + padding_char: Padding, +) { + let num = num.to_string(); + let s = if flags.group { + group_num(&num) + } else { + Cow::Borrowed(num.as_str()) + }; + let s = format!("{s:0>precision$}", precision = precision.unwrap_or(0)); + pad_and_print(&s, flags.left, width, padding_char); +} + +/// Prints an unsigned octal integer value based on the provided flags, width, and precision. +/// +/// # Arguments +/// +/// * `num` - The unsigned octal integer value to be printed. +/// * `flags` - A reference to the Flags struct containing formatting flags. +/// * `width` - The width of the field for the printed unsigned octal integer. +/// * `precision` - An Option containing the precision value. +/// * `padding_char` - The padding character as determined by `determine_padding_char`. +fn print_unsigned_oct( + num: u32, + flags: &Flags, + width: usize, + precision: Option, + padding_char: Padding, +) { + let prefix = if flags.alter { "0" } else { "" }; + let s = format!( + "{prefix}{num:0>precision$o}", + precision = precision.unwrap_or(0) + ); + pad_and_print(&s, flags.left, width, padding_char); +} + +/// Prints an unsigned hexadecimal integer value based on the provided flags, width, and precision. +/// +/// # Arguments +/// +/// * `num` - The unsigned hexadecimal integer value to be printed. +/// * `flags` - A reference to the Flags struct containing formatting flags. +/// * `width` - The width of the field for the printed unsigned hexadecimal integer. +/// * `precision` - An Option containing the precision value. +/// * `padding_char` - The padding character as determined by `determine_padding_char`. +fn print_unsigned_hex( + num: u64, + flags: &Flags, + width: usize, + precision: Option, + padding_char: Padding, +) { + let prefix = if flags.alter { "0x" } else { "" }; + let s = format!( + "{prefix}{num:0>precision$x}", + precision = precision.unwrap_or(0) + ); + pad_and_print(&s, flags.left, width, padding_char); +} + impl Stater { fn generate_tokens(format_str: &str, use_printf: bool) -> UResult> { let mut tokens = Vec::new(); From 2c1aa229a0ffbe99a43fb93e1de23934341e03e2 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 14 Apr 2023 23:20:23 +0200 Subject: [PATCH 139/477] install: split/doc copy into smaller functions --- src/uu/install/src/install.rs | 167 +++++++++++++++++++++++++--------- 1 file changed, 123 insertions(+), 44 deletions(-) diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 039aa1b153..e0307fe34b 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -682,36 +682,23 @@ fn chown_optional_user_group(path: &Path, b: &Behavior) -> UResult<()> { Ok(()) } -/// Copy one file to a new location, changing metadata. -/// -/// Returns a Result type with the Err variant containing the error message. +/// Perform backup before overwriting. /// /// # Parameters /// -/// _from_ must exist as a non-directory. -/// _to_ must be a non-existent file, whose parent directory exists. +/// * `to` - The destination file path. +/// * `b` - The behavior configuration. /// -/// # Errors +/// # Returns /// -/// If the copy system call fails, we print a verbose error and return an empty error value. +/// Returns an Option containing the backup path, or None if backup is not needed. /// -#[allow(clippy::cognitive_complexity)] -fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> { - if b.compare && !need_copy(from, to, b)? { - return Ok(()); - } - // Declare the path here as we may need it for the verbose output below. - let mut backup_path = None; - - // Perform backup, if any, before overwriting 'to' - // - // The codes actually making use of the backup process don't seem to agree - // on how best to approach the issue. (mv and ln, for example) +fn perform_backup(to: &Path, b: &Behavior) -> UResult> { if to.exists() { if b.verbose { println!("removed {}", to.quote()); } - backup_path = backup_control::get_backup_path(b.backup_mode, to, &b.suffix); + let backup_path = backup_control::get_backup_path(b.backup_mode, to, &b.suffix); if let Some(ref backup_path) = backup_path { // TODO!! if let Err(err) = fs::rename(to, backup_path) { @@ -723,8 +710,24 @@ fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> { .into()); } } + Ok(backup_path) + } else { + Ok(None) } +} +/// Copy a file from one path to another. +/// +/// # Parameters +/// +/// * `from` - The source file path. +/// * `to` - The destination file path. +/// +/// # Returns +/// +/// Returns an empty Result or an error in case of failure. +/// +fn copy_file(from: &Path, to: &Path) -> UResult<()> { if from.as_os_str() == "/dev/null" { /* workaround a limitation of fs::copy * https://github.com/rust-lang/rust/issues/79390 @@ -737,27 +740,53 @@ fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> { } else if let Err(err) = fs::copy(from, to) { return Err(InstallError::InstallFailed(from.to_path_buf(), to.to_path_buf(), err).into()); } + Ok(()) +} - if b.strip && cfg!(not(windows)) { - match process::Command::new(&b.strip_program).arg(to).output() { - Ok(o) => { - if !o.status.success() { - // Follow GNU's behavior: if strip fails, removes the target - let _ = fs::remove_file(to); - return Err(InstallError::StripProgramFailed( - String::from_utf8(o.stderr).unwrap_or_default(), - ) - .into()); - } - } - Err(e) => { +/// Strip a file using an external program. +/// +/// # Parameters +/// +/// * `to` - The destination file path. +/// * `b` - The behavior configuration. +/// +/// # Returns +/// +/// Returns an empty Result or an error in case of failure. +/// +fn strip_file(to: &Path, b: &Behavior) -> UResult<()> { + match process::Command::new(&b.strip_program).arg(to).output() { + Ok(o) => { + if !o.status.success() { // Follow GNU's behavior: if strip fails, removes the target let _ = fs::remove_file(to); - return Err(InstallError::StripProgramFailed(e.to_string()).into()); + return Err(InstallError::StripProgramFailed( + String::from_utf8(o.stderr).unwrap_or_default(), + ) + .into()); } } + Err(e) => { + // Follow GNU's behavior: if strip fails, removes the target + let _ = fs::remove_file(to); + return Err(InstallError::StripProgramFailed(e.to_string()).into()); + } } + Ok(()) +} +/// Set ownership and permissions on the destination file. +/// +/// # Parameters +/// +/// * `to` - The destination file path. +/// * `b` - The behavior configuration. +/// +/// # Returns +/// +/// Returns an empty Result or an error in case of failure. +/// +fn set_ownership_and_permissions(to: &Path, b: &Behavior) -> UResult<()> { // Silent the warning as we want to the error message #[allow(clippy::question_mark)] if mode::chmod(to, b.mode()).is_err() { @@ -766,20 +795,70 @@ fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> { chown_optional_user_group(to, b)?; - if b.preserve_timestamps { - let meta = match fs::metadata(from) { - Ok(meta) => meta, - Err(e) => return Err(InstallError::MetadataFailed(e).into()), - }; + Ok(()) +} - let modified_time = FileTime::from_last_modification_time(&meta); - let accessed_time = FileTime::from_last_access_time(&meta); +/// Preserve timestamps on the destination file. +/// +/// # Parameters +/// +/// * `from` - The source file path. +/// * `to` - The destination file path. +/// +/// # Returns +/// +/// Returns an empty Result or an error in case of failure. +/// +fn preserve_timestamps(from: &Path, to: &Path) -> UResult<()> { + let meta = match fs::metadata(from) { + Ok(meta) => meta, + Err(e) => return Err(InstallError::MetadataFailed(e).into()), + }; - match set_file_times(to, accessed_time, modified_time) { - Ok(_) => {} - Err(e) => show_error!("{}", e), + let modified_time = FileTime::from_last_modification_time(&meta); + let accessed_time = FileTime::from_last_access_time(&meta); + + match set_file_times(to, accessed_time, modified_time) { + Ok(_) => Ok(()), + Err(e) => { + show_error!("{}", e); + Ok(()) } } +} + +/// Copy one file to a new location, changing metadata. +/// +/// Returns a Result type with the Err variant containing the error message. +/// +/// # Parameters +/// +/// _from_ must exist as a non-directory. +/// _to_ must be a non-existent file, whose parent directory exists. +/// +/// # Errors +/// +/// If the copy system call fails, we print a verbose error and return an empty error value. +/// +fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> { + if b.compare && !need_copy(from, to, b)? { + return Ok(()); + } + // Declare the path here as we may need it for the verbose output below. + let backup_path = perform_backup(to, b)?; + + copy_file(from, to)?; + + #[cfg(not(windows))] + if b.strip { + strip_file(to, b)?; + } + + set_ownership_and_permissions(to, b)?; + + if b.preserve_timestamps { + preserve_timestamps(from, to)?; + } if b.verbose { print!("{} -> {}", from.quote(), to.quote()); From 25fbcd89a5fab08cc4dc5aac45477b3f2b262317 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 14 Apr 2023 23:36:51 +0200 Subject: [PATCH 140/477] fmt:uumain: split/doc copy into smaller functions --- src/uu/fmt/src/fmt.rs | 103 ++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 34 deletions(-) diff --git a/src/uu/fmt/src/fmt.rs b/src/uu/fmt/src/fmt.rs index bd03b5497a..0fd863730f 100644 --- a/src/uu/fmt/src/fmt.rs +++ b/src/uu/fmt/src/fmt.rs @@ -11,7 +11,7 @@ use clap::{crate_version, Arg, ArgAction, Command}; use std::cmp; use std::fs::File; use std::io::{stdin, stdout, Write}; -use std::io::{BufReader, BufWriter, Read}; +use std::io::{BufReader, BufWriter, Read, Stdout}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; use uucore::{format_usage, help_about, help_usage, show_warning}; @@ -60,10 +60,16 @@ pub struct FmtOptions { goal: usize, tabwidth: usize, } - -#[uucore::main] -#[allow(clippy::cognitive_complexity)] -pub fn uumain(args: impl uucore::Args) -> UResult<()> { +/// Parse the command line arguments and return the list of files and formatting options. +/// +/// # Arguments +/// +/// * `args` - Command line arguments. +/// +/// # Returns +/// +/// A tuple containing a vector of file names and a `FmtOptions` struct. +fn parse_arguments(args: impl uucore::Args) -> UResult<(Vec, FmtOptions)> { let matches = uu_app().try_get_matches_from(args)?; let mut files: Vec = matches @@ -177,39 +183,68 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { files.push("-".to_owned()); } - let mut ostream = BufWriter::new(stdout()); + Ok((files, fmt_opts)) +} - for i in files.iter().map(|x| &x[..]) { - let mut fp = match i { - "-" => BufReader::new(Box::new(stdin()) as Box), - _ => match File::open(i) { - Ok(f) => BufReader::new(Box::new(f) as Box), - Err(e) => { - show_warning!("{}: {}", i.maybe_quote(), e); - continue; - } - }, - }; - let p_stream = ParagraphStream::new(&fmt_opts, &mut fp); - for para_result in p_stream { - match para_result { - Err(s) => { - ostream - .write_all(s.as_bytes()) - .map_err_context(|| "failed to write output".to_string())?; - ostream - .write_all(b"\n") - .map_err_context(|| "failed to write output".to_string())?; - } - Ok(para) => break_lines(¶, &fmt_opts, &mut ostream) - .map_err_context(|| "failed to write output".to_string())?, +/// Process the content of a file and format it according to the provided options. +/// +/// # Arguments +/// +/// * `file_name` - The name of the file to process. A value of "-" represents the standard input. +/// * `fmt_opts` - A reference to a `FmtOptions` struct containing the formatting options. +/// * `ostream` - A mutable reference to a `BufWriter` wrapping the standard output. +/// +/// # Returns +/// +/// A `UResult<()>` indicating success or failure. +fn process_file( + file_name: &str, + fmt_opts: &FmtOptions, + ostream: &mut BufWriter, +) -> UResult<()> { + let mut fp = match file_name { + "-" => BufReader::new(Box::new(stdin()) as Box), + _ => match File::open(file_name) { + Ok(f) => BufReader::new(Box::new(f) as Box), + Err(e) => { + show_warning!("{}: {}", file_name.maybe_quote(), e); + return Ok(()); + } + }, + }; + + let p_stream = ParagraphStream::new(fmt_opts, &mut fp); + for para_result in p_stream { + match para_result { + Err(s) => { + ostream + .write_all(s.as_bytes()) + .map_err_context(|| "failed to write output".to_string())?; + ostream + .write_all(b"\n") + .map_err_context(|| "failed to write output".to_string())?; } + Ok(para) => break_lines(¶, fmt_opts, ostream) + .map_err_context(|| "failed to write output".to_string())?, } + } + + // flush the output after each file + ostream + .flush() + .map_err_context(|| "failed to write output".to_string())?; + + Ok(()) +} + +#[uucore::main] +pub fn uumain(args: impl uucore::Args) -> UResult<()> { + let (files, fmt_opts) = parse_arguments(args)?; + + let mut ostream = BufWriter::new(stdout()); - // flush the output after each file - ostream - .flush() - .map_err_context(|| "failed to write output".to_string())?; + for file_name in &files { + process_file(file_name, &fmt_opts, &mut ostream)?; } Ok(()) From 4a96feb36b0880c7b6fa7ca8477a81ed31841395 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 18 Apr 2023 16:42:46 +0200 Subject: [PATCH 141/477] docs: document fmt in GNU extensions --- docs/src/extensions.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/src/extensions.md b/docs/src/extensions.md index 3e84f70d80..7aaf9db14f 100644 --- a/docs/src/extensions.md +++ b/docs/src/extensions.md @@ -43,3 +43,10 @@ therefore welcomed. `cut` can separate fields by whitespace (Space and Tab) with `-w` flag. This feature is adopted from [FreeBSD](https://www.freebsd.org/cgi/man.cgi?cut). + +## `fmt` + +`fmt` has additional flags for prefixes: `-P/--skip-prefix`, `-x/--exact-prefix`, and +`-X/--exact-skip-prefix`. With `-m/--preserve-headers`, an attempt is made to detect and preserve +mail headers in the input. `-q/--quick` breaks lines more quickly. And `-T/--tab-width` defines the +number of spaces representing a tab when determining the line length. From 20e32971dd3f6efe388755ecda57860d052da738 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sun, 9 Apr 2023 16:19:57 +0200 Subject: [PATCH 142/477] tail/args: Fix parsing when -F is used together with --retry or --follow --- Cargo.lock | 1 + Cargo.toml | 1 + src/uu/tail/Cargo.toml | 3 ++ src/uu/tail/src/args.rs | 91 ++++++++++++++++++++++++++++++++------ tests/by-util/test_tail.rs | 17 +++---- 5 files changed, 91 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db4e2035ab..69cf9d7043 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3179,6 +3179,7 @@ dependencies = [ "libc", "memchr", "notify", + "rstest", "same-file", "uucore", "winapi-util", diff --git a/Cargo.toml b/Cargo.toml index 98c899b98f..b4983a6cc6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -311,6 +311,7 @@ rand_core = "0.6" rayon = "1.7" redox_syscall = "0.2" regex = "1.7.3" +rstest = "0.17.0" rust-ini = "0.18.0" same-file = "1.0.6" selinux = "0.4" diff --git a/src/uu/tail/Cargo.toml b/src/uu/tail/Cargo.toml index f58adf8aba..a82670f9e8 100644 --- a/src/uu/tail/Cargo.toml +++ b/src/uu/tail/Cargo.toml @@ -29,6 +29,9 @@ fundu = { workspace=true } windows-sys = { workspace=true, features = ["Win32_System_Threading", "Win32_Foundation"] } winapi-util = { workspace=true } +[dev-dependencies] +rstest = { workspace=true } + [[bin]] name = "tail" path = "src/main.rs" diff --git a/src/uu/tail/src/args.rs b/src/uu/tail/src/args.rs index 8e039b5f4b..55014e0298 100644 --- a/src/uu/tail/src/args.rs +++ b/src/uu/tail/src/args.rs @@ -8,7 +8,7 @@ use crate::paths::Input; use crate::{parse, platform, Quotable}; use clap::crate_version; -use clap::{parser::ValueSource, Arg, ArgAction, ArgMatches, Command}; +use clap::{Arg, ArgAction, ArgMatches, Command}; use fundu::DurationParser; use is_terminal::IsTerminal; use same_file::Handle; @@ -182,19 +182,44 @@ impl Settings { } pub fn from(matches: &clap::ArgMatches) -> UResult { - let mut settings: Self = Self { - follow: if matches.get_flag(options::FOLLOW_RETRY) { - Some(FollowMode::Name) - } else if matches.value_source(options::FOLLOW) != Some(ValueSource::CommandLine) { - None - } else if matches.get_one::(options::FOLLOW) - == Some(String::from("name")).as_ref() + // We're parsing --follow, -F and --retry under the following conditions: + // * -F sets --retry and --follow=name + // * plain --follow or short -f is the same like specifying --follow=descriptor + // * All these options and flags can occur multiple times as command line arguments + let follow_retry = matches.get_flag(options::FOLLOW_RETRY); + // We don't need to check for occurrences of --retry if -F was specified which already sets + // retry + let retry = follow_retry || matches.get_flag(options::RETRY); + let follow = match ( + follow_retry, + matches + .get_one::(options::FOLLOW) + .map(|s| s.as_str()), + ) { + // -F and --follow if -F is specified after --follow. We don't need to care about the + // value of --follow. + (true, Some(_)) + // It's ok to use `index_of` instead of `indices_of` since -F and --follow + // overwrite themselves (not only the value but also the index). + if matches.index_of(options::FOLLOW_RETRY) > matches.index_of(options::FOLLOW) => { Some(FollowMode::Name) - } else { - Some(FollowMode::Descriptor) - }, - retry: matches.get_flag(options::RETRY) || matches.get_flag(options::FOLLOW_RETRY), + } + // * -F and --follow=name if --follow=name is specified after -F + // * No occurrences of -F but --follow=name + // * -F and no occurrences of --follow + (_, Some("name")) | (true, None) => Some(FollowMode::Name), + // * -F and --follow=descriptor (or plain --follow, -f) if --follow=descriptor is + // specified after -F + // * No occurrences of -F but --follow=descriptor, --follow, -f + (_, Some(_)) => Some(FollowMode::Descriptor), + // The default for no occurrences of -F or --follow + (false, None) => None, + }; + + let mut settings: Self = Self { + follow, + retry, use_polling: matches.get_flag(options::USE_POLLING), mode: FilterMode::from(matches)?, verbose: matches.get_flag(options::verbosity::VERBOSE), @@ -469,7 +494,7 @@ pub fn uu_app() -> Command { Arg::new(options::FOLLOW) .short('f') .long(options::FOLLOW) - .default_value("descriptor") + .default_missing_value("descriptor") .num_args(0..=1) .require_equals(true) .value_parser(["descriptor", "name"]) @@ -544,13 +569,14 @@ pub fn uu_app() -> Command { Arg::new(options::RETRY) .long(options::RETRY) .help("Keep trying to open a file if it is inaccessible") + .overrides_with(options::RETRY) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::FOLLOW_RETRY) .short('F') .help("Same as --follow=name --retry") - .overrides_with_all([options::RETRY, options::FOLLOW]) + .overrides_with(options::FOLLOW_RETRY) .action(ArgAction::SetTrue), ) .arg( @@ -570,6 +596,8 @@ pub fn uu_app() -> Command { #[cfg(test)] mod tests { + use rstest::rstest; + use crate::parse::ObsoleteArgs; use super::*; @@ -616,4 +644,39 @@ mod tests { let result = Settings::from_obsolete_args(&args, Some(&"file".into())); assert_eq!(result.follow, Some(FollowMode::Name)); } + + #[rstest] + #[case::default(vec![], None, false)] + #[case::retry(vec!["--retry"], None, true)] + #[case::multiple_retry(vec!["--retry", "--retry"], None, true)] + #[case::follow_long(vec!["--follow"], Some(FollowMode::Descriptor), false)] + #[case::follow_short(vec!["-f"], Some(FollowMode::Descriptor), false)] + #[case::follow_long_with_retry(vec!["--follow", "--retry"], Some(FollowMode::Descriptor), true)] + #[case::follow_short_with_retry(vec!["-f", "--retry"], Some(FollowMode::Descriptor), true)] + #[case::follow_overwrites_previous_selection_1(vec!["--follow=name", "--follow=descriptor"], Some(FollowMode::Descriptor), false)] + #[case::follow_overwrites_previous_selection_2(vec!["--follow=descriptor", "--follow=name"], Some(FollowMode::Name), false)] + #[case::big_f(vec!["-F"], Some(FollowMode::Name), true)] + #[case::multiple_big_f(vec!["-F", "-F"], Some(FollowMode::Name), true)] + #[case::big_f_with_retry_then_does_not_change(vec!["-F", "--retry"], Some(FollowMode::Name), true)] + #[case::big_f_with_follow_descriptor_then_change(vec!["-F", "--follow=descriptor"], Some(FollowMode::Descriptor), true)] + #[case::multiple_big_f_with_follow_descriptor_then_no_change(vec!["-F", "--follow=descriptor", "-F"], Some(FollowMode::Name), true)] + #[case::big_f_with_follow_short_then_change(vec!["-F", "-f"], Some(FollowMode::Descriptor), true)] + #[case::follow_descriptor_with_big_f_then_change(vec!["--follow=descriptor", "-F"], Some(FollowMode::Name), true)] + #[case::follow_short_with_big_f_then_change(vec!["-f", "-F"], Some(FollowMode::Name), true)] + #[case::big_f_with_follow_name_then_not_change(vec!["-F", "--follow=name"], Some(FollowMode::Name), true)] + #[case::follow_name_with_big_f_then_not_change(vec!["--follow=name", "-F"], Some(FollowMode::Name), true)] + #[case::big_f_with_multiple_long_follow(vec!["--follow=name", "-F", "--follow=descriptor"], Some(FollowMode::Descriptor), true)] + #[case::big_f_with_multiple_long_follow_name(vec!["--follow=name", "-F", "--follow=name"], Some(FollowMode::Name), true)] + #[case::big_f_with_multiple_short_follow(vec!["-f", "-F", "-f"], Some(FollowMode::Descriptor), true)] + #[case::multiple_big_f_with_multiple_short_follow(vec!["-f", "-F", "-f", "-F"], Some(FollowMode::Name), true)] + fn test_parse_settings_follow_mode_and_retry( + #[case] args: Vec<&str>, + #[case] expected_follow_mode: Option, + #[case] expected_retry: bool, + ) { + let settings = + Settings::from(&uu_app().no_binary_name(true).get_matches_from(args)).unwrap(); + assert_eq!(settings.follow, expected_follow_mode); + assert_eq!(settings.retry, expected_retry); + } } diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index 2f83f303bc..f3e55e434a 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -4358,14 +4358,7 @@ fn test_follow_when_file_and_symlink_are_pointing_to_same_file_and_append_data() .stdout_only(expected_stdout); } -// Fails with: -// 'Assertion failed. Expected 'tail' to be running but exited with status=exit status: 1. -// stdout: -// stderr: tail: warning: --retry ignored; --retry is useful only when following -// tail: error reading 'dir': Is a directory -// ' #[test] -#[cfg(disabled_until_fixed)] fn test_args_when_directory_given_shorthand_big_f_together_with_retry() { let scene = TestScenario::new(util_name!()); let fixtures = &scene.fixtures; @@ -4377,9 +4370,17 @@ fn test_args_when_directory_given_shorthand_big_f_together_with_retry() { tail: {0}: cannot follow end of this type of file\n", dirname ); - let mut child = scene.ucmd().args(&["-F", "--retry", "dir"]).run_no_wait(); + child.make_assertion_with_delay(500).is_alive(); + child + .kill() + .make_assertion() + .with_current_output() + .stderr_only(&expected_stderr); + + let mut child = scene.ucmd().args(&["--retry", "-F", "dir"]).run_no_wait(); + child.make_assertion_with_delay(500).is_alive(); child .kill() From 54178d491c7b5b43f0b4105792ba752926402c11 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 16:14:17 +0000 Subject: [PATCH 143/477] fix(deps): update rust crate dunce to 1.0.4 --- Cargo.lock | 4 ++-- src/uucore/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33e33d31a7..bd20d6e111 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -812,9 +812,9 @@ dependencies = [ [[package]] name = "dunce" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "either" diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 69c23b3cf7..0dc247541e 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -21,7 +21,7 @@ path="src/lib/lib.rs" clap = { workspace=true } uucore_procs = { workspace=true } dns-lookup = { version="1.0.8", optional=true } -dunce = "1.0.3" +dunce = "1.0.4" wild = "2.1" glob = "0.3.1" # * optional From 78ce521c01f902955a50d6cf8b88b42b05df37a4 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Fri, 14 Apr 2023 19:19:57 +0200 Subject: [PATCH 144/477] ci: Use nextest as test runner instead of cargo test --- .config/nextest.toml | 6 ++++ .github/workflows/CICD.yml | 32 ++++++++++++-------- .github/workflows/android.yml | 2 ++ .github/workflows/freebsd.yml | 12 ++++++-- GNUmakefile | 5 +++- util/android-commands.sh | 56 ++++++++++++++++++++++++++++++++--- 6 files changed, 93 insertions(+), 20 deletions(-) create mode 100644 .config/nextest.toml diff --git a/.config/nextest.toml b/.config/nextest.toml new file mode 100644 index 0000000000..3ba8bb393a --- /dev/null +++ b/.config/nextest.toml @@ -0,0 +1,6 @@ +[profile.ci] +retries = 2 +status-level = "all" +final-status-level = "skip" +failure-output = "immediate-final" +fail-fast = false diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 2a67c7d978..32fd305369 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -1,8 +1,8 @@ name: CICD -# spell-checker:ignore (abbrev/names) CICD CodeCOV MacOS MinGW MSVC musl -# spell-checker:ignore (env/flags) Awarnings Ccodegen Coverflow Cpanic Dwarnings RUSTDOCFLAGS RUSTFLAGS Zpanic -# spell-checker:ignore (jargon) SHAs deps dequote softprops subshell toolchain +# spell-checker:ignore (abbrev/names) CICD CodeCOV MacOS MinGW MSVC musl taiki +# spell-checker:ignore (env/flags) Awarnings Ccodegen Coverflow Cpanic Dwarnings RUSTDOCFLAGS RUSTFLAGS Zpanic CARGOFLAGS +# spell-checker:ignore (jargon) SHAs deps dequote softprops subshell toolchain fuzzers # spell-checker:ignore (people) Peltoche rivy # spell-checker:ignore (shell/tools) choco clippy dmake dpkg esac fakeroot fdesc fdescfs gmake grcov halium lcov libssl mkdir popd printf pushd rsync rustc rustfmt rustup shopt utmpdump xargs # spell-checker:ignore (misc) aarch alnum armhf bindir busytest coreutils defconfig DESTDIR gecos gnueabihf issuecomment maint multisize nullglob onexitbegin onexitend pell runtest Swatinem tempfile testsuite toybox uutils @@ -357,6 +357,7 @@ jobs: rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} --profile minimal rustup default ${{ env.RUST_MIN_SRV }} - uses: Swatinem/rust-cache@v2 + - uses: taiki-e/install-action@nextest - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - name: Initialize workflow variables @@ -404,10 +405,11 @@ jobs: RUSTUP_TOOLCHAIN=stable cargo fetch --locked --quiet RUSTUP_TOOLCHAIN=stable cargo tree --all --locked --no-dev-dependencies --no-indent ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} | grep -vE "$PWD" | sort --unique - name: Test - run: cargo test -v ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} -p uucore -p coreutils + run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} -p uucore -p coreutils env: RUSTFLAGS: "-Awarnings" RUST_BACKTRACE: "1" + CARGO_TERM_COLOR: always deps: name: Dependencies @@ -451,6 +453,7 @@ jobs: ## Install `rust` toolchain rustup toolchain install stable --no-self-update --profile minimal rustup default stable + - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -458,12 +461,12 @@ jobs: shell: bash run: | make build - - name: "`make test`" + - name: "`make nextest`" shell: bash - run: | - make test + run: make nextest CARGOFLAGS="--profile ci --hide-progress-bar" env: RUST_BACKTRACE: "1" + CARGO_TERM_COLOR: "always" - name: "`make install`" shell: bash run: | @@ -497,13 +500,15 @@ jobs: ## Install `rust` toolchain rustup toolchain install stable --no-self-update --profile minimal rustup default stable + - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - name: Test - run: cargo test ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} + run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: RUST_BACKTRACE: "1" + CARGO_TERM_COLOR: "always" build_rust_nightly: name: Build/nightly @@ -527,13 +532,15 @@ jobs: ## Install `rust` toolchain rustup toolchain install nightly --no-self-update --profile minimal rustup default nightly + - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - name: Test - run: cargo test ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} + run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: RUST_BACKTRACE: "1" + CARGO_TERM_COLOR: "always" compute_size: name: Binary sizes @@ -1060,6 +1067,7 @@ jobs: ## rust toolchain ~ install rustup toolchain install ${{ matrix.job.toolchain }} --no-self-update --profile minimal rustup default ${{ matrix.job.toolchain }} + - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -1122,7 +1130,7 @@ jobs: CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo -n "-puu_${u} "; done;)" outputs CARGO_UTILITY_LIST_OPTIONS - name: Test uucore - run: cargo test --no-fail-fast -p uucore + run: cargo nextest run --profile ci --hide-progress-bar -p uucore env: CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" @@ -1131,7 +1139,7 @@ jobs: RUST_BACKTRACE: "1" # RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }} - name: Test - run: cargo test ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-fail-fast + run: cargo nextest run --profile ci --hide-progress-bar ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" @@ -1140,7 +1148,7 @@ jobs: RUST_BACKTRACE: "1" # RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }} - name: Test individual utilities - run: cargo test --no-fail-fast ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} + run: cargo nextest run --profile ci --hide-progress-bar ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} env: CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 059fe6d814..06c39f961f 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -1,5 +1,7 @@ name: Android +# spell-checker:ignore TERMUX reactivecircus Swatinem noaudio pkill swiftshader + on: [push, pull_request] permissions: diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml index 2ff1674348..9507b3a564 100644 --- a/.github/workflows/freebsd.yml +++ b/.github/workflows/freebsd.yml @@ -1,6 +1,6 @@ name: FreeBSD -# spell-checker:ignore sshfs usesh vmactions +# spell-checker:ignore sshfs usesh vmactions taiki Swatinem esac fdescfs fdesc env: # * style job configuration @@ -156,6 +156,9 @@ jobs: curl https://sh.rustup.rs -sSf --output rustup.sh sh rustup.sh -y --profile=minimal . $HOME/.cargo/env + # Install nextest + mkdir -p ~/.cargo/bin + curl -LsSf https://get.nexte.st/latest/freebsd | tar zxf - -C ~/.cargo/bin ## Info # environment echo "## environment" @@ -168,6 +171,7 @@ jobs: # tooling info echo "## tooling info" cargo -V + cargo nextest --version rustc -V # # To ensure that files are cleaned up, we don't want to exit on error @@ -175,9 +179,11 @@ jobs: cd "${WORKSPACE}" unset FAULT cargo build || FAULT=1 + export PATH=~/.cargo/bin:${PATH} export RUST_BACKTRACE=1 - if (test -z "\$FAULT"); then cargo test --features '${{ matrix.job.features }}' || FAULT=1 ; fi - if (test -z "\$FAULT"); then cargo test --all-features -p uucore || FAULT=1 ; fi + export CARGO_TERM_COLOR=always + if (test -z "\$FAULT"); then cargo nextest run --hide-progress-bar --profile ci --features '${{ matrix.job.features }}' || FAULT=1 ; fi + if (test -z "\$FAULT"); then cargo nextest run --hide-progress-bar --profile ci --all-features -p uucore || FAULT=1 ; fi # Clean to avoid to rsync back the files cargo clean if (test -n "\$FAULT"); then exit 1 ; fi diff --git a/GNUmakefile b/GNUmakefile index 81b90d32f3..26d6de5ba6 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,4 @@ -# spell-checker:ignore (misc) testsuite runtest findstring (targets) busytest toybox distclean pkgs ; (vars/env) BINDIR BUILDDIR CARGOFLAGS DESTDIR DOCSDIR INSTALLDIR INSTALLEES MULTICALL DATAROOTDIR TESTDIR +# spell-checker:ignore (misc) testsuite runtest findstring (targets) busytest toybox distclean pkgs nextest ; (vars/env) BINDIR BUILDDIR CARGOFLAGS DESTDIR DOCSDIR INSTALLDIR INSTALLEES MULTICALL DATAROOTDIR TESTDIR # Config options PROFILE ?= debug @@ -289,6 +289,9 @@ $(foreach test,$(filter-out $(SKIP_UTILS),$(PROGS)),$(eval $(call TEST_BUSYBOX,$ test: ${CARGO} test ${CARGOFLAGS} --features "$(TESTS) $(TEST_SPEC_FEATURE)" --no-default-features $(TEST_NO_FAIL_FAST) +nextest: + ${CARGO} nextest run ${CARGOFLAGS} --features "$(TESTS) $(TEST_SPEC_FEATURE)" --no-default-features $(TEST_NO_FAIL_FAST) + test_toybox: -(cd $(TOYBOX_SRC)/ && make tests) diff --git a/util/android-commands.sh b/util/android-commands.sh index 42e27ad886..02999f5da9 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -1,5 +1,5 @@ #!/bin/bash -# spell-checker:ignore termux keyevent sdcard binutils unmatch adb's dumpsys logcat pkill +# spell-checker:ignore termux keyevent sdcard binutils unmatch adb's dumpsys logcat pkill nextest # There are three shells: the host's, adb, and termux. Only adb lets us run # commands directly on the emulated device, only termux provides a GNU @@ -73,9 +73,50 @@ snapshot () { apk="$1" echo "running snapshot" adb install -g "$apk" + + echo "Prepare and install system packages" probe='/sdcard/pkg.probe' - command="'yes | pkg install rust binutils openssl -y; touch $probe'" + log='/sdcard/pkg.log' + command="'{ mkdir -vp ~/.cargo/bin; yes | pkg install rust binutils openssl -y; echo \$? > $probe; } &> $log'" + run_termux_command "$command" "$probe" + return_code=$? + + adb pull "$log" . + cat $(basename "$log") + + if [[ $return_code -ne 0 ]]; then return $return_code; fi + + echo "Installing cargo-nextest" + probe='/sdcard/nextest.probe' + log='/sdcard/nextest.log' + # We need to install nextest via cargo currently, since there is no pre-built binary for android x86 + command="'cargo install cargo-nextest &> $log; touch $probe'" + run_termux_command "$command" "$probe" + + adb pull "$log" . + cat $(basename "$log") + + echo "Info about cargo and rust" + probe='/sdcard/info.probe' + log='/sdcard/info.log' + command="'{ \ + set -x; \ + echo \$HOME; \ + PATH=\$HOME/.cargo/bin:\$PATH; \ + export PATH; \ + echo \$PATH; \ + pwd; \ + command -v rustc && rustc --version; \ + ls -la ~/.cargo/bin; \ + cargo --list; \ + cargo nextest --version; \ + set +x; \ + } &> $log; touch $probe'" run_termux_command "$command" "$probe" + + adb pull "$log" . + cat $(basename "$log") + echo "snapshot complete" adb shell input text "exit" && hit_enter && hit_enter } @@ -120,8 +161,15 @@ build () { tests () { probe='/sdcard/tests.probe' - export RUST_BACKTRACE=1 - command="'cd ~/coreutils && timeout --preserve-status --verbose -k 1m 60m cargo test --features feat_os_unix_android --no-fail-fast >/sdcard/tests.log 2>&1; echo \$? >$probe'" + command="'\ + export PATH=\$HOME/.cargo/bin:\$PATH; \ + export RUST_BACKTRACE=1; \ + export CARGO_TERM_COLOR=always; \ + cd ~/coreutils || { echo 1 > $probe; exit; }; \ + timeout --preserve-status --verbose -k 1m 60m \ + cargo nextest run --profile ci --hide-progress-bar --features feat_os_unix_android \ + &>/sdcard/tests.log; \ + echo \$? >$probe'" run_termux_command "$command" "$probe" return_code=$? adb pull /sdcard/tests.log . From 037aaf0a3679914994533cdd5fddb82468ac4531 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Fri, 14 Apr 2023 19:23:43 +0200 Subject: [PATCH 145/477] android-commands.sh: Reformat file with shftm --- util/android-commands.sh | 56 +++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/util/android-commands.sh b/util/android-commands.sh index 02999f5da9..5d6039413c 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -14,12 +14,11 @@ # success, some other number for errors (an empty file is basically the same as # 0). Note that the return codes are text, not raw bytes. - this_repo="$(dirname $(dirname -- "$(readlink -- "${0}")"))" -help () { +help() { echo \ -"Usage: $0 COMMAND [ARG] + "Usage: $0 COMMAND [ARG] where COMMAND is one of: snapshot APK install APK and dependencies on an emulator to prep a snapshot @@ -43,7 +42,7 @@ hit_enter() { launch_termux() { echo "launching termux" - if ! adb shell 'am start -n com.termux/.HomeActivity' ; then + if ! adb shell 'am start -n com.termux/.HomeActivity'; then echo "failed to launch termux" exit 1 fi @@ -58,18 +57,21 @@ launch_termux() { } run_termux_command() { - command="$1" # text of the escaped command, including creating the probe! - probe="$2" # unique file that indicates the command is complete + command="$1" # text of the escaped command, including creating the probe! + probe="$2" # unique file that indicates the command is complete launch_termux adb shell input text "$command" && hit_enter - while ! adb shell "ls $probe" 2>/dev/null; do echo "waiting for $probe"; sleep 30; done + while ! adb shell "ls $probe" 2>/dev/null; do + echo "waiting for $probe" + sleep 30 + done return_code=$(adb shell "cat $probe") adb shell "rm $probe" echo "return code: $return_code" return $return_code } -snapshot () { +snapshot() { apk="$1" echo "running snapshot" adb install -g "$apk" @@ -121,7 +123,7 @@ snapshot () { adb shell input text "exit" && hit_enter && hit_enter } -sync () { +sync() { repo="$1" echo "running sync $1" # android doesn't allow symlinks on shared dirs, and adb can't selectively push files @@ -148,7 +150,7 @@ sync () { run_termux_command "$command" "$probe" } -build () { +build() { probe='/sdcard/build.probe' command="'cd ~/coreutils && cargo build --features feat_os_unix_android 2>/sdcard/build.log; echo \$? >$probe'" echo "running build" @@ -159,7 +161,7 @@ build () { return $return_code } -tests () { +tests() { probe='/sdcard/tests.probe' command="'\ export PATH=\$HOME/.cargo/bin:\$PATH; \ @@ -182,16 +184,34 @@ exit_code=0 if [ $# -eq 1 ]; then case "$1" in - sync) sync "$this_repo"; exit_code=$?;; - build) build; exit_code=$?;; - tests) tests; exit_code=$?;; - *) help;; + sync) + sync "$this_repo" + exit_code=$? + ;; + build) + build + exit_code=$? + ;; + tests) + tests + exit_code=$? + ;; + *) help ;; esac elif [ $# -eq 2 ]; then case "$1" in - snapshot) snapshot "$2"; exit_code=$?;; - sync) sync "$2"; exit_code=$?;; - *) help; exit 1;; + snapshot) + snapshot "$2" + exit_code=$? + ;; + sync) + sync "$2" + exit_code=$? + ;; + *) + help + exit 1 + ;; esac else help From 18d5e9a3bb287ded426b28e4597e499693540906 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 15 Apr 2023 10:30:43 +0200 Subject: [PATCH 146/477] Update CONTRIBUTING.md: Add nextest usage examples --- CONTRIBUTING.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8199b6d87d..8f66b2bba8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ - + # Contributing to coreutils @@ -137,6 +137,14 @@ If you also want to test the core utilities: cargo test -p uucore -p coreutils ``` +Running the complete test suite might take a while. We use [nextest](https://nexte.st/index.html) in +the CI and you might want to try it out locally. It can speed up the execution time of the whole +test run significantly if the cpu has multiple cores. + +```shell +cargo nextest run --features unix --no-fail-fast +``` + To debug: ```shell @@ -171,6 +179,15 @@ To include tests for unimplemented behavior: make UTILS='UTILITY_1 UTILITY_2' SPEC=y test ``` +To run tests with `nextest` just use the nextest target. Note you'll need to +[install](https://nexte.st/book/installation.html) `nextest` first. The `nextest` target accepts the +same arguments like the default `test` target, so it's possible to pass arguments to `nextest run` +via `CARGOFLAGS`: + +```shell +make CARGOFLAGS='--no-fail-fast' UTILS='UTILITY_1 UTILITY_2' nextest +``` + ### Run Busybox Tests This testing functionality is only available on *nix operating systems and @@ -326,7 +343,6 @@ if changes are not reflected in the report then run `cargo clean` and run the ab If you are using stable version of Rust that doesn't enable code coverage instrumentation by default then add `-Z-Zinstrument-coverage` flag to `RUSTFLAGS` env variable specified above. - ## Other implementations The Coreutils have different implementations, with different levels of completions: @@ -339,10 +355,9 @@ The Coreutils have different implementations, with different levels of completio * [SerenityOS](https://github.com/SerenityOS/serenity/tree/master/Userland/Utilities) * [Initial Unix](https://github.com/dspinellis/unix-history-repo) -However, when reimplementing the tools/options in Rust, don't read their source codes +However, when reimplementing the tools/options in Rust, don't read their source codes when they are using reciprocal licenses (ex: GNU GPL, GNU LGPL, etc). - ## Licensing uutils is distributed under the terms of the MIT License; see the `LICENSE` file From 3495b82499a0cdfb782f300016428709a8bbb803 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 15 Apr 2023 13:22:51 +0200 Subject: [PATCH 147/477] ci/android: Use different caching strategy --- .github/workflows/android.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 06c39f961f..97e1e60f1d 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -32,15 +32,15 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - - name: AVD cache - uses: actions/cache@v3 + - name: Restore AVD cache + uses: actions/cache/restore@v3 id: avd-cache with: path: | ~/.android/avd/* ~/.android/avd/*/snapshots/* ~/.android/adb* - key: avd-${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }} + key: avd-${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }}+nextest - name: Create and cache emulator image if: steps.avd-cache.outputs.cache-hit != 'true' uses: reactivecircus/android-emulator-runner@v2 @@ -53,11 +53,21 @@ jobs: force-avd-creation: true emulator-options: -no-snapshot-load -noaudio -no-boot-anim -camera-back none script: | + set -e wget https://github.com/termux/termux-app/releases/download/${{ env.TERMUX }}/termux-app_${{ env.TERMUX }}+github-debug_${{ matrix.arch }}.apk util/android-commands.sh snapshot termux-app_${{ env.TERMUX }}+github-debug_${{ matrix.arch }}.apk adb -s emulator-5554 emu avd snapshot save ${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }} echo "Emulator image created." pkill -9 qemu-system-x86_64 + - name: Save AVD cache + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v3 + with: + path: | + ~/.android/avd/* + ~/.android/avd/*/snapshots/* + ~/.android/adb* + key: avd-${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }}+nextest - name: Build and Test uses: reactivecircus/android-emulator-runner@v2 with: From 72041568e71fd28842e23c92ff05f898e6d78382 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 20 Apr 2023 15:22:26 +0200 Subject: [PATCH 148/477] fmt: cleanup tests --- tests/by-util/test_fmt.rs | 62 +++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 35 deletions(-) diff --git a/tests/by-util/test_fmt.rs b/tests/by-util/test_fmt.rs index 316add0386..afce9acd8d 100644 --- a/tests/by-util/test_fmt.rs +++ b/tests/by-util/test_fmt.rs @@ -7,47 +7,39 @@ fn test_invalid_arg() { #[test] fn test_fmt() { - let result = new_ucmd!().arg("one-word-per-line.txt").run(); - //.stdout_is_fixture("call_graph.expected"); - assert_eq!( - result.stdout_str().trim(), - "this is a file with one word per line" - ); + new_ucmd!() + .arg("one-word-per-line.txt") + .succeeds() + .stdout_is("this is a file with one word per line\n"); } #[test] -fn test_fmt_q() { - let result = new_ucmd!().arg("-q").arg("one-word-per-line.txt").run(); - //.stdout_is_fixture("call_graph.expected"); - assert_eq!( - result.stdout_str().trim(), - "this is a file with one word per line" - ); +fn test_fmt_quick() { + for param in ["-q", "--quick"] { + new_ucmd!() + .args(&["one-word-per-line.txt", param]) + .succeeds() + .stdout_is("this is a file with one word per line\n"); + } } #[test] -fn test_fmt_w_too_big() { - let result = new_ucmd!() - .arg("-w") - .arg("2501") - .arg("one-word-per-line.txt") - .run(); - //.stdout_is_fixture("call_graph.expected"); - assert_eq!( - result.stderr_str().trim(), - "fmt: invalid width: '2501': Numerical result out of range" - ); +fn test_fmt_width() { + for param in ["-w", "--width"] { + new_ucmd!() + .args(&["one-word-per-line.txt", param, "10"]) + .succeeds() + .stdout_is("this is\na file\nwith one\nword per\nline\n"); + } } + #[test] -fn test_fmt_w() { - let result = new_ucmd!() - .arg("-w") - .arg("10") - .arg("one-word-per-line.txt") - .run(); - //.stdout_is_fixture("call_graph.expected"); - assert_eq!( - result.stdout_str().trim(), - "this is\na file\nwith one\nword per\nline" - ); +fn test_fmt_width_too_big() { + for param in ["-w", "--width"] { + new_ucmd!() + .args(&["one-word-per-line.txt", param, "2501"]) + .fails() + .code_is(1) + .stderr_is("fmt: invalid width: '2501': Numerical result out of range\n"); + } } From c571a314055266f11465548fd2077a49d7a6e91d Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 20 Apr 2023 16:44:50 +0200 Subject: [PATCH 149/477] GNU/coreutils: update reference to 9.3 --- .github/workflows/GnuTests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 790bcce3ff..894e29ea8a 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -42,7 +42,7 @@ jobs: outputs path_GNU path_GNU_tests path_reference path_UUTILS # repo_default_branch="${{ github.event.repository.default_branch }}" - repo_GNU_ref="v9.2" + repo_GNU_ref="v9.3" repo_reference_branch="${{ github.event.repository.default_branch }}" outputs repo_default_branch repo_GNU_ref repo_reference_branch # @@ -315,7 +315,7 @@ jobs: with: repository: 'coreutils/coreutils' path: 'gnu' - ref: 'v9.2' + ref: 'v9.3' submodules: recursive - name: Install `rust` toolchain run: | From f155185df699fefe0581565d3df82210ae1d782e Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sun, 16 Apr 2023 13:33:56 +0200 Subject: [PATCH 150/477] util/android-commands: Fix shellcheck warnings. Reformat file. --- util/android-commands.sh | 70 ++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/util/android-commands.sh b/util/android-commands.sh index 5d6039413c..a0f662aacd 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -14,7 +14,7 @@ # success, some other number for errors (an empty file is basically the same as # 0). Note that the return codes are text, not raw bytes. -this_repo="$(dirname $(dirname -- "$(readlink -- "${0}")"))" +this_repo="$(dirname "$(dirname -- "$(readlink -- "${0}")")")" help() { echo \ @@ -68,7 +68,7 @@ run_termux_command() { return_code=$(adb shell "cat $probe") adb shell "rm $probe" echo "return code: $return_code" - return $return_code + return "$return_code" } snapshot() { @@ -84,7 +84,7 @@ snapshot() { return_code=$? adb pull "$log" . - cat $(basename "$log") + cat "$(basename "$log")" if [[ $return_code -ne 0 ]]; then return $return_code; fi @@ -96,7 +96,7 @@ snapshot() { run_termux_command "$command" "$probe" adb pull "$log" . - cat $(basename "$log") + cat "$(basename "$log")" echo "Info about cargo and rust" probe='/sdcard/info.probe' @@ -117,7 +117,7 @@ snapshot() { run_termux_command "$command" "$probe" adb pull "$log" . - cat $(basename "$log") + cat "$(basename "$log")" echo "snapshot complete" adb shell input text "exit" && hit_enter && hit_enter @@ -129,21 +129,21 @@ sync() { # android doesn't allow symlinks on shared dirs, and adb can't selectively push files symlinks=$(find "$repo" -type l) # dash doesn't support process substitution :( - echo $symlinks | sort >symlinks + echo "$symlinks" | sort >symlinks git -C "$repo" diff --name-status | cut -f 2 >modified modified_links=$(join symlinks modified) - if [ ! -z "$modified_links" ]; then + if [ -n "$modified_links" ]; then echo "You have modified symlinks. Either stash or commit them, then try again: $modified_links" exit 1 fi - if ! git ls-files --error-unmatch $symlinks >/dev/null; then + if ! git ls-files --error-unmatch "$symlinks" >/dev/null; then echo "You have untracked symlinks. Either remove or commit them, then try again." exit 1 fi - rm $symlinks + rm "$symlinks" # adb's shell user only has access to shared dirs... adb push "$repo" /sdcard/coreutils - git -C "$repo" checkout $symlinks + git -C "$repo" checkout "$symlinks" # ...but shared dirs can't build, so move it home as termux probe='/sdcard/mv.probe' command="'cp -r /sdcard/coreutils ~/; touch $probe'" @@ -184,34 +184,34 @@ exit_code=0 if [ $# -eq 1 ]; then case "$1" in - sync) - sync "$this_repo" - exit_code=$? - ;; - build) - build - exit_code=$? - ;; - tests) - tests - exit_code=$? - ;; - *) help ;; + sync) + sync "$this_repo" + exit_code=$? + ;; + build) + build + exit_code=$? + ;; + tests) + tests + exit_code=$? + ;; + *) help ;; esac elif [ $# -eq 2 ]; then case "$1" in - snapshot) - snapshot "$2" - exit_code=$? - ;; - sync) - sync "$2" - exit_code=$? - ;; - *) - help - exit 1 - ;; + snapshot) + snapshot "$2" + exit_code=$? + ;; + sync) + sync "$2" + exit_code=$? + ;; + *) + help + exit 1 + ;; esac else help From 56d8b5a617cd3b169d0604874a064553f8f5efec Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Tue, 18 Apr 2023 23:14:07 +0200 Subject: [PATCH 151/477] ci/android: Remove caching with Swatinem/rust-cache and sccache. --- .github/workflows/android.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 97e1e60f1d..33b914bc37 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -1,6 +1,6 @@ name: Android -# spell-checker:ignore TERMUX reactivecircus Swatinem noaudio pkill swiftshader +# spell-checker:ignore TERMUX reactivecircus Swatinem noaudio pkill swiftshader dtolnay juliangruber on: [push, pull_request] @@ -25,13 +25,8 @@ jobs: arch: [x86] # , arm64-v8a env: TERMUX: v0.118.0 - SCCACHE_GHA_ENABLED: "true" - RUSTC_WRAPPER: "sccache" steps: - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@v2 - - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 - name: Restore AVD cache uses: actions/cache/restore@v3 id: avd-cache From ad5d33f1a9f7e5774901573ff8388017c1c93150 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Wed, 19 Apr 2023 16:08:48 +0200 Subject: [PATCH 152/477] ci/android: Fix and improve caching. Fix and improve android-commands.sh --- .github/workflows/android.yml | 43 +++- util/android-commands.sh | 373 ++++++++++++++++++++++++++-------- 2 files changed, 318 insertions(+), 98 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 33b914bc37..a6929b171c 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -35,7 +35,8 @@ jobs: ~/.android/avd/* ~/.android/avd/*/snapshots/* ~/.android/adb* - key: avd-${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }}+nextest + ~/__rustc_hash__ + key: avd-${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }}+nextest+rustc-hash - name: Create and cache emulator image if: steps.avd-cache.outputs.cache-hit != 'true' uses: reactivecircus/android-emulator-runner@v2 @@ -44,16 +45,11 @@ jobs: target: ${{ matrix.target }} arch: ${{ matrix.arch }} ram-size: 2048M - disk-size: 5120M + disk-size: 7GB force-avd-creation: true emulator-options: -no-snapshot-load -noaudio -no-boot-anim -camera-back none script: | - set -e - wget https://github.com/termux/termux-app/releases/download/${{ env.TERMUX }}/termux-app_${{ env.TERMUX }}+github-debug_${{ matrix.arch }}.apk - util/android-commands.sh snapshot termux-app_${{ env.TERMUX }}+github-debug_${{ matrix.arch }}.apk - adb -s emulator-5554 emu avd snapshot save ${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }} - echo "Emulator image created." - pkill -9 qemu-system-x86_64 + util/android-commands.sh init "${{ matrix.arch }}" "${{ matrix.api-level }}" "${{ env.TERMUX }}" - name: Save AVD cache if: steps.avd-cache.outputs.cache-hit != 'true' uses: actions/cache/save@v3 @@ -62,7 +58,22 @@ jobs: ~/.android/avd/* ~/.android/avd/*/snapshots/* ~/.android/adb* - key: avd-${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }}+nextest + ~/__rustc_hash__ + key: avd-${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }}+nextest+rustc-hash + - uses: juliangruber/read-file-action@v1 + id: read_rustc_hash + with: + # ~ expansion didn't work + path: /Users/runner/__rustc_hash__ + trim: true + - name: Restore rust cache + id: rust-cache + uses: actions/cache/restore@v3 + with: + path: ~/__rust_cache__ + # The version vX at the end of the key is just a development version to avoid conflicts in + # the github cache during the development of this workflow + key: ${{ matrix.arch }}_${{ matrix.target}}_${{ steps.read_rustc_hash.outputs.content }}_${{ hashFiles('**/Cargo.toml', '**/Cargo.lock') }}_v3 - name: Build and Test uses: reactivecircus/android-emulator-runner@v2 with: @@ -70,10 +81,20 @@ jobs: target: ${{ matrix.target }} arch: ${{ matrix.arch }} ram-size: 2048M - disk-size: 5120M + disk-size: 7GB force-avd-creation: false emulator-options: -no-snapshot-save -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -snapshot ${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }} + # This is not a usual script. Every line is executed in a separate shell with `sh -c`. If + # one of the lines returns with error the whole script is failed (like running a script with + # set -e) and in consequences the other lines (shells) are not executed. script: | - util/android-commands.sh sync + util/android-commands.sh sync_host util/android-commands.sh build util/android-commands.sh tests + if [[ "${{ steps.rust-cache.outputs.cache-hit }}" != 'true' ]]; then util/android-commands.sh sync_image; fi; exit 0 + - name: Save rust cache + if: steps.rust-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v3 + with: + path: ~/__rust_cache__ + key: ${{ matrix.arch }}_${{ matrix.target}}_${{ steps.read_rustc_hash.outputs.content }}_${{ hashFiles('**/Cargo.toml', '**/Cargo.lock') }}_v3 diff --git a/util/android-commands.sh b/util/android-commands.sh index a0f662aacd..ae57962432 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -1,5 +1,5 @@ #!/bin/bash -# spell-checker:ignore termux keyevent sdcard binutils unmatch adb's dumpsys logcat pkill nextest +# spell-checker:ignore termux keyevent sdcard binutils unmatch adb's dumpsys logcat pkill nextest logfile # There are three shells: the host's, adb, and termux. Only adb lets us run # commands directly on the emulated device, only termux provides a GNU @@ -8,29 +8,36 @@ # This means that the commands sent to termux are first parsed as arguments in # this shell, then as arguments in the adb shell, before finally being used as # text inputs to the app. Hence, the "'wrapping'" on those commands. -# There's no way to get any feedback from termux, so every time we run a -# command on it, we make sure it ends by creating a unique *.probe file at the -# end of the command. The contents of the file are used as a return code: 0 on -# success, some other number for errors (an empty file is basically the same as -# 0). Note that the return codes are text, not raw bytes. +# There's no way to get any direct feedback from termux, so every time we run a +# command on it, we make sure it creates a unique *.probe file which is polled +# every 30 seconds together with the current output of the command in a *.log file. +# The contents of the probe file are used as a return code: 0 on success, some +# other number for errors (an empty file is basically the same as 0). Note that +# the return codes are text, not raw bytes. this_repo="$(dirname "$(dirname -- "$(readlink -- "${0}")")")" +cache_dir_name="__rust_cache__" help() { echo \ "Usage: $0 COMMAND [ARG] where COMMAND is one of: + init download termux and initialize the emulator image snapshot APK install APK and dependencies on an emulator to prep a snapshot (you can, but probably don't want to, run this for physical devices -- just set up termux and the dependencies yourself) - sync [REPO] push the repo at REPO to the device, deleting and restoring all - symlinks (locally) in the process; by default, REPO is: + sync_host [REPO] + push the repo at REPO to the device, deleting and restoring all symlinks (locally) + in the process; The cached rust directories are restored, too; by default, REPO is: $this_repo + sync_image [REPO] + copy the repo/target and the HOME/.cargo directories from the device back to the + host; by default, REPO is: $this_repo build run \`cargo build --features feat_os_unix_android\` on the - device, then pull the output as build.log + device tests run \`cargo test --features feat_os_unix_android\` on the - device, then pull the output as tests.log + device If you have multiple devices, use the ANDROID_SERIAL environment variable to specify which to connect to." @@ -40,6 +47,10 @@ hit_enter() { adb shell input keyevent 66 } +exit_termux() { + adb shell input text "exit" && hit_enter && hit_enter +} + launch_termux() { echo "launching termux" if ! adb shell 'am start -n com.termux/.HomeActivity'; then @@ -56,127 +67,295 @@ launch_termux() { adb shell 'rm /sdcard/launch.probe' && echo "removed launch.probe" } +# Usage: run_termux_command +# +# Runs the command specified in $1 in a termux shell, polling for the probe specified in $2 (and the +# current output). If polling the probe succeeded the command is considered to have finished. This +# method prints the current stdout and stderr of the command every SLEEP_INTERVAL seconds and +# finishes a command run with a summary. It returns with the exit code of the probe if specified as +# file content of the probe. +# +# Positional arguments +# $1 The command to execute in the termux shell +# $2 The path to the probe. The file name must end with `.probe` +# +# It's possible to overwrite settings by specifying the setting the variable before calling this +# method (Default in parentheses): +# keep_log 0|1 Keeps the logs after running the command if set to 1. The log file name is +# derived from the probe file name (the last component of the path) and +# `.probe` replaced with `.log. (0) +# debug 0|1 Adds additional debugging output to the log file if set to 1. (1) +# timeout SECONDS The timeout in full SECONDS for the command to complete before giving up. (3600) +# retries RETRIES The number of retries for trying to fix possible issues when we're not receiving +# any progress from the emulator. (3) +# sleep_interval +# SECONDS The time interval in full SECONDS between polls for the probe and the current +# output. (5) run_termux_command() { - command="$1" # text of the escaped command, including creating the probe! - probe="$2" # unique file that indicates the command is complete + # shellcheck disable=SC2155 + local command="$(echo "$1" | sed -E "s/^['](.*)[']$/\1/")" # text of the escaped command, including creating the probe! + local probe="$2" # unique file that indicates the command is complete + local keep_log=${keep_log:-0} + local debug=${debug:-1} + + log_name="$(basename -s .probe "${probe}").log" # probe name must have suffix .probe + log_file="/sdcard/${log_name}" + log_read="${log_name}.read" + echo 0 >"${log_read}" + if [[ $debug -eq 1 ]]; then + shell_command="'set -x; { ${command}; } &> ${log_file}; set +x'" + else + shell_command="'{ ${command}; } &> ${log_file}'" + fi + launch_termux - adb shell input text "$command" && hit_enter + echo "Running command: ${command}" + start=$(date +%s) + adb shell input text "$shell_command" && sleep 3 && hit_enter + # just for safety wait a little bit before polling for the probe and the log file + sleep 5 + + local timeout=${timeout:-3600} + local retries=${retries:-3} + local sleep_interval=${sleep_interval:-5} + try_fix=3 while ! adb shell "ls $probe" 2>/dev/null; do - echo "waiting for $probe" - sleep 30 + echo -n "Waiting for $probe: " + + if [[ -e "$log_name" ]]; then + rm "$log_name" + fi + + adb pull "$log_file" . || try_fix=$((try_fix - 1)) + if [[ -e "$log_name" ]]; then + tail -n +"$(<"$log_read")" "$log_name" + echo + wc -l <"${log_name}" | tr -d "[:space:]" >"$log_read" + fi + + if [[ retries -le 0 ]]; then + echo "Maximum retries reached running command. Aborting ..." + return 1 + elif [[ try_fix -le 0 ]]; then + retries=$((retries - 1)) + try_fix=3 + # Since there is no output, there is no way to know what is happening inside. See if + # hitting the enter key solves the issue, sometimes the github runner is just a little + # bit slow. + echo "No output received. Trying to fix the issue ... (${retries} retries left)" + hit_enter + fi + + sleep "$sleep_interval" + timeout=$((timeout - sleep_interval)) + + if [[ $timeout -le 0 ]]; then + echo "Timeout reached running command. Aborting ..." + return 1 + fi done - return_code=$(adb shell "cat $probe") - adb shell "rm $probe" - echo "return code: $return_code" - return "$return_code" + end=$(date +%s) + + return_code=$(adb shell "cat $probe") || return_code=0 + adb shell "rm ${probe}" + + adb pull "$log_file" . + echo "==================================== SUMMARY ===================================" + echo "Command: ${command}" + echo "Finished in $((end - start)) seconds." + echo "Output was:" + cat "$log_name" + echo "Return code: $return_code" + echo "================================================================================" + + adb shell "rm ${log_file}" + [[ $keep_log -ne 1 ]] && rm -f "$log_name" + rm -f "$log_read" "$probe" + + # shellcheck disable=SC2086 + return $return_code +} + +init() { + arch="$1" + api_level="$2" + termux="$3" + + # shellcheck disable=SC2015 + wget "https://github.com/termux/termux-app/releases/download/${termux}/termux-app_${termux}+github-debug_${arch}.apk" && + snapshot "termux-app_${termux}+github-debug_${arch}.apk" && + hash_rustc && + exit_termux && + adb -s emulator-5554 emu avd snapshot save "${api_level}-${arch}+termux-${termux}" && + echo "Emulator image created." || { + pkill -9 qemu-system-x86_64 + return 1 + } + pkill -9 qemu-system-x86_64 || true } snapshot() { apk="$1" - echo "running snapshot" + echo "Running snapshot" adb install -g "$apk" echo "Prepare and install system packages" probe='/sdcard/pkg.probe' - log='/sdcard/pkg.log' - command="'{ mkdir -vp ~/.cargo/bin; yes | pkg install rust binutils openssl -y; echo \$? > $probe; } &> $log'" - run_termux_command "$command" "$probe" - return_code=$? - - adb pull "$log" . - cat "$(basename "$log")" - - if [[ $return_code -ne 0 ]]; then return $return_code; fi + command="'mkdir -vp ~/.cargo/bin; yes | pkg install rust binutils openssl tar -y; echo \$? > $probe'" + run_termux_command "$command" "$probe" || return echo "Installing cargo-nextest" probe='/sdcard/nextest.probe' - log='/sdcard/nextest.log' # We need to install nextest via cargo currently, since there is no pre-built binary for android x86 - command="'cargo install cargo-nextest &> $log; touch $probe'" + command="'\ +export CARGO_TERM_COLOR=always; \ +cargo install cargo-nextest; \ +echo \$? > $probe'" run_termux_command "$command" "$probe" - - adb pull "$log" . - cat "$(basename "$log")" + return_code=$? echo "Info about cargo and rust" probe='/sdcard/info.probe' - log='/sdcard/info.log' - command="'{ \ - set -x; \ - echo \$HOME; \ - PATH=\$HOME/.cargo/bin:\$PATH; \ - export PATH; \ - echo \$PATH; \ - pwd; \ - command -v rustc && rustc --version; \ - ls -la ~/.cargo/bin; \ - cargo --list; \ - cargo nextest --version; \ - set +x; \ - } &> $log; touch $probe'" + command="'echo \$HOME; \ +PATH=\$HOME/.cargo/bin:\$PATH; \ +export PATH; \ +echo \$PATH; \ +pwd; \ +command -v rustc && rustc -Vv; \ +ls -la ~/.cargo/bin; \ +cargo --list; \ +cargo nextest --version; \ +touch $probe'" run_termux_command "$command" "$probe" - adb pull "$log" . - cat "$(basename "$log")" - - echo "snapshot complete" - adb shell input text "exit" && hit_enter && hit_enter + echo "Snapshot complete" + # shellcheck disable=SC2086 + return $return_code } -sync() { +sync_host() { repo="$1" - echo "running sync $1" + cache_home="${HOME}/${cache_dir_name}" + cache_dest="/sdcard/${cache_dir_name}" + + echo "Running sync host -> image: ${repo}" + # android doesn't allow symlinks on shared dirs, and adb can't selectively push files symlinks=$(find "$repo" -type l) # dash doesn't support process substitution :( echo "$symlinks" | sort >symlinks + git -C "$repo" diff --name-status | cut -f 2 >modified modified_links=$(join symlinks modified) if [ -n "$modified_links" ]; then echo "You have modified symlinks. Either stash or commit them, then try again: $modified_links" exit 1 fi - if ! git ls-files --error-unmatch "$symlinks" >/dev/null; then + #shellcheck disable=SC2086 + if ! git ls-files --error-unmatch $symlinks >/dev/null; then echo "You have untracked symlinks. Either remove or commit them, then try again." exit 1 fi - rm "$symlinks" + + #shellcheck disable=SC2086 + rm $symlinks # adb's shell user only has access to shared dirs... - adb push "$repo" /sdcard/coreutils - git -C "$repo" checkout "$symlinks" + adb push -a "$repo" /sdcard/coreutils + [[ -e "$cache_home" ]] && adb push -a "$cache_home" "$cache_dest" + + #shellcheck disable=SC2086 + git -C "$repo" checkout $symlinks + # ...but shared dirs can't build, so move it home as termux - probe='/sdcard/mv.probe' - command="'cp -r /sdcard/coreutils ~/; touch $probe'" - run_termux_command "$command" "$probe" + probe='/sdcard/sync.probe' + command="'mv /sdcard/coreutils ~/; \ +cd ~/coreutils; \ +if [[ -e ${cache_dest} ]]; then \ +rm -rf ~/.cargo ./target; \ +tar xzf ${cache_dest}/cargo.tgz -C ~/; \ +ls -la ~/.cargo; \ +tar xzf ${cache_dest}/target.tgz; \ +ls -la ./target; \ +rm -rf ${cache_dest}; \ +fi; \ +touch $probe'" + run_termux_command "$command" "$probe" || return + + echo "Finished sync host -> image: ${repo}" +} + +sync_image() { + repo="$1" + cache_home="${HOME}/${cache_dir_name}" + cache_dest="/sdcard/${cache_dir_name}" + + echo "Running sync image -> host: ${repo}" + + probe='/sdcard/cache.probe' + command="'rm -rf /sdcard/coreutils ${cache_dest}; \ +mkdir -p ${cache_dest}; \ +cd ${cache_dest}; \ +tar czf cargo.tgz -C ~/ .cargo; \ +tar czf target.tgz -C ~/coreutils target; \ +ls -la ${cache_dest}; \ +echo \$? > ${probe}'" + run_termux_command "$command" "$probe" || return + + rm -rf "$cache_home" + adb pull -a "$cache_dest" "$cache_home" || return + + echo "Finished sync image -> host: ${repo}" } build() { + echo "Running build" + probe='/sdcard/build.probe' - command="'cd ~/coreutils && cargo build --features feat_os_unix_android 2>/sdcard/build.log; echo \$? >$probe'" - echo "running build" - run_termux_command "$command" "$probe" - return_code=$? - adb pull /sdcard/build.log . - cat build.log - return $return_code + command="'export CARGO_TERM_COLOR=always; \ +export CARGO_INCREMENTAL=0; \ +cd ~/coreutils && cargo build --features feat_os_unix_android; \ +echo \$? >$probe'" + run_termux_command "$command" "$probe" || return + + echo "Finished build" } tests() { + echo "Running tests" + probe='/sdcard/tests.probe' - command="'\ - export PATH=\$HOME/.cargo/bin:\$PATH; \ - export RUST_BACKTRACE=1; \ - export CARGO_TERM_COLOR=always; \ - cd ~/coreutils || { echo 1 > $probe; exit; }; \ - timeout --preserve-status --verbose -k 1m 60m \ - cargo nextest run --profile ci --hide-progress-bar --features feat_os_unix_android \ - &>/sdcard/tests.log; \ - echo \$? >$probe'" - run_termux_command "$command" "$probe" - return_code=$? - adb pull /sdcard/tests.log . - cat tests.log - return $return_code + command="'export PATH=\$HOME/.cargo/bin:\$PATH; \ +export RUST_BACKTRACE=1; \ +export CARGO_TERM_COLOR=always; \ +export CARGO_INCREMENTAL=0; \ +cd ~/coreutils; \ +timeout --preserve-status --verbose -k 1m 60m \ + cargo nextest run --profile ci --hide-progress-bar --features feat_os_unix_android; \ +echo \$? >$probe'" + run_termux_command "$command" "$probe" || return + + echo "Finished tests" +} + +hash_rustc() { + probe='/sdcard/rustc.probe' + tmp_hash="__rustc_hash__.tmp" + hash="__rustc_hash__" + + echo "Hashing rustc version: ${HOME}/${hash}" + + command="'rustc -Vv; echo \$? > ${probe}'" + keep_log=1 + debug=0 + run_termux_command "$command" "$probe" || return + rm -f "$tmp_hash" + mv "rustc.log" "$tmp_hash" || return + # sha256sum is not available. shasum is the macos native program. + shasum -a 256 "$tmp_hash" | cut -f 1 -d ' ' | tr -d '[:space:]' >"${HOME}/${hash}" || return + + rm -f "$tmp_hash" + + echo "Finished hashing rustc version: ${HOME}/${hash}" } #adb logcat & @@ -184,8 +363,12 @@ exit_code=0 if [ $# -eq 1 ]; then case "$1" in - sync) - sync "$this_repo" + sync_host) + sync_host "$this_repo" + exit_code=$? + ;; + sync_image) + sync_image "$this_repo" exit_code=$? ;; build) @@ -204,8 +387,24 @@ elif [ $# -eq 2 ]; then snapshot "$2" exit_code=$? ;; - sync) - sync "$2" + sync_host) + sync_host "$2" + exit_code=$? + ;; + sync_image) + sync_image "$2" + exit_code=$? + ;; + *) + help + exit 1 + ;; + esac +elif [ $# -eq 4 ]; then + case "$1" in + init) + shift + init "$@" exit_code=$? ;; *) From 790958e4f38cb88550600276ba17aa7a85b428d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Apr 2023 17:09:10 +0000 Subject: [PATCH 153/477] fix(deps): update rust crate libc to 0.2.142 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a073424cf8..0634e1ad9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1299,9 +1299,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.141" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libloading" diff --git a/Cargo.toml b/Cargo.toml index 719dfc327d..e3da0212a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -289,7 +289,7 @@ half = "2.2" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" -libc = "0.2.141" +libc = "0.2.142" lscolors = { version = "0.14.0", default-features=false, features = ["nu-ansi-term"] } memchr = "2" nix = { version="0.26", default-features=false } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 0dc247541e..669971a69f 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -32,7 +32,7 @@ time = { workspace=true, optional=true, features = ["formatting", "local-offset" data-encoding = { version="2.3", optional=true } data-encoding-macro = { version="0.1.12", optional=true } z85 = { version="3.0.5", optional=true } -libc = { version="0.2.141", optional=true } +libc = { version="0.2.142", optional=true } once_cell = { workspace=true } os_display = "0.1.3" From 47e61f064c0468e2e8d875b5aa24b1b23dc7126a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 20 Apr 2023 21:42:46 +0200 Subject: [PATCH 154/477] Fix a comment in the rustdoc --- tests/common/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/util.rs b/tests/common/util.rs index 5d72a7abfd..0898a4ad76 100644 --- a/tests/common/util.rs +++ b/tests/common/util.rs @@ -2016,7 +2016,7 @@ impl UChild { /// Read, consume and return the output as [`String`] from [`Child`]'s stdout. /// - /// See also [`UChild::stdout_bytes] for side effects. + /// See also [`UChild::stdout_bytes`] for side effects. pub fn stdout(&mut self) -> String { String::from_utf8(self.stdout_bytes()).unwrap() } From efa361dd7c2d39fb6f3eef702fe7f39d889f62d4 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 20 Apr 2023 23:00:46 +0200 Subject: [PATCH 155/477] Fix some trivial clippy warnings --- tests/by-util/test_cp.rs | 3 +-- tests/by-util/test_ls.rs | 4 ++-- tests/by-util/test_pwd.rs | 2 +- tests/by-util/test_tee.rs | 7 ++++--- tests/by-util/test_yes.rs | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index dfbbc1473a..12dd625c88 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1392,15 +1392,14 @@ fn test_cp_target_file_dev_null() { fn test_cp_one_file_system() { use crate::common::util::AtPath; use walkdir::WalkDir; - let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; // Test must be run as root (or with `sudo -E`) if scene.cmd("whoami").run().stdout_str() != "root\n" { return; } - let at = scene.fixtures.clone(); let at_src = AtPath::new(&at.plus(TEST_MOUNT_COPY_FROM_FOLDER)); let at_dst = AtPath::new(&at.plus(TEST_COPY_TO_FOLDER_NEW)); diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 1a189a25ad..f3f9c74cf5 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1239,7 +1239,7 @@ fn test_ls_long_total_size() { ("long_si", "total 8.2k"), ] .iter() - .cloned() + .copied() .collect() } else { [ @@ -1248,7 +1248,7 @@ fn test_ls_long_total_size() { ("long_si", "total 2"), ] .iter() - .cloned() + .copied() .collect() }; diff --git a/tests/by-util/test_pwd.rs b/tests/by-util/test_pwd.rs index 5719e87d24..076e72089a 100644 --- a/tests/by-util/test_pwd.rs +++ b/tests/by-util/test_pwd.rs @@ -27,7 +27,7 @@ fn test_deleted_dir() { use std::process::Command; let ts = TestScenario::new(util_name!()); - let at = ts.fixtures.clone(); + let at = ts.fixtures; let output = Command::new("sh") .arg("-c") .arg(format!( diff --git a/tests/by-util/test_tee.rs b/tests/by-util/test_tee.rs index 946c60d0ae..41751f2662 100644 --- a/tests/by-util/test_tee.rs +++ b/tests/by-util/test_tee.rs @@ -118,9 +118,10 @@ mod linux_only { use std::os::unix::io::FromRawFd; let mut fds: [c_int; 2] = [0, 0]; - if unsafe { libc::pipe(&mut fds as *mut c_int) } != 0 { - panic!("Failed to create pipe"); - } + assert!( + !(unsafe { libc::pipe(&mut fds as *mut c_int) } != 0), + "Failed to create pipe" + ); // Drop the read end of the pipe let _ = unsafe { File::from_raw_fd(fds[0]) }; diff --git a/tests/by-util/test_yes.rs b/tests/by-util/test_yes.rs index 9f03780b74..c054a6e5f3 100644 --- a/tests/by-util/test_yes.rs +++ b/tests/by-util/test_yes.rs @@ -6,12 +6,12 @@ use std::os::unix::process::ExitStatusExt; use crate::common::util::TestScenario; #[cfg(unix)] -fn check_termination(result: &ExitStatus) { +fn check_termination(result: ExitStatus) { assert_eq!(result.signal(), Some(libc::SIGPIPE)); } #[cfg(not(unix))] -fn check_termination(result: &ExitStatus) { +fn check_termination(result: ExitStatus) { assert!(result.success(), "yes did not exit successfully"); } @@ -23,7 +23,7 @@ fn run(args: &[&str], expected: &[u8]) { child.close_stdout(); #[allow(deprecated)] - check_termination(&child.wait_with_output().unwrap().status); + check_termination(child.wait_with_output().unwrap().status); assert_eq!(buf.as_slice(), expected); } From 98fb8fa1440c7f00369393a5310d3dc91b0c712a Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 21 Apr 2023 08:32:49 +0200 Subject: [PATCH 156/477] test,wc: use vars directly in format! strings --- src/uu/test/src/error.rs | 10 +++++----- src/uu/wc/src/utf8/read.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/uu/test/src/error.rs b/src/uu/test/src/error.rs index e9ab1c0822..ced4b216af 100644 --- a/src/uu/test/src/error.rs +++ b/src/uu/test/src/error.rs @@ -16,12 +16,12 @@ pub type ParseResult = Result; impl std::fmt::Display for ParseError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::Expected(s) => write!(f, "expected {}", s), + Self::Expected(s) => write!(f, "expected {s}"), Self::ExpectedValue => write!(f, "expected value"), - Self::MissingArgument(s) => write!(f, "missing argument after {}", s), - Self::ExtraArgument(s) => write!(f, "extra argument {}", s), - Self::UnknownOperator(s) => write!(f, "unknown operator {}", s), - Self::InvalidInteger(s) => write!(f, "invalid integer {}", s), + Self::MissingArgument(s) => write!(f, "missing argument after {s}"), + Self::ExtraArgument(s) => write!(f, "extra argument {s}"), + Self::UnknownOperator(s) => write!(f, "unknown operator {s}"), + Self::InvalidInteger(s) => write!(f, "invalid integer {s}"), } } } diff --git a/src/uu/wc/src/utf8/read.rs b/src/uu/wc/src/utf8/read.rs index 79b8ad8aeb..eb4684f7f6 100644 --- a/src/uu/wc/src/utf8/read.rs +++ b/src/uu/wc/src/utf8/read.rs @@ -28,9 +28,9 @@ impl<'a> fmt::Display for BufReadDecoderError<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { BufReadDecoderError::InvalidByteSequence(bytes) => { - write!(f, "invalid byte sequence: {:02x?}", bytes) + write!(f, "invalid byte sequence: {bytes:02x?}") } - BufReadDecoderError::Io(ref err) => write!(f, "underlying bytestream error: {}", err), + BufReadDecoderError::Io(ref err) => write!(f, "underlying bytestream error: {err}"), } } } From 3272d14fab0303b1a96aa924a6c85073dcb45899 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 21 Apr 2023 10:14:44 +0200 Subject: [PATCH 157/477] uudoc: fix clippy warnings --- src/bin/uudoc.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index 7d1a9cff55..02dafc98ae 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -178,7 +178,7 @@ impl<'a, 'b> MDWriter<'a, 'b> { fn usage(&mut self) -> io::Result<()> { if let Some(markdown) = &self.markdown { - let usage = help_parser::parse_usage(&markdown); + let usage = help_parser::parse_usage(markdown); let usage = usage.replace("{}", self.name); writeln!(self.w, "\n```")?; @@ -191,7 +191,7 @@ impl<'a, 'b> MDWriter<'a, 'b> { fn about(&mut self) -> io::Result<()> { if let Some(markdown) = &self.markdown { - writeln!(self.w, "{}", help_parser::parse_about(&markdown)) + writeln!(self.w, "{}", help_parser::parse_about(markdown)) } else { Ok(()) } @@ -199,7 +199,7 @@ impl<'a, 'b> MDWriter<'a, 'b> { fn after_help(&mut self) -> io::Result<()> { if let Some(markdown) = &self.markdown { - if let Some(after_help) = help_parser::parse_section("after help", &markdown) { + if let Some(after_help) = help_parser::parse_section("after help", markdown) { return writeln!(self.w, "\n\n{after_help}"); } } @@ -254,10 +254,10 @@ impl<'a, 'b> MDWriter<'a, 'b> { write!(self.w, "
")?; let mut first = true; for l in arg.get_long_and_visible_aliases().unwrap_or_default() { - if !first { - write!(self.w, ", ")?; - } else { + if first { first = false; + } else { + write!(self.w, ", ")?; } write!(self.w, "")?; write!(self.w, "--{}", l)?; @@ -275,10 +275,10 @@ impl<'a, 'b> MDWriter<'a, 'b> { write!(self.w, "")?; } for s in arg.get_short_and_visible_aliases().unwrap_or_default() { - if !first { - write!(self.w, ", ")?; - } else { + if first { first = false; + } else { + write!(self.w, ", ")?; } write!(self.w, "")?; write!(self.w, "-{}", s)?; From 7730c8171d0c43586314cb7920425fc908f9b6ef Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 21 Apr 2023 17:01:40 +0200 Subject: [PATCH 158/477] du: fix clippy warning in test --- tests/by-util/test_du.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index a965d3fc69..699746f03f 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -301,7 +301,7 @@ fn test_du_dereference_args() { let result = ts.ucmd().arg("-D").arg("-s").arg("sublink").succeeds(); let stdout = result.stdout_str(); - assert!(!stdout.starts_with("0")); + assert!(!stdout.starts_with('0')); assert!(stdout.contains("sublink")); // Without the option From e82ba6e7073fa1ff0cd3c42005cb4cecf70f075b Mon Sep 17 00:00:00 2001 From: m11o Date: Sat, 22 Apr 2023 16:10:26 +0900 Subject: [PATCH 159/477] readlink: move help strings to markdown file --- src/uu/readlink/readlink.md | 7 +++++++ src/uu/readlink/src/readlink.rs | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 src/uu/readlink/readlink.md diff --git a/src/uu/readlink/readlink.md b/src/uu/readlink/readlink.md new file mode 100644 index 0000000000..7215acbec0 --- /dev/null +++ b/src/uu/readlink/readlink.md @@ -0,0 +1,7 @@ +# readlink + +``` +readlink [OPTION]... [FILE]... +``` + +Print value of a symbolic link or canonical file name. diff --git a/src/uu/readlink/src/readlink.rs b/src/uu/readlink/src/readlink.rs index 8afb184be9..807f515d40 100644 --- a/src/uu/readlink/src/readlink.rs +++ b/src/uu/readlink/src/readlink.rs @@ -14,10 +14,10 @@ use std::path::{Path, PathBuf}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; use uucore::fs::{canonicalize, MissingHandling, ResolveMode}; -use uucore::{format_usage, show_error}; +use uucore::{format_usage, show_error, help_about, help_usage}; -const ABOUT: &str = "Print value of a symbolic link or canonical file name."; -const USAGE: &str = "{} [OPTION]... [FILE]..."; +const ABOUT: &str = help_about!("readlink.md"); +const USAGE: &str = help_usage!("readlink.md"); const OPT_CANONICALIZE: &str = "canonicalize"; const OPT_CANONICALIZE_MISSING: &str = "canonicalize-missing"; const OPT_CANONICALIZE_EXISTING: &str = "canonicalize-existing"; From b84a94b8895137819f5eda95db74dc16febba69c Mon Sep 17 00:00:00 2001 From: m11o Date: Sat, 22 Apr 2023 16:11:36 +0900 Subject: [PATCH 160/477] refactor: use override_help instead of override_usage --- src/uu/readlink/src/readlink.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/readlink/src/readlink.rs b/src/uu/readlink/src/readlink.rs index 807f515d40..0d6e9fc1b1 100644 --- a/src/uu/readlink/src/readlink.rs +++ b/src/uu/readlink/src/readlink.rs @@ -99,7 +99,7 @@ pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(crate_version!()) .about(ABOUT) - .override_help(format_usage(USAGE)) + .override_usage(format_usage(USAGE)) .infer_long_args(true) .arg( Arg::new(OPT_CANONICALIZE) From 31c1d9c956dac70f3b8ffe4a58d3426e9cf50678 Mon Sep 17 00:00:00 2001 From: m11o Date: Sat, 22 Apr 2023 16:33:58 +0900 Subject: [PATCH 161/477] fix format --- src/uu/readlink/src/readlink.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/readlink/src/readlink.rs b/src/uu/readlink/src/readlink.rs index 0d6e9fc1b1..e247c61469 100644 --- a/src/uu/readlink/src/readlink.rs +++ b/src/uu/readlink/src/readlink.rs @@ -14,7 +14,7 @@ use std::path::{Path, PathBuf}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; use uucore::fs::{canonicalize, MissingHandling, ResolveMode}; -use uucore::{format_usage, show_error, help_about, help_usage}; +use uucore::{format_usage, help_about, help_usage, show_error}; const ABOUT: &str = help_about!("readlink.md"); const USAGE: &str = help_usage!("readlink.md"); From e94f1d8eb7d4ab0ed0f7c35119e9d6eaab6f4b15 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 23 Apr 2023 15:27:24 +0200 Subject: [PATCH 162/477] mv: -i show no error if overwriting is declined --- src/uu/mv/src/mv.rs | 34 ++++++++++++++++++---------------- tests/by-util/test_mv.rs | 20 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index ba6f2198a7..d0a1a766f9 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -24,7 +24,7 @@ use std::os::windows; use std::path::{Path, PathBuf}; use uucore::backup_control::{self, BackupMode}; use uucore::display::Quotable; -use uucore::error::{FromIo, UError, UResult, USimpleError, UUsageError}; +use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError}; use uucore::{format_usage, help_about, help_usage, prompt_yes, show}; use fs_extra::dir::{ @@ -378,21 +378,23 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> UR } } - let rename_result = rename(sourcepath, &targetpath, b, multi_progress.as_ref()) - .map_err_context(|| { - format!( - "cannot move {} to {}", - sourcepath.quote(), - targetpath.quote() - ) - }); - - if let Err(e) = rename_result { - match multi_progress { - Some(ref pb) => pb.suspend(|| show!(e)), - None => show!(e), - }; - }; + match rename(sourcepath, &targetpath, b, multi_progress.as_ref()) { + Err(e) if e.to_string() == "" => set_exit_code(1), + Err(e) => { + let e = e.map_err_context(|| { + format!( + "cannot move {} to {}", + sourcepath.quote(), + targetpath.quote() + ) + }); + match multi_progress { + Some(ref pb) => pb.suspend(|| show!(e)), + None => show!(e), + }; + } + Ok(()) => (), + } if let Some(ref pb) = count_progress { pb.inc(1); diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index f9b0c59ea8..0342341071 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -181,6 +181,26 @@ fn test_mv_interactive() { assert!(at.file_exists(file_b)); } +#[test] +fn test_mv_interactive_with_dir_as_target() { + let (at, mut ucmd) = at_and_ucmd!(); + + let file = "test_mv_interactive_file"; + let target_dir = "target"; + + at.mkdir(target_dir); + at.touch(file); + at.touch(format!("{target_dir}/{file}")); + + ucmd.arg(file) + .arg(target_dir) + .arg("-i") + .pipe_in("n") + .fails() + .stderr_does_not_contain("cannot move") + .no_stdout(); +} + #[test] fn test_mv_arg_update_interactive() { let (at, mut ucmd) = at_and_ucmd!(); From f9b7423eef273591df8d2723f1c995fab887c4b9 Mon Sep 17 00:00:00 2001 From: vix <1@1.1> Date: Sun, 23 Apr 2023 20:29:54 +0200 Subject: [PATCH 163/477] Add flush after calculating factor --- src/uu/factor/src/cli.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uu/factor/src/cli.rs b/src/uu/factor/src/cli.rs index 9f3d55db9f..714b38e5ef 100644 --- a/src/uu/factor/src/cli.rs +++ b/src/uu/factor/src/cli.rs @@ -52,6 +52,7 @@ fn print_factors_str( writeln!(factors_buffer, "{}:{}", x, factor(x))?; } w.write_all(factors_buffer.as_bytes())?; + w.flush()?; Ok(()) }) } From d1454628e191b92508114c8168f2755d17fe3557 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Fri, 21 Apr 2023 21:58:53 +0200 Subject: [PATCH 164/477] tail: Change static global variables to const --- src/uu/tail/src/args.rs | 37 ++++++++++++++++++------------------- src/uu/tail/src/text.rs | 28 ++++++++++++++-------------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/uu/tail/src/args.rs b/src/uu/tail/src/args.rs index 55014e0298..5fb5ef2b3e 100644 --- a/src/uu/tail/src/args.rs +++ b/src/uu/tail/src/args.rs @@ -24,22 +24,22 @@ const USAGE: &str = help_usage!("tail.md"); pub mod options { pub mod verbosity { - pub static QUIET: &str = "quiet"; - pub static VERBOSE: &str = "verbose"; + pub const QUIET: &str = "quiet"; + pub const VERBOSE: &str = "verbose"; } - pub static BYTES: &str = "bytes"; - pub static FOLLOW: &str = "follow"; - pub static LINES: &str = "lines"; - pub static PID: &str = "pid"; - pub static SLEEP_INT: &str = "sleep-interval"; - pub static ZERO_TERM: &str = "zero-terminated"; - pub static DISABLE_INOTIFY_TERM: &str = "-disable-inotify"; // NOTE: three hyphens is correct - pub static USE_POLLING: &str = "use-polling"; - pub static RETRY: &str = "retry"; - pub static FOLLOW_RETRY: &str = "F"; - pub static MAX_UNCHANGED_STATS: &str = "max-unchanged-stats"; - pub static ARG_FILES: &str = "files"; - pub static PRESUME_INPUT_PIPE: &str = "-presume-input-pipe"; // NOTE: three hyphens is correct + pub const BYTES: &str = "bytes"; + pub const FOLLOW: &str = "follow"; + pub const LINES: &str = "lines"; + pub const PID: &str = "pid"; + pub const SLEEP_INT: &str = "sleep-interval"; + pub const ZERO_TERM: &str = "zero-terminated"; + pub const DISABLE_INOTIFY_TERM: &str = "-disable-inotify"; // NOTE: three hyphens is correct + pub const USE_POLLING: &str = "use-polling"; + pub const RETRY: &str = "retry"; + pub const FOLLOW_RETRY: &str = "F"; + pub const MAX_UNCHANGED_STATS: &str = "max-unchanged-stats"; + pub const ARG_FILES: &str = "files"; + pub const PRESUME_INPUT_PIPE: &str = "-presume-input-pipe"; // NOTE: three hyphens is correct } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -470,12 +470,11 @@ pub fn parse_args(args: impl uucore::Args) -> UResult { pub fn uu_app() -> Command { #[cfg(target_os = "linux")] - pub static POLLING_HELP: &str = "Disable 'inotify' support and use polling instead"; + const POLLING_HELP: &str = "Disable 'inotify' support and use polling instead"; #[cfg(all(unix, not(target_os = "linux")))] - pub static POLLING_HELP: &str = "Disable 'kqueue' support and use polling instead"; + const POLLING_HELP: &str = "Disable 'kqueue' support and use polling instead"; #[cfg(target_os = "windows")] - pub static POLLING_HELP: &str = - "Disable 'ReadDirectoryChanges' support and use polling instead"; + const POLLING_HELP: &str = "Disable 'ReadDirectoryChanges' support and use polling instead"; Command::new(uucore::util_name()) .version(crate_version!()) diff --git a/src/uu/tail/src/text.rs b/src/uu/tail/src/text.rs index 0e4a26f39a..e7686d301e 100644 --- a/src/uu/tail/src/text.rs +++ b/src/uu/tail/src/text.rs @@ -5,20 +5,20 @@ // spell-checker:ignore (ToDO) kqueue -pub static DASH: &str = "-"; -pub static DEV_STDIN: &str = "/dev/stdin"; -pub static STDIN_HEADER: &str = "standard input"; -pub static NO_FILES_REMAINING: &str = "no files remaining"; -pub static NO_SUCH_FILE: &str = "No such file or directory"; -pub static BECOME_INACCESSIBLE: &str = "has become inaccessible"; -pub static BAD_FD: &str = "Bad file descriptor"; +pub const DASH: &str = "-"; +pub const DEV_STDIN: &str = "/dev/stdin"; +pub const STDIN_HEADER: &str = "standard input"; +pub const NO_FILES_REMAINING: &str = "no files remaining"; +pub const NO_SUCH_FILE: &str = "No such file or directory"; +pub const BECOME_INACCESSIBLE: &str = "has become inaccessible"; +pub const BAD_FD: &str = "Bad file descriptor"; #[cfg(target_os = "linux")] -pub static BACKEND: &str = "inotify"; +pub const BACKEND: &str = "inotify"; #[cfg(all(unix, not(target_os = "linux")))] -pub static BACKEND: &str = "kqueue"; +pub const BACKEND: &str = "kqueue"; #[cfg(target_os = "windows")] -pub static BACKEND: &str = "ReadDirectoryChanges"; -pub static FD0: &str = "/dev/fd/0"; -pub static IS_A_DIRECTORY: &str = "Is a directory"; -pub static DEV_TTY: &str = "/dev/tty"; -pub static DEV_PTMX: &str = "/dev/ptmx"; +pub const BACKEND: &str = "ReadDirectoryChanges"; +pub const FD0: &str = "/dev/fd/0"; +pub const IS_A_DIRECTORY: &str = "Is a directory"; +pub const DEV_TTY: &str = "/dev/tty"; +pub const DEV_PTMX: &str = "/dev/ptmx"; From c6f6c87780898d8add9a4e8cf864c088c76216a6 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sun, 23 Apr 2023 23:11:01 +0200 Subject: [PATCH 165/477] tests/tail: Change static global variables to const --- tests/by-util/test_tail.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index f3e55e434a..7a812dc74e 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -36,15 +36,15 @@ use tail::chunks::BUFFER_SIZE as CHUNK_BUFFER_SIZE; ))] use tail::text; -static FOOBAR_TXT: &str = "foobar.txt"; -static FOOBAR_2_TXT: &str = "foobar2.txt"; -static FOOBAR_WITH_NULL_TXT: &str = "foobar_with_null.txt"; +const FOOBAR_TXT: &str = "foobar.txt"; +const FOOBAR_2_TXT: &str = "foobar2.txt"; +const FOOBAR_WITH_NULL_TXT: &str = "foobar_with_null.txt"; #[allow(dead_code)] -static FOLLOW_NAME_TXT: &str = "follow_name.txt"; +const FOLLOW_NAME_TXT: &str = "follow_name.txt"; #[allow(dead_code)] -static FOLLOW_NAME_SHORT_EXP: &str = "follow_name_short.expected"; +const FOLLOW_NAME_SHORT_EXP: &str = "follow_name_short.expected"; #[allow(dead_code)] -static FOLLOW_NAME_EXP: &str = "follow_name.expected"; +const FOLLOW_NAME_EXP: &str = "follow_name.expected"; #[cfg(not(windows))] const DEFAULT_SLEEP_INTERVAL_MILLIS: u64 = 1000; From d18ccc6a2a202caebfcddcc79b153a4bfb7af357 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Mon, 24 Apr 2023 15:01:28 +0900 Subject: [PATCH 166/477] runcon: move help strings to markdown file (#4774) --- src/uu/runcon/runcon.md | 18 ++++++++++++++++++ src/uu/runcon/src/runcon.rs | 17 ++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 src/uu/runcon/runcon.md diff --git a/src/uu/runcon/runcon.md b/src/uu/runcon/runcon.md new file mode 100644 index 0000000000..1911c50447 --- /dev/null +++ b/src/uu/runcon/runcon.md @@ -0,0 +1,18 @@ +# runcon + +``` +runcon [CONTEXT COMMAND [ARG...]] +runcon [-c] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [ARG...]"; +``` + +Run command with specified security context under SELinux enabled systems. + +## After Help + +Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, ROLE, TYPE, and USER. + +If none of --compute, --type, --user, --role or --range is specified, then the first argument is used as the complete context. + +Note that only carefully-chosen contexts are likely to successfully run. + +With neither CONTEXT nor COMMAND are specified, then this prints the current security context. diff --git a/src/uu/runcon/src/runcon.rs b/src/uu/runcon/src/runcon.rs index 4ee3c6eba9..a22bff4702 100644 --- a/src/uu/runcon/src/runcon.rs +++ b/src/uu/runcon/src/runcon.rs @@ -5,7 +5,7 @@ use uucore::error::{UResult, UUsageError}; use clap::{crate_version, Arg, ArgAction, Command}; use selinux::{OpaqueSecurityContext, SecurityClass, SecurityContext}; -use uucore::format_usage; +use uucore::{format_usage, help_about, help_section, help_usage}; use std::borrow::Cow; use std::ffi::{CStr, CString, OsStr, OsString}; @@ -18,18 +18,9 @@ mod errors; use errors::error_exit_status; use errors::{Error, Result, RunconError}; -const ABOUT: &str = "Run command with specified security context."; -const USAGE: &str = "\ - {} [CONTEXT COMMAND [ARG...]] - {} [-c] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [ARG...]"; -const DESCRIPTION: &str = "Run COMMAND with completely-specified CONTEXT, or with current or \ - transitioned security context modified by one or more of \ - LEVEL, ROLE, TYPE, and USER.\n\n\ - If none of --compute, --type, --user, --role or --range is specified, \ - then the first argument is used as the complete context.\n\n\ - Note that only carefully-chosen contexts are likely to successfully run.\n\n\ - With neither CONTEXT nor COMMAND are specified, \ - then this prints the current security context."; +const ABOUT: &str = help_about!("runcon.md"); +const USAGE: &str = help_usage!("runcon.md"); +const DESCRIPTION: &str = help_section!("after help", "runcon.md"); pub mod options { pub const COMPUTE: &str = "compute"; From afa5c15581fad94882f922f5db89f287c0a57489 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 21 Apr 2023 16:53:15 +0200 Subject: [PATCH 167/477] gnu test: don't sync the po files We aren't testing the locale yet. --- util/build-gnu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/build-gnu.sh b/util/build-gnu.sh index 9035fa69b3..486cf3227b 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -67,7 +67,7 @@ if test -f gnu-built; then echo "'rm -f $(pwd)/gnu-built' to force the build" echo "Note: the customization of the tests will still happen" else - ./bootstrap + ./bootstrap --skip-po ./configure --quiet --disable-gcc-warnings #Add timeout to to protect against hangs sed -i 's|^"\$@|/usr/bin/timeout 600 "\$@|' build-aux/test-driver From c3656e561cde70c2a860d11a5747c24387105b20 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 21 Apr 2023 23:54:08 +0200 Subject: [PATCH 168/477] touch: -h -r should not fail when running on broken symlink Fixes the beginning of: tests/touch/no-dereference.sh --- src/uu/touch/src/touch.rs | 20 ++++++++++++++------ tests/by-util/test_touch.rs | 9 +++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index eeb1dd13ab..8d96b1b161 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -305,13 +305,21 @@ pub fn uu_app() -> Command { ) } +// Function to get metadata of the provided path +// If `follow` is true, the function will try to follow symlinks +// If `follow` is false or the symlink is broken, the function will return metadata of the symlink itself fn stat(path: &Path, follow: bool) -> UResult<(FileTime, FileTime)> { - let metadata = if follow { - fs::symlink_metadata(path) - } else { - fs::metadata(path) - } - .map_err_context(|| format!("failed to get attributes of {}", path.quote()))?; + // Try to get metadata using fs::metadata + // If the path is a symlink and `follow` is true, fs::metadata will follow the symlink + let metadata = match fs::metadata(path) { + // If successful, use the metadata + Ok(metadata) => metadata, + // If there's a NotFound error and `follow` is false, try to get metadata of the symlink itself + Err(e) if e.kind() == std::io::ErrorKind::NotFound && !follow => fs::symlink_metadata(path) + .map_err_context(|| format!("failed to get attributes of {}", path.quote()))?, + // If it's any other error, return the error + Err(e) => return Err(e.into()), + }; Ok(( FileTime::from_last_access_time(&metadata), diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index ae3a28e49f..89a7cacaff 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -816,3 +816,12 @@ fn test_touch_trailing_slash_no_create() { at.relative_symlink_dir("dir2", "link2"); ucmd.args(&["-c", "link2/"]).succeeds(); } + +#[test] +fn test_touch_no_dereference_ref_dangling() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("file"); + at.relative_symlink_file("nowhere", "dangling"); + + ucmd.args(&["-h", "-r", "dangling", "file"]).succeeds(); +} From aaea758b6a7865ee786ac743a1828d08ae3e370e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 22 Apr 2023 08:56:01 +0200 Subject: [PATCH 169/477] touch: -h should not fail when running on broken symlink Fixes more of tests/touch/no-dereference.sh --- src/uu/touch/src/touch.rs | 13 ++++++++++++- tests/by-util/test_touch.rs | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index 8d96b1b161..de19241342 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -139,15 +139,25 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let path = pathbuf.as_path(); - if let Err(e) = path.metadata() { + // Check the metadata of the path + let metadata_result = if matches.get_flag(options::NO_DEREF) { + path.symlink_metadata() + } else { + path.metadata() + }; + + if let Err(e) = metadata_result { + // If the error is not a NotFound error, return the error with context if e.kind() != std::io::ErrorKind::NotFound { return Err(e.map_err_context(|| format!("setting times of {}", filename.quote()))); } + // If the NO_CREATE flag is set, skip this iteration if matches.get_flag(options::NO_CREATE) { continue; } + // If the NO_DEREF flag is set, show an error and skip this iteration if matches.get_flag(options::NO_DEREF) { show!(USimpleError::new( 1, @@ -159,6 +169,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { continue; } + // Create the file, and handle errors by showing the error and skipping this iteration if let Err(e) = File::create(path) { show!(e.map_err_context(|| format!("cannot touch {}", path.quote()))); continue; diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index 89a7cacaff..a2e3787775 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -825,3 +825,11 @@ fn test_touch_no_dereference_ref_dangling() { ucmd.args(&["-h", "-r", "dangling", "file"]).succeeds(); } + +#[test] +fn test_touch_no_dereference_dangling() { + let (at, mut ucmd) = at_and_ucmd!(); + at.relative_symlink_file("nowhere", "dangling"); + + ucmd.args(&["-h", "dangling"]).succeeds(); +} From 84e061048753656b3f4eaf627e8d6efef1034190 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 22 Apr 2023 18:54:43 +0200 Subject: [PATCH 170/477] touch: don't generate an error on 'touch -h -' --- src/uu/touch/src/touch.rs | 18 ++++++++++++++---- tests/by-util/test_touch.rs | 7 +++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index de19241342..45a51f02d6 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -209,14 +209,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } - if matches.get_flag(options::NO_DEREF) { - set_symlink_file_times(path, atime, mtime) - } else { + // sets the file access and modification times for a file or a symbolic link. + // The filename, access time (atime), and modification time (mtime) are provided as inputs. + + // If the filename is not "-", indicating a special case for touch -h -, + // the code checks if the NO_DEREF flag is set, which means the user wants to + // set the times for a symbolic link itself, rather than the file it points to. + if filename == "-" { filetime::set_file_times(path, atime, mtime) + } else { + let should_set_symlink_times = matches.get_flag(options::NO_DEREF); + if should_set_symlink_times { + set_symlink_file_times(path, atime, mtime) + } else { + filetime::set_file_times(path, atime, mtime) + } } .map_err_context(|| format!("setting times of {}", path.quote()))?; } - Ok(()) } diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index a2e3787775..7d2b8ad3fb 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -833,3 +833,10 @@ fn test_touch_no_dereference_dangling() { ucmd.args(&["-h", "dangling"]).succeeds(); } + +#[test] +fn test_touch_dash() { + let (_, mut ucmd) = at_and_ucmd!(); + + ucmd.args(&["-h", "-"]).succeeds().no_stderr().no_stdout(); +} From c262fa936c758fdf4db2d931ee6bbb6ca62147fd Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 24 Apr 2023 11:47:59 +0200 Subject: [PATCH 171/477] Improve the doc and simplify the code Co-authored-by: Daniel Hofstetter --- src/uu/touch/src/touch.rs | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index 45a51f02d6..818a8c9f68 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -139,7 +139,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let path = pathbuf.as_path(); - // Check the metadata of the path let metadata_result = if matches.get_flag(options::NO_DEREF) { path.symlink_metadata() } else { @@ -147,17 +146,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { }; if let Err(e) = metadata_result { - // If the error is not a NotFound error, return the error with context if e.kind() != std::io::ErrorKind::NotFound { return Err(e.map_err_context(|| format!("setting times of {}", filename.quote()))); } - // If the NO_CREATE flag is set, skip this iteration if matches.get_flag(options::NO_CREATE) { continue; } - // If the NO_DEREF flag is set, show an error and skip this iteration if matches.get_flag(options::NO_DEREF) { show!(USimpleError::new( 1, @@ -169,7 +165,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { continue; } - // Create the file, and handle errors by showing the error and skipping this iteration if let Err(e) = File::create(path) { show!(e.map_err_context(|| format!("cannot touch {}", path.quote()))); continue; @@ -217,13 +212,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { // set the times for a symbolic link itself, rather than the file it points to. if filename == "-" { filetime::set_file_times(path, atime, mtime) + } else if matches.get_flag(options::NO_DEREF) { + set_symlink_file_times(path, atime, mtime) } else { - let should_set_symlink_times = matches.get_flag(options::NO_DEREF); - if should_set_symlink_times { - set_symlink_file_times(path, atime, mtime) - } else { - filetime::set_file_times(path, atime, mtime) - } + filetime::set_file_times(path, atime, mtime) } .map_err_context(|| format!("setting times of {}", path.quote()))?; } @@ -326,19 +318,14 @@ pub fn uu_app() -> Command { ) } -// Function to get metadata of the provided path -// If `follow` is true, the function will try to follow symlinks -// If `follow` is false or the symlink is broken, the function will return metadata of the symlink itself +// Get metadata of the provided path +// If `follow` is `true`, the function will try to follow symlinks +// If `follow` is `false` or the symlink is broken, the function will return metadata of the symlink itself fn stat(path: &Path, follow: bool) -> UResult<(FileTime, FileTime)> { - // Try to get metadata using fs::metadata - // If the path is a symlink and `follow` is true, fs::metadata will follow the symlink let metadata = match fs::metadata(path) { - // If successful, use the metadata Ok(metadata) => metadata, - // If there's a NotFound error and `follow` is false, try to get metadata of the symlink itself Err(e) if e.kind() == std::io::ErrorKind::NotFound && !follow => fs::symlink_metadata(path) .map_err_context(|| format!("failed to get attributes of {}", path.quote()))?, - // If it's any other error, return the error Err(e) => return Err(e.into()), }; From fd02bd13a1807a33701cf9ad96d9621480d6f633 Mon Sep 17 00:00:00 2001 From: m11o Date: Mon, 24 Apr 2023 23:35:52 +0900 Subject: [PATCH 172/477] seq: move help strings to md file --- src/uu/seq/seq.md | 9 +++++++++ src/uu/seq/src/seq.rs | 10 ++++------ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 src/uu/seq/seq.md diff --git a/src/uu/seq/seq.md b/src/uu/seq/seq.md new file mode 100644 index 0000000000..065404e200 --- /dev/null +++ b/src/uu/seq/seq.md @@ -0,0 +1,9 @@ +# seq + +Display numbers from FIRST to LAST, in steps of INCREMENT. + +``` +seq [OPTION]... LAST +seq [OPTION]... FIRST LAST +seq [OPTION]... FIRST INCREMENT LAST"; +``` diff --git a/src/uu/seq/src/seq.rs b/src/uu/seq/src/seq.rs index 40bac84496..3e42e17084 100644 --- a/src/uu/seq/src/seq.rs +++ b/src/uu/seq/src/seq.rs @@ -12,9 +12,9 @@ use num_traits::Zero; use uucore::error::FromIo; use uucore::error::UResult; -use uucore::format_usage; use uucore::memo::printf; use uucore::show; +use uucore::{format_usage, help_about, help_usage}; mod error; mod extendedbigdecimal; @@ -27,11 +27,9 @@ use crate::extendedbigint::ExtendedBigInt; use crate::number::Number; use crate::number::PreciseNumber; -static ABOUT: &str = "Display numbers from FIRST to LAST, in steps of INCREMENT."; -const USAGE: &str = "\ - {} [OPTION]... LAST - {} [OPTION]... FIRST LAST - {} [OPTION]... FIRST INCREMENT LAST"; +const ABOUT: &str = help_about!("seq.md"); +const USAGE: &str = help_usage!("seq.md"); + static OPT_SEPARATOR: &str = "separator"; static OPT_TERMINATOR: &str = "terminator"; static OPT_WIDTHS: &str = "widths"; From 1cb0a673a0c4791688dd1fa101eff5bc6e4a80cc Mon Sep 17 00:00:00 2001 From: m11o Date: Mon, 24 Apr 2023 23:38:45 +0900 Subject: [PATCH 173/477] change static keyword to const keyword --- src/uu/seq/src/seq.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/uu/seq/src/seq.rs b/src/uu/seq/src/seq.rs index 3e42e17084..e48d22bd97 100644 --- a/src/uu/seq/src/seq.rs +++ b/src/uu/seq/src/seq.rs @@ -30,12 +30,12 @@ use crate::number::PreciseNumber; const ABOUT: &str = help_about!("seq.md"); const USAGE: &str = help_usage!("seq.md"); -static OPT_SEPARATOR: &str = "separator"; -static OPT_TERMINATOR: &str = "terminator"; -static OPT_WIDTHS: &str = "widths"; -static OPT_FORMAT: &str = "format"; +const OPT_SEPARATOR: &str = "separator"; +const OPT_TERMINATOR: &str = "terminator"; +const OPT_WIDTHS: &str = "widths"; +const OPT_FORMAT: &str = "format"; -static ARG_NUMBERS: &str = "numbers"; +const ARG_NUMBERS: &str = "numbers"; #[derive(Clone)] struct SeqOptions<'a> { From dd89ec709b39d9ec522c14a3267c2481edd88172 Mon Sep 17 00:00:00 2001 From: m11o Date: Mon, 24 Apr 2023 23:44:28 +0900 Subject: [PATCH 174/477] remove todo comment `-f` option is implemented in #2918 --- src/uu/seq/src/seq.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/uu/seq/src/seq.rs b/src/uu/seq/src/seq.rs index e48d22bd97..97382ed1b0 100644 --- a/src/uu/seq/src/seq.rs +++ b/src/uu/seq/src/seq.rs @@ -2,7 +2,6 @@ // * // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -// TODO: Support -f flag // spell-checker:ignore (ToDO) istr chiter argptr ilen extendedbigdecimal extendedbigint numberparse use std::io::{stdout, ErrorKind, Write}; use std::process::exit; From d1aa1ac96385d84cf5f77f2c69e2a2dd158e3371 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 23 Apr 2023 23:15:32 +0200 Subject: [PATCH 175/477] Use the humantime_to_duration crate --- Cargo.lock | 32 ++++++++++++++++++++++++------ Cargo.toml | 3 ++- src/uu/touch/Cargo.toml | 2 ++ src/uu/touch/src/touch.rs | 39 +++---------------------------------- tests/by-util/test_touch.rs | 15 +++++++++++++- 5 files changed, 47 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0634e1ad9e..7b9b884510 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,6 +34,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "aho-corasick" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +dependencies = [ + "memchr", +] + [[package]] name = "aliasable" version = "0.1.3" @@ -569,7 +578,7 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fdaa01904c12a8989dbfa110b41ef27efc432ac9934f691b9732f01cb64dc01" dependencies = [ - "aho-corasick", + "aho-corasick 0.7.19", "byteorder", "cpp_common", "lazy_static", @@ -1145,6 +1154,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "humantime_to_duration" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d564881e1f668089d5653740167844f6ca8af54cd56bd6951f3dca85ba354fc" +dependencies = [ + "regex", + "time", +] + [[package]] name = "iana-time-zone" version = "0.1.53" @@ -1880,11 +1899,11 @@ checksum = "f1bfbf25d7eb88ddcbb1ec3d755d0634da8f7657b2cb8b74089121409ab8228f" [[package]] name = "regex" -version = "1.7.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ - "aho-corasick", + "aho-corasick 1.0.1", "memchr", "regex-syntax", ] @@ -1897,9 +1916,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "rlimit" @@ -3213,6 +3232,7 @@ version = "0.0.18" dependencies = [ "clap", "filetime", + "humantime_to_duration", "time", "uucore", "windows-sys 0.45.0", diff --git a/Cargo.toml b/Cargo.toml index e3da0212a2..f422555ef0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ # coreutils (uutils) # * see the repository LICENSE, README, and CONTRIBUTING files for more information -# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen +# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen humantime [package] name = "coreutils" @@ -286,6 +286,7 @@ fundu = "0.5.0" gcd = "2.3" glob = "0.3.1" half = "2.2" +humantime_to_duration = "0.1.2" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" diff --git a/src/uu/touch/Cargo.toml b/src/uu/touch/Cargo.toml index 794273bba7..0bb89ec849 100644 --- a/src/uu/touch/Cargo.toml +++ b/src/uu/touch/Cargo.toml @@ -1,3 +1,4 @@ +# spell-checker:ignore humantime [package] name = "uu_touch" version = "0.0.18" @@ -17,6 +18,7 @@ path = "src/touch.rs" [dependencies] filetime = { workspace=true } clap = { workspace=true } +humantime_to_duration = { workspace=true } time = { workspace=true, features = ["parsing", "formatting", "local-offset", "macros"] } uucore = { workspace=true, features=["libc"] } diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index eeb1dd13ab..8bd483712d 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -6,7 +6,7 @@ // For the full copyright and license information, please view the LICENSE file // that was distributed with this source code. -// spell-checker:ignore (ToDO) filetime strptime utcoff strs datetime MMDDhhmm clapv PWSTR lpszfilepath hresult mktime YYYYMMDDHHMM YYMMDDHHMM DATETIME YYYYMMDDHHMMS subsecond +// spell-checker:ignore (ToDO) filetime strptime utcoff strs datetime MMDDhhmm clapv PWSTR lpszfilepath hresult mktime YYYYMMDDHHMM YYMMDDHHMM DATETIME YYYYMMDDHHMMS subsecond humantime use clap::builder::ValueParser; use clap::{crate_version, Arg, ArgAction, ArgGroup, Command}; @@ -83,7 +83,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { ) { (Some(reference), Some(date)) => { let (atime, mtime) = stat(Path::new(reference), !matches.get_flag(options::NO_DEREF))?; - if let Some(offset) = parse_relative_time(date) { + if let Ok(offset) = humantime_to_duration::from_str(date) { let mut seconds = offset.whole_seconds(); let mut nanos = offset.subsec_nanoseconds(); if nanos < 0 { @@ -428,7 +428,7 @@ fn parse_date(s: &str) -> UResult { } } - if let Some(duration) = parse_relative_time(s) { + if let Ok(duration) = humantime_to_duration::from_str(s) { let now_local = time::OffsetDateTime::now_local().unwrap(); let diff = now_local.checked_add(duration).unwrap(); return Ok(local_dt_to_filetime(diff)); @@ -437,39 +437,6 @@ fn parse_date(s: &str) -> UResult { Err(USimpleError::new(1, format!("Unable to parse date: {s}"))) } -fn parse_relative_time(s: &str) -> Option { - // Relative time, like "-1 hour" or "+3 days". - // - // TODO Add support for "year" and "month". - // TODO Add support for times without spaces like "-1hour". - let tokens: Vec<&str> = s.split_whitespace().collect(); - match &tokens[..] { - [num_str, "fortnight" | "fortnights"] => num_str - .parse::() - .ok() - .map(|n| time::Duration::weeks(2 * n)), - ["fortnight" | "fortnights"] => Some(time::Duration::weeks(2)), - [num_str, "week" | "weeks"] => num_str.parse::().ok().map(time::Duration::weeks), - ["week" | "weeks"] => Some(time::Duration::weeks(1)), - [num_str, "day" | "days"] => num_str.parse::().ok().map(time::Duration::days), - ["day" | "days"] => Some(time::Duration::days(1)), - [num_str, "hour" | "hours"] => num_str.parse::().ok().map(time::Duration::hours), - ["hour" | "hours"] => Some(time::Duration::hours(1)), - [num_str, "minute" | "minutes" | "min" | "mins"] => { - num_str.parse::().ok().map(time::Duration::minutes) - } - ["minute" | "minutes" | "min" | "mins"] => Some(time::Duration::minutes(1)), - [num_str, "second" | "seconds" | "sec" | "secs"] => { - num_str.parse::().ok().map(time::Duration::seconds) - } - ["second" | "seconds" | "sec" | "secs"] => Some(time::Duration::seconds(1)), - ["now" | "today"] => Some(time::Duration::ZERO), - ["yesterday"] => Some(time::Duration::days(-1)), - ["tomorrow"] => Some(time::Duration::days(1)), - _ => None, - } -} - fn parse_timestamp(s: &str) -> UResult { // TODO: handle error let now = time::OffsetDateTime::now_utc(); diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index ae3a28e49f..d13da0bf6c 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -608,7 +608,15 @@ fn test_touch_set_date_relative_smoke() { // > (equivalent to ‘day’), the string ‘yesterday’ is worth one day // > in the past (equivalent to ‘day ago’). // - let times = ["yesterday", "tomorrow", "now"]; + let times = [ + "yesterday", + "tomorrow", + "now", + "2 seconds", + "2 years 1 week", + "2 days ago", + "2 months and 1 second", + ]; for time in times { let (at, mut ucmd) = at_and_ucmd!(); at.touch("f"); @@ -617,6 +625,11 @@ fn test_touch_set_date_relative_smoke() { .no_stderr() .no_stdout(); } + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("f"); + ucmd.args(&["-d", "a", "f"]) + .fails() + .stderr_contains("touch: Unable to parse date"); } #[test] From b9f5fc4b7c64bd4b69171ec9b5ab638844a0a281 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 24 Apr 2023 22:17:44 +0200 Subject: [PATCH 176/477] Ignore the duplicate declaration for aho-corasick MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit error[duplicate]: found 2 duplicate entries for crate 'aho-corasick' ┌─ /github/workspace/Cargo.lock:4:1 │ 4 │ ╭ aho-corasick 0.7.19 registry+https://github.com/rust-lang/crates.io-index 5 │ │ aho-corasick 1.0.1 registry+https://github.com/rust-lang/crates.io-index │ ╰────────────────────────────────────────────────────────────────────────^ lock entries │ = aho-corasick v0.7.19 └── cpp_macros v0.5.7 └── cpp v0.5.7 └── uu_stdbuf_libstdbuf v0.0.18 └── (build) uu_stdbuf v0.0.18 └── coreutils v0.0.18 = aho-corasick v1.0.1 └── regex v1.8.1 ├── bindgen v0.63.0 │ ├── (build) fts-sys v0.2.4 │ │ └── uu_chcon v0.0.18 │ │ └── coreutils v0.0.18 │ └── (build) selinux-sys v0.6.2 │ └── selinux v0.4.0 --- deny.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deny.toml b/deny.toml index aa05cdf3e7..31a1707546 100644 --- a/deny.toml +++ b/deny.toml @@ -69,6 +69,8 @@ skip = [ { name = "linux-raw-sys", version = "0.1.4" }, # is-terminal { name = "windows-sys", version = "0.45.0" }, + # cpp_macros + { name = "aho-corasick", version = "0.7.19" }, ] # spell-checker: enable From f187a5ccffc1d927662d266612532eef1d201e59 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sun, 23 Apr 2023 08:43:03 -0700 Subject: [PATCH 177/477] Fix a warning in upstream code on Rust nightly. Rust nightly recently [started] issuing the following warning when compiling coreutils: [started]: https://github.com/rust-lang/rust/pull/109944 ``` warning: getting the inner pointer of a temporary `CString` --> src/uucore/src/lib/features/entries.rs:324:67 | 324 | let data = $fnam(CString::new(k).unwrap().as_ptr()); | ------------------------ ^^^^^^ this pointer will be invalid | | | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime ... 340 | f!(getpwnam, getpwuid, uid_t, Passwd); | ------------------------------------- in this macro invocation | = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned = help: for more information, see https://doc.rust-lang.org/reference/destructors.html = note: `#[warn(temporary_cstring_as_ptr)]` on by default = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) ``` There doesn't seem to be an actual problem in this case, as the pointer is only used within the statement. --- src/uucore/src/lib/features/entries.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uucore/src/lib/features/entries.rs b/src/uucore/src/lib/features/entries.rs index 1e8f2417ab..c0229aa3e9 100644 --- a/src/uucore/src/lib/features/entries.rs +++ b/src/uucore/src/lib/features/entries.rs @@ -321,7 +321,8 @@ macro_rules! f { } else { // SAFETY: We're holding PW_LOCK. unsafe { - let data = $fnam(CString::new(k).unwrap().as_ptr()); + let cstring = CString::new(k).unwrap(); + let data = $fnam(cstring.as_ptr()); if !data.is_null() { Ok($st::from_raw(ptr::read(data as *const _))) } else { From 54deb3043c67399d0d925b97b2f9ff5f14f5734e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Apr 2023 05:29:58 +0000 Subject: [PATCH 178/477] chore(deps): update rust crate regex to 1.8.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f422555ef0..622b3a7c29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -311,7 +311,7 @@ rand = { version = "0.8", features = ["small_rng"] } rand_core = "0.6" rayon = "1.7" redox_syscall = "0.2" -regex = "1.7.3" +regex = "1.8.1" rstest = "0.17.0" rust-ini = "0.18.0" same-file = "1.0.6" From 804274dbf46cd62615dbc3033d90524cbd83745a Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 25 Apr 2023 11:33:48 +0200 Subject: [PATCH 179/477] mv: adapt -n behavior to GNU mv 9.3 --- src/uu/mv/src/mv.rs | 7 ++++++- tests/by-util/test_mv.rs | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index d0a1a766f9..e234ac857e 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -419,7 +419,12 @@ fn rename( } match b.overwrite { - OverwriteMode::NoClobber => return Ok(()), + OverwriteMode::NoClobber => { + return Err(io::Error::new( + io::ErrorKind::Other, + format!("not replacing {}", to.quote()), + )); + } OverwriteMode::Interactive => { if !prompt_yes!("overwrite {}?", to.quote()) { return Err(io::Error::new(io::ErrorKind::Other, "")); diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 0342341071..43a09c52e5 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -232,8 +232,9 @@ fn test_mv_no_clobber() { ucmd.arg("-n") .arg(file_a) .arg(file_b) - .succeeds() - .no_stderr(); + .fails() + .code_is(1) + .stderr_only(format!("mv: not replacing '{file_b}'\n")); assert!(at.file_exists(file_a)); assert!(at.file_exists(file_b)); From eba000ddcc991bb168c80b8f7b60d8c51c745558 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 25 Apr 2023 05:14:09 -0700 Subject: [PATCH 180/477] Use `expected_result` in test_ls to avoid spurious failures As the existing comment says, the expected output here is dependent on the platform, so use the `expected_result` utility to avoid hard-coding specific results for each platform. This fixes spurious failures on my machine. --- tests/by-util/test_ls.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 1a189a25ad..0779a28855 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1,6 +1,6 @@ // spell-checker:ignore (words) READMECAREFULLY birthtime doesntexist oneline somebackup lrwx somefile somegroup somehiddenbackup somehiddenfile tabsize aaaaaaaa bbbb cccc dddddddd ncccc -#[cfg(feature = "feat_selinux")] +#[cfg(any(unix, feature = "feat_selinux"))] use crate::common::util::expected_result; use crate::common::util::TestScenario; #[cfg(all(unix, feature = "chmod"))] @@ -1776,9 +1776,15 @@ fn test_ls_order_time() { at.open("test-4").metadata().unwrap().accessed().unwrap(); // It seems to be dependent on the platform whether the access time is actually set - #[cfg(all(unix, not(target_os = "android")))] - result.stdout_only("test-3\ntest-4\ntest-2\ntest-1\n"); - #[cfg(any(windows, target_os = "android"))] + #[cfg(unix)] + { + let expected = unwrap_or_return!(expected_result(&scene, &["-t", arg])); + at.open("test-3").metadata().unwrap().accessed().unwrap(); + at.open("test-4").metadata().unwrap().accessed().unwrap(); + + result.stdout_only(expected.stdout_str()); + } + #[cfg(windows)] result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n"); } From 98dd31c00d5a7e5be5991b8fdd8437ce8c395543 Mon Sep 17 00:00:00 2001 From: m11o Date: Tue, 25 Apr 2023 22:00:22 +0900 Subject: [PATCH 181/477] split: move help strings to markdown file --- src/uu/split/split.md | 11 +++++++++++ src/uu/split/src/split.rs | 12 +++++------- 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 src/uu/split/split.md diff --git a/src/uu/split/split.md b/src/uu/split/split.md new file mode 100644 index 0000000000..d43b771591 --- /dev/null +++ b/src/uu/split/split.md @@ -0,0 +1,11 @@ +# split + +``` +split [OPTION]... [INPUT [PREFIX]] +``` + +Create output files containing consecutive or interleaved sections of input + +## After Help + +Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is -, read standard input. diff --git a/src/uu/split/src/split.rs b/src/uu/split/src/split.rs index d737c85134..f09a6517f4 100644 --- a/src/uu/split/src/split.rs +++ b/src/uu/split/src/split.rs @@ -23,7 +23,7 @@ use std::io::{stdin, BufRead, BufReader, BufWriter, ErrorKind, Read, Write}; use std::path::Path; use uucore::display::Quotable; use uucore::error::{FromIo, UIoError, UResult, USimpleError, UUsageError}; -use uucore::format_usage; +use uucore::{format_usage, help_about, help_usage, help_section}; use uucore::parse_size::{parse_size, ParseSizeError}; use uucore::uio_error; @@ -47,11 +47,9 @@ static OPT_ELIDE_EMPTY_FILES: &str = "elide-empty-files"; static ARG_INPUT: &str = "input"; static ARG_PREFIX: &str = "prefix"; -const USAGE: &str = "{} [OPTION]... [INPUT [PREFIX]]"; -const AFTER_HELP: &str = "\ - Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default \ - size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is \ - -, read standard input."; +const ABOUT: &str = help_about!("split.md"); +const USAGE: &str = help_usage!("split.md"); +const AFTER_HELP: &str = help_section!("after help", "split.md"); #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { @@ -66,7 +64,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(crate_version!()) - .about("Create output files containing consecutive or interleaved sections of input") + .about(ABOUT) .after_help(AFTER_HELP) .override_usage(format_usage(USAGE)) .infer_long_args(true) From 869614d343cde2d4c8a3aa03f63e56a2954ea520 Mon Sep 17 00:00:00 2001 From: m11o Date: Tue, 25 Apr 2023 22:01:10 +0900 Subject: [PATCH 182/477] fix cargo fmt --- src/uu/split/src/split.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/split/src/split.rs b/src/uu/split/src/split.rs index f09a6517f4..2bf62e39ea 100644 --- a/src/uu/split/src/split.rs +++ b/src/uu/split/src/split.rs @@ -23,9 +23,9 @@ use std::io::{stdin, BufRead, BufReader, BufWriter, ErrorKind, Read, Write}; use std::path::Path; use uucore::display::Quotable; use uucore::error::{FromIo, UIoError, UResult, USimpleError, UUsageError}; -use uucore::{format_usage, help_about, help_usage, help_section}; use uucore::parse_size::{parse_size, ParseSizeError}; use uucore::uio_error; +use uucore::{format_usage, help_about, help_section, help_usage}; static OPT_BYTES: &str = "bytes"; static OPT_LINE_BYTES: &str = "line-bytes"; From 0b84aa52f327b4290296ef63724bfc868e30417e Mon Sep 17 00:00:00 2001 From: m11o Date: Tue, 25 Apr 2023 22:26:47 +0900 Subject: [PATCH 183/477] fix check-spell --- src/uu/split/split.md | 2 ++ src/uu/split/src/split.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/uu/split/split.md b/src/uu/split/split.md index d43b771591..d3a481fd30 100644 --- a/src/uu/split/split.md +++ b/src/uu/split/split.md @@ -1,3 +1,5 @@ + + # split ``` diff --git a/src/uu/split/src/split.rs b/src/uu/split/src/split.rs index 2bf62e39ea..6e29e6f4b0 100644 --- a/src/uu/split/src/split.rs +++ b/src/uu/split/src/split.rs @@ -5,7 +5,7 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -// spell-checker:ignore (ToDO) PREFIXaa PREFIXab nbbbb ncccc +// spell-checker:ignore nbbbb ncccc mod filenames; mod number; From 1f3ea00d3339f0d5dfa70755f9a0e804acf1a97d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Apr 2023 13:40:07 +0000 Subject: [PATCH 184/477] chore(deps): update rust crate humantime_to_duration to 0.1.3 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b9b884510..90af50e20b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1156,9 +1156,9 @@ dependencies = [ [[package]] name = "humantime_to_duration" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d564881e1f668089d5653740167844f6ca8af54cd56bd6951f3dca85ba354fc" +checksum = "46276b15cd421d8262968eb5c3a075ae4a40bd787762ca0ddfead00fd5f6fbce" dependencies = [ "regex", "time", diff --git a/Cargo.toml b/Cargo.toml index 622b3a7c29..bae5080da9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -286,7 +286,7 @@ fundu = "0.5.0" gcd = "2.3" glob = "0.3.1" half = "2.2" -humantime_to_duration = "0.1.2" +humantime_to_duration = "0.1.3" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" From 12686c478e7eff788289227bfc70f9f9ffd192d1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 25 Apr 2023 05:22:49 -0700 Subject: [PATCH 185/477] Avoid spurious failures in the presence of non-zero default nice Make `test_get_current_niceness` query the libc nice value instead of hard-coding a value of zero. This avoids a spurious failure on systems which have a non-zero default nice value. This fixes spurious failures on my machine. --- tests/by-util/test_nice.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/by-util/test_nice.rs b/tests/by-util/test_nice.rs index e2af88dfd9..4e8d5a2ee3 100644 --- a/tests/by-util/test_nice.rs +++ b/tests/by-util/test_nice.rs @@ -1,11 +1,14 @@ +// spell-checker:ignore libc's use crate::common::util::TestScenario; #[test] #[cfg(not(target_os = "android"))] fn test_get_current_niceness() { - // NOTE: this assumes the test suite is being run with a default niceness - // of 0, which may not necessarily be true - new_ucmd!().run().stdout_is("0\n"); + // Test that the nice command with no arguments returns the default nice + // value, which we determine by querying libc's `nice` in our own process. + new_ucmd!() + .run() + .stdout_is(format!("{}\n", unsafe { libc::nice(0) })); } #[test] From d4630c83b4aec9e3b122f2a486c4b99299d21ddd Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 25 Apr 2023 21:27:52 -0700 Subject: [PATCH 186/477] mv: add 'renamed ' in the beginning when verbose flag is set --- src/uu/mv/src/mv.rs | 4 ++-- tests/by-util/test_mv.rs | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index d0a1a766f9..b79c43ad39 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -455,12 +455,12 @@ fn rename( if b.verbose { let message = match backup_path { Some(path) => format!( - "{} -> {} (backup: {})", + "renamed {} -> {} (backup: {})", from.quote(), to.quote(), path.quote() ), - None => format!("{} -> {}", from.quote(), to.quote()), + None => format!("renamed {} -> {}", from.quote(), to.quote()), }; match multi_progress { diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 0342341071..e4064e68ad 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -745,7 +745,9 @@ fn test_mv_backup_dir() { .arg(dir_a) .arg(dir_b) .succeeds() - .stdout_only(format!("'{dir_a}' -> '{dir_b}' (backup: '{dir_b}~')\n")); + .stdout_only(format!( + "renamed '{dir_a}' -> '{dir_b}' (backup: '{dir_b}~')\n" + )); assert!(!at.dir_exists(dir_a)); assert!(at.dir_exists(dir_b)); @@ -817,7 +819,7 @@ fn test_mv_verbose() { .arg(file_a) .arg(file_b) .succeeds() - .stdout_only(format!("'{file_a}' -> '{file_b}'\n")); + .stdout_only(format!("renamed '{file_a}' -> '{file_b}'\n")); at.touch(file_a); scene @@ -826,7 +828,9 @@ fn test_mv_verbose() { .arg(file_a) .arg(file_b) .succeeds() - .stdout_only(format!("'{file_a}' -> '{file_b}' (backup: '{file_b}~')\n")); + .stdout_only(format!( + "renamed '{file_a}' -> '{file_b}' (backup: '{file_b}~')\n" + )); } #[test] From 31578ea18da3b65ac40b43883bf0ef487d15959b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Apr 2023 04:41:44 +0000 Subject: [PATCH 187/477] chore(deps): update davidanson/markdownlint-cli2-action action to v10 --- .github/workflows/CICD.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 32fd305369..efbafcc7f8 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -331,7 +331,7 @@ jobs: shell: bash run: | RUSTDOCFLAGS="-Dwarnings" cargo doc ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-deps --workspace --document-private-items - - uses: DavidAnson/markdownlint-cli2-action@v9 + - uses: DavidAnson/markdownlint-cli2-action@v10 with: command: fix globs: | From 583a247d9dab9c4afef34d70c4e3f6bac5890d85 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 26 Apr 2023 08:48:02 +0200 Subject: [PATCH 188/477] Improve the date md page --- src/uu/date/date-usage.mkd | 119 ++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 55 deletions(-) diff --git a/src/uu/date/date-usage.mkd b/src/uu/date/date-usage.mkd index 8290010956..5489028e4d 100644 --- a/src/uu/date/date-usage.mkd +++ b/src/uu/date/date-usage.mkd @@ -2,64 +2,65 @@ -``` text FORMAT controls the output. Interpreted sequences are: - %% a literal % - %a locale's abbreviated weekday name (e.g., Sun) - %A locale's full weekday name (e.g., Sunday) - %b locale's abbreviated month name (e.g., Jan) - %B locale's full month name (e.g., January) - %c locale's date and time (e.g., Thu Mar 3 23:05:25 2005) - %C century; like %Y, except omit last two digits (e.g., 20) - %d day of month (e.g., 01) - %D date; same as %m/%d/%y - %e day of month, space padded; same as %_d - %F full date; same as %Y-%m-%d - %g last two digits of year of ISO week number (see %G) - %G year of ISO week number (see %V); normally useful only with %V - %h same as %b - %H hour (00..23) - %I hour (01..12) - %j day of year (001..366) - %k hour, space padded ( 0..23); same as %_H - %l hour, space padded ( 1..12); same as %_I - %m month (01..12) - %M minute (00..59) - %n a newline - %N nanoseconds (000000000..999999999) - %p locale's equivalent of either AM or PM; blank if not known - %P like %p, but lower case - %q quarter of year (1..4) - %r locale's 12-hour clock time (e.g., 11:11:04 PM) - %R 24-hour hour and minute; same as %H:%M - %s seconds since 1970-01-01 00:00:00 UTC - %S second (00..60) - %t a tab - %T time; same as %H:%M:%S - %u day of week (1..7); 1 is Monday - %U week number of year, with Sunday as first day of week (00..53) - %V ISO week number, with Monday as first day of week (01..53) - %w day of week (0..6); 0 is Sunday - %W week number of year, with Monday as first day of week (00..53) - %x locale's date representation (e.g., 12/31/99) - %X locale's time representation (e.g., 23:13:48) - %y last two digits of year (00..99) - %Y year - %z +hhmm numeric time zone (e.g., -0400) - %:z +hh:mm numeric time zone (e.g., -04:00) - %::z +hh:mm:ss numeric time zone (e.g., -04:00:00) - %:::z numeric time zone with : to necessary precision (e.g., -04, +05:30) - %Z alphabetic time zone abbreviation (e.g., EDT) +| Sequence | Description | Example | +| -------- | -------------------------------------------------------------------- | ---------------------- | +| %% | a literal % | % | +| %a | locale's abbreviated weekday name | Sun | +| %A | locale's full weekday name | Sunday | +| %b | locale's abbreviated month name | Jan | +| %B | locale's full month name | January | +| %c | locale's date and time | Thu Mar 3 23:05:25 2005| +| %C | century; like %Y, except omit last two digits | 20 | +| %d | day of month | 01 | +| %D | date; same as %m/%d/%y | 12/31/99 | +| %e | day of month, space padded; same as %_d | 3 | +| %F | full date; same as %Y-%m-%d | 2005-03-03 | +| %g | last two digits of year of ISO week number (see %G) | 05 | +| %G | year of ISO week number (see %V); normally useful only with %V | 2005 | +| %h | same as %b | Jan | +| %H | hour (00..23) | 23 | +| %I | hour (01..12) | 11 | +| %j | day of year (001..366) | 062 | +| %k | hour, space padded ( 0..23); same as %_H | 3 | +| %l | hour, space padded ( 1..12); same as %_I | 9 | +| %m | month (01..12) | 03 | +| %M | minute (00..59) | 30 | +| %n | a newline | \n | +| %N | nanoseconds (000000000..999999999) | 123456789 | +| %p | locale's equivalent of either AM or PM; blank if not known | PM | +| %P | like %p, but lower case | pm | +| %q | quarter of year (1..4) | 1 | +| %r | locale's 12-hour clock time | 11:11:04 PM | +| %R | 24-hour hour and minute; same as %H:%M | 23:30 | +| %s | seconds since 1970-01-01 00:00:00 UTC | 1615432800 | +| %S | second (00..60) | 30 | +| %t | a tab | \t | +| %T | time; same as %H:%M:%S | 23:30:30 | +| %u | day of week (1..7); 1 is Monday | 4 | +| %U | week number of year, with Sunday as first day of week (00..53) | 10 | +| %V | ISO week number, with Monday as first day of week (01..53) | 12 | +| %w | day of week (0..6); 0 is Sunday | 4 | +| %W | week number of year, with Monday as first day of week (00..53) | 11 | +| %x | locale's date representation (e.g., 12/31/99) | 03/03/2005 | +| %X | locale's time representation (e.g., 23:13:48) | 23:30:30 | +| %y | last two digits of year (00..99) | 05 | +| %Y | year | 2005 | +| %z | +hhmm numeric time zone (e.g., -0400) | -0400 | +| %:z | +hh:mm numeric time zone (e.g., -04:00) | -04:00 | +| %::z | +hh:mm:ss numeric time zone (e.g., -04:00:00) | -04:00:00 | +| %:::z | numeric time zone with : to necessary precision (e.g., -04, +05:30) | -04 | +| %Z | alphabetic time zone abbreviation (e.g., EDT) | EDT | By default, date pads numeric fields with zeroes. The following optional flags may follow '%': - - (hyphen) do not pad the field - _ (underscore) pad with spaces - 0 (zero) pad with zeros - ^ use upper case if possible - # use opposite case if possible +* `-` (hyphen) do not pad the field +* `_` (underscore) pad with spaces +* `0` (zero) pad with zeros +* `^` use upper case if possible +* `#` use opposite case if possible After any flags comes an optional field width, as a decimal number; then an optional modifier, which is either @@ -68,11 +69,19 @@ O to use the locale's alternate numeric symbols if available. Examples: Convert seconds since the epoch (1970-01-01 UTC) to a date - $ date --date='@2147483647' + +``` +date --date='@2147483647' +``` Show the time on the west coast of the US (use tzselect(1) to find TZ) - $ TZ='America/Los_Angeles' date + +``` +TZ='America/Los_Angeles' date +``` Show the local time for 9AM next Friday on the west coast of the US - $ date --date='TZ="America/Los_Angeles" 09:00 next Fri' + +``` +date --date='TZ="America/Los_Angeles" 09:00 next Fri' ``` From 9b67ad05b842cc71d8dbc787a11c7c98bd9fc6c3 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 26 Apr 2023 10:38:39 +0200 Subject: [PATCH 189/477] build-gnu.sh: always update PATH in Makefile --- util/build-gnu.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/build-gnu.sh b/util/build-gnu.sh index 486cf3227b..2e089dcf94 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -63,6 +63,8 @@ for binary in $(./build-aux/gen-lists-of-programs.sh --list-progs); do done if test -f gnu-built; then + # Change the PATH in the Makefile to test the uutils coreutils instead of the GNU coreutils + sed -i "s/^[[:blank:]]*PATH=.*/ PATH='${UU_BUILD_DIR//\//\\/}\$(PATH_SEPARATOR)'\"\$\$PATH\" \\\/" Makefile echo "GNU build already found. Skip" echo "'rm -f $(pwd)/gnu-built' to force the build" echo "Note: the customization of the tests will still happen" From eb45666bb64d1e0f37b6f7682cb0940ca759f3d8 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 26 Apr 2023 10:40:27 +0200 Subject: [PATCH 190/477] docs: mention UU_MAKE_PROFILE in CONTRIBUTING.md --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f66b2bba8..7dc2565c14 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -217,6 +217,8 @@ To run uutils against the GNU test suite locally, run the following commands: ```shell bash util/build-gnu.sh +# Build uutils without release optimizations +UU_MAKE_PROFILE=debug 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 From aeeb3c90cf803dbf547424fad5154cb1d6345e83 Mon Sep 17 00:00:00 2001 From: John Shin Date: Wed, 26 Apr 2023 09:47:03 -0700 Subject: [PATCH 191/477] mv: check if --target is a directory --- src/uu/mv/src/error.rs | 4 +++- src/uu/mv/src/mv.rs | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/uu/mv/src/error.rs b/src/uu/mv/src/error.rs index 103c1116ab..7810c3a950 100644 --- a/src/uu/mv/src/error.rs +++ b/src/uu/mv/src/error.rs @@ -15,6 +15,7 @@ pub enum MvError { DirectoryToNonDirectory(String), NonDirectoryToDirectory(String, String), NotADirectory(String), + TargetNotADirectory(String), } impl Error for MvError {} @@ -34,7 +35,8 @@ impl Display for MvError { Self::NonDirectoryToDirectory(s, t) => { write!(f, "cannot overwrite non-directory {t} with directory {s}") } - Self::NotADirectory(t) => write!(f, "target {t} is not a directory"), + Self::NotADirectory(t) => write!(f, "target {t}: Not a directory"), + Self::TargetNotADirectory(t) => write!(f, "target directory {t}: Not a directory"), } } } diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index d0a1a766f9..53446dd8a1 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -320,7 +320,12 @@ fn exec(files: &[OsString], b: &Behavior) -> UResult<()> { fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> UResult<()> { if !target_dir.is_dir() { - return Err(MvError::NotADirectory(target_dir.quote().to_string()).into()); + match b.target_dir { + Some(_) => { + return Err(MvError::TargetNotADirectory(target_dir.quote().to_string()).into()) + } + None => return Err(MvError::NotADirectory(target_dir.quote().to_string()).into()), + } } let canonized_target_dir = target_dir From 825d240ef052f4d95b83c22783c76074a3db7233 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 26 Apr 2023 00:11:11 +0200 Subject: [PATCH 192/477] date -d supports - 1 year ago, 2 second, etc --- Cargo.lock | 2 ++ src/uu/date/Cargo.toml | 4 ++++ src/uu/date/src/date.rs | 21 ++++++++++++++++++--- tests/by-util/test_date.rs | 23 +++++++++++++++++++++++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 90af50e20b..a74acc33a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2538,7 +2538,9 @@ version = "0.0.18" dependencies = [ "chrono", "clap", + "humantime_to_duration", "libc", + "time", "uucore", "windows-sys 0.45.0", ] diff --git a/src/uu/date/Cargo.toml b/src/uu/date/Cargo.toml index fab98f20d9..923ca4aa74 100644 --- a/src/uu/date/Cargo.toml +++ b/src/uu/date/Cargo.toml @@ -1,3 +1,4 @@ +# spell-checker:ignore humantime [package] name = "uu_date" version = "0.0.18" @@ -16,8 +17,11 @@ path = "src/date.rs" [dependencies] chrono = { workspace=true } +#/ TODO: check if we can avoid chrono+time +time = { workspace=true } clap = { workspace=true } uucore = { workspace=true } +humantime_to_duration = { workspace=true } [target.'cfg(unix)'.dependencies] libc = { workspace=true } diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index ab874cb32e..8b43386203 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -6,10 +6,10 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (chrono) Datelike Timelike ; (format) DATEFILE MMDDhhmm ; (vars) datetime datetimes +// spell-checker:ignore (chrono) Datelike Timelike ; (format) DATEFILE MMDDhhmm ; (vars) datetime datetimes humantime use chrono::format::{Item, StrftimeItems}; -use chrono::{DateTime, FixedOffset, Local, Offset, Utc}; +use chrono::{DateTime, Duration as ChronoDuration, FixedOffset, Local, Offset, Utc}; #[cfg(windows)] use chrono::{Datelike, Timelike}; use clap::{crate_version, Arg, ArgAction, Command}; @@ -18,6 +18,7 @@ use libc::{clock_settime, timespec, CLOCK_REALTIME}; use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::PathBuf; +use time::Duration; use uucore::display::Quotable; #[cfg(not(any(target_os = "redox")))] use uucore::error::FromIo; @@ -96,6 +97,7 @@ enum DateSource { Now, Custom(String), File(PathBuf), + Human(Duration), } enum Iso8601Format { @@ -168,7 +170,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { }; let date_source = if let Some(date) = matches.get_one::(OPT_DATE) { - DateSource::Custom(date.into()) + if let Ok(duration) = humantime_to_duration::from_str(date.as_str()) { + DateSource::Human(duration) + } else { + DateSource::Custom(date.into()) + } } else if let Some(file) = matches.get_one::(OPT_FILE) { DateSource::File(file.into()) } else { @@ -219,6 +225,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let iter = std::iter::once(date); Box::new(iter) } + DateSource::Human(ref input) => { + // Get the current DateTime and convert the input time::Duration to chrono::Duration + // for things like "1 year ago" + let current_time = DateTime::::from(Local::now()); + let input_chrono = ChronoDuration::seconds(input.as_seconds_f32() as i64) + + ChronoDuration::nanoseconds(input.subsec_nanoseconds() as i64); + let iter = std::iter::once(Ok(current_time + input_chrono)); + Box::new(iter) + } DateSource::File(ref path) => { if path.is_dir() { return Err(USimpleError::new( diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index a1bdda6518..edad87bd6c 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -334,6 +334,29 @@ fn test_invalid_format_string() { assert!(result.stderr_str().starts_with("date: invalid format ")); } +#[test] +fn test_date_string_human() { + let date_formats = vec![ + "1 year ago", + "1 year", + "2 months ago", + "15 days ago", + "1 week ago", + "5 hours ago", + "30 minutes ago", + "10 seconds", + ]; + let re = Regex::new(r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}\n$").unwrap(); + for date_format in date_formats { + new_ucmd!() + .arg("-d") + .arg(date_format) + .arg("+%Y-%m-%d %S:%M") + .succeeds() + .stdout_matches(&re); + } +} + #[test] fn test_invalid_date_string() { new_ucmd!() From 111723aa84b4b1b5f6ae81f71cbc1770e581210f Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 26 Apr 2023 22:43:48 +0200 Subject: [PATCH 193/477] rename date-usage.mkd => date-usage.md --- src/uu/date/{date-usage.mkd => date-usage.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/uu/date/{date-usage.mkd => date-usage.md} (100%) diff --git a/src/uu/date/date-usage.mkd b/src/uu/date/date-usage.md similarity index 100% rename from src/uu/date/date-usage.mkd rename to src/uu/date/date-usage.md From 746331cc651e507b2edda362ca5f89cd5b87a6b8 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Thu, 27 Apr 2023 15:13:46 +0900 Subject: [PATCH 194/477] stdbuf: move help strings to markdown file (#4792) --- src/uu/stdbuf/src/stdbuf.rs | 22 +++++----------------- src/uu/stdbuf/stdbuf.md | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 17 deletions(-) create mode 100644 src/uu/stdbuf/stdbuf.md diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index 2bfb6f908e..e02dd28bc8 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -17,23 +17,11 @@ use tempfile::tempdir; use tempfile::TempDir; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; use uucore::parse_size::parse_size; -use uucore::{crash, format_usage}; - -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."; -const USAGE: &str = "{} OPTION... COMMAND"; -static LONG_HELP: &str = "If MODE is 'L' the corresponding stream will be line buffered.\n\ - This option is invalid with standard input.\n\n\ - If MODE is '0' the corresponding stream will be unbuffered.\n\n\ - Otherwise MODE is a number which may be followed by one of the following:\n\n\ - KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\ - In this case the corresponding stream will be fully buffered with the buffer size set to \ - MODE bytes.\n\n\ - NOTE: If COMMAND adjusts the buffering of its standard streams ('tee' does for e.g.) then \ - that will override corresponding settings changed by 'stdbuf'.\n\ - Also some filters (like 'dd' and 'cat' etc.) don't use streams for I/O, \ - and are thus unaffected by 'stdbuf' settings.\n"; +use uucore::{crash, format_usage, help_about, help_section, help_usage}; + +const ABOUT: &str = help_about!("stdbuf.md"); +const USAGE: &str = help_usage!("stdbuf.md"); +const LONG_HELP: &str = help_section!("after help", "stdbuf.md"); mod options { pub const INPUT: &str = "input"; diff --git a/src/uu/stdbuf/stdbuf.md b/src/uu/stdbuf/stdbuf.md new file mode 100644 index 0000000000..e0062e6271 --- /dev/null +++ b/src/uu/stdbuf/stdbuf.md @@ -0,0 +1,24 @@ +# stdbuf + +``` +stdbuf [OPTION]... COMMAND +``` + +Run `COMMAND`, with modified buffering operations for its standard streams. + +Mandatory arguments to long options are mandatory for short options too. + +## After Help + +If `MODE` is 'L' the corresponding stream will be line buffered. +This option is invalid with standard input. + +If `MODE` is '0' the corresponding stream will be unbuffered. + +Otherwise, `MODE` is a number which may be followed by one of the following: + +KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y. +In this case the corresponding stream will be fully buffered with the buffer size set to `MODE` bytes. + +NOTE: If `COMMAND` adjusts the buffering of its standard streams (`tee` does for e.g.) then that will override corresponding settings changed by `stdbuf`. +Also some filters (like `dd` and `cat` etc.) don't use streams for I/O, and are thus unaffected by `stdbuf` settings. From eb8f353a2ffb9671f729d9773173e7f890028b32 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 27 Apr 2023 09:17:39 +0200 Subject: [PATCH 195/477] date usage help: Remove the examples in the description table we have a new column with examples --- src/uu/date/date-usage.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/uu/date/date-usage.md b/src/uu/date/date-usage.md index 5489028e4d..bf2dc469d3 100644 --- a/src/uu/date/date-usage.md +++ b/src/uu/date/date-usage.md @@ -43,15 +43,15 @@ FORMAT controls the output. Interpreted sequences are: | %V | ISO week number, with Monday as first day of week (01..53) | 12 | | %w | day of week (0..6); 0 is Sunday | 4 | | %W | week number of year, with Monday as first day of week (00..53) | 11 | -| %x | locale's date representation (e.g., 12/31/99) | 03/03/2005 | -| %X | locale's time representation (e.g., 23:13:48) | 23:30:30 | +| %x | locale's date representation | 03/03/2005 | +| %X | locale's time representation | 23:30:30 | | %y | last two digits of year (00..99) | 05 | | %Y | year | 2005 | -| %z | +hhmm numeric time zone (e.g., -0400) | -0400 | -| %:z | +hh:mm numeric time zone (e.g., -04:00) | -04:00 | -| %::z | +hh:mm:ss numeric time zone (e.g., -04:00:00) | -04:00:00 | -| %:::z | numeric time zone with : to necessary precision (e.g., -04, +05:30) | -04 | -| %Z | alphabetic time zone abbreviation (e.g., EDT) | EDT | +| %z | +hhmm numeric time zone | -0400 | +| %:z | +hh:mm numeric time zone | -04:00 | +| %::z | +hh:mm:ss numeric time zone | -04:00:00 | +| %:::z | numeric time zone with : to necessary precision | -04, +05:30 | +| %Z | alphabetic time zone abbreviation | EDT | By default, date pads numeric fields with zeroes. The following optional flags may follow '%': From ecde4b6aa3894f4ee7bdd408fe9ebc0f3f8ec29c Mon Sep 17 00:00:00 2001 From: John Shin Date: Thu, 27 Apr 2023 04:46:48 -0700 Subject: [PATCH 196/477] core: introduce update controller for mv and cp --- src/uucore/src/lib/lib.rs | 1 + src/uucore/src/lib/mods.rs | 1 + src/uucore/src/lib/mods/update_control.rs | 57 +++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 src/uucore/src/lib/mods/update_control.rs diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index 00162ddbba..e76e540c8d 100644 --- a/src/uucore/src/lib/lib.rs +++ b/src/uucore/src/lib/lib.rs @@ -26,6 +26,7 @@ pub use crate::mods::os; pub use crate::mods::panic; pub use crate::mods::quoting_style; pub use crate::mods::ranges; +pub use crate::mods::update_control; pub use crate::mods::version_cmp; // * string parsing modules diff --git a/src/uucore/src/lib/mods.rs b/src/uucore/src/lib/mods.rs index 4b6c53f953..71d288c69a 100644 --- a/src/uucore/src/lib/mods.rs +++ b/src/uucore/src/lib/mods.rs @@ -6,6 +6,7 @@ pub mod error; pub mod os; pub mod panic; pub mod ranges; +pub mod update_control; pub mod version_cmp; // dir and vdir also need access to the quoting_style module pub mod quoting_style; diff --git a/src/uucore/src/lib/mods/update_control.rs b/src/uucore/src/lib/mods/update_control.rs new file mode 100644 index 0000000000..a743b93409 --- /dev/null +++ b/src/uucore/src/lib/mods/update_control.rs @@ -0,0 +1,57 @@ +use clap::ArgMatches; + +pub static UPDATE_CONTROL_VALUES: &[&str] = &["all", "none", "old", ""]; + +pub const UPDATE_CONTROL_LONG_HELP: &str = "VERY LONG HELP"; + +#[derive(Clone, Eq, PartialEq)] +pub enum UpdateMode { + ReplaceAll, + ReplaceNone, + ReplaceIfOlder, +} + +pub mod arguments { + use clap::ArgAction; + + pub static OPT_UPDATE: &str = "update"; + pub static OPT_UPDATE_NO_ARG: &str = "u"; + + pub fn update() -> clap::Arg { + clap::Arg::new(OPT_UPDATE) + .long("update") + .help("some help") + .value_parser(["", "none", "all", "older"]) + .num_args(0..=1) + .default_missing_value("all") + .require_equals(true) + .overrides_with("update") + .action(clap::ArgAction::Set) + } + + pub fn update_no_args() -> clap::Arg { + clap::Arg::new(OPT_UPDATE_NO_ARG) + .short('u') + .help("like ") + .action(ArgAction::SetTrue) + } +} + +pub fn determine_update_mode(matches: &ArgMatches) -> UpdateMode { + if matches.contains_id(arguments::OPT_UPDATE) { + if let Some(mode) = matches.get_one::(arguments::OPT_UPDATE) { + match mode.as_str() { + "all" | "" => UpdateMode::ReplaceAll, + "none" => UpdateMode::ReplaceNone, + "older" => UpdateMode::ReplaceIfOlder, + _ => unreachable!("other args restricted by clap"), + } + } else { + unreachable!("other args restricted by clap") + } + } else if matches.get_flag(arguments::OPT_UPDATE_NO_ARG) { + UpdateMode::ReplaceIfOlder + } else { + UpdateMode::ReplaceAll + } +} From 0e8dd894a3700835ca63f04c8636533f4343aa4e Mon Sep 17 00:00:00 2001 From: John Shin Date: Thu, 27 Apr 2023 04:48:41 -0700 Subject: [PATCH 197/477] mv: implement update=[switch] --- src/uu/mv/src/mv.rs | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index d0a1a766f9..2951550c63 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -25,6 +25,7 @@ use std::path::{Path, PathBuf}; use uucore::backup_control::{self, BackupMode}; use uucore::display::Quotable; use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError}; +use uucore::update_control::{self, UpdateMode}; use uucore::{format_usage, help_about, help_usage, prompt_yes, show}; use fs_extra::dir::{ @@ -38,7 +39,7 @@ pub struct Behavior { overwrite: OverwriteMode, backup: BackupMode, suffix: String, - update: bool, + update: UpdateMode, target_dir: Option, no_target_dir: bool, verbose: bool, @@ -62,14 +63,15 @@ static OPT_NO_CLOBBER: &str = "no-clobber"; static OPT_STRIP_TRAILING_SLASHES: &str = "strip-trailing-slashes"; static OPT_TARGET_DIRECTORY: &str = "target-directory"; static OPT_NO_TARGET_DIRECTORY: &str = "no-target-directory"; -static OPT_UPDATE: &str = "update"; static OPT_VERBOSE: &str = "verbose"; static OPT_PROGRESS: &str = "progress"; static ARG_FILES: &str = "files"; #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let mut app = uu_app().after_help(backup_control::BACKUP_CONTROL_LONG_HELP); + let mut app = uu_app() + .after_help(backup_control::BACKUP_CONTROL_LONG_HELP) + .after_help(update_control::UPDATE_CONTROL_LONG_HELP); let matches = app.try_get_matches_from_mut(args)?; if !matches.contains_id(OPT_TARGET_DIRECTORY) @@ -96,6 +98,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let overwrite_mode = determine_overwrite_mode(&matches); let backup_mode = backup_control::determine_backup_mode(&matches)?; + let update_mode = update_control::determine_update_mode(&matches); if overwrite_mode == OverwriteMode::NoClobber && backup_mode != BackupMode::NoBackup { return Err(UUsageError::new( @@ -110,7 +113,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { overwrite: overwrite_mode, backup: backup_mode, suffix: backup_suffix, - update: matches.get_flag(OPT_UPDATE), + update: update_mode, target_dir: matches .get_one::(OPT_TARGET_DIRECTORY) .map(OsString::from), @@ -131,6 +134,8 @@ pub fn uu_app() -> Command { .infer_long_args(true) .arg(backup_control::arguments::backup()) .arg(backup_control::arguments::backup_no_args()) + .arg(update_control::arguments::update()) + .arg(update_control::arguments::update_no_args()) .arg( Arg::new(OPT_FORCE) .short('f') @@ -176,16 +181,6 @@ pub fn uu_app() -> Command { .help("treat DEST as a normal file") .action(ArgAction::SetTrue), ) - .arg( - Arg::new(OPT_UPDATE) - .short('u') - .long(OPT_UPDATE) - .help( - "move only when the SOURCE file is newer than the destination file \ - or when the destination file is missing", - ) - .action(ArgAction::SetTrue), - ) .arg( Arg::new(OPT_VERBOSE) .short('v') @@ -412,7 +407,9 @@ fn rename( let mut backup_path = None; if to.exists() { - if b.update && b.overwrite == OverwriteMode::Interactive { + if (b.update == UpdateMode::ReplaceIfOlder || b.update == UpdateMode::ReplaceNone) + && b.overwrite == OverwriteMode::Interactive + { // `mv -i --update old new` when `new` exists doesn't move anything // and exit with 0 return Ok(()); @@ -433,7 +430,9 @@ fn rename( rename_with_fallback(to, backup_path, multi_progress)?; } - if b.update && fs::metadata(from)?.modified()? <= fs::metadata(to)?.modified()? { + if (b.update == UpdateMode::ReplaceIfOlder) + && fs::metadata(from)?.modified()? <= fs::metadata(to)?.modified()? + { return Ok(()); } } From 9dc84e906114ce4368d66d621301b46f845977c1 Mon Sep 17 00:00:00 2001 From: John Shin Date: Thu, 27 Apr 2023 04:49:27 -0700 Subject: [PATCH 198/477] cp: implement update=[switch] --- src/uu/cp/src/cp.rs | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 80540d222e..f302d48737 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -40,6 +40,7 @@ use uucore::error::{set_exit_code, UClapError, UError, UResult, UUsageError}; use uucore::fs::{ canonicalize, paths_refer_to_same_file, FileInformation, MissingHandling, ResolveMode, }; +use uucore::update_control::{self, UpdateMode}; use uucore::{crash, format_usage, help_about, help_usage, prompt_yes, show_error, show_warning}; use crate::copydir::copy_directory; @@ -224,7 +225,7 @@ pub struct Options { recursive: bool, backup_suffix: String, target_dir: Option, - update: bool, + update: UpdateMode, verbose: bool, progress_bar: bool, } @@ -264,7 +265,6 @@ mod options { pub const STRIP_TRAILING_SLASHES: &str = "strip-trailing-slashes"; pub const SYMBOLIC_LINK: &str = "symbolic-link"; pub const TARGET_DIRECTORY: &str = "target-directory"; - pub const UPDATE: &str = "update"; pub const VERBOSE: &str = "verbose"; } @@ -296,6 +296,8 @@ pub fn uu_app() -> Command { .about(ABOUT) .override_usage(format_usage(USAGE)) .infer_long_args(true) + .arg(update_control::arguments::update()) + .arg(update_control::arguments::update_no_args()) .arg( Arg::new(options::TARGET_DIRECTORY) .short('t') @@ -393,16 +395,6 @@ pub fn uu_app() -> Command { .arg(backup_control::arguments::backup()) .arg(backup_control::arguments::backup_no_args()) .arg(backup_control::arguments::suffix()) - .arg( - Arg::new(options::UPDATE) - .short('u') - .long(options::UPDATE) - .help( - "copy only when the SOURCE file is newer than the destination file \ - or when the destination file is missing", - ) - .action(ArgAction::SetTrue), - ) .arg( Arg::new(options::REFLINK) .long(options::REFLINK) @@ -641,7 +633,11 @@ impl CopyMode { Self::Link } else if matches.get_flag(options::SYMBOLIC_LINK) { Self::SymLink - } else if matches.get_flag(options::UPDATE) { + } else if matches + .get_one::(update_control::arguments::OPT_UPDATE) + .is_some() + || matches.get_flag(update_control::arguments::OPT_UPDATE_NO_ARG) + { Self::Update } else if matches.get_flag(options::ATTRIBUTES_ONLY) { Self::AttrOnly @@ -749,6 +745,7 @@ impl Options { Err(e) => return Err(Error::Backup(format!("{e}"))), Ok(mode) => mode, }; + let update_mode = update_control::determine_update_mode(matches); let backup_suffix = backup_control::determine_backup_suffix(matches); @@ -826,7 +823,7 @@ impl Options { || matches.get_flag(options::DEREFERENCE), one_file_system: matches.get_flag(options::ONE_FILE_SYSTEM), parents: matches.get_flag(options::PARENTS), - update: matches.get_flag(options::UPDATE), + update: update_mode, verbose: matches.get_flag(options::VERBOSE), strip_trailing_slashes: matches.get_flag(options::STRIP_TRAILING_SLASHES), reflink_mode: { @@ -1473,7 +1470,9 @@ fn copy_file( symlinked_files: &mut HashSet, source_in_command_line: bool, ) -> CopyResult<()> { - if options.update && options.overwrite == OverwriteMode::Interactive(ClobberMode::Standard) { + if (options.update == UpdateMode::ReplaceIfOlder || options.update == UpdateMode::ReplaceNone) + && options.overwrite == OverwriteMode::Interactive(ClobberMode::Standard) + { // `cp -i --update old new` when `new` exists doesn't copy anything // and exit with 0 return Ok(()); From c49769865a1e9b894880a6904a20009dace84c50 Mon Sep 17 00:00:00 2001 From: m11o Date: Thu, 27 Apr 2023 22:14:52 +0900 Subject: [PATCH 199/477] stty: move help strings to markdown file --- src/uu/stty/src/stty.rs | 9 +++------ src/uu/stty/stty.md | 9 +++++++++ 2 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 src/uu/stty/stty.md diff --git a/src/uu/stty/src/stty.rs b/src/uu/stty/src/stty.rs index 928c3f1774..19340830de 100644 --- a/src/uu/stty/src/stty.rs +++ b/src/uu/stty/src/stty.rs @@ -18,7 +18,7 @@ use std::ops::ControlFlow; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; use uucore::error::{UResult, USimpleError}; -use uucore::format_usage; +use uucore::{format_usage, help_usage, help_about}; #[cfg(not(any( target_os = "freebsd", @@ -31,11 +31,8 @@ use uucore::format_usage; use flags::BAUD_RATES; use flags::{CONTROL_FLAGS, INPUT_FLAGS, LOCAL_FLAGS, OUTPUT_FLAGS}; -const USAGE: &str = "\ - {} [-F DEVICE | --file=DEVICE] [SETTING]... - {} [-F DEVICE | --file=DEVICE] [-a|--all] - {} [-F DEVICE | --file=DEVICE] [-g|--save]"; -const SUMMARY: &str = "Print or change terminal characteristics."; +const USAGE: &str = help_usage!("stty.md"); +const SUMMARY: &str = help_about!("stty.md"); #[derive(Clone, Copy, Debug)] pub struct Flag { diff --git a/src/uu/stty/stty.md b/src/uu/stty/stty.md new file mode 100644 index 0000000000..6aa1decf5e --- /dev/null +++ b/src/uu/stty/stty.md @@ -0,0 +1,9 @@ +# stty + +``` +stty [-F DEVICE | --file=DEVICE] [SETTING]... +stty [-F DEVICE | --file=DEVICE] [-a|--all] +stty [-F DEVICE | --file=DEVICE] [-g|--save] +``` + +Print or change terminal characteristics. From 0391239273d1ec98c64330df84095ab4e5fb21f9 Mon Sep 17 00:00:00 2001 From: m11o Date: Thu, 27 Apr 2023 22:17:37 +0900 Subject: [PATCH 200/477] fix cargo fmt --- src/uu/stty/src/stty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/stty/src/stty.rs b/src/uu/stty/src/stty.rs index 19340830de..e096624713 100644 --- a/src/uu/stty/src/stty.rs +++ b/src/uu/stty/src/stty.rs @@ -18,7 +18,7 @@ use std::ops::ControlFlow; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; use uucore::error::{UResult, USimpleError}; -use uucore::{format_usage, help_usage, help_about}; +use uucore::{format_usage, help_about, help_usage}; #[cfg(not(any( target_os = "freebsd", From 467cbf30dee78ad967ae33513c6c0b7e5ea19134 Mon Sep 17 00:00:00 2001 From: Niyaz Nigmatullin Date: Wed, 26 Apr 2023 14:22:35 +0300 Subject: [PATCH 201/477] [tests/ls] Support user names containing dots - Fix regex's in tests for `ls -l` --- tests/by-util/test_ls.rs | 91 +++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 0779a28855..84efb9daa4 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1276,7 +1276,7 @@ fn test_ls_long_formats() { // Zero or one "." for indicating a file with security context // Regex for three names, so all of author, group and owner - let re_three = Regex::new(r"[xrw-]{9}\.? \d ([-0-9_a-z_A-Z]+ ){3}0").unwrap(); + let re_three = Regex::new(r"[xrw-]{9}\.? \d ([-0-9_a-z.A-Z]+ ){3}0").unwrap(); #[cfg(unix)] let re_three_num = Regex::new(r"[xrw-]{9}\.? \d (\d+ ){3}0").unwrap(); @@ -1285,13 +1285,13 @@ fn test_ls_long_formats() { // - group and owner // - author and owner // - author and group - let re_two = Regex::new(r"[xrw-]{9}\.? \d ([-0-9_a-z_A-Z]+ ){2}0").unwrap(); + let re_two = Regex::new(r"[xrw-]{9}\.? \d ([-0-9_a-z.A-Z]+ ){2}0").unwrap(); #[cfg(unix)] let re_two_num = Regex::new(r"[xrw-]{9}\.? \d (\d+ ){2}0").unwrap(); // Regex for one name: author, group or owner - let re_one = Regex::new(r"[xrw-]{9}\.? \d [-0-9_a-z_A-Z]+ 0").unwrap(); + let re_one = Regex::new(r"[xrw-]{9}\.? \d [-0-9_a-z.A-Z]+ 0").unwrap(); #[cfg(unix)] let re_one_num = Regex::new(r"[xrw-]{9}\.? \d \d+ 0").unwrap(); @@ -1640,88 +1640,103 @@ fn test_ls_styles() { at.touch("test"); let re_full = Regex::new( - r"[a-z-]* \d* \w* \w* \d* \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d* (\+|\-)\d{4} test\n", + r"[a-z-]* \d* [\w.]* [\w.]* \d* \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d* (\+|\-)\d{4} test\n", ) .unwrap(); let re_long = - Regex::new(r"[a-z-]* \d* \w* \w* \d* \d{4}-\d{2}-\d{2} \d{2}:\d{2} test\n").unwrap(); - let re_iso = Regex::new(r"[a-z-]* \d* \w* \w* \d* \d{2}-\d{2} \d{2}:\d{2} test\n").unwrap(); + Regex::new(r"[a-z-]* \d* [\w.]* [\w.]* \d* \d{4}-\d{2}-\d{2} \d{2}:\d{2} test\n").unwrap(); + let re_iso = + Regex::new(r"[a-z-]* \d* [\w.]* [\w.]* \d* \d{2}-\d{2} \d{2}:\d{2} test\n").unwrap(); let re_locale = - Regex::new(r"[a-z-]* \d* \w* \w* \d* [A-Z][a-z]{2} ( |\d)\d \d{2}:\d{2} test\n").unwrap(); - let re_custom_format = Regex::new(r"[a-z-]* \d* \w* \w* \d* \d{4}__\d{2} test\n").unwrap(); + Regex::new(r"[a-z-]* \d* [\w.]* [\w.]* \d* [A-Z][a-z]{2} ( |\d)\d \d{2}:\d{2} test\n") + .unwrap(); + let re_custom_format = + Regex::new(r"[a-z-]* \d* [\w.]* [\w.]* \d* \d{4}__\d{2} test\n").unwrap(); //full-iso - let result = scene + scene .ucmd() .arg("-l") .arg("--time-style=full-iso") - .succeeds(); - assert!(re_full.is_match(result.stdout_str())); + .succeeds() + .stdout_matches(&re_full); //long-iso - let result = scene + scene .ucmd() .arg("-l") .arg("--time-style=long-iso") - .succeeds(); - assert!(re_long.is_match(result.stdout_str())); + .succeeds() + .stdout_matches(&re_long); //iso - let result = scene.ucmd().arg("-l").arg("--time-style=iso").succeeds(); - assert!(re_iso.is_match(result.stdout_str())); + scene + .ucmd() + .arg("-l") + .arg("--time-style=iso") + .succeeds() + .stdout_matches(&re_iso); //locale - let result = scene.ucmd().arg("-l").arg("--time-style=locale").succeeds(); - assert!(re_locale.is_match(result.stdout_str())); + scene + .ucmd() + .arg("-l") + .arg("--time-style=locale") + .succeeds() + .stdout_matches(&re_locale); //+FORMAT - let result = scene + scene .ucmd() .arg("-l") .arg("--time-style=+%Y__%M") - .succeeds(); - assert!(re_custom_format.is_match(result.stdout_str())); + .succeeds() + .stdout_matches(&re_custom_format); // Also fails due to not having full clap support for time_styles scene.ucmd().arg("-l").arg("-time-style=invalid").fails(); //Overwrite options tests - let result = scene + scene .ucmd() .arg("-l") .arg("--time-style=long-iso") .arg("--time-style=iso") - .succeeds(); - assert!(re_iso.is_match(result.stdout_str())); - let result = scene + .succeeds() + .stdout_matches(&re_iso); + scene .ucmd() .arg("--time-style=iso") .arg("--full-time") - .succeeds(); - assert!(re_full.is_match(result.stdout_str())); - let result = scene + .succeeds() + .stdout_matches(&re_full); + scene .ucmd() .arg("--full-time") .arg("--time-style=iso") - .succeeds(); - assert!(re_iso.is_match(result.stdout_str())); + .succeeds() + .stdout_matches(&re_iso); - let result = scene + scene .ucmd() .arg("--full-time") .arg("--time-style=iso") .arg("--full-time") - .succeeds(); - assert!(re_full.is_match(result.stdout_str())); + .succeeds() + .stdout_matches(&re_full); - let result = scene + scene .ucmd() .arg("--full-time") .arg("-x") .arg("-l") - .succeeds(); - assert!(re_full.is_match(result.stdout_str())); + .succeeds() + .stdout_matches(&re_full); at.touch("test2"); - let result = scene.ucmd().arg("--full-time").arg("-x").succeeds(); - assert_eq!(result.stdout_str(), "test test2\n"); + scene + .ucmd() + .arg("--full-time") + .arg("-x") + .succeeds() + .stdout_is("test test2\n"); } #[test] From a93bccb5b93d1fb1adb5e032f95d9c4c25c72155 Mon Sep 17 00:00:00 2001 From: John Shin Date: Thu, 27 Apr 2023 15:35:21 -0700 Subject: [PATCH 202/477] mv: add tests for --target --- tests/by-util/test_mv.rs | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 0342341071..3b5aa3ee3d 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -55,6 +55,63 @@ fn test_mv_move_file_into_dir() { assert!(at.file_exists(format!("{dir}/{file}"))); } +#[test] +fn test_mv_move_file_into_dir_with_target_arg() { + let (at, mut ucmd) = at_and_ucmd!(); + let dir = "test_mv_move_file_into_dir_with_target_arg_dir"; + let file = "test_mv_move_file_into_dir_with_target_arg_file"; + + at.mkdir(dir); + at.touch(file); + + ucmd.arg("--target") + .arg(dir) + .arg(file) + .succeeds() + .no_stderr(); + + assert!(at.file_exists(format!("{dir}/{file}"))) +} + +#[test] +fn test_mv_move_file_into_file_with_target_arg() { + let (at, mut ucmd) = at_and_ucmd!(); + let file1 = "test_mv_move_file_into_file_with_target_arg_file1"; + let file2 = "test_mv_move_file_into_file_with_target_arg_file2"; + + at.touch(file1); + at.touch(file2); + + ucmd.arg("--target") + .arg(file1) + .arg(file2) + .fails() + .stderr_is(format!("mv: target directory '{file1}': Not a directory\n")); + + assert!(at.file_exists(file1)) +} + +#[test] +fn test_mv_move_multiple_files_into_file() { + let (at, mut ucmd) = at_and_ucmd!(); + let file1 = "test_mv_move_multiple_files_into_file1"; + let file2 = "test_mv_move_multiple_files_into_file2"; + let file3 = "test_mv_move_multiple_files_into_file3"; + + at.touch(file1); + at.touch(file2); + at.touch(file3); + + ucmd.arg(file1) + .arg(file2) + .arg(file3) + .fails() + .stderr_is(format!("mv: target '{file3}': Not a directory\n")); + + assert!(at.file_exists(file1)); + assert!(at.file_exists(file2)); +} + #[test] fn test_mv_move_file_between_dirs() { let (at, mut ucmd) = at_and_ucmd!(); From 3ca1fa8dfd207dffa209ea464f6e56dbf27149da Mon Sep 17 00:00:00 2001 From: m11o Date: Fri, 28 Apr 2023 20:21:44 +0900 Subject: [PATCH 203/477] sum: move help strings to markdown file --- src/uu/sum/src/sum.rs | 7 +++---- src/uu/sum/sum.md | 9 +++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 src/uu/sum/sum.md diff --git a/src/uu/sum/src/sum.rs b/src/uu/sum/src/sum.rs index 1134f24448..0ea415b134 100644 --- a/src/uu/sum/src/sum.rs +++ b/src/uu/sum/src/sum.rs @@ -13,11 +13,10 @@ use std::io::{stdin, Read}; use std::path::Path; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; -use uucore::{format_usage, show}; +use uucore::{format_usage, help_about, help_usage, show}; -static USAGE: &str = "{} [OPTION]... [FILE]..."; -static ABOUT: &str = "Checksum and count the blocks in a file.\n\n\ - With no FILE, or when FILE is -, read standard input."; +const USAGE: &str = help_usage!("sum.md"); +const ABOUT: &str = help_about!("sum.md"); // This can be replaced with usize::div_ceil once it is stabilized. // This implementation approach is optimized for when `b` is a constant, diff --git a/src/uu/sum/sum.md b/src/uu/sum/sum.md new file mode 100644 index 0000000000..ca3adb81f3 --- /dev/null +++ b/src/uu/sum/sum.md @@ -0,0 +1,9 @@ +# sum + +``` +sum [OPTION]... [FILE]..." +``` + +Checksum and count the blocks in a file. + +With no FILE, or when FILE is -, read standard input. From c254900db92b994e2e6b038d4869ba0610dd3c79 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 22 Jun 2022 09:37:16 +0200 Subject: [PATCH 204/477] paste: handle list ending with unescaped backslash --- src/uu/paste/src/paste.rs | 14 +++++++++++--- tests/by-util/test_paste.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/uu/paste/src/paste.rs b/src/uu/paste/src/paste.rs index d7a4d325c6..c8d8076355 100644 --- a/src/uu/paste/src/paste.rs +++ b/src/uu/paste/src/paste.rs @@ -12,7 +12,7 @@ use std::fmt::Display; use std::fs::File; use std::io::{stdin, stdout, BufRead, BufReader, Read, Write}; use std::path::Path; -use uucore::error::{FromIo, UResult}; +use uucore::error::{FromIo, UResult, USimpleError}; use uucore::{format_usage, help_about, help_usage}; const ABOUT: &str = help_about!("paste.md"); @@ -129,6 +129,16 @@ fn paste( files.push(file); } + if delimiters.ends_with('\\') && !delimiters.ends_with("\\\\") { + return Err(USimpleError::new( + 1, + format!( + "delimiter list ends with an unescaped backslash: {}", + delimiters + ), + )); + } + let delimiters: Vec = unescape(delimiters).chars().collect(); let mut delim_count = 0; let mut delim_length = 1; @@ -222,10 +232,8 @@ fn paste( } // Unescape all special characters -// TODO: this will need work to conform to GNU implementation fn unescape(s: &str) -> String { s.replace("\\n", "\n") .replace("\\t", "\t") .replace("\\\\", "\\") - .replace('\\', "") } diff --git a/tests/by-util/test_paste.rs b/tests/by-util/test_paste.rs index 2e119846ed..fa7ead3359 100644 --- a/tests/by-util/test_paste.rs +++ b/tests/by-util/test_paste.rs @@ -156,6 +156,37 @@ fn test_multi_stdin() { } } +#[test] +fn test_delimiter_list_ending_with_escaped_backslash() { + for d in ["-d", "--delimiters"] { + let (at, mut ucmd) = at_and_ucmd!(); + let mut ins = vec![]; + for (i, _in) in ["a\n", "b\n"].iter().enumerate() { + let file = format!("in{}", i); + at.write(&file, _in); + ins.push(file); + } + ucmd.args(&[d, "\\\\"]) + .args(&ins) + .succeeds() + .stdout_is("a\\b\n"); + } +} + +#[test] +fn test_delimiter_list_ending_with_unescaped_backslash() { + for d in ["-d", "--delimiters"] { + new_ucmd!() + .args(&[d, "\\"]) + .fails() + .stderr_contains("delimiter list ends with an unescaped backslash: \\"); + new_ucmd!() + .args(&[d, "_\\"]) + .fails() + .stderr_contains("delimiter list ends with an unescaped backslash: _\\"); + } +} + #[test] fn test_data() { for example in EXAMPLE_DATA { From 736a00a85f7e7bc5823327bc8b413d2bcdaf3957 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 28 Apr 2023 15:08:01 +0200 Subject: [PATCH 205/477] paste: ignore failing test on Windows --- tests/by-util/test_paste.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/by-util/test_paste.rs b/tests/by-util/test_paste.rs index fa7ead3359..da92daa32f 100644 --- a/tests/by-util/test_paste.rs +++ b/tests/by-util/test_paste.rs @@ -157,6 +157,8 @@ fn test_multi_stdin() { } #[test] +// TODO: make this test work on Windows +#[cfg(not(windows))] fn test_delimiter_list_ending_with_escaped_backslash() { for d in ["-d", "--delimiters"] { let (at, mut ucmd) = at_and_ucmd!(); From ee3da4284c8ad844498f6b3314054f5f9321925b Mon Sep 17 00:00:00 2001 From: John Shin Date: Fri, 28 Apr 2023 18:39:41 -0700 Subject: [PATCH 206/477] mv: update gnu error message to match the one generated by clap --- util/build-gnu.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/build-gnu.sh b/util/build-gnu.sh index 486cf3227b..9364961dc0 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -220,6 +220,9 @@ sed -i -Ez "s/\n([^\n#]*pad-3\.2[^\n]*)\n([^\n]*)\n([^\n]*)/\n# uutils\/numfmt s # Update the GNU error message to match the one generated by clap sed -i -e "s/\$prog: multiple field specifications/error: The argument '--field ' was provided more than once, but cannot be used multiple times\n\nUsage: numfmt [OPTION]... [NUMBER]...\n\n\nFor more information try '--help'/g" tests/misc/numfmt.pl +sed -i -e "s/Try 'mv --help' for more information/For more information, try '--help'/g" tests/mv/diag.sh +sed -i -e "s/mv: missing file operand/error: the following required arguments were not provided:\n ...\n\nUsage: mv [OPTION]... [-T] SOURCE DEST\n mv [OPTION]... SOURCE... DIRECTORY\n mv [OPTION]... -t DIRECTORY SOURCE...\n/g" tests/mv/diag.sh +sed -i -e "s/mv: missing destination file operand after 'no-file'/error: The argument '...' requires at least 2 values, but only 1 was provided\n\nUsage: mv [OPTION]... [-T] SOURCE DEST\n mv [OPTION]... SOURCE... DIRECTORY\n mv [OPTION]... -t DIRECTORY SOURCE...\n/g" tests/mv/diag.sh # GNU doesn't support width > INT_MAX # disable these test cases From bc7a01dd3bfd20689026a76e2eb31bea5f875779 Mon Sep 17 00:00:00 2001 From: m11o Date: Sat, 29 Apr 2023 15:51:55 +0900 Subject: [PATCH 207/477] sync: move help strings to markdown file --- src/uu/sync/src/sync.rs | 7 ++++--- src/uu/sync/sync.md | 7 +++++++ 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 src/uu/sync/sync.md diff --git a/src/uu/sync/src/sync.rs b/src/uu/sync/src/sync.rs index 120e31dfee..e12703bcab 100644 --- a/src/uu/sync/src/sync.rs +++ b/src/uu/sync/src/sync.rs @@ -19,10 +19,11 @@ use uucore::display::Quotable; #[cfg(any(target_os = "linux", target_os = "android"))] use uucore::error::FromIo; use uucore::error::{UResult, USimpleError}; -use uucore::format_usage; +use uucore::{format_usage, help_about, help_usage}; + +const ABOUT: &str = help_about!("sync.md"); +const USAGE: &str = help_usage!("sync.md"); -static ABOUT: &str = "Synchronize cached writes to persistent storage"; -const USAGE: &str = "{} [OPTION]... FILE..."; pub mod options { pub static FILE_SYSTEM: &str = "file-system"; pub static DATA: &str = "data"; diff --git a/src/uu/sync/sync.md b/src/uu/sync/sync.md new file mode 100644 index 0000000000..2fdd363399 --- /dev/null +++ b/src/uu/sync/sync.md @@ -0,0 +1,7 @@ +# sync + +``` +sync [OPTION]... FILE... +``` + +Synchronize cached writes to persistent storage From 5a77608ef94096fd33b8744e550b81aa2632d7cf Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 29 Apr 2023 09:48:05 +0200 Subject: [PATCH 208/477] move the declaration on a single line --- util/build-gnu.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/util/build-gnu.sh b/util/build-gnu.sh index 9364961dc0..cc7dceedcd 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -220,9 +220,7 @@ sed -i -Ez "s/\n([^\n#]*pad-3\.2[^\n]*)\n([^\n]*)\n([^\n]*)/\n# uutils\/numfmt s # Update the GNU error message to match the one generated by clap sed -i -e "s/\$prog: multiple field specifications/error: The argument '--field ' was provided more than once, but cannot be used multiple times\n\nUsage: numfmt [OPTION]... [NUMBER]...\n\n\nFor more information try '--help'/g" tests/misc/numfmt.pl -sed -i -e "s/Try 'mv --help' for more information/For more information, try '--help'/g" tests/mv/diag.sh -sed -i -e "s/mv: missing file operand/error: the following required arguments were not provided:\n ...\n\nUsage: mv [OPTION]... [-T] SOURCE DEST\n mv [OPTION]... SOURCE... DIRECTORY\n mv [OPTION]... -t DIRECTORY SOURCE...\n/g" tests/mv/diag.sh -sed -i -e "s/mv: missing destination file operand after 'no-file'/error: The argument '...' requires at least 2 values, but only 1 was provided\n\nUsage: mv [OPTION]... [-T] SOURCE DEST\n mv [OPTION]... SOURCE... DIRECTORY\n mv [OPTION]... -t DIRECTORY SOURCE...\n/g" tests/mv/diag.sh +sed -i -e "s/Try 'mv --help' for more information/For more information, try '--help'/g" -e "s/mv: missing file operand/error: the following required arguments were not provided:\n ...\n\nUsage: mv [OPTION]... [-T] SOURCE DEST\n mv [OPTION]... SOURCE... DIRECTORY\n mv [OPTION]... -t DIRECTORY SOURCE...\n/g" -e "s/mv: missing destination file operand after 'no-file'/error: The argument '...' requires at least 2 values, but only 1 was provided\n\nUsage: mv [OPTION]... [-T] SOURCE DEST\n mv [OPTION]... SOURCE... DIRECTORY\n mv [OPTION]... -t DIRECTORY SOURCE...\n/g" tests/mv/diag.sh # GNU doesn't support width > INT_MAX # disable these test cases From 6f44d9b7aff1abe25944315c68055ab424a72f78 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 29 Apr 2023 10:52:03 +0200 Subject: [PATCH 209/477] android: use cargo test instead of nextest nextest does build because of: 2023-04-29T08:03:36.5411530Z Compiling log v0.4.17 2023-04-29T08:03:36.5412100Z error[E0432]: unresolved import linux_raw_sys::ioctl 2023-04-29T08:03:36.5412710Z --> /data/data/com.termux/files/home/.cargo/registry/src/github.com-1285ae84e5963aae/rustix-0.37.17/src/backend/libc/io/syscalls.rs:384:24 2023-04-29T08:03:36.5413150Z | 2023-04-29T08:03:36.5413830Z 384 | use linux_raw_sys::ioctl::EXT4_IOC_RESIZE_FS; 2023-04-29T08:03:36.5414380Z | could not find ioctl in linux_raw_sys 2023-04-29T08:03:36.5414590Z 2023-04-29T08:03:36.5414840Z For more information about this error, try rustc --explain E0432. 2023-04-29T08:03:36.5415280Z error: could not compile rustix due to previous error 2023-04-29T08:03:36.5415730Z warning: build failed, waiting for other jobs to finish... https://github.com/nextest-rs/nextest/issues/862 --- util/android-commands.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/util/android-commands.sh b/util/android-commands.sh index ae57962432..5eae1639fb 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -209,7 +209,7 @@ snapshot() { # We need to install nextest via cargo currently, since there is no pre-built binary for android x86 command="'\ export CARGO_TERM_COLOR=always; \ -cargo install cargo-nextest; \ +#cargo install cargo-nextest; \ echo \$? > $probe'" run_termux_command "$command" "$probe" return_code=$? @@ -224,7 +224,7 @@ pwd; \ command -v rustc && rustc -Vv; \ ls -la ~/.cargo/bin; \ cargo --list; \ -cargo nextest --version; \ +#cargo nextest --version; \ touch $probe'" run_termux_command "$command" "$probe" @@ -330,7 +330,8 @@ export CARGO_TERM_COLOR=always; \ export CARGO_INCREMENTAL=0; \ cd ~/coreutils; \ timeout --preserve-status --verbose -k 1m 60m \ - cargo nextest run --profile ci --hide-progress-bar --features feat_os_unix_android; \ + cargo test --features feat_os_unix_android; \ +# cargo nextest run --profile ci --hide-progress-bar --features feat_os_unix_android; \ echo \$? >$probe'" run_termux_command "$command" "$probe" || return From 0c9c54275e44a68273e925db594521952249afa3 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 29 Apr 2023 12:37:08 +0200 Subject: [PATCH 210/477] simplify it --- util/android-commands.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/util/android-commands.sh b/util/android-commands.sh index 5eae1639fb..d9c07fb69b 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -328,10 +328,7 @@ tests() { export RUST_BACKTRACE=1; \ export CARGO_TERM_COLOR=always; \ export CARGO_INCREMENTAL=0; \ -cd ~/coreutils; \ -timeout --preserve-status --verbose -k 1m 60m \ - cargo test --features feat_os_unix_android; \ -# cargo nextest run --profile ci --hide-progress-bar --features feat_os_unix_android; \ +cd ~/coreutils && cargo test --features feat_os_unix_android; \ echo \$? >$probe'" run_termux_command "$command" "$probe" || return From ffa2118717c268997c7170e6bd430666bf8e2e06 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 29 Apr 2023 12:47:48 +0200 Subject: [PATCH 211/477] add debug info --- util/android-commands.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/util/android-commands.sh b/util/android-commands.sh index d9c07fb69b..a2d39220ce 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -119,6 +119,7 @@ run_termux_command() { local retries=${retries:-3} local sleep_interval=${sleep_interval:-5} try_fix=3 + echo "run_termux_command with timeout=$timeout / retries=$retries / sleep_interval=$sleep_interval" while ! adb shell "ls $probe" 2>/dev/null; do echo -n "Waiting for $probe: " From 7cfdbe676cc2d3665d4a00ed691a1e6d2a4f1d33 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 29 Apr 2023 16:16:00 +0200 Subject: [PATCH 212/477] mv: validate --target arg --- src/uu/mv/src/mv.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 7fcc70a573..d583a13382 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -106,14 +106,22 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let backup_suffix = backup_control::determine_backup_suffix(&matches); + let target_dir = matches + .get_one::(OPT_TARGET_DIRECTORY) + .map(OsString::from); + + if let Some(ref maybe_dir) = target_dir { + if !Path::new(&maybe_dir).is_dir() { + return Err(MvError::TargetNotADirectory(maybe_dir.quote().to_string()).into()); + } + } + let behavior = Behavior { overwrite: overwrite_mode, backup: backup_mode, suffix: backup_suffix, update: matches.get_flag(OPT_UPDATE), - target_dir: matches - .get_one::(OPT_TARGET_DIRECTORY) - .map(OsString::from), + target_dir, no_target_dir: matches.get_flag(OPT_NO_TARGET_DIRECTORY), verbose: matches.get_flag(OPT_VERBOSE), strip_slashes: matches.get_flag(OPT_STRIP_TRAILING_SLASHES), @@ -320,12 +328,7 @@ fn exec(files: &[OsString], b: &Behavior) -> UResult<()> { fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> UResult<()> { if !target_dir.is_dir() { - match b.target_dir { - Some(_) => { - return Err(MvError::TargetNotADirectory(target_dir.quote().to_string()).into()) - } - None => return Err(MvError::NotADirectory(target_dir.quote().to_string()).into()), - } + return Err(MvError::NotADirectory(target_dir.quote().to_string()).into()); } let canonized_target_dir = target_dir From 4e712140fe4e1b33a4a01ee5ef2f2e77a1cead8d Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 29 Apr 2023 18:48:10 +0200 Subject: [PATCH 213/477] Do not run test_closes_file_descriptors on android Closes: #4736 --- tests/by-util/test_cp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index dfbbc1473a..d658d9c2b1 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1542,7 +1542,7 @@ fn test_cp_reflink_insufficient_permission() { .stderr_only("cp: 'unreadable' -> 'existing_file.txt': Permission denied (os error 13)\n"); } -#[cfg(any(target_os = "linux", target_os = "android"))] +#[cfg(target_os = "linux")] #[test] fn test_closes_file_descriptors() { use procfs::process::Process; From ac068e0487d216ccc7c312ecc84697f92191eff5 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 29 Apr 2023 19:23:56 +0200 Subject: [PATCH 214/477] Disable test_sort::test_compress_fail & test_chmod::test_mode_after_dash_dash on android --- tests/by-util/test_chmod.rs | 1 + tests/by-util/test_sort.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_chmod.rs b/tests/by-util/test_chmod.rs index acba00854f..697bc939ec 100644 --- a/tests/by-util/test_chmod.rs +++ b/tests/by-util/test_chmod.rs @@ -538,6 +538,7 @@ fn test_invalid_arg() { } #[test] +#[cfg(not(target_os = "android"))] fn test_mode_after_dash_dash() { let (at, ucmd) = at_and_ucmd!(); run_single_test( diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index a61db56b0f..114907393d 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -876,7 +876,7 @@ fn sort_empty_chunk() { } #[test] -#[cfg(any(target_os = "linux", target_os = "android"))] +#[cfg(target_os = "linux")] fn test_compress() { new_ucmd!() .args(&[ From ba8fa58a9a002d74f4230a3e09587ff61b93abd1 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 29 Apr 2023 19:49:44 +0200 Subject: [PATCH 215/477] android: increase the retries + sleep --- util/android-commands.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/android-commands.sh b/util/android-commands.sh index a2d39220ce..d958215e58 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -116,8 +116,8 @@ run_termux_command() { sleep 5 local timeout=${timeout:-3600} - local retries=${retries:-3} - local sleep_interval=${sleep_interval:-5} + local retries=${retries:-10} + local sleep_interval=${sleep_interval:-10} try_fix=3 echo "run_termux_command with timeout=$timeout / retries=$retries / sleep_interval=$sleep_interval" while ! adb shell "ls $probe" 2>/dev/null; do From 53ae5c33c961be2d9309f6446f39e7c57460894a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 29 Apr 2023 20:39:18 +0200 Subject: [PATCH 216/477] Disable test_sort::test_compress_fail (for real) & test_cp::test_cp_arg_interactive_update on android --- tests/by-util/test_cp.rs | 1 + tests/by-util/test_sort.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index d658d9c2b1..7a0743bd1c 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -257,6 +257,7 @@ fn test_cp_arg_interactive() { } #[test] +#[cfg(not(target_os = "android"))] fn test_cp_arg_interactive_update() { // -u -i won't show the prompt to validate the override or not // Therefore, the error code will be 0 diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index 114907393d..e66a405abb 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -876,7 +876,7 @@ fn sort_empty_chunk() { } #[test] -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "android"))] fn test_compress() { new_ucmd!() .args(&[ @@ -915,6 +915,7 @@ fn test_compress_merge() { } #[test] +#[cfg(not(target_os = "android"))] fn test_compress_fail() { #[cfg(not(windows))] TestScenario::new(util_name!()) From 9dff7d86cbf461391d4a3ee7e7fe3487f2ce3689 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 29 Apr 2023 21:29:47 +0200 Subject: [PATCH 217/477] Disable test_factor::test_parallel on android --- tests/by-util/test_factor.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/by-util/test_factor.rs b/tests/by-util/test_factor.rs index 59940e2e3a..1c75413702 100644 --- a/tests/by-util/test_factor.rs +++ b/tests/by-util/test_factor.rs @@ -35,6 +35,7 @@ fn test_valid_arg_exponents() { #[test] #[cfg(feature = "sort")] +#[cfg(not(target_os = "android"))] fn test_parallel() { use crate::common::util::AtPath; use hex_literal::hex; From 22490ae978c58be9fe84f27662dfbbfa01309d48 Mon Sep 17 00:00:00 2001 From: iambasanta Date: Sun, 30 Apr 2023 10:32:58 +0545 Subject: [PATCH 218/477] tr: move help string to markdown file --- src/uu/tr/src/tr.rs | 12 +++++------- src/uu/tr/tr.md | 11 +++++++++++ 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 src/uu/tr/tr.md diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs index 8ccd083660..9abbca6311 100644 --- a/src/uu/tr/src/tr.rs +++ b/src/uu/tr/src/tr.rs @@ -13,17 +13,15 @@ use clap::{crate_version, Arg, ArgAction, Command}; use nom::AsBytes; use operation::{translate_input, Sequence, SqueezeOperation, TranslateOperation}; use std::io::{stdin, stdout, BufReader, BufWriter}; -use uucore::{format_usage, show}; +use uucore::{format_usage, help_about, help_section, help_usage, show}; use crate::operation::DeleteOperation; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError, UUsageError}; -const ABOUT: &str = "Translate or delete characters"; -const USAGE: &str = "{} [OPTION]... SET1 [SET2]"; -const LONG_USAGE: &str = "\ - Translate, squeeze, and/or delete characters from standard input, \ - writing to standard output."; +const ABOUT: &str = help_about!("tr.md"); +const AFTER_HELP: &str = help_section!("after help", "tr.md"); +const USAGE: &str = help_usage!("tr.md"); mod options { pub const COMPLEMENT: &str = "complement"; @@ -37,7 +35,7 @@ mod options { pub fn uumain(args: impl uucore::Args) -> UResult<()> { let args = args.collect_lossy(); - let matches = uu_app().after_help(LONG_USAGE).try_get_matches_from(args)?; + let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; let delete_flag = matches.get_flag(options::DELETE); let complement_flag = matches.get_flag(options::COMPLEMENT); diff --git a/src/uu/tr/tr.md b/src/uu/tr/tr.md new file mode 100644 index 0000000000..93349eeaa8 --- /dev/null +++ b/src/uu/tr/tr.md @@ -0,0 +1,11 @@ +# tr + +``` +tr [OPTION]... SET1 [SET2] +``` + +Translate or delete characters + +## After help + +Translate, squeeze, and/or delete characters from standard input, writing to standard output. From e46b05722f00031d5a21bc4e77de74176bfeac37 Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Sun, 30 Apr 2023 15:51:14 +0900 Subject: [PATCH 219/477] timeout: move help strings to markdown file (#4806) * timeout: move help strings to markdown file --- src/uu/timeout/src/timeout.rs | 6 +++--- src/uu/timeout/timeout.md | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 src/uu/timeout/timeout.md diff --git a/src/uu/timeout/src/timeout.rs b/src/uu/timeout/src/timeout.rs index 153beea3d6..531f29e824 100644 --- a/src/uu/timeout/src/timeout.rs +++ b/src/uu/timeout/src/timeout.rs @@ -22,12 +22,12 @@ use uucore::process::ChildExt; use uucore::signals::enable_pipe_errors; use uucore::{ - format_usage, show_error, + format_usage, help_about, help_usage, show_error, signals::{signal_by_name_or_value, signal_name_by_value}, }; -static ABOUT: &str = "Start COMMAND, and kill it if still running after DURATION."; -const USAGE: &str = "{} [OPTION] DURATION COMMAND..."; +const ABOUT: &str = help_about!("timeout.md"); +const USAGE: &str = help_usage!("timeout.md"); pub mod options { pub static FOREGROUND: &str = "foreground"; diff --git a/src/uu/timeout/timeout.md b/src/uu/timeout/timeout.md new file mode 100644 index 0000000000..f992ab3277 --- /dev/null +++ b/src/uu/timeout/timeout.md @@ -0,0 +1,7 @@ +# timeout + +``` +timeout [OPTION] DURATION COMMAND... +``` + +Start `COMMAND`, and kill it if still running after `DURATION`. From 1055918c310be7b5b472cae7ccb102e415fb3d7d Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 30 Apr 2023 16:58:29 +0200 Subject: [PATCH 220/477] Document why we can't use nextest for now --- util/android-commands.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/android-commands.sh b/util/android-commands.sh index d958215e58..9f1d28db89 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -4,7 +4,7 @@ # There are three shells: the host's, adb, and termux. Only adb lets us run # commands directly on the emulated device, only termux provides a GNU # environment on the emulated device (to e.g. run cargo). So we use adb to -# launch termux, then to send keystrokes to it while it's running. +# launch termux, then to send keystrokes to it while it's ruMbdfhnRrVnning. # This means that the commands sent to termux are first parsed as arguments in # this shell, then as arguments in the adb shell, before finally being used as # text inputs to the app. Hence, the "'wrapping'" on those commands. @@ -210,7 +210,7 @@ snapshot() { # We need to install nextest via cargo currently, since there is no pre-built binary for android x86 command="'\ export CARGO_TERM_COLOR=always; \ -#cargo install cargo-nextest; \ +# build fails for now (https://github.com/nextest-rs/nextest/issues/862): cargo install cargo-nextest; \ echo \$? > $probe'" run_termux_command "$command" "$probe" return_code=$? From bbb218c0e273b696dc039c5e3013cfc0f46855b9 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 30 Apr 2023 17:21:34 +0200 Subject: [PATCH 221/477] Remove bad c/p --- util/android-commands.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/android-commands.sh b/util/android-commands.sh index 9f1d28db89..668815f7d0 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -4,7 +4,7 @@ # There are three shells: the host's, adb, and termux. Only adb lets us run # commands directly on the emulated device, only termux provides a GNU # environment on the emulated device (to e.g. run cargo). So we use adb to -# launch termux, then to send keystrokes to it while it's ruMbdfhnRrVnning. +# launch termux, then to send keystrokes to it while it's running. # This means that the commands sent to termux are first parsed as arguments in # this shell, then as arguments in the adb shell, before finally being used as # text inputs to the app. Hence, the "'wrapping'" on those commands. From 70b69efadbe588f189afcc97c23d489a05dcb8dd Mon Sep 17 00:00:00 2001 From: iambasanta <68998545+iambasanta@users.noreply.github.com> Date: Sun, 30 Apr 2023 23:35:28 +0545 Subject: [PATCH 222/477] sort: Move help strings to markdown file (#4808) * sort: Move help strings to markdown file * Correction for spell check --- src/uu/sort/sort.md | 21 +++++++++++++++++++++ src/uu/sort/src/sort.rs | 21 +++++---------------- 2 files changed, 26 insertions(+), 16 deletions(-) create mode 100644 src/uu/sort/sort.md diff --git a/src/uu/sort/sort.md b/src/uu/sort/sort.md new file mode 100644 index 0000000000..1d1aa5d5ff --- /dev/null +++ b/src/uu/sort/sort.md @@ -0,0 +1,21 @@ + + +# sort + +``` +sort [OPTION]... [FILE]... +``` + +Display sorted concatenation of all FILE(s). With no FILE, or when FILE is -, read standard input. + +## After help + +The key format is `FIELD[.CHAR][OPTIONS][,FIELD[.CHAR]][OPTIONS]`. + +Fields by default are separated by the first whitespace after a non-whitespace character. Use `-t` to specify a custom separator. +In the default case, whitespace is appended at the beginning of each field. Custom separators however are not included in fields. + +`FIELD` and `CHAR` both start at 1 (i.e. they are 1-indexed). If there is no end specified after a comma, the end will be the end of the line. +If `CHAR` is set 0, it means the end of the field. `CHAR` defaults to 1 for the start position and to 0 for the end position. + +Valid options are: `MbdfhnRrV`. They override the global options for this key. diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 5b309e4135..1744148f2f 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -45,26 +45,15 @@ use std::str::Utf8Error; use unicode_width::UnicodeWidthStr; use uucore::display::Quotable; use uucore::error::{set_exit_code, strip_errno, UError, UResult, USimpleError, UUsageError}; -use uucore::format_usage; use uucore::parse_size::{ParseSizeError, Parser}; use uucore::version_cmp::version_cmp; +use uucore::{format_usage, help_about, help_section, help_usage}; use crate::tmp_dir::TmpDirWrapper; -const ABOUT: &str = "\ - Display sorted concatenation of all FILE(s). \ - With no FILE, or when FILE is -, read standard input."; -const USAGE: &str = "{} [OPTION]... [FILE]..."; - -const LONG_HELP_KEYS: &str = "The key format is FIELD[.CHAR][OPTIONS][,FIELD[.CHAR]][OPTIONS]. - -Fields by default are separated by the first whitespace after a non-whitespace character. Use -t to specify a custom separator. -In the default case, whitespace is appended at the beginning of each field. Custom separators however are not included in fields. - -FIELD and CHAR both start at 1 (i.e. they are 1-indexed). If there is no end specified after a comma, the end will be the end of the line. -If CHAR is set 0, it means the end of the field. CHAR defaults to 1 for the start position and to 0 for the end position. - -Valid options are: MbdfhnRrV. They override the global options for this key."; +const ABOUT: &str = help_about!("sort.md"); +const USAGE: &str = help_usage!("sort.md"); +const AFTER_HELP: &str = help_section!("after help", "sort.md"); mod options { pub mod modes { @@ -1292,7 +1281,7 @@ pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(crate_version!()) .about(ABOUT) - .after_help(LONG_HELP_KEYS) + .after_help(AFTER_HELP) .override_usage(format_usage(USAGE)) .infer_long_args(true) .disable_help_flag(true) From 75e33695e5a187238773fc588bc28145637567c2 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 30 Apr 2023 20:08:06 +0200 Subject: [PATCH 223/477] Disable test_gnu_options on android --- tests/by-util/test_chmod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/by-util/test_chmod.rs b/tests/by-util/test_chmod.rs index 697bc939ec..9e3c7d2da7 100644 --- a/tests/by-util/test_chmod.rs +++ b/tests/by-util/test_chmod.rs @@ -650,6 +650,7 @@ fn test_gnu_invalid_mode() { } #[test] +#[cfg(not(target_os = "android"))] fn test_gnu_options() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; From 2f8df653c51718f5a3e75c39eaec157c10825ad6 Mon Sep 17 00:00:00 2001 From: John Shin Date: Thu, 27 Apr 2023 05:14:46 -0700 Subject: [PATCH 224/477] core mv cp: update help doc for 'update' functionality --- src/uu/cp/src/cp.rs | 64 +++++++++++++++++------ src/uu/mv/src/mv.rs | 14 ++++- src/uucore/src/lib/mods/update_control.rs | 8 ++- 3 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index f302d48737..b0c7796790 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -279,6 +279,21 @@ static PRESERVABLE_ATTRIBUTES: &[&str] = &[ "all", ]; +static CP_UPDATE_LONG_HELP: &str = +"Do not copy a non-directory that has an existing destination with the same or newer modification timestamp; +instead, silently skip the file without failing. If timestamps are being preserved, the comparison is to the +source timestamp truncated to the resolutions of the destination file system and of the system calls used to +update timestamps; this avoids duplicate work if several ‘cp -pu’ commands are executed with the same source +and destination. This option is ignored if the -n or --no-clobber option is also specified. Also, if +--preserve=links is also specified (like with ‘cp -au’ for example), that will take precedence; consequently, +depending on the order that files are processed from the source, newer files in the destination may be +replaced, to mirror hard links in the source. which gives more control over which existing files in the +destination are replaced, and its value can be one of the following: + +all This is the default operation when an --update option is not specified, and results in all existing files in the destination being replaced. +none This is similar to the --no-clobber option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. +older This is the default operation when --update is specified, and results in files being replaced if they’re older than the corresponding source file."; + #[cfg(not(unix))] static PRESERVABLE_ATTRIBUTES: &[&str] = &["mode", "timestamps", "context", "links", "xattr", "all"]; @@ -558,6 +573,7 @@ pub fn uu_app() -> Command { pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app() .after_help(backup_control::BACKUP_CONTROL_LONG_HELP) + .after_help(CP_UPDATE_LONG_HELP) .try_get_matches_from(args); // The error is parsed here because we do not want version or help being printed to stderr. @@ -1628,22 +1644,38 @@ fn copy_file( } CopyMode::Update => { if dest.exists() { - let dest_metadata = fs::symlink_metadata(dest)?; - - let src_time = source_metadata.modified()?; - let dest_time = dest_metadata.modified()?; - if src_time <= dest_time { - return Ok(()); - } else { - copy_helper( - source, - dest, - options, - context, - source_is_symlink, - source_is_fifo, - symlinked_files, - )?; + match options.update { + update_control::UpdateMode::ReplaceAll => { + copy_helper( + source, + dest, + options, + context, + source_is_symlink, + source_is_fifo, + symlinked_files, + )?; + } + update_control::UpdateMode::ReplaceNone => return Ok(()), + update_control::UpdateMode::ReplaceIfOlder => { + let dest_metadata = fs::symlink_metadata(dest)?; + + let src_time = source_metadata.modified()?; + let dest_time = dest_metadata.modified()?; + if src_time <= dest_time { + return Ok(()); + } else { + copy_helper( + source, + dest, + options, + context, + source_is_symlink, + source_is_fifo, + symlinked_files, + )?; + } + } } } else { copy_helper( diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 2951550c63..2524466005 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -67,11 +67,23 @@ static OPT_VERBOSE: &str = "verbose"; static OPT_PROGRESS: &str = "progress"; static ARG_FILES: &str = "files"; +static MV_UPDATE_LONG_HELP: &str = + "Do not move a non-directory that has an existing destination with the same or newer modification timestamp; +instead, silently skip the file without failing. If the move is across file system boundaries, the comparison is +to the source timestamp truncated to the resolutions of the destination file system and of the system calls used +to update timestamps; this avoids duplicate work if several ‘mv -u’ commands are executed with the same source +and destination. This option is ignored if the -n or --no-clobber option is also specified. which gives more control +over which existing files in the destination are replaced, and its value can be one of the following: + +all This is the default operation when an --update option is not specified, and results in all existing files in the destination being replaced. +none This is similar to the --no-clobber option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. +older This is the default operation when --update is specified, and results in files being replaced if they’re older than the corresponding source file."; + #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let mut app = uu_app() .after_help(backup_control::BACKUP_CONTROL_LONG_HELP) - .after_help(update_control::UPDATE_CONTROL_LONG_HELP); + .after_help(MV_UPDATE_LONG_HELP); let matches = app.try_get_matches_from_mut(args)?; if !matches.contains_id(OPT_TARGET_DIRECTORY) diff --git a/src/uucore/src/lib/mods/update_control.rs b/src/uucore/src/lib/mods/update_control.rs index a743b93409..ab97b0412b 100644 --- a/src/uucore/src/lib/mods/update_control.rs +++ b/src/uucore/src/lib/mods/update_control.rs @@ -2,8 +2,6 @@ use clap::ArgMatches; pub static UPDATE_CONTROL_VALUES: &[&str] = &["all", "none", "old", ""]; -pub const UPDATE_CONTROL_LONG_HELP: &str = "VERY LONG HELP"; - #[derive(Clone, Eq, PartialEq)] pub enum UpdateMode { ReplaceAll, @@ -20,10 +18,10 @@ pub mod arguments { pub fn update() -> clap::Arg { clap::Arg::new(OPT_UPDATE) .long("update") - .help("some help") + .help("move only when the SOURCE file is newer than the destination file or when the destination file is missing") .value_parser(["", "none", "all", "older"]) .num_args(0..=1) - .default_missing_value("all") + .default_missing_value("older") .require_equals(true) .overrides_with("update") .action(clap::ArgAction::Set) @@ -32,7 +30,7 @@ pub mod arguments { pub fn update_no_args() -> clap::Arg { clap::Arg::new(OPT_UPDATE_NO_ARG) .short('u') - .help("like ") + .help("like --update but does not accept an argument") .action(ArgAction::SetTrue) } } From ed3ff105400df0221a3b904143df1e17f8185405 Mon Sep 17 00:00:00 2001 From: John Shin Date: Sun, 30 Apr 2023 18:52:13 -0700 Subject: [PATCH 225/477] cp: write tests for --update --- src/uu/mv/src/mv.rs | 16 +++-- tests/by-util/test_cp.rs | 127 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 6 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 2524466005..2edf916249 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -427,6 +427,16 @@ fn rename( return Ok(()); } + if b.update == UpdateMode::ReplaceNone { + return Ok(()); + } + + if (b.update == UpdateMode::ReplaceIfOlder) + && fs::metadata(from)?.modified()? <= fs::metadata(to)?.modified()? + { + return Ok(()); + } + match b.overwrite { OverwriteMode::NoClobber => return Ok(()), OverwriteMode::Interactive => { @@ -441,12 +451,6 @@ fn rename( if let Some(ref backup_path) = backup_path { rename_with_fallback(to, backup_path, multi_progress)?; } - - if (b.update == UpdateMode::ReplaceIfOlder) - && fs::metadata(from)?.modified()? <= fs::metadata(to)?.modified()? - { - return Ok(()); - } } // "to" may no longer exist if it was backed up diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index dfbbc1473a..4e241e0644 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -244,6 +244,133 @@ fn test_cp_arg_update_interactive_error() { .no_stdout(); } +#[test] +fn test_cp_arg_update_none() { + let (at, mut ucmd) = at_and_ucmd!(); + + ucmd.arg(TEST_HELLO_WORLD_SOURCE) + .arg(TEST_HOW_ARE_YOU_SOURCE) + .arg("--update=none") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n") +} + +#[test] +fn test_cp_arg_update_all() { + let (at, mut ucmd) = at_and_ucmd!(); + + ucmd.arg(TEST_HELLO_WORLD_SOURCE) + .arg(TEST_HOW_ARE_YOU_SOURCE) + .arg("--update=all") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!( + at.read(TEST_HOW_ARE_YOU_SOURCE), + at.read(TEST_HELLO_WORLD_SOURCE) + ) +} + +#[test] +fn test_cp_arg_update_older_dest_not_older_than_src() { + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_cp_arg_update_oldler_file1"; + let new = "test_cp_arg_update_oldler_file2"; + + at.touch(old); + sleep(Duration::from_secs(1)); + at.touch(new); + + at.append(old, "old content\n"); + at.append(new, "new content\n"); + + ucmd.arg(old) + .arg(new) + .arg("--update=older") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(new), "new content\n") +} + +#[test] +fn test_cp_arg_update_older_dest_older_than_src() { + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_cp_arg_update_oldler_file1"; + let new = "test_cp_arg_update_oldler_file2"; + + at.touch(old); + at.append(old, "old content\n"); + sleep(Duration::from_secs(1)); + at.touch(new); + at.append(new, "new content\n"); + + ucmd.arg(new) + .arg(old) + .arg("--update=older") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(old), "new content\n") +} + +#[test] +fn test_cp_arg_update_short_fail() { + // same as --update=older + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_cp_arg_update_oldler_file1"; + let new = "test_cp_arg_update_oldler_file2"; + + at.touch(old); + sleep(Duration::from_secs(1)); + at.touch(new); + + at.append(old, "old content\n"); + at.append(new, "new content\n"); + + ucmd.arg(old) + .arg(new) + .arg("-u") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(new), "new content\n") +} + +#[test] +fn test_cp_arg_update_short_succeed() { + // same as --update=older + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_cp_arg_update_oldler_file1"; + let new = "test_cp_arg_update_oldler_file2"; + + at.touch(old); + at.touch(new); + + at.append(old, "old content\n"); + at.append(new, "new content\n"); + + ucmd.arg(new) + .arg(old) + .arg("-u") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(new), "new content\n") +} + #[test] fn test_cp_arg_interactive() { let (at, mut ucmd) = at_and_ucmd!(); From 78412c5a6111677c590f4736955e5632b0e3ac82 Mon Sep 17 00:00:00 2001 From: John Shin Date: Sun, 30 Apr 2023 19:29:19 -0700 Subject: [PATCH 226/477] mv: add tests for --update --- tests/by-util/test_mv.rs | 164 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 0342341071..2c5f859106 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -1,5 +1,7 @@ use crate::common::util::TestScenario; use filetime::FileTime; +use std::thread::sleep; +use std::time::Duration; #[test] fn test_invalid_arg() { @@ -658,6 +660,168 @@ fn test_mv_update_option() { assert!(!at.file_exists(file_b)); } +#[test] +fn test_mv_arg_update_none() { + let (at, mut ucmd) = at_and_ucmd!(); + + let file1 = "test_mv_arg_update_none_file1"; + let file2 = "test_mv_arg_update_none_file2"; + + at.touch(file1); + at.touch(file2); + + let file1_content = "file1 content\n"; + let file2_content = "file2 content\n"; + + at.append(file1, file1_content); + at.append(file2, file2_content); + + ucmd.arg(file1) + .arg(file2) + .arg("--update=none") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(file2), file2_content) +} + +#[test] +fn test_mv_arg_update_all() { + let (at, mut ucmd) = at_and_ucmd!(); + + let file1 = "test_mv_arg_update_none_file1"; + let file2 = "test_mv_arg_update_none_file2"; + + at.touch(file1); + at.touch(file2); + + let file1_content = "file1 content\n"; + let file2_content = "file2 content\n"; + + at.append(file1, file1_content); + at.append(file2, file2_content); + + ucmd.arg(file1) + .arg(file2) + .arg("--update=all") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(file2), file1_content) +} + +#[test] +fn test_mv_arg_update_older_dest_not_older() { + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_mv_arg_update_none_file1"; + let new = "test_mv_arg_update_none_file2"; + let old_content = "file1 content\n"; + let new_content = "file2 content\n"; + + at.touch(old); + at.append(old, old_content); + + sleep(Duration::from_secs(1)); + + at.touch(new); + at.append(new, new_content); + + ucmd.arg(old) + .arg(new) + .arg("--update=older") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(new), new_content) +} + +#[test] +fn test_mv_arg_update_older_dest_older() { + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_mv_arg_update_none_file1"; + let new = "test_mv_arg_update_none_file2"; + let old_content = "file1 content\n"; + let new_content = "file2 content\n"; + + at.touch(old); + at.append(old, old_content); + + sleep(Duration::from_secs(1)); + + at.touch(new); + at.append(new, new_content); + + ucmd.arg(new) + .arg(old) + .arg("--update=all") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(old), new_content) +} + +#[test] +fn test_mv_arg_update_short_overwrite() { + // same as --update=older + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_mv_arg_update_none_file1"; + let new = "test_mv_arg_update_none_file2"; + let old_content = "file1 content\n"; + let new_content = "file2 content\n"; + + at.touch(old); + at.append(old, old_content); + + sleep(Duration::from_secs(1)); + + at.touch(new); + at.append(new, new_content); + + ucmd.arg(new) + .arg(old) + .arg("-u") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(old), new_content) +} + +#[test] +fn test_mv_arg_update_short_no_overwrite() { + // same as --update=older + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_mv_arg_update_none_file1"; + let new = "test_mv_arg_update_none_file2"; + let old_content = "file1 content\n"; + let new_content = "file2 content\n"; + + at.touch(old); + at.append(old, old_content); + + sleep(Duration::from_secs(1)); + + at.touch(new); + at.append(new, new_content); + + ucmd.arg(old) + .arg(new) + .arg("-u") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(new), new_content) +} + #[test] fn test_mv_target_dir() { let (at, mut ucmd) = at_and_ucmd!(); From 2f975e913e40616928b8bbcf516773cf9a824d36 Mon Sep 17 00:00:00 2001 From: John Shin Date: Sun, 30 Apr 2023 20:02:53 -0700 Subject: [PATCH 227/477] cp: move after help to md file --- src/uu/cp/cp.md | 16 ++++++++++++++++ src/uu/cp/src/cp.rs | 10 +++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/uu/cp/cp.md b/src/uu/cp/cp.md index 5f3cabc18b..aadf4006b9 100644 --- a/src/uu/cp/cp.md +++ b/src/uu/cp/cp.md @@ -7,3 +7,19 @@ cp [OPTION]... -t DIRECTORY SOURCE... ``` Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. + +## After Help + +Do not copy a non-directory that has an existing destination with the same or newer modification timestamp; +instead, silently skip the file without failing. If timestamps are being preserved, the comparison is to the +source timestamp truncated to the resolutions of the destination file system and of the system calls used to +update timestamps; this avoids duplicate work if several ‘cp -pu’ commands are executed with the same source +and destination. This option is ignored if the -n or --no-clobber option is also specified. Also, if +--preserve=links is also specified (like with ‘cp -au’ for example), that will take precedence; consequently, +depending on the order that files are processed from the source, newer files in the destination may be replaced, +to mirror hard links in the source. which gives more control over which existing files in the destination are +replaced, and its value can be one of the following: + +all This is the default operation when an --update option is not specified, and results in all existing files in the destination being replaced. +none This is similar to the --no-clobber option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. +older This is the default operation when --update is specified, and results in files being replaced if they’re older than the corresponding source file. diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index b0c7796790..5e791cc3bf 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -41,7 +41,9 @@ use uucore::fs::{ canonicalize, paths_refer_to_same_file, FileInformation, MissingHandling, ResolveMode, }; use uucore::update_control::{self, UpdateMode}; -use uucore::{crash, format_usage, help_about, help_usage, prompt_yes, show_error, show_warning}; +use uucore::{ + crash, format_usage, help_about, help_section, help_usage, prompt_yes, show_error, show_warning, +}; use crate::copydir::copy_directory; @@ -232,6 +234,7 @@ pub struct Options { const ABOUT: &str = help_about!("cp.md"); const USAGE: &str = help_usage!("cp.md"); +const AFTER_HELP: &str = help_section!("after help", "cp.md"); static EXIT_ERR: i32 = 1; @@ -310,9 +313,8 @@ pub fn uu_app() -> Command { .version(crate_version!()) .about(ABOUT) .override_usage(format_usage(USAGE)) + .after_help(AFTER_HELP) .infer_long_args(true) - .arg(update_control::arguments::update()) - .arg(update_control::arguments::update_no_args()) .arg( Arg::new(options::TARGET_DIRECTORY) .short('t') @@ -410,6 +412,8 @@ pub fn uu_app() -> Command { .arg(backup_control::arguments::backup()) .arg(backup_control::arguments::backup_no_args()) .arg(backup_control::arguments::suffix()) + .arg(update_control::arguments::update()) + .arg(update_control::arguments::update_no_args()) .arg( Arg::new(options::REFLINK) .long(options::REFLINK) From f83468d530d4018291e02c79aea928eea80cda3a Mon Sep 17 00:00:00 2001 From: John Shin Date: Sun, 30 Apr 2023 20:03:22 -0700 Subject: [PATCH 228/477] mv: move after help to md file --- src/uu/mv/mv.md | 14 +++++++++++++- src/uu/mv/src/mv.rs | 28 ++++++++-------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/uu/mv/mv.md b/src/uu/mv/mv.md index 772e4bfaf4..7a5821351f 100644 --- a/src/uu/mv/mv.md +++ b/src/uu/mv/mv.md @@ -5,5 +5,17 @@ mv [OPTION]... [-T] SOURCE DEST mv [OPTION]... SOURCE... DIRECTORY mv [OPTION]... -t DIRECTORY SOURCE... ``` - Move `SOURCE` to `DEST`, or multiple `SOURCE`(s) to `DIRECTORY`. + +## After Help + +Do not move a non-directory that has an existing destination with the same or newer modification timestamp; +instead, silently skip the file without failing. If the move is across file system boundaries, the comparison is +to the source timestamp truncated to the resolutions of the destination file system and of the system calls used +to update timestamps; this avoids duplicate work if several ‘mv -u’ commands are executed with the same source +and destination. This option is ignored if the -n or --no-clobber option is also specified. which gives more control +over which existing files in the destination are replaced, and its value can be one of the following: + +all This is the default operation when an --update option is not specified, and results in all existing files in the destination being replaced. +none This is similar to the --no-clobber option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. +older This is the default operation when --update is specified, and results in files being replaced if they’re older than the corresponding source file. diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 2edf916249..db2b4153bd 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -26,7 +26,7 @@ use uucore::backup_control::{self, BackupMode}; use uucore::display::Quotable; use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError}; use uucore::update_control::{self, UpdateMode}; -use uucore::{format_usage, help_about, help_usage, prompt_yes, show}; +use uucore::{format_usage, help_about, help_section, help_usage, prompt_yes, show}; use fs_extra::dir::{ get_size as dir_get_size, move_dir, move_dir_with_progress, CopyOptions as DirCopyOptions, @@ -56,6 +56,7 @@ pub enum OverwriteMode { const ABOUT: &str = help_about!("mv.md"); const USAGE: &str = help_usage!("mv.md"); +const AFTER_HELP: &str = help_section!("after help", "mv.md"); static OPT_FORCE: &str = "force"; static OPT_INTERACTIVE: &str = "interactive"; @@ -67,23 +68,9 @@ static OPT_VERBOSE: &str = "verbose"; static OPT_PROGRESS: &str = "progress"; static ARG_FILES: &str = "files"; -static MV_UPDATE_LONG_HELP: &str = - "Do not move a non-directory that has an existing destination with the same or newer modification timestamp; -instead, silently skip the file without failing. If the move is across file system boundaries, the comparison is -to the source timestamp truncated to the resolutions of the destination file system and of the system calls used -to update timestamps; this avoids duplicate work if several ‘mv -u’ commands are executed with the same source -and destination. This option is ignored if the -n or --no-clobber option is also specified. which gives more control -over which existing files in the destination are replaced, and its value can be one of the following: - -all This is the default operation when an --update option is not specified, and results in all existing files in the destination being replaced. -none This is similar to the --no-clobber option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. -older This is the default operation when --update is specified, and results in files being replaced if they’re older than the corresponding source file."; - #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let mut app = uu_app() - .after_help(backup_control::BACKUP_CONTROL_LONG_HELP) - .after_help(MV_UPDATE_LONG_HELP); + let mut app = uu_app().after_help(backup_control::BACKUP_CONTROL_LONG_HELP); let matches = app.try_get_matches_from_mut(args)?; if !matches.contains_id(OPT_TARGET_DIRECTORY) @@ -143,11 +130,8 @@ pub fn uu_app() -> Command { .version(crate_version!()) .about(ABOUT) .override_usage(format_usage(USAGE)) + .after_help(AFTER_HELP) .infer_long_args(true) - .arg(backup_control::arguments::backup()) - .arg(backup_control::arguments::backup_no_args()) - .arg(update_control::arguments::update()) - .arg(update_control::arguments::update_no_args()) .arg( Arg::new(OPT_FORCE) .short('f') @@ -175,7 +159,11 @@ pub fn uu_app() -> Command { .help("remove any trailing slashes from each SOURCE argument") .action(ArgAction::SetTrue), ) + .arg(backup_control::arguments::backup()) + .arg(backup_control::arguments::backup_no_args()) .arg(backup_control::arguments::suffix()) + .arg(update_control::arguments::update()) + .arg(update_control::arguments::update_no_args()) .arg( Arg::new(OPT_TARGET_DIRECTORY) .short('t') From b707b690c5b45ce090c3a87372366763272b13e9 Mon Sep 17 00:00:00 2001 From: John Shin Date: Sun, 30 Apr 2023 20:16:01 -0700 Subject: [PATCH 229/477] cp: remove long help --- src/uu/cp/src/cp.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 5e791cc3bf..64278bf131 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -282,21 +282,6 @@ static PRESERVABLE_ATTRIBUTES: &[&str] = &[ "all", ]; -static CP_UPDATE_LONG_HELP: &str = -"Do not copy a non-directory that has an existing destination with the same or newer modification timestamp; -instead, silently skip the file without failing. If timestamps are being preserved, the comparison is to the -source timestamp truncated to the resolutions of the destination file system and of the system calls used to -update timestamps; this avoids duplicate work if several ‘cp -pu’ commands are executed with the same source -and destination. This option is ignored if the -n or --no-clobber option is also specified. Also, if ---preserve=links is also specified (like with ‘cp -au’ for example), that will take precedence; consequently, -depending on the order that files are processed from the source, newer files in the destination may be -replaced, to mirror hard links in the source. which gives more control over which existing files in the -destination are replaced, and its value can be one of the following: - -all This is the default operation when an --update option is not specified, and results in all existing files in the destination being replaced. -none This is similar to the --no-clobber option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. -older This is the default operation when --update is specified, and results in files being replaced if they’re older than the corresponding source file."; - #[cfg(not(unix))] static PRESERVABLE_ATTRIBUTES: &[&str] = &["mode", "timestamps", "context", "links", "xattr", "all"]; @@ -577,7 +562,6 @@ pub fn uu_app() -> Command { pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app() .after_help(backup_control::BACKUP_CONTROL_LONG_HELP) - .after_help(CP_UPDATE_LONG_HELP) .try_get_matches_from(args); // The error is parsed here because we do not want version or help being printed to stderr. From 0e95ce571ff9afd2bfb2840a0f58b20cae83c0e9 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 1 May 2023 08:40:07 +0200 Subject: [PATCH 230/477] gnu: adjust tests/rm/inaccessible.sh error message --- util/build-gnu.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/build-gnu.sh b/util/build-gnu.sh index 8e78c5a99a..13fef7bb92 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -166,6 +166,9 @@ sed -i -e "s|rm: cannot remove 'a/1'|rm: cannot remove 'a'|g" tests/rm/rm2.sh sed -i -e "s|removed directory 'a/'|removed directory 'a'|g" tests/rm/v-slash.sh +# 'rel' doesn't exist. Our implementation is giving a better message. +sed -i -e "s|rm: cannot remove 'rel': Permission denied|rm: cannot remove 'rel': No such file or directory|g" tests/rm/inaccessible.sh + # overlay-headers.sh test intends to check for inotify events, # however there's a bug because `---dis` is an alias for: `---disable-inotify` sed -i -e "s|---dis ||g" tests/tail-2/overlay-headers.sh From 2d4dfc3d7ddbb063f3d258f0b8359ef18ddbf2b3 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 1 May 2023 10:54:14 +0200 Subject: [PATCH 231/477] cp: add support POSIXLY_CORRECT=1 when dealing with dangling links GNU: tests/cp/thru-dangling.sh --- src/uu/cp/src/cp.rs | 1 + tests/by-util/test_cp.rs | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 80540d222e..3ccff03036 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -1498,6 +1498,7 @@ fn copy_file( options.overwrite, OverwriteMode::Clobber(ClobberMode::RemoveDestination) ) + && std::env::var_os("POSIXLY_CORRECT").is_none() { return Err(Error::Error(format!( "not writing through dangling symlink '{}'", diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index dfbbc1473a..8c08d4c0a7 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1902,6 +1902,17 @@ fn test_copy_through_dangling_symlink() { .stderr_only("cp: not writing through dangling symlink 'target'\n"); } +#[test] +fn test_copy_through_dangling_symlink_posixly_correct() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("file"); + at.symlink_file("nonexistent", "target"); + ucmd.arg("file") + .arg("target") + .env("POSIXLY_CORRECT", "1") + .succeeds(); +} + #[test] fn test_copy_through_dangling_symlink_no_dereference() { let (at, mut ucmd) = at_and_ucmd!(); From c5327cf0a0158d357ba116399291c7e4b715d702 Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 1 May 2023 03:46:14 -0700 Subject: [PATCH 232/477] core: add docs for update control --- src/uucore/src/lib/mods/update_control.rs | 87 ++++++++++++++++++++++- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/src/uucore/src/lib/mods/update_control.rs b/src/uucore/src/lib/mods/update_control.rs index ab97b0412b..5bbca0e49b 100644 --- a/src/uucore/src/lib/mods/update_control.rs +++ b/src/uucore/src/lib/mods/update_control.rs @@ -1,11 +1,57 @@ +//! Implement GNU-style update functionality. +//! +//! - pre-defined [`clap`-Arguments][1] for inclusion in utilities that +//! implement updates +//! - determination of the [update mode][2] +//! +//! Update-functionality is implemented by the following utilities: +//! +//! - `cp` +//! - `mv` +//! +//! +//! [1]: arguments +//! [2]: `determine_update_mode()` +//! +//! +//! # Usage example +//! +//! ``` +//! #[macro_use] +//! extern crate uucore; +//! +//! use clap::{Command, Arg, ArgMatches}; +//! use uucore::update_control::{self, UpdateMode}; +//! +//! fn main() { +//! let matches = Command::new("command") +//! .arg(update_control::arguments::update()) +//! .arg(update_control::arguments::update_no_args()) +//! .get_matches_from(vec![ +//! "commmand", "--update=older" +//! ]); +//! +//! let update_mode = update_control::determine_update_mode(&matches); +//! +//! // handle cases +//! if update_mode == UpdateMode::ReplaceIfOlder { +//! // do +//! } else { +//! unreachable!() +//! } +//! } +//! ``` use clap::ArgMatches; -pub static UPDATE_CONTROL_VALUES: &[&str] = &["all", "none", "old", ""]; - -#[derive(Clone, Eq, PartialEq)] +// Available update mode +#[derive(Clone, Debug, Eq, PartialEq)] pub enum UpdateMode { + // --update=`all`, `` ReplaceAll, + // --update=`none` ReplaceNone, + // --update=`older` + // -u ReplaceIfOlder, } @@ -15,6 +61,7 @@ pub mod arguments { pub static OPT_UPDATE: &str = "update"; pub static OPT_UPDATE_NO_ARG: &str = "u"; + // `--update` argument, defaults to `older` if no values after provided pub fn update() -> clap::Arg { clap::Arg::new(OPT_UPDATE) .long("update") @@ -27,6 +74,7 @@ pub mod arguments { .action(clap::ArgAction::Set) } + // `-u` argument pub fn update_no_args() -> clap::Arg { clap::Arg::new(OPT_UPDATE_NO_ARG) .short('u') @@ -35,6 +83,37 @@ pub mod arguments { } } +/// Determine the "mode" for the update operation to perform, if any. +/// +/// Parses the backup options and converts them to an instance of +/// `UpdateMode` for further processing. +/// +/// Takes [`clap::ArgMatches`] as argument which **must** contain the options +/// from [`arguments::update()`] or [`arguments::update_no_args()`]. Otherwise +/// the `ReplaceAll` mode is returned unconditionally. +/// +/// # Examples +/// +/// Here's how one would integrate the update mode determination into an +/// application. +/// +/// ``` +/// #[macro_use] +/// extern crate uucore; +/// use uucore::update_control::{self, UpdateMode}; +/// use clap::{Command, Arg, ArgMatches}; +/// +/// fn main() { +/// let matches = Command::new("command") +/// .arg(update_control::arguments::update()) +/// .arg(update_control::arguments::update_no_args()) +/// .get_matches_from(vec![ +/// "command", "--update=all" +/// ]); +/// +/// let update_mode = update_control::determine_update_mode(&matches); +/// assert_eq!(update_mode, UpdateMode::ReplaceAll) +/// } pub fn determine_update_mode(matches: &ArgMatches) -> UpdateMode { if matches.contains_id(arguments::OPT_UPDATE) { if let Some(mode) = matches.get_one::(arguments::OPT_UPDATE) { @@ -48,8 +127,10 @@ pub fn determine_update_mode(matches: &ArgMatches) -> UpdateMode { unreachable!("other args restricted by clap") } } else if matches.get_flag(arguments::OPT_UPDATE_NO_ARG) { + // short form of this option is equivalent to using --update=older UpdateMode::ReplaceIfOlder } else { + // no option was present UpdateMode::ReplaceAll } } From 92e1b3f7c076c08b74b510e771acf983243315a1 Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 1 May 2023 03:53:52 -0700 Subject: [PATCH 233/477] cp: fix documentation --- src/uu/cp/cp.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/uu/cp/cp.md b/src/uu/cp/cp.md index aadf4006b9..7485340f2a 100644 --- a/src/uu/cp/cp.md +++ b/src/uu/cp/cp.md @@ -13,13 +13,13 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. Do not copy a non-directory that has an existing destination with the same or newer modification timestamp; instead, silently skip the file without failing. If timestamps are being preserved, the comparison is to the source timestamp truncated to the resolutions of the destination file system and of the system calls used to -update timestamps; this avoids duplicate work if several ‘cp -pu’ commands are executed with the same source -and destination. This option is ignored if the -n or --no-clobber option is also specified. Also, if ---preserve=links is also specified (like with ‘cp -au’ for example), that will take precedence; consequently, +update timestamps; this avoids duplicate work if several `cp -pu` commands are executed with the same source +and destination. This option is ignored if the `-n` or `--no-clobber` option is also specified. Also, if +`--preserve=links` is also specified (like with `cp -au` for example), that will take precedence; consequently, depending on the order that files are processed from the source, newer files in the destination may be replaced, to mirror hard links in the source. which gives more control over which existing files in the destination are replaced, and its value can be one of the following: -all This is the default operation when an --update option is not specified, and results in all existing files in the destination being replaced. -none This is similar to the --no-clobber option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. -older This is the default operation when --update is specified, and results in files being replaced if they’re older than the corresponding source file. +* `all` This is the default operation when an `--update` option is not specified, and results in all existing files in the destination being replaced. +* `none` This is similar to the `--no-clobber` option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. +* `older` This is the default operation when `--update` is specified, and results in files being replaced if they’re older than the corresponding source file. From 6625cfe88a569def06cfde66894904997eb7ab03 Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 1 May 2023 03:54:04 -0700 Subject: [PATCH 234/477] mv: fix documentation --- src/uu/mv/mv.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/uu/mv/mv.md b/src/uu/mv/mv.md index 7a5821351f..c31c6d07c4 100644 --- a/src/uu/mv/mv.md +++ b/src/uu/mv/mv.md @@ -12,10 +12,10 @@ Move `SOURCE` to `DEST`, or multiple `SOURCE`(s) to `DIRECTORY`. Do not move a non-directory that has an existing destination with the same or newer modification timestamp; instead, silently skip the file without failing. If the move is across file system boundaries, the comparison is to the source timestamp truncated to the resolutions of the destination file system and of the system calls used -to update timestamps; this avoids duplicate work if several ‘mv -u’ commands are executed with the same source -and destination. This option is ignored if the -n or --no-clobber option is also specified. which gives more control +to update timestamps; this avoids duplicate work if several `mv -u` commands are executed with the same source +and destination. This option is ignored if the `-n` or `--no-clobber` option is also specified. which gives more control over which existing files in the destination are replaced, and its value can be one of the following: -all This is the default operation when an --update option is not specified, and results in all existing files in the destination being replaced. -none This is similar to the --no-clobber option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. -older This is the default operation when --update is specified, and results in files being replaced if they’re older than the corresponding source file. +* `all` This is the default operation when an `--update` option is not specified, and results in all existing files in the destination being replaced. +* `none` This is similar to the `--no-clobber` option, in that no files in the destination are replaced, but also skipping a file does not induce a failure. +* `older` This is the default operation when `--update` is specified, and results in files being replaced if they’re older than the corresponding source file. From 66a9169e55b665e0e8a085a9c53b5a3570f7aa31 Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 1 May 2023 03:54:56 -0700 Subject: [PATCH 235/477] cp: fix typos --- tests/by-util/test_cp.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 4e241e0644..a933343b19 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -279,8 +279,8 @@ fn test_cp_arg_update_all() { fn test_cp_arg_update_older_dest_not_older_than_src() { let (at, mut ucmd) = at_and_ucmd!(); - let old = "test_cp_arg_update_oldler_file1"; - let new = "test_cp_arg_update_oldler_file2"; + let old = "test_cp_arg_update_older_file1"; + let new = "test_cp_arg_update_older_file2"; at.touch(old); sleep(Duration::from_secs(1)); @@ -303,8 +303,8 @@ fn test_cp_arg_update_older_dest_not_older_than_src() { fn test_cp_arg_update_older_dest_older_than_src() { let (at, mut ucmd) = at_and_ucmd!(); - let old = "test_cp_arg_update_oldler_file1"; - let new = "test_cp_arg_update_oldler_file2"; + let old = "test_cp_arg_update_older_file1"; + let new = "test_cp_arg_update_older_file2"; at.touch(old); at.append(old, "old content\n"); @@ -327,8 +327,8 @@ fn test_cp_arg_update_short_fail() { // same as --update=older let (at, mut ucmd) = at_and_ucmd!(); - let old = "test_cp_arg_update_oldler_file1"; - let new = "test_cp_arg_update_oldler_file2"; + let old = "test_cp_arg_update_older_file1"; + let new = "test_cp_arg_update_older_file2"; at.touch(old); sleep(Duration::from_secs(1)); @@ -352,8 +352,8 @@ fn test_cp_arg_update_short_succeed() { // same as --update=older let (at, mut ucmd) = at_and_ucmd!(); - let old = "test_cp_arg_update_oldler_file1"; - let new = "test_cp_arg_update_oldler_file2"; + let old = "test_cp_arg_update_older_file1"; + let new = "test_cp_arg_update_older_file2"; at.touch(old); at.touch(new); From 97c30d7f290d92692067fe867f2e4d9eb9bcfdc4 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 1 May 2023 14:07:21 +0200 Subject: [PATCH 236/477] Bump fundu to 0.5.1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a74acc33a5..72e78bcc07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -962,9 +962,9 @@ dependencies = [ [[package]] name = "fundu" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd020eeb034c9fc682e8fe6b9a28e1c0eda92eeb347c38776c09a0b227cdf9e5" +checksum = "2a37cfff04a32112c22c5497b20b0b09100fca406e76afd47b2ba5ab33d7a851" [[package]] name = "futures" diff --git a/Cargo.toml b/Cargo.toml index bae5080da9..b27986c1cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -282,7 +282,7 @@ filetime = "0.2" fnv = "1.0.7" fs_extra = "1.3.0" fts-sys = "0.2" -fundu = "0.5.0" +fundu = "0.5.1" gcd = "2.3" glob = "0.3.1" half = "2.2" From ad37db8da30718556d560086c02bc2dc20791b84 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 1 May 2023 14:25:59 +0200 Subject: [PATCH 237/477] sleep: fix broken tests due to fundu update --- tests/by-util/test_sleep.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/by-util/test_sleep.rs b/tests/by-util/test_sleep.rs index 06a22deae0..13aa882b9b 100644 --- a/tests/by-util/test_sleep.rs +++ b/tests/by-util/test_sleep.rs @@ -10,7 +10,7 @@ fn test_invalid_time_interval() { new_ucmd!() .arg("xyz") .fails() - .usage_error("invalid time interval 'xyz': Invalid character: 'x' at position 1"); + .usage_error("invalid time interval 'xyz': Invalid input: 'xyz' at position 1"); new_ucmd!() .args(&["--", "-1"]) .fails() @@ -211,7 +211,7 @@ fn test_sleep_when_input_has_only_whitespace_then_error(#[case] input: &str) { #[test] fn test_sleep_when_multiple_input_some_with_error_then_shows_all_errors() { - let expected = "invalid time interval 'abc': Invalid character: 'a' at position 1\n\ + let expected = "invalid time interval 'abc': Invalid input: 'abc' at position 1\n\ sleep: invalid time interval '1years': Invalid time unit: 'years' at position 2\n\ sleep: invalid time interval ' ': Found only whitespace in input"; From 6d89e9bfd7d4625c583ba74277d5c5dbd423557b Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 1 May 2023 15:57:56 +0200 Subject: [PATCH 238/477] cksum: remove "-a="s from markdown file --- src/uu/cksum/cksum.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/uu/cksum/cksum.md b/src/uu/cksum/cksum.md index c54132ef52..4b0d25f32c 100644 --- a/src/uu/cksum/cksum.md +++ b/src/uu/cksum/cksum.md @@ -10,14 +10,14 @@ Print CRC and size for each file DIGEST determines the digest algorithm and default output format: -- `-a=sysv`: (equivalent to sum -s) -- `-a=bsd`: (equivalent to sum -r) -- `-a=crc`: (equivalent to cksum) -- `-a=md5`: (equivalent to md5sum) -- `-a=sha1`: (equivalent to sha1sum) -- `-a=sha224`: (equivalent to sha224sum) -- `-a=sha256`: (equivalent to sha256sum) -- `-a=sha384`: (equivalent to sha384sum) -- `-a=sha512`: (equivalent to sha512sum) -- `-a=blake2b`: (equivalent to b2sum) -- `-a=sm3`: (only available through cksum) +- `sysv`: (equivalent to sum -s) +- `bsd`: (equivalent to sum -r) +- `crc`: (equivalent to cksum) +- `md5`: (equivalent to md5sum) +- `sha1`: (equivalent to sha1sum) +- `sha224`: (equivalent to sha224sum) +- `sha256`: (equivalent to sha256sum) +- `sha384`: (equivalent to sha384sum) +- `sha512`: (equivalent to sha512sum) +- `blake2b`: (equivalent to b2sum) +- `sm3`: (only available through cksum) From 60c0b661c3476a0bdc9ffd9d52078aae9b6f910e Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 1 May 2023 17:22:08 -0700 Subject: [PATCH 239/477] core: fix typo in update control --- src/uucore/src/lib/mods/update_control.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uucore/src/lib/mods/update_control.rs b/src/uucore/src/lib/mods/update_control.rs index 5bbca0e49b..c0b2cc5ef9 100644 --- a/src/uucore/src/lib/mods/update_control.rs +++ b/src/uucore/src/lib/mods/update_control.rs @@ -28,7 +28,7 @@ //! .arg(update_control::arguments::update()) //! .arg(update_control::arguments::update_no_args()) //! .get_matches_from(vec![ -//! "commmand", "--update=older" +//! "command", "--update=older" //! ]); //! //! let update_mode = update_control::determine_update_mode(&matches); From 36e93e12d662b2e629862d0ca434e5e2319dccb6 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 2 May 2023 12:38:12 -0700 Subject: [PATCH 240/477] core: add header notice for update control --- src/uucore/src/lib/mods/update_control.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/uucore/src/lib/mods/update_control.rs b/src/uucore/src/lib/mods/update_control.rs index c0b2cc5ef9..cf5deb55c7 100644 --- a/src/uucore/src/lib/mods/update_control.rs +++ b/src/uucore/src/lib/mods/update_control.rs @@ -1,3 +1,10 @@ +// This file is part of the uutils coreutils package. +// +// (c) John Shin +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + //! Implement GNU-style update functionality. //! //! - pre-defined [`clap`-Arguments][1] for inclusion in utilities that @@ -28,7 +35,7 @@ //! .arg(update_control::arguments::update()) //! .arg(update_control::arguments::update_no_args()) //! .get_matches_from(vec![ -//! "command", "--update=older" +//! "commmand", "--update=older" //! ]); //! //! let update_mode = update_control::determine_update_mode(&matches); From 06d4603bead429a17f510cc06f8886bf463b908f Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 2 May 2023 12:40:04 -0700 Subject: [PATCH 241/477] core: fix typo in update control --- src/uucore/src/lib/mods/update_control.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uucore/src/lib/mods/update_control.rs b/src/uucore/src/lib/mods/update_control.rs index cf5deb55c7..83dd505cf0 100644 --- a/src/uucore/src/lib/mods/update_control.rs +++ b/src/uucore/src/lib/mods/update_control.rs @@ -68,7 +68,7 @@ pub mod arguments { pub static OPT_UPDATE: &str = "update"; pub static OPT_UPDATE_NO_ARG: &str = "u"; - // `--update` argument, defaults to `older` if no values after provided + // `--update` argument, defaults to `older` if no values are provided pub fn update() -> clap::Arg { clap::Arg::new(OPT_UPDATE) .long("update") From 460d3460691a5b27141b247e792ffc9605fe445f Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 2 May 2023 12:42:39 -0700 Subject: [PATCH 242/477] core: remove '' case for the update argument --- src/uucore/src/lib/mods/update_control.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uucore/src/lib/mods/update_control.rs b/src/uucore/src/lib/mods/update_control.rs index 83dd505cf0..13057dfc55 100644 --- a/src/uucore/src/lib/mods/update_control.rs +++ b/src/uucore/src/lib/mods/update_control.rs @@ -73,7 +73,7 @@ pub mod arguments { clap::Arg::new(OPT_UPDATE) .long("update") .help("move only when the SOURCE file is newer than the destination file or when the destination file is missing") - .value_parser(["", "none", "all", "older"]) + .value_parser(["none", "all", "older"]) .num_args(0..=1) .default_missing_value("older") .require_equals(true) @@ -125,7 +125,7 @@ pub fn determine_update_mode(matches: &ArgMatches) -> UpdateMode { if matches.contains_id(arguments::OPT_UPDATE) { if let Some(mode) = matches.get_one::(arguments::OPT_UPDATE) { match mode.as_str() { - "all" | "" => UpdateMode::ReplaceAll, + "all" => UpdateMode::ReplaceAll, "none" => UpdateMode::ReplaceNone, "older" => UpdateMode::ReplaceIfOlder, _ => unreachable!("other args restricted by clap"), From 90e0d3030f64942f9c85d9a8084744d563d7dbde Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Wed, 3 May 2023 04:48:59 +0900 Subject: [PATCH 243/477] test: move help strings to markdown file (#4816) --- src/uu/test/src/test.rs | 95 +++++++---------------------------------- src/uu/test/test.md | 79 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 79 deletions(-) create mode 100644 src/uu/test/test.md diff --git a/src/uu/test/src/test.rs b/src/uu/test/src/test.rs index 313ef04131..b0a8fc6131 100644 --- a/src/uu/test/src/test.rs +++ b/src/uu/test/src/test.rs @@ -20,82 +20,27 @@ use std::fs; use std::os::unix::fs::MetadataExt; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError}; -use uucore::format_usage; +use uucore::{format_usage, help_about, help_section}; +const ABOUT: &str = help_about!("test.md"); + +// The help_usage method replaces util name (the first word) with {}. +// And, The format_usage method replaces {} with execution_phrase ( e.g. test or [ ). +// However, This test command has two util names. +// So, we use test or [ instead of {} so that the usage string is correct. const USAGE: &str = "\ - {} EXPRESSION - {} - [ EXPRESSION ] - [ ] - [ OPTION"; +test EXPRESSION +test +[ EXPRESSION ] +[ ] +[ OPTION"; // We use after_help so that this comes after the usage string (it would come before if we used about) -const AFTER_HELP: &str = " -Exit with the status determined by EXPRESSION. - -An omitted EXPRESSION defaults to false. Otherwise, -EXPRESSION is true or false and sets exit status. It is one of: - - ( EXPRESSION ) EXPRESSION is true - ! EXPRESSION EXPRESSION is false - EXPRESSION1 -a EXPRESSION2 both EXPRESSION1 and EXPRESSION2 are true - EXPRESSION1 -o EXPRESSION2 either EXPRESSION1 or EXPRESSION2 is true - - -n STRING the length of STRING is nonzero - STRING equivalent to -n STRING - -z STRING the length of STRING is zero - STRING1 = STRING2 the strings are equal - STRING1 != STRING2 the strings are not equal - - INTEGER1 -eq INTEGER2 INTEGER1 is equal to INTEGER2 - INTEGER1 -ge INTEGER2 INTEGER1 is greater than or equal to INTEGER2 - INTEGER1 -gt INTEGER2 INTEGER1 is greater than INTEGER2 - INTEGER1 -le INTEGER2 INTEGER1 is less than or equal to INTEGER2 - INTEGER1 -lt INTEGER2 INTEGER1 is less than INTEGER2 - INTEGER1 -ne INTEGER2 INTEGER1 is not equal to INTEGER2 - - FILE1 -ef FILE2 FILE1 and FILE2 have the same device and inode numbers - FILE1 -nt FILE2 FILE1 is newer (modification date) than FILE2 - FILE1 -ot FILE2 FILE1 is older than FILE2 - - -b FILE FILE exists and is block special - -c FILE FILE exists and is character special - -d FILE FILE exists and is a directory - -e FILE FILE exists - -f FILE FILE exists and is a regular file - -g FILE FILE exists and is set-group-ID - -G FILE FILE exists and is owned by the effective group ID - -h FILE FILE exists and is a symbolic link (same as -L) - -k FILE FILE exists and has its sticky bit set - -L FILE FILE exists and is a symbolic link (same as -h) - -N FILE FILE exists and has been modified since it was last read - -O FILE FILE exists and is owned by the effective user ID - -p FILE FILE exists and is a named pipe - -r FILE FILE exists and read permission is granted - -s FILE FILE exists and has a size greater than zero - -S FILE FILE exists and is a socket - -t FD file descriptor FD is opened on a terminal - -u FILE FILE exists and its set-user-ID bit is set - -w FILE FILE exists and write permission is granted - -x FILE FILE exists and execute (or search) permission is granted - -Except for -h and -L, all FILE-related tests dereference symbolic links. -Beware that parentheses need to be escaped (e.g., by backslashes) for shells. -INTEGER may also be -l STRING, which evaluates to the length of STRING. - -NOTE: Binary -a and -o are inherently ambiguous. Use 'test EXPR1 && test -EXPR2' or 'test EXPR1 || test EXPR2' instead. - -NOTE: [ honors the --help and --version options, but test does not. -test treats each of those as it treats any other nonempty STRING. - -NOTE: your shell may have its own version of test and/or [, which usually supersedes -the version described here. Please refer to your shell's documentation -for details about the options it supports."; - -const ABOUT: &str = "Check file types and compare values."; +const AFTER_HELP: &str = help_section!("after help", "test.md"); pub fn uu_app() -> Command { + // Disable printing of -h and -v as valid alternatives for --help and --version, + // since we don't recognize -h and -v as help/version flags. Command::new(uucore::util_name()) .version(crate_version!()) .about(ABOUT) @@ -112,15 +57,7 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> { if binary_name.ends_with('[') { // If invoked as [ we should recognize --help and --version (but not -h or -v) if args.len() == 1 && (args[0] == "--help" || args[0] == "--version") { - // Let clap pretty-print help and version - Command::new(binary_name) - .version(crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) - // Disable printing of -h and -v as valid alternatives for --help and --version, - // since we don't recognize -h and -v as help/version flags. - .get_matches_from(std::iter::once(program).chain(args.into_iter())); + uu_app().get_matches_from(std::iter::once(program).chain(args.into_iter())); return Ok(()); } // If invoked via name '[', matching ']' must be in the last arg diff --git a/src/uu/test/test.md b/src/uu/test/test.md new file mode 100644 index 0000000000..e67eb1824a --- /dev/null +++ b/src/uu/test/test.md @@ -0,0 +1,79 @@ +# test + +``` +test EXPRESSION +test +[ EXPRESSION ] +[ ] +[ OPTION +``` + +Check file types and compare values. + +## After Help + +Exit with the status determined by `EXPRESSION`. + +An omitted `EXPRESSION` defaults to false. +Otherwise, `EXPRESSION` is true or false and sets exit status. + +It is one of: + +* ( EXPRESSION ) `EXPRESSION` is true +* ! EXPRESSION `EXPRESSION` is false +* EXPRESSION1 -a EXPRESSION2 both `EXPRESSION1` and `EXPRESSION2` are true +* EXPRESSION1 -o EXPRESSION2 either `EXPRESSION1` or `EXPRESSION2` is true + +String operations: +* -n STRING the length of `STRING` is nonzero +* STRING equivalent to -n `STRING` +* -z STRING the length of `STRING` is zero +* STRING1 = STRING2 the strings are equal +* STRING1 != STRING2 the strings are not equal + +Integer comparisons: +* INTEGER1 -eq INTEGER2 `INTEGER1` is equal to `INTEGER2` +* INTEGER1 -ge INTEGER2 `INTEGER1` is greater than or equal to `INTEGER2` +* INTEGER1 -gt INTEGER2 `INTEGER1` is greater than `INTEGER2` +* INTEGER1 -le INTEGER2 `INTEGER1` is less than or equal to `INTEGER2` +* INTEGER1 -lt INTEGER2 `INTEGER1` is less than `INTEGER2` +* INTEGER1 -ne INTEGER2 `INTEGER1` is not equal to `INTEGER2` + +File operations: +* FILE1 -ef FILE2 `FILE1` and `FILE2` have the same device and inode numbers +* FILE1 -nt FILE2 `FILE1` is newer (modification date) than `FILE2` +* FILE1 -ot FILE2 `FILE1` is older than `FILE2` + +* -b FILE `FILE` exists and is block special +* -c FILE `FILE` exists and is character special +* -d FILE `FILE` exists and is a directory +* -e FILE `FILE` exists +* -f FILE `FILE` exists and is a regular file +* -g FILE `FILE` exists and is set-group-ID +* -G FILE `FILE` exists and is owned by the effective group ID +* -h FILE `FILE` exists and is a symbolic link (same as -L) +* -k FILE `FILE` exists and has its sticky bit set +* -L FILE `FILE` exists and is a symbolic link (same as -h) +* -N FILE `FILE` exists and has been modified since it was last read +* -O FILE `FILE` exists and is owned by the effective user ID +* -p FILE `FILE` exists and is a named pipe +* -r FILE `FILE` exists and read permission is granted +* -s FILE `FILE` exists and has a size greater than zero +* -S FILE `FILE` exists and is a socket +* -t FD `file` descriptor `FD` is opened on a terminal +* -u FILE `FILE` exists and its set-user-ID bit is set +* -w FILE `FILE` exists and write permission is granted +* -x FILE `FILE` exists and execute (or search) permission is granted + +Except for `-h` and `-L`, all FILE-related tests dereference (follow) symbolic links. +Beware that parentheses need to be escaped (e.g., by backslashes) for shells. +`INTEGER` may also be -l `STRING`, which evaluates to the length of `STRING`. + +NOTE: Binary `-a` and `-o` are inherently ambiguous. +Use `test EXPR1 && test EXPR2` or `test EXPR1 || test EXPR2` instead. + +NOTE: `[` honors the `--help` and `--version` options, but test does not. +test treats each of those as it treats any other nonempty `STRING`. + +NOTE: your shell may have its own version of `test` and/or `[`, which usually supersedes the version described here. +Please refer to your shell's documentation for details about the options it supports. From 3b8f3d04f47d5d6b5194e84cf54ea00d25baec83 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 2 May 2023 12:49:49 -0700 Subject: [PATCH 244/477] core: remove unnecessary if statement in update control --- src/uucore/src/lib/mods/update_control.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/uucore/src/lib/mods/update_control.rs b/src/uucore/src/lib/mods/update_control.rs index 13057dfc55..3cd81e0120 100644 --- a/src/uucore/src/lib/mods/update_control.rs +++ b/src/uucore/src/lib/mods/update_control.rs @@ -122,16 +122,12 @@ pub mod arguments { /// assert_eq!(update_mode, UpdateMode::ReplaceAll) /// } pub fn determine_update_mode(matches: &ArgMatches) -> UpdateMode { - if matches.contains_id(arguments::OPT_UPDATE) { - if let Some(mode) = matches.get_one::(arguments::OPT_UPDATE) { - match mode.as_str() { - "all" => UpdateMode::ReplaceAll, - "none" => UpdateMode::ReplaceNone, - "older" => UpdateMode::ReplaceIfOlder, - _ => unreachable!("other args restricted by clap"), - } - } else { - unreachable!("other args restricted by clap") + if let Some(mode) = matches.get_one::(arguments::OPT_UPDATE) { + match mode.as_str() { + "all" => UpdateMode::ReplaceAll, + "none" => UpdateMode::ReplaceNone, + "older" => UpdateMode::ReplaceIfOlder, + _ => unreachable!("other args restricted by clap"), } } else if matches.get_flag(arguments::OPT_UPDATE_NO_ARG) { // short form of this option is equivalent to using --update=older From 6a100976c7fe5322feab654bd1f381741def4950 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 2 May 2023 13:30:38 -0700 Subject: [PATCH 245/477] mv: simplify tests for update --- tests/by-util/test_mv.rs | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 29a22ce102..d0885a92a9 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -724,15 +724,11 @@ fn test_mv_arg_update_none() { let file1 = "test_mv_arg_update_none_file1"; let file2 = "test_mv_arg_update_none_file2"; - - at.touch(file1); - at.touch(file2); - let file1_content = "file1 content\n"; let file2_content = "file2 content\n"; - at.append(file1, file1_content); - at.append(file2, file2_content); + at.write(file1, file1_content); + at.write(file2, file2_content); ucmd.arg(file1) .arg(file2) @@ -750,15 +746,11 @@ fn test_mv_arg_update_all() { let file1 = "test_mv_arg_update_none_file1"; let file2 = "test_mv_arg_update_none_file2"; - - at.touch(file1); - at.touch(file2); - let file1_content = "file1 content\n"; let file2_content = "file2 content\n"; - at.append(file1, file1_content); - at.append(file2, file2_content); + at.write(file1, file1_content); + at.write(file2, file2_content); ucmd.arg(file1) .arg(file2) @@ -779,13 +771,11 @@ fn test_mv_arg_update_older_dest_not_older() { let old_content = "file1 content\n"; let new_content = "file2 content\n"; - at.touch(old); - at.append(old, old_content); + at.write(old, old_content); sleep(Duration::from_secs(1)); - at.touch(new); - at.append(new, new_content); + at.write(new, new_content); ucmd.arg(old) .arg(new) @@ -806,13 +796,11 @@ fn test_mv_arg_update_older_dest_older() { let old_content = "file1 content\n"; let new_content = "file2 content\n"; - at.touch(old); - at.append(old, old_content); + at.write(old, old_content); sleep(Duration::from_secs(1)); - at.touch(new); - at.append(new, new_content); + at.write(new, new_content); ucmd.arg(new) .arg(old) @@ -834,13 +822,11 @@ fn test_mv_arg_update_short_overwrite() { let old_content = "file1 content\n"; let new_content = "file2 content\n"; - at.touch(old); - at.append(old, old_content); + at.write(old, old_content); sleep(Duration::from_secs(1)); - at.touch(new); - at.append(new, new_content); + at.write(new, new_content); ucmd.arg(new) .arg(old) @@ -862,13 +848,11 @@ fn test_mv_arg_update_short_no_overwrite() { let old_content = "file1 content\n"; let new_content = "file2 content\n"; - at.touch(old); - at.append(old, old_content); + at.write(old, old_content); sleep(Duration::from_secs(1)); - at.touch(new); - at.append(new, new_content); + at.write(new, new_content); ucmd.arg(old) .arg(new) From c0e4e4f757f52c31934bfc2efb36ef462bd21bf9 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 2 May 2023 13:35:06 -0700 Subject: [PATCH 246/477] cp: simplify tests for update --- tests/by-util/test_cp.rs | 55 +++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index a933343b19..33bdcb3a8b 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -279,15 +279,13 @@ fn test_cp_arg_update_all() { fn test_cp_arg_update_older_dest_not_older_than_src() { let (at, mut ucmd) = at_and_ucmd!(); - let old = "test_cp_arg_update_older_file1"; - let new = "test_cp_arg_update_older_file2"; + let old = "test_cp_arg_update_dest_not_older_file1"; + let new = "test_cp_arg_update_dest_not_older_file2"; + let old_content = "old content\n"; + let new_content = "new content\n"; - at.touch(old); - sleep(Duration::from_secs(1)); - at.touch(new); - - at.append(old, "old content\n"); - at.append(new, "new content\n"); + at.write(old, old_content); + at.write(new, new_content); ucmd.arg(old) .arg(new) @@ -303,14 +301,16 @@ fn test_cp_arg_update_older_dest_not_older_than_src() { fn test_cp_arg_update_older_dest_older_than_src() { let (at, mut ucmd) = at_and_ucmd!(); - let old = "test_cp_arg_update_older_file1"; - let new = "test_cp_arg_update_older_file2"; + let old = "test_cp_arg_update_dest_older_file1"; + let new = "test_cp_arg_update_dest_older_file2"; + let old_content = "old content\n"; + let new_content = "new content\n"; + + at.write(old, old_content); - at.touch(old); - at.append(old, "old content\n"); sleep(Duration::from_secs(1)); - at.touch(new); - at.append(new, "new content\n"); + + at.write(new, new_content); ucmd.arg(new) .arg(old) @@ -327,15 +327,16 @@ fn test_cp_arg_update_short_fail() { // same as --update=older let (at, mut ucmd) = at_and_ucmd!(); - let old = "test_cp_arg_update_older_file1"; - let new = "test_cp_arg_update_older_file2"; + let old = "test_cp_arg_update_short_no_overwrite_file1"; + let new = "test_cp_arg_update_short_no_overwrite_file2"; + let old_content = "old content\n"; + let new_content = "new content\n"; + + at.write(old, old_content); - at.touch(old); sleep(Duration::from_secs(1)); - at.touch(new); - at.append(old, "old content\n"); - at.append(new, "new content\n"); + at.write(new, new_content); ucmd.arg(old) .arg(new) @@ -352,14 +353,16 @@ fn test_cp_arg_update_short_succeed() { // same as --update=older let (at, mut ucmd) = at_and_ucmd!(); - let old = "test_cp_arg_update_older_file1"; - let new = "test_cp_arg_update_older_file2"; + let old = "test_cp_arg_update_short_overwrite_file1"; + let new = "test_cp_arg_update_short_overwrite_file2"; + let old_content = "old content\n"; + let new_content = "new content\n"; + + at.write(old, old_content); - at.touch(old); - at.touch(new); + sleep(Duration::from_secs(1)); - at.append(old, "old content\n"); - at.append(new, "new content\n"); + at.write(new, new_content); ucmd.arg(new) .arg(old) From 983fee0cead753e2a0482bd5dfd3fe5d5018830f Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 2 May 2023 13:35:52 -0700 Subject: [PATCH 247/477] cp: fix wrong test names for update --- tests/by-util/test_cp.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 33bdcb3a8b..7f293edcf5 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -323,7 +323,7 @@ fn test_cp_arg_update_older_dest_older_than_src() { } #[test] -fn test_cp_arg_update_short_fail() { +fn test_cp_arg_update_short_no_overwrite() { // same as --update=older let (at, mut ucmd) = at_and_ucmd!(); @@ -349,7 +349,7 @@ fn test_cp_arg_update_short_fail() { } #[test] -fn test_cp_arg_update_short_succeed() { +fn test_cp_arg_update_short_overwrite() { // same as --update=older let (at, mut ucmd) = at_and_ucmd!(); @@ -371,7 +371,7 @@ fn test_cp_arg_update_short_succeed() { .no_stderr() .no_stdout(); - assert_eq!(at.read(new), "new content\n") + assert_eq!(at.read(old), "new content\n") } #[test] From 918c36b4851f4ea79894687d7bcf1d896c08188b Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 2 May 2023 13:46:08 -0700 Subject: [PATCH 248/477] cp: write test for multiple update args --- tests/by-util/test_cp.rs | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 7f293edcf5..5376ba3638 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -374,6 +374,62 @@ fn test_cp_arg_update_short_overwrite() { assert_eq!(at.read(old), "new content\n") } +#[test] +fn test_cp_arg_update_none_then_all() { + // take last if multiple update args are supplied, + // update=all wins in this case + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_cp_arg_update_none_then_all_file1"; + let new = "test_cp_arg_update_none_then_all_file2"; + let old_content = "old content\n"; + let new_content = "new content\n"; + + at.write(old, old_content); + + sleep(Duration::from_secs(1)); + + at.write(new, new_content); + + ucmd.arg(old) + .arg(new) + .arg("--update=none") + .arg("--update=all") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(new), "old content\n") +} + +#[test] +fn test_cp_arg_update_all_then_none() { + // take last if multiple update args are supplied, + // update=none wins in this case + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_cp_arg_update_all_then_none_file1"; + let new = "test_cp_arg_update_all_then_none_file2"; + let old_content = "old content\n"; + let new_content = "new content\n"; + + at.write(old, old_content); + + sleep(Duration::from_secs(1)); + + at.write(new, new_content); + + ucmd.arg(old) + .arg(new) + .arg("--update=all") + .arg("--update=none") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(new), "new content\n") +} + #[test] fn test_cp_arg_interactive() { let (at, mut ucmd) = at_and_ucmd!(); From 8ad2fa3cc1cfe1d238607a0b783bbde681d4a594 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 2 May 2023 13:46:43 -0700 Subject: [PATCH 249/477] mv: write test for multiple update args --- tests/by-util/test_mv.rs | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index d0885a92a9..5bf41b09be 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -787,6 +787,62 @@ fn test_mv_arg_update_older_dest_not_older() { assert_eq!(at.read(new), new_content) } +#[test] +fn test_cp_arg_update_none_then_all() { + // take last if multiple update args are supplied, + // update=all wins in this case + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_cp_arg_update_none_then_all_file1"; + let new = "test_cp_arg_update_none_then_all_file2"; + let old_content = "old content\n"; + let new_content = "new content\n"; + + at.write(old, old_content); + + sleep(Duration::from_secs(1)); + + at.write(new, new_content); + + ucmd.arg(old) + .arg(new) + .arg("--update=none") + .arg("--update=all") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(new), "old content\n") +} + +#[test] +fn test_cp_arg_update_all_then_none() { + // take last if multiple update args are supplied, + // update=none wins in this case + let (at, mut ucmd) = at_and_ucmd!(); + + let old = "test_cp_arg_update_all_then_none_file1"; + let new = "test_cp_arg_update_all_then_none_file2"; + let old_content = "old content\n"; + let new_content = "new content\n"; + + at.write(old, old_content); + + sleep(Duration::from_secs(1)); + + at.write(new, new_content); + + ucmd.arg(old) + .arg(new) + .arg("--update=all") + .arg("--update=none") + .succeeds() + .no_stderr() + .no_stdout(); + + assert_eq!(at.read(new), "new content\n") +} + #[test] fn test_mv_arg_update_older_dest_older() { let (at, mut ucmd) = at_and_ucmd!(); From 898628fa3aae6f48d722e2e8821ca0e98e0017d6 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 2 May 2023 13:54:31 -0700 Subject: [PATCH 250/477] core: fix typo in update control --- src/uucore/src/lib/mods/update_control.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uucore/src/lib/mods/update_control.rs b/src/uucore/src/lib/mods/update_control.rs index 3cd81e0120..e46afd1852 100644 --- a/src/uucore/src/lib/mods/update_control.rs +++ b/src/uucore/src/lib/mods/update_control.rs @@ -35,7 +35,7 @@ //! .arg(update_control::arguments::update()) //! .arg(update_control::arguments::update_no_args()) //! .get_matches_from(vec![ -//! "commmand", "--update=older" +//! "command", "--update=older" //! ]); //! //! let update_mode = update_control::determine_update_mode(&matches); From aae3f2f99cefedfa69e46459ece7fbe4aabbc659 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 2 May 2023 22:41:55 +0200 Subject: [PATCH 251/477] Ride along: fix some trivial clippy warnings --- src/uucore/src/lib/features/mode.rs | 2 +- tests/by-util/test_mv.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uucore/src/lib/features/mode.rs b/src/uucore/src/lib/features/mode.rs index a54824d18e..9435e3201a 100644 --- a/src/uucore/src/lib/features/mode.rs +++ b/src/uucore/src/lib/features/mode.rs @@ -209,7 +209,7 @@ mod test { assert_eq!(super::parse_mode("u+x").unwrap(), 0o766); assert_eq!( super::parse_mode("+x").unwrap(), - if !crate::os::is_wsl_1() { 0o777 } else { 0o776 } + if crate::os::is_wsl_1() { 0o776 } else { 0o777 } ); assert_eq!(super::parse_mode("a-w").unwrap(), 0o444); assert_eq!(super::parse_mode("g-r").unwrap(), 0o626); diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 0195957353..f455c4e734 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -70,7 +70,7 @@ fn test_mv_move_file_into_dir_with_target_arg() { .succeeds() .no_stderr(); - assert!(at.file_exists(format!("{dir}/{file}"))) + assert!(at.file_exists(format!("{dir}/{file}"))); } #[test] @@ -88,7 +88,7 @@ fn test_mv_move_file_into_file_with_target_arg() { .fails() .stderr_is(format!("mv: target directory '{file1}': Not a directory\n")); - assert!(at.file_exists(file1)) + assert!(at.file_exists(file1)); } #[test] From 923a62c6beb8fe26c371576e424c3e9d296e18f7 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 3 May 2023 10:07:46 +0200 Subject: [PATCH 252/477] mv: fix function/file names in tests --- tests/by-util/test_mv.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 5bf41b09be..ce9e26a819 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -788,13 +788,13 @@ fn test_mv_arg_update_older_dest_not_older() { } #[test] -fn test_cp_arg_update_none_then_all() { +fn test_mv_arg_update_none_then_all() { // take last if multiple update args are supplied, // update=all wins in this case let (at, mut ucmd) = at_and_ucmd!(); - let old = "test_cp_arg_update_none_then_all_file1"; - let new = "test_cp_arg_update_none_then_all_file2"; + let old = "test_mv_arg_update_none_then_all_file1"; + let new = "test_mv_arg_update_none_then_all_file2"; let old_content = "old content\n"; let new_content = "new content\n"; @@ -816,13 +816,13 @@ fn test_cp_arg_update_none_then_all() { } #[test] -fn test_cp_arg_update_all_then_none() { +fn test_mv_arg_update_all_then_none() { // take last if multiple update args are supplied, // update=none wins in this case let (at, mut ucmd) = at_and_ucmd!(); - let old = "test_cp_arg_update_all_then_none_file1"; - let new = "test_cp_arg_update_all_then_none_file2"; + let old = "test_mv_arg_update_all_then_none_file1"; + let new = "test_mv_arg_update_all_then_none_file2"; let old_content = "old content\n"; let new_content = "new content\n"; From 546631c8e77bb6256d6b211306ed71b5bbf0e16f Mon Sep 17 00:00:00 2001 From: Thomas Hurst Date: Wed, 3 May 2023 16:30:53 +0000 Subject: [PATCH 253/477] dd: Tidy includes --- src/uu/dd/src/dd.rs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 15c7e8ed4a..541c85ff95 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -33,9 +33,12 @@ use std::os::unix::fs::FileTypeExt; #[cfg(any(target_os = "linux", target_os = "android"))] use std::os::unix::fs::OpenOptionsExt; use std::path::Path; -use std::sync::mpsc; +use std::sync::{ + atomic::{AtomicBool, Ordering::Relaxed}, + mpsc, Arc, +}; use std::thread; -use std::time; +use std::time::{Duration, Instant}; use clap::{crate_version, Arg, Command}; use gcd::Gcd; @@ -65,14 +68,6 @@ struct Settings { status: Option, } -use std::thread::sleep; -use std::time::Duration; - -use std::sync::{ - atomic::{AtomicBool, Ordering::Relaxed}, - Arc, -}; - #[derive(Debug, Clone)] pub struct Alarm { interval: Duration, @@ -84,9 +79,9 @@ impl Alarm { let trigger = Arc::new(AtomicBool::default()); let weak_trigger = Arc::downgrade(&trigger); - std::thread::spawn(move || { + thread::spawn(move || { while let Some(trigger) = weak_trigger.upgrade() { - sleep(interval); + thread::sleep(interval); trigger.store(true, Relaxed); } }); @@ -646,7 +641,7 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // of its report includes the throughput in bytes per second, // which requires knowing how long the process has been // running. - let start = time::Instant::now(); + let start = Instant::now(); // A good buffer size for reading. // @@ -718,7 +713,7 @@ fn finalize( output: &mut Output, rstat: ReadStat, wstat: WriteStat, - start: time::Instant, + start: Instant, prog_tx: &mpsc::Sender, output_thread: thread::JoinHandle, ) -> std::io::Result<()> { From 01a8623d216599449f6c895996e6ba64c12fbd89 Mon Sep 17 00:00:00 2001 From: Thomas Hurst Date: Wed, 3 May 2023 16:31:14 +0000 Subject: [PATCH 254/477] dd: Add documentation to Alarm struct --- src/uu/dd/src/dd.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 541c85ff95..41b7eb7732 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -68,6 +68,15 @@ struct Settings { status: Option, } +/// A timer which triggers on a given interval +/// +/// After being constructed with [`Alarm::with_interval`], [`Alarm::is_triggered`] +/// will return true once per the given [`Duration`]. +/// +/// Can be cloned, but the trigger status is shared across all instances so only +/// the first caller each interval will yield true. +/// +/// When all instances are dropped the background thread will exit on the next interval. #[derive(Debug, Clone)] pub struct Alarm { interval: Duration, @@ -671,6 +680,11 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // Create a common buffer with a capacity of the block size. // This is the max size needed. let mut buf = vec![BUF_INIT_BYTE; bsize]; + + // Spawn a timer thread to provide a scheduled signal indicating when we + // should send an update of our progress to the reporting thread. + // + // This avoids the need to query the OS monotonic clock for every block. let alarm = Alarm::with_interval(Duration::from_secs(1)); // The main read/write loop. From 6547bec2ef6b68085f6ea0ed329f5d858a855448 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 2 May 2023 22:42:33 +0200 Subject: [PATCH 255/477] uucore/detect_symlink_loop: add a function to detect symlink loops --- Cargo.lock | 1 + src/uucore/Cargo.toml | 1 + src/uucore/src/lib/features/fs.rs | 72 +++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 72e78bcc07..05b86a9860 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3407,6 +3407,7 @@ dependencies = [ "sha2", "sha3", "sm3", + "tempfile", "thiserror", "time", "uucore_procs", diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 669971a69f..d5fe9e54c3 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -54,6 +54,7 @@ nix = { workspace=true, features = ["fs", "uio", "zerocopy", "signal"] } [dev-dependencies] clap = { workspace=true } once_cell = { workspace=true } +tempfile = { workspace=true } [target.'cfg(target_os = "windows")'.dependencies] winapi-util = { version= "0.1.5", optional=true } diff --git a/src/uucore/src/lib/features/fs.rs b/src/uucore/src/lib/features/fs.rs index b82eba94a8..6dc371a10c 100644 --- a/src/uucore/src/lib/features/fs.rs +++ b/src/uucore/src/lib/features/fs.rs @@ -584,10 +584,45 @@ pub fn make_path_relative_to, P2: AsRef>(path: P1, to: P2) components.iter().collect() } +/// Checks if there is a symlink loop in the given path. +/// +/// A symlink loop is a chain of symlinks where the last symlink points back to one of the previous symlinks in the chain. +/// +/// # Arguments +/// +/// * `path` - A reference to a `Path` representing the starting path to check for symlink loops. +/// +/// # Returns +/// +/// * `bool` - Returns `true` if a symlink loop is detected, `false` otherwise. +pub fn is_symlink_loop(path: &Path) -> bool { + let mut visited_symlinks = HashSet::new(); + let mut current_path = path.to_path_buf(); + + while let (Ok(metadata), Ok(link)) = ( + current_path.symlink_metadata(), + fs::read_link(¤t_path), + ) { + if !metadata.file_type().is_symlink() { + return false; + } + if !visited_symlinks.insert(current_path.clone()) { + return true; + } + current_path = link; + } + + false +} + #[cfg(test)] mod tests { // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; + #[cfg(unix)] + use std::os::unix; + #[cfg(unix)] + use tempfile::tempdir; struct NormalizePathTestCase<'a> { path: &'a str, @@ -695,4 +730,41 @@ mod tests { display_permissions_unix(S_IFCHR | S_ISVTX as mode_t | 0o054, true) ); } + + #[cfg(unix)] + #[test] + fn test_is_symlink_loop_no_loop() { + let temp_dir = tempdir().unwrap(); + let file_path = temp_dir.path().join("file.txt"); + let symlink_path = temp_dir.path().join("symlink"); + + fs::write(&file_path, "test content").unwrap(); + unix::fs::symlink(&file_path, &symlink_path).unwrap(); + + assert!(!is_symlink_loop(&symlink_path)); + } + + #[cfg(unix)] + #[test] + fn test_is_symlink_loop_direct_loop() { + let temp_dir = tempdir().unwrap(); + let symlink_path = temp_dir.path().join("loop"); + + unix::fs::symlink(&symlink_path, &symlink_path).unwrap(); + + assert!(is_symlink_loop(&symlink_path)); + } + + #[cfg(unix)] + #[test] + fn test_is_symlink_loop_indirect_loop() { + let temp_dir = tempdir().unwrap(); + let symlink1_path = temp_dir.path().join("symlink1"); + let symlink2_path = temp_dir.path().join("symlink2"); + + unix::fs::symlink(&symlink1_path, &symlink2_path).unwrap(); + unix::fs::symlink(&symlink2_path, &symlink1_path).unwrap(); + + assert!(is_symlink_loop(&symlink1_path)); + } } From 832fd2d2c6915b3a60ff8d01d3919159992e4933 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 2 May 2023 23:22:13 +0200 Subject: [PATCH 256/477] cp: fix cp -f f loop when loop is a symlink loop Fix: tests/cp/thru-dangling.sh --- src/uu/cp/src/cp.rs | 7 ++++--- tests/by-util/test_cp.rs | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 3ccff03036..00af0f2519 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -38,7 +38,8 @@ use uucore::backup_control::{self, BackupMode}; use uucore::display::Quotable; use uucore::error::{set_exit_code, UClapError, UError, UResult, UUsageError}; use uucore::fs::{ - canonicalize, paths_refer_to_same_file, FileInformation, MissingHandling, ResolveMode, + canonicalize, is_symlink_loop, paths_refer_to_same_file, FileInformation, MissingHandling, + ResolveMode, }; use uucore::{crash, format_usage, help_about, help_usage, prompt_yes, show_error, show_warning}; @@ -1388,11 +1389,10 @@ fn handle_existing_dest( backup_dest(dest, &backup_path)?; } } - match options.overwrite { // FIXME: print that the file was removed if --verbose is enabled OverwriteMode::Clobber(ClobberMode::Force) => { - if fs::metadata(dest)?.permissions().readonly() { + if is_symlink_loop(dest) || fs::metadata(dest)?.permissions().readonly() { fs::remove_file(dest)?; } } @@ -1498,6 +1498,7 @@ fn copy_file( options.overwrite, OverwriteMode::Clobber(ClobberMode::RemoveDestination) ) + && !is_symlink_loop(dest) && std::env::var_os("POSIXLY_CORRECT").is_none() { return Err(Error::Error(format!( diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index b77ad474e6..c633ceea4c 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -2309,6 +2309,20 @@ fn test_remove_destination_symbolic_link_loop() { assert!(at.file_exists("loop")); } +#[test] +#[cfg(not(windows))] +fn test_cp_symbolic_link_loop() { + let (at, mut ucmd) = at_and_ucmd!(); + at.symlink_file("loop", "loop"); + at.plus("loop"); + at.touch("f"); + ucmd.args(&["-f", "f", "loop"]) + .succeeds() + .no_stdout() + .no_stderr(); + assert!(at.file_exists("loop")); +} + /// Test that copying a directory to itself is disallowed. #[test] fn test_copy_directory_to_itself_disallowed() { From 1c8aac0883da366cb47ea7f755d41f2831fb1b9b Mon Sep 17 00:00:00 2001 From: John Shin Date: Wed, 3 May 2023 16:05:21 -0700 Subject: [PATCH 257/477] mv: return err if response is negative when moving a dir to existing dest during an interactive mode --- src/uu/mv/src/mv.rs | 2 +- tests/by-util/test_mv.rs | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 1a7897a91a..9632ddabf2 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -292,7 +292,7 @@ fn exec(files: &[OsString], b: &Behavior) -> UResult<()> { OverwriteMode::NoClobber => return Ok(()), OverwriteMode::Interactive => { if !prompt_yes!("overwrite {}? ", target.quote()) { - return Ok(()); + return Err(io::Error::new(io::ErrorKind::Other, "").into()); } } OverwriteMode::Force => {} diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index ce9e26a819..d61cd45dcf 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -260,6 +260,27 @@ fn test_mv_interactive_with_dir_as_target() { .no_stdout(); } +#[test] +fn test_mv_interactive_dir_to_file_not_affirmative() { + let (at, mut ucmd) = at_and_ucmd!(); + + let dir = "test_mv_interactive_dir_to_file_not_affirmative_dir"; + let file = "test_mv_interactive_dir_to_file_not_affirmative_file"; + + at.mkdir(dir); + at.touch(file); + + ucmd.arg(dir) + .arg(file) + .arg("-i") + .pipe_in("n") + .fails() + .no_stderr() + .no_stdout(); + + assert!(at.dir_exists(dir)); +} + #[test] fn test_mv_arg_update_interactive() { let (at, mut ucmd) = at_and_ucmd!(); From a8228909391d7565dd5c79fa901bdac4cf2bffdc Mon Sep 17 00:00:00 2001 From: m11o Date: Thu, 4 May 2023 08:41:56 +0900 Subject: [PATCH 258/477] fix help message in chgrp --- src/uu/chgrp/chgrp.md | 2 +- src/uu/chgrp/src/chgrp.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/chgrp/chgrp.md b/src/uu/chgrp/chgrp.md index 47c1ae5e49..79bc068d2d 100644 --- a/src/uu/chgrp/chgrp.md +++ b/src/uu/chgrp/chgrp.md @@ -4,7 +4,7 @@ ``` chgrp [OPTION]... GROUP FILE... -[OPTION]... --reference=RFILE FILE... +chgrp [OPTION]... --reference=RFILE FILE... ``` Change the group of each FILE to GROUP. diff --git a/src/uu/chgrp/src/chgrp.rs b/src/uu/chgrp/src/chgrp.rs index 15a248ddf6..e63dd9eb7d 100644 --- a/src/uu/chgrp/src/chgrp.rs +++ b/src/uu/chgrp/src/chgrp.rs @@ -18,7 +18,7 @@ use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; use std::fs; use std::os::unix::fs::MetadataExt; -static ABOUT: &str = help_about!("chgrp.md"); +const ABOUT: &str = help_about!("chgrp.md"); const USAGE: &str = help_usage!("chgrp.md"); fn parse_gid_and_uid(matches: &ArgMatches) -> UResult<(Option, Option, IfFrom)> { From 84567336a88c4fbe865b2982e82d3e27d444b908 Mon Sep 17 00:00:00 2001 From: John Shin Date: Wed, 3 May 2023 23:54:28 -0700 Subject: [PATCH 259/477] mv: update test case so it doesn't fail --- tests/by-util/test_mv.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index d61cd45dcf..7ce76832a3 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -275,7 +275,6 @@ fn test_mv_interactive_dir_to_file_not_affirmative() { .arg("-i") .pipe_in("n") .fails() - .no_stderr() .no_stdout(); assert!(at.dir_exists(dir)); From 93c8623da9f8e8020fc8ffa8ecf61ca8ff10ef9e Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 5 May 2023 10:11:40 +0200 Subject: [PATCH 260/477] mv: if more than one of -i, -n, -f, latest "wins" --- src/uu/mv/mv.md | 2 ++ src/uu/mv/src/mv.rs | 3 +++ tests/by-util/test_mv.rs | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/uu/mv/mv.md b/src/uu/mv/mv.md index c31c6d07c4..460e84a1d0 100644 --- a/src/uu/mv/mv.md +++ b/src/uu/mv/mv.md @@ -9,6 +9,8 @@ Move `SOURCE` to `DEST`, or multiple `SOURCE`(s) to `DIRECTORY`. ## After Help +If you specify more than one of `-i`, `-f`, `-n`, only the final one takes effect. + Do not move a non-directory that has an existing destination with the same or newer modification timestamp; instead, silently skip the file without failing. If the move is across file system boundaries, the comparison is to the source timestamp truncated to the resolutions of the destination file system and of the system calls used diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 9632ddabf2..2a2d6d3483 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -145,6 +145,7 @@ pub fn uu_app() -> Command { .short('f') .long(OPT_FORCE) .help("do not prompt before overwriting") + .overrides_with_all([OPT_INTERACTIVE, OPT_NO_CLOBBER]) .action(ArgAction::SetTrue), ) .arg( @@ -152,6 +153,7 @@ pub fn uu_app() -> Command { .short('i') .long(OPT_INTERACTIVE) .help("prompt before override") + .overrides_with_all([OPT_FORCE, OPT_NO_CLOBBER]) .action(ArgAction::SetTrue), ) .arg( @@ -159,6 +161,7 @@ pub fn uu_app() -> Command { .short('n') .long(OPT_NO_CLOBBER) .help("do not overwrite an existing file") + .overrides_with_all([OPT_FORCE, OPT_INTERACTIVE]) .action(ArgAction::SetTrue), ) .arg( diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index b3ecb33c2f..edeb47a96d 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -280,6 +280,41 @@ fn test_mv_interactive_dir_to_file_not_affirmative() { assert!(at.dir_exists(dir)); } +#[test] +fn test_mv_interactive_no_clobber_force_last_arg_wins() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let file_a = "a.txt"; + let file_b = "b.txt"; + + at.touch(file_a); + at.touch(file_b); + + scene + .ucmd() + .args(&[file_a, file_b, "-f", "-i", "-n"]) + .fails() + .stderr_is(format!("mv: not replacing '{file_b}'\n")); + + scene + .ucmd() + .args(&[file_a, file_b, "-n", "-f", "-i"]) + .fails() + .stderr_is(format!("mv: overwrite '{file_b}'? ")); + + at.write(file_a, "aa"); + + scene + .ucmd() + .args(&[file_a, file_b, "-i", "-n", "-f"]) + .succeeds() + .no_output(); + + assert!(!at.file_exists(file_a)); + assert_eq!("aa", at.read(file_b)); +} + #[test] fn test_mv_arg_update_interactive() { let (at, mut ucmd) = at_and_ucmd!(); From ea2b725abbac4a3108612c87b424a6ed15cb7284 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 5 May 2023 15:16:41 +0200 Subject: [PATCH 261/477] mv: fix help output --- src/uu/mv/src/mv.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 2a2d6d3483..f26920227a 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -70,7 +70,7 @@ static ARG_FILES: &str = "files"; #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let mut app = uu_app().after_help(backup_control::BACKUP_CONTROL_LONG_HELP); + let mut app = uu_app(); let matches = app.try_get_matches_from_mut(args)?; if !matches.contains_id(OPT_TARGET_DIRECTORY) @@ -138,7 +138,10 @@ pub fn uu_app() -> Command { .version(crate_version!()) .about(ABOUT) .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) + .after_help(format!( + "{AFTER_HELP}\n\n{}", + backup_control::BACKUP_CONTROL_LONG_HELP + )) .infer_long_args(true) .arg( Arg::new(OPT_FORCE) From 4481604f87bde396b98744290bdf1dd536df4fdd Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 5 May 2023 16:12:34 +0200 Subject: [PATCH 262/477] cp: fix "after help" output --- src/uu/cp/src/cp.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 54616e75ed..270335b975 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -299,7 +299,10 @@ pub fn uu_app() -> Command { .version(crate_version!()) .about(ABOUT) .override_usage(format_usage(USAGE)) - .after_help(AFTER_HELP) + .after_help(format!( + "{AFTER_HELP}\n\n{}", + backup_control::BACKUP_CONTROL_LONG_HELP + )) .infer_long_args(true) .arg( Arg::new(options::TARGET_DIRECTORY) @@ -561,13 +564,11 @@ pub fn uu_app() -> Command { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let matches = uu_app() - .after_help(backup_control::BACKUP_CONTROL_LONG_HELP) - .try_get_matches_from(args); + let matches = uu_app().try_get_matches_from(args); // The error is parsed here because we do not want version or help being printed to stderr. if let Err(e) = matches { - let mut app = uu_app().after_help(backup_control::BACKUP_CONTROL_LONG_HELP); + let mut app = uu_app(); match e.kind() { clap::error::ErrorKind::DisplayHelp => { From 94daed8afbfffcf89f511bfca04c0e905fe75ee1 Mon Sep 17 00:00:00 2001 From: m11o Date: Sat, 6 May 2023 00:34:55 +0900 Subject: [PATCH 263/477] tsort: move help strings to markdown file --- src/uu/tsort/src/tsort.rs | 8 +++----- src/uu/tsort/tsort.md | 9 +++++++++ 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 src/uu/tsort/tsort.md diff --git a/src/uu/tsort/src/tsort.rs b/src/uu/tsort/src/tsort.rs index cb179699db..a70f32dfdd 100644 --- a/src/uu/tsort/src/tsort.rs +++ b/src/uu/tsort/src/tsort.rs @@ -12,12 +12,10 @@ use std::io::{stdin, BufRead, BufReader, Read}; use std::path::Path; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; -use uucore::format_usage; +use uucore::{format_usage, help_about, help_usage}; -static ABOUT: &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."; -static USAGE: &str = "{} [OPTIONS] FILE"; +const ABOUT: &str = help_about!("tsort.md"); +const USAGE: &str = help_usage!("tsort.md"); mod options { pub const FILE: &str = "file"; diff --git a/src/uu/tsort/tsort.md b/src/uu/tsort/tsort.md new file mode 100644 index 0000000000..4a5621a6ca --- /dev/null +++ b/src/uu/tsort/tsort.md @@ -0,0 +1,9 @@ +# tsort + +``` +tsort [OPTIONS] FILE +``` + +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. From 55071b9ad522186945637176e75a94bd2b8a013c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 19:32:32 +0000 Subject: [PATCH 264/477] chore(deps): update rust crate sha3 to 0.10.8 --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05b86a9860..0762bb5bd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1277,9 +1277,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -2097,9 +2097,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest", "keccak", diff --git a/Cargo.toml b/Cargo.toml index b27986c1cd..ebf3f8ccbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -337,7 +337,7 @@ hex = "0.4.3" md-5 = "0.10.5" sha1 = "0.10.5" sha2 = "0.10.6" -sha3 = "0.10.7" +sha3 = "0.10.8" blake2b_simd = "1.0.1" blake3 = "1.3.3" sm3 = "0.4.1" From 8f4367c3bc228885e0f485828569860a6a71dcd7 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 6 May 2023 10:32:18 +0200 Subject: [PATCH 265/477] to make it clearer --- src/uu/tsort/tsort.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uu/tsort/tsort.md b/src/uu/tsort/tsort.md index 4a5621a6ca..5effbf1e70 100644 --- a/src/uu/tsort/tsort.md +++ b/src/uu/tsort/tsort.md @@ -5,5 +5,6 @@ tsort [OPTIONS] FILE ``` Topological sort the strings in FILE. -Strings are defined as any sequence of tokens separated by whitespace (tab, space, or newline). +Strings are defined as any sequence of tokens separated by whitespace (tab, space, or newline), ordering them based on dependencies in a directed acyclic graph (DAG). +Useful for scheduling and determining execution order. If FILE is not passed in, stdin is used instead. From ada1df2e8e69a3569a5855d665d2541ef0cdbaac Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 6 May 2023 10:50:04 +0200 Subject: [PATCH 266/477] android: try to use nextest again --- util/android-commands.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/util/android-commands.sh b/util/android-commands.sh index 668815f7d0..4b504de564 100755 --- a/util/android-commands.sh +++ b/util/android-commands.sh @@ -210,7 +210,7 @@ snapshot() { # We need to install nextest via cargo currently, since there is no pre-built binary for android x86 command="'\ export CARGO_TERM_COLOR=always; \ -# build fails for now (https://github.com/nextest-rs/nextest/issues/862): cargo install cargo-nextest; \ +cargo install cargo-nextest; \ echo \$? > $probe'" run_termux_command "$command" "$probe" return_code=$? @@ -225,7 +225,7 @@ pwd; \ command -v rustc && rustc -Vv; \ ls -la ~/.cargo/bin; \ cargo --list; \ -#cargo nextest --version; \ +cargo nextest --version; \ touch $probe'" run_termux_command "$command" "$probe" @@ -329,7 +329,9 @@ tests() { export RUST_BACKTRACE=1; \ export CARGO_TERM_COLOR=always; \ export CARGO_INCREMENTAL=0; \ -cd ~/coreutils && cargo test --features feat_os_unix_android; \ +cd ~/coreutils; \ +timeout --preserve-status --verbose -k 1m 60m \ +cargo nextest run --profile ci --hide-progress-bar --features feat_os_unix_android; \ echo \$? >$probe'" run_termux_command "$command" "$probe" || return From 40aaae003e6ee51d0b6312cb375289f9321213eb Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 6 May 2023 13:25:35 +0200 Subject: [PATCH 267/477] mv: improve help text Co-authored-by: Sylvestre Ledru --- src/uu/mv/mv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/mv/mv.md b/src/uu/mv/mv.md index 460e84a1d0..6fcee46973 100644 --- a/src/uu/mv/mv.md +++ b/src/uu/mv/mv.md @@ -9,7 +9,7 @@ Move `SOURCE` to `DEST`, or multiple `SOURCE`(s) to `DIRECTORY`. ## After Help -If you specify more than one of `-i`, `-f`, `-n`, only the final one takes effect. +When specifying more than one of -i, -f, -n, only the final one will take effect. Do not move a non-directory that has an existing destination with the same or newer modification timestamp; instead, silently skip the file without failing. If the move is across file system boundaries, the comparison is From e35d477a8cf28a9cabed9496400fab49247dd3a3 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 6 May 2023 14:50:40 +0200 Subject: [PATCH 268/477] change the cognitive_complexity to a lower value --- .clippy.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.clippy.toml b/.clippy.toml index 22fd4be737..bee70857bd 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -1 +1,2 @@ msrv = "1.64.0" +cognitive-complexity-threshold = 10 From f8d7bebed30c777dcb0e8fb157b0184f11af871e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 6 May 2023 14:50:55 +0200 Subject: [PATCH 269/477] ignore some cognitive_complexity for now --- src/bin/coreutils.rs | 1 + src/uu/cat/src/cat.rs | 1 + src/uu/cp/src/cp.rs | 2 ++ src/uu/csplit/src/csplit.rs | 1 + src/uu/date/src/date.rs | 1 + src/uu/dd/src/dd.rs | 1 + src/uu/dd/src/parseargs.rs | 2 ++ src/uu/dircolors/src/dircolors.rs | 1 + src/uu/du/src/du.rs | 2 ++ src/uu/env/src/env.rs | 1 + src/uu/expand/src/expand.rs | 1 + src/uu/fmt/src/fmt.rs | 1 + src/uu/fmt/src/linebreak.rs | 1 + src/uu/fmt/src/parasplit.rs | 1 + src/uu/fold/src/fold.rs | 1 + src/uu/hashsum/src/hashsum.rs | 1 + src/uu/head/src/head.rs | 1 + src/uu/head/src/parse.rs | 1 + src/uu/join/src/join.rs | 1 + src/uu/ln/src/ln.rs | 2 ++ src/uu/ls/src/ls.rs | 5 +++++ src/uu/mv/src/mv.rs | 1 + src/uu/nl/src/helper.rs | 1 + src/uu/nl/src/nl.rs | 1 + src/uu/numfmt/src/options.rs | 1 + src/uu/od/src/parse_formats.rs | 1 + src/uu/paste/src/paste.rs | 1 + src/uu/pr/src/pr.rs | 2 ++ src/uu/ptx/src/ptx.rs | 1 + src/uu/rm/src/rm.rs | 2 ++ src/uu/shred/src/shred.rs | 1 + src/uu/sort/src/numeric_str_cmp.rs | 1 + src/uu/sort/src/sort.rs | 2 ++ src/uu/tac/src/tac.rs | 1 + src/uu/tail/src/follow/watch.rs | 2 ++ src/uu/touch/src/touch.rs | 1 + src/uu/unexpand/src/unexpand.rs | 1 + src/uu/wc/src/utf8/read.rs | 1 + src/uu/wc/src/wc.rs | 1 + src/uucore/src/lib/features/fs.rs | 2 ++ src/uucore/src/lib/features/perms.rs | 3 +++ .../features/tokenize/num_format/formatters/float_common.rs | 2 ++ .../src/lib/features/tokenize/num_format/formatters/intf.rs | 1 + .../src/lib/features/tokenize/num_format/num_format.rs | 1 + src/uucore/src/lib/features/tokenize/sub.rs | 2 ++ src/uucore/src/lib/features/tokenize/unescaped_text.rs | 1 + 46 files changed, 63 insertions(+) diff --git a/src/bin/coreutils.rs b/src/bin/coreutils.rs index cc18d3ee23..8440689c64 100644 --- a/src/bin/coreutils.rs +++ b/src/bin/coreutils.rs @@ -47,6 +47,7 @@ fn name(binary_path: &Path) -> Option<&str> { binary_path.file_stem()?.to_str() } +#[allow(clippy::cognitive_complexity)] fn main() { uucore::panic::mute_sigpipe_panic(); diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index e90bdd1165..4a5e7e0ad3 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -456,6 +456,7 @@ fn write_fast(handle: &mut InputHandle) -> CatResult<()> { /// Outputs file contents to stdout in a line-by-line fashion, /// propagating any errors that might occur. +#[allow(clippy::cognitive_complexity)] fn write_lines( handle: &mut InputHandle, options: &OutputOptions, diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 270335b975..3e69e5791b 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -727,6 +727,7 @@ impl Attributes { } impl Options { + #[allow(clippy::cognitive_complexity)] fn from_matches(matches: &ArgMatches) -> CopyResult { let not_implemented_opts = vec![ #[cfg(not(any(windows, unix)))] @@ -1467,6 +1468,7 @@ fn aligned_ancestors<'a>(source: &'a Path, dest: &'a Path) -> Vec<(&'a Path, &'a /// /// The original permissions of `source` will be copied to `dest` /// after a successful copy. +#[allow(clippy::cognitive_complexity)] fn copy_file( progress_bar: &Option, source: &Path, diff --git a/src/uu/csplit/src/csplit.rs b/src/uu/csplit/src/csplit.rs index 6e1eaf1a3a..1a94b41565 100644 --- a/src/uu/csplit/src/csplit.rs +++ b/src/uu/csplit/src/csplit.rs @@ -356,6 +356,7 @@ impl<'a> SplitWriter<'a> { /// - if no line matched, an [`CsplitError::MatchNotFound`]. /// - if there are not enough lines to accommodate the offset, an /// [`CsplitError::LineOutOfRange`]. + #[allow(clippy::cognitive_complexity)] fn do_to_match( &mut self, pattern_as_str: &str, diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index 8b43386203..a94ffd65fd 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -141,6 +141,7 @@ impl<'a> From<&'a str> for Rfc3339Format { } #[uucore::main] +#[allow(clippy::cognitive_complexity)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args)?; diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 6f75f4707d..836456635c 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -752,6 +752,7 @@ fn finalize( } #[cfg(any(target_os = "linux", target_os = "android"))] +#[allow(clippy::cognitive_complexity)] fn make_linux_oflags(oflags: &OFlags) -> Option { let mut flag = 0; diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index 96f6ebfaa6..b9a3baf09a 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -293,6 +293,7 @@ impl Parser { } } + #[allow(clippy::cognitive_complexity)] fn parse_input_flags(&mut self, val: &str) -> Result<(), ParseError> { let mut i = &mut self.iflag; for f in val.split(',') { @@ -324,6 +325,7 @@ impl Parser { Ok(()) } + #[allow(clippy::cognitive_complexity)] fn parse_output_flags(&mut self, val: &str) -> Result<(), ParseError> { let mut o = &mut self.oflag; for f in val.split(',') { diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 6b2bd9a98b..fe78924f43 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -284,6 +284,7 @@ enum ParseState { use std::collections::HashMap; use uucore::{format_usage, parse_glob}; +#[allow(clippy::cognitive_complexity)] fn parse(lines: T, fmt: &OutputFmt, fp: &str) -> Result where T: IntoIterator, diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index f6a631d205..3325ca1f5d 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -289,6 +289,7 @@ fn choose_size(matches: &ArgMatches, stat: &Stat) -> u64 { // this takes `my_stat` to avoid having to stat files multiple times. // XXX: this should use the impl Trait return type when it is stabilized +#[allow(clippy::cognitive_complexity)] fn du( mut my_stat: Stat, options: &Options, @@ -521,6 +522,7 @@ fn build_exclude_patterns(matches: &ArgMatches) -> UResult> { } #[uucore::main] +#[allow(clippy::cognitive_complexity)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let args = args.collect_ignore(); diff --git a/src/uu/env/src/env.rs b/src/uu/env/src/env.rs index 0ef191b8d4..b293bc9bf6 100644 --- a/src/uu/env/src/env.rs +++ b/src/uu/env/src/env.rs @@ -175,6 +175,7 @@ pub fn uu_app() -> Command { .arg(Arg::new("vars").action(ArgAction::Append)) } +#[allow(clippy::cognitive_complexity)] fn run_env(args: impl uucore::Args) -> UResult<()> { let app = uu_app(); let matches = app.try_get_matches_from(args).with_exit_code(125)?; diff --git a/src/uu/expand/src/expand.rs b/src/uu/expand/src/expand.rs index 40928aeaf3..98b292771e 100644 --- a/src/uu/expand/src/expand.rs +++ b/src/uu/expand/src/expand.rs @@ -373,6 +373,7 @@ enum CharType { Other, } +#[allow(clippy::cognitive_complexity)] fn expand(options: &Options) -> std::io::Result<()> { use self::CharType::*; diff --git a/src/uu/fmt/src/fmt.rs b/src/uu/fmt/src/fmt.rs index 0fd863730f..d144bdd8a9 100644 --- a/src/uu/fmt/src/fmt.rs +++ b/src/uu/fmt/src/fmt.rs @@ -69,6 +69,7 @@ pub struct FmtOptions { /// # Returns /// /// A tuple containing a vector of file names and a `FmtOptions` struct. +#[allow(clippy::cognitive_complexity)] fn parse_arguments(args: impl uucore::Args) -> UResult<(Vec, FmtOptions)> { let matches = uu_app().try_get_matches_from(args)?; diff --git a/src/uu/fmt/src/linebreak.rs b/src/uu/fmt/src/linebreak.rs index 75cd633bb8..e86623c883 100644 --- a/src/uu/fmt/src/linebreak.rs +++ b/src/uu/fmt/src/linebreak.rs @@ -223,6 +223,7 @@ struct LineBreak<'a> { fresh: bool, } +#[allow(clippy::cognitive_complexity)] fn find_kp_breakpoints<'a, T: Iterator>>( iter: T, args: &BreakArgs<'a>, diff --git a/src/uu/fmt/src/parasplit.rs b/src/uu/fmt/src/parasplit.rs index d2e3d292dd..a2d70b088e 100644 --- a/src/uu/fmt/src/parasplit.rs +++ b/src/uu/fmt/src/parasplit.rs @@ -275,6 +275,7 @@ impl<'a> ParagraphStream<'a> { impl<'a> Iterator for ParagraphStream<'a> { type Item = Result; + #[allow(clippy::cognitive_complexity)] fn next(&mut self) -> Option> { // return a NoFormatLine in an Err; it should immediately be output let noformat = match self.lines.peek() { diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index 01eba0b82a..d53573d822 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -207,6 +207,7 @@ fn fold_file_bytewise(mut file: BufReader, spaces: bool, width: usiz /// /// If `spaces` is `true`, attempt to break lines at whitespace boundaries. #[allow(unused_assignments)] +#[allow(clippy::cognitive_complexity)] fn fold_file(mut file: BufReader, spaces: bool, width: usize) -> UResult<()> { let mut line = String::new(); let mut output = String::new(); diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index 44e0cbcd80..af05ddbd99 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -224,6 +224,7 @@ fn detect_algo( /// # Panics /// /// Panics if multiple hash algorithms are specified or if a required flag is missing. +#[allow(clippy::cognitive_complexity)] fn create_algorithm_from_flags(matches: &ArgMatches) -> (&'static str, Box, usize) { let mut alg: Option> = None; let mut name: &'static str = ""; diff --git a/src/uu/head/src/head.rs b/src/uu/head/src/head.rs index b9ac5024bd..2ccf20904e 100644 --- a/src/uu/head/src/head.rs +++ b/src/uu/head/src/head.rs @@ -432,6 +432,7 @@ fn head_file(input: &mut std::fs::File, options: &HeadOptions) -> std::io::Resul } } +#[allow(clippy::cognitive_complexity)] fn uu_head(options: &HeadOptions) -> UResult<()> { let mut first = true; for file in &options.files { diff --git a/src/uu/head/src/parse.rs b/src/uu/head/src/parse.rs index cbfc971529..b24b6591ef 100644 --- a/src/uu/head/src/parse.rs +++ b/src/uu/head/src/parse.rs @@ -13,6 +13,7 @@ pub enum ParseError { } /// Parses obsolete syntax /// head -NUM\[kmzv\] // spell-checker:disable-line +#[allow(clippy::cognitive_complexity)] pub fn parse_obsolete(src: &str) -> Option, ParseError>> { let mut chars = src.char_indices(); if let Some((_, '-')) = chars.next() { diff --git a/src/uu/join/src/join.rs b/src/uu/join/src/join.rs index baf70c2597..de1a9181be 100644 --- a/src/uu/join/src/join.rs +++ b/src/uu/join/src/join.rs @@ -600,6 +600,7 @@ impl<'a> State<'a> { } #[uucore::main] +#[allow(clippy::cognitive_complexity)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args)?; diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index d98f3afb15..c2bf25c5c2 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -292,6 +292,7 @@ fn exec(files: &[PathBuf], settings: &Settings) -> UResult<()> { link(&files[0], &files[1], settings) } +#[allow(clippy::cognitive_complexity)] fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings) -> UResult<()> { if !target_dir.is_dir() { return Err(LnError::TargetIsDirectory(target_dir.to_owned()).into()); @@ -364,6 +365,7 @@ fn relative_path<'a>(src: &'a Path, dst: &Path) -> Cow<'a, Path> { src.into() } +#[allow(clippy::cognitive_complexity)] fn link(src: &Path, dst: &Path, settings: &Settings) -> UResult<()> { let mut backup_path = None; let source: Cow<'_, Path> = if settings.relative { diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 52ac489ef2..db8024c2e7 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -650,6 +650,7 @@ fn extract_indicator_style(options: &clap::ArgMatches) -> IndicatorStyle { } impl Config { + #[allow(clippy::cognitive_complexity)] pub fn from(options: &clap::ArgMatches) -> UResult { let context = options.get_flag(options::CONTEXT); let (mut format, opt) = extract_format(options); @@ -1997,6 +1998,7 @@ fn should_display(entry: &DirEntry, config: &Config) -> bool { .any(|p| p.matches_with(&file_name, options)) } +#[allow(clippy::cognitive_complexity)] fn enter_directory( path_data: &PathData, read_dir: ReadDir, @@ -2187,6 +2189,7 @@ fn display_additional_leading_info( Ok(result) } +#[allow(clippy::cognitive_complexity)] fn display_items(items: &[PathData], config: &Config, out: &mut BufWriter) -> UResult<()> { // `-Z`, `--context`: // Display the SELinux security context or '?' if none is found. When used with the `-l` @@ -2376,6 +2379,7 @@ fn display_grid( /// ``` /// that decide the maximum possible character count of each field. #[allow(clippy::write_literal)] +#[allow(clippy::cognitive_complexity)] fn display_item_long( item: &PathData, padding: &PaddingCollection, @@ -2806,6 +2810,7 @@ fn classify_file(path: &PathData, out: &mut BufWriter) -> Option { /// Note that non-unicode sequences in symlink targets are dealt with using /// [`std::path::Path::to_string_lossy`]. #[allow(unused_variables)] +#[allow(clippy::cognitive_complexity)] fn display_file_name( path: &PathData, config: &Config, diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 9632ddabf2..fdf8d358bc 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -321,6 +321,7 @@ fn exec(files: &[OsString], b: &Behavior) -> UResult<()> { } } +#[allow(clippy::cognitive_complexity)] fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> UResult<()> { if !target_dir.is_dir() { return Err(MvError::NotADirectory(target_dir.quote().to_string()).into()); diff --git a/src/uu/nl/src/helper.rs b/src/uu/nl/src/helper.rs index fa59d329aa..a62936d75b 100644 --- a/src/uu/nl/src/helper.rs +++ b/src/uu/nl/src/helper.rs @@ -25,6 +25,7 @@ fn parse_style(chars: &[char]) -> Result { // parse_options loads the options into the settings, returning an array of // error messages. +#[allow(clippy::cognitive_complexity)] pub fn parse_options(settings: &mut crate::Settings, opts: &clap::ArgMatches) -> Vec { // This vector holds error messages encountered. let mut errs: Vec = vec![]; diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index eb33eb3b8f..44fdec8c72 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -236,6 +236,7 @@ pub fn uu_app() -> Command { } // nl implements the main functionality for an individual buffer. +#[allow(clippy::cognitive_complexity)] fn nl(reader: &mut BufReader, settings: &Settings) -> UResult<()> { let regexp: regex::Regex = regex::Regex::new(r".?").unwrap(); let mut line_no = settings.starting_line_number; diff --git a/src/uu/numfmt/src/options.rs b/src/uu/numfmt/src/options.rs index 131ad378b5..b70cf87e4a 100644 --- a/src/uu/numfmt/src/options.rs +++ b/src/uu/numfmt/src/options.rs @@ -95,6 +95,7 @@ impl FromStr for FormatOptions { // An optional zero (%010f) will zero pad the number. // An optional negative value (%-10f) will left align. // An optional precision (%.1f) determines the precision of the number. + #[allow(clippy::cognitive_complexity)] fn from_str(s: &str) -> Result { let mut iter = s.chars().peekable(); let mut options = Self::default(); diff --git a/src/uu/od/src/parse_formats.rs b/src/uu/od/src/parse_formats.rs index 9614ed9c04..c414abebe8 100644 --- a/src/uu/od/src/parse_formats.rs +++ b/src/uu/od/src/parse_formats.rs @@ -96,6 +96,7 @@ fn od_argument_with_option(ch: char) -> bool { /// arguments with parameters like -w16 can only appear at the end: -fvoxw16 /// parameters of -t/--format specify 1 or more formats. /// if -- appears on the command line, parsing should stop. +#[allow(clippy::cognitive_complexity)] pub fn parse_format_flags(args: &[String]) -> Result, String> { let mut formats = Vec::new(); diff --git a/src/uu/paste/src/paste.rs b/src/uu/paste/src/paste.rs index c8d8076355..6e52727f7c 100644 --- a/src/uu/paste/src/paste.rs +++ b/src/uu/paste/src/paste.rs @@ -111,6 +111,7 @@ pub fn uu_app() -> Command { ) } +#[allow(clippy::cognitive_complexity)] fn paste( filenames: Vec, serial: bool, diff --git a/src/uu/pr/src/pr.rs b/src/uu/pr/src/pr.rs index 63df207daf..b3be8a755a 100644 --- a/src/uu/pr/src/pr.rs +++ b/src/uu/pr/src/pr.rs @@ -488,6 +488,7 @@ fn parse_usize(matches: &ArgMatches, opt: &str) -> Option .map(from_parse_error_to_pr_error) } +#[allow(clippy::cognitive_complexity)] fn build_options( matches: &ArgMatches, paths: &[&str], @@ -1021,6 +1022,7 @@ fn print_page( Ok(lines_written) } +#[allow(clippy::cognitive_complexity)] fn write_columns( lines: &[FileLine], options: &OutputOptions, diff --git a/src/uu/ptx/src/ptx.rs b/src/uu/ptx/src/ptx.rs index 4d411ed311..ecfd67ce81 100644 --- a/src/uu/ptx/src/ptx.rs +++ b/src/uu/ptx/src/ptx.rs @@ -107,6 +107,7 @@ struct WordFilter { } impl WordFilter { + #[allow(clippy::cognitive_complexity)] fn new(matches: &clap::ArgMatches, config: &Config) -> UResult { let (o, oset): (bool, HashSet) = if matches.contains_id(options::ONLY_FILE) { let words = diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 02aa96e241..7937faf745 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -274,6 +274,7 @@ fn remove(files: &[String], options: &Options) -> bool { had_err } +#[allow(clippy::cognitive_complexity)] fn handle_dir(path: &Path, options: &Options) -> bool { let mut had_err = false; @@ -422,6 +423,7 @@ fn remove_file(path: &Path, options: &Options) -> bool { false } +#[allow(clippy::cognitive_complexity)] fn prompt_file(path: &Path, options: &Options, is_dir: bool) -> bool { // If interactive is Never we never want to send prompts if options.interactive == InteractiveMode::Never { diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 1c7d6ab136..89f857b19f 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -361,6 +361,7 @@ fn pass_name(pass_type: &PassType) -> String { } #[allow(clippy::too_many_arguments)] +#[allow(clippy::cognitive_complexity)] fn wipe_file( path_str: &str, n_passes: usize, diff --git a/src/uu/sort/src/numeric_str_cmp.rs b/src/uu/sort/src/numeric_str_cmp.rs index 21d733877d..05f81c8978 100644 --- a/src/uu/sort/src/numeric_str_cmp.rs +++ b/src/uu/sort/src/numeric_str_cmp.rs @@ -52,6 +52,7 @@ impl NumInfo { /// 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. + #[allow(clippy::cognitive_complexity)] pub fn parse(num: &str, parse_settings: &NumInfoParseSettings) -> (Self, Range) { let mut exponent = -1; let mut had_decimal_pt = false; diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 1744148f2f..80c2275e96 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -1033,6 +1033,7 @@ fn make_sort_mode_arg(mode: &'static str, short: char, help: &'static str) -> Ar } #[uucore::main] +#[allow(clippy::cognitive_complexity)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let args = args.collect_ignore(); let mut settings = GlobalSettings::default(); @@ -1654,6 +1655,7 @@ fn compare_by<'a>( // In contrast to numeric compare, GNU general numeric/FP sort *should* recognize positive signs and // scientific notation, so we strip those lines only after the end of the following numeric string. // For example, 5e10KFD would be 5e10 or 5x10^10 and +10000HFKJFK would become 10000. +#[allow(clippy::cognitive_complexity)] fn get_leading_gen(input: &str) -> Range { let trimmed = input.trim_start(); let leading_whitespace_len = input.len() - trimmed.len(); diff --git a/src/uu/tac/src/tac.rs b/src/uu/tac/src/tac.rs index aef9932a27..96bb82f1e1 100644 --- a/src/uu/tac/src/tac.rs +++ b/src/uu/tac/src/tac.rs @@ -222,6 +222,7 @@ fn buffer_tac(data: &[u8], before: bool, separator: &str) -> std::io::Result<()> Ok(()) } +#[allow(clippy::cognitive_complexity)] fn tac(filenames: &[&str], before: bool, regex: bool, separator: &str) -> UResult<()> { // Compile the regular expression pattern if it is provided. let maybe_pattern = if regex { diff --git a/src/uu/tail/src/follow/watch.rs b/src/uu/tail/src/follow/watch.rs index 2c3cf10b85..67ad8f0c2c 100644 --- a/src/uu/tail/src/follow/watch.rs +++ b/src/uu/tail/src/follow/watch.rs @@ -303,6 +303,7 @@ impl Observer { Ok(()) } + #[allow(clippy::cognitive_complexity)] fn handle_event( &mut self, event: ¬ify::Event, @@ -471,6 +472,7 @@ impl Observer { } } +#[allow(clippy::cognitive_complexity)] pub fn follow(mut observer: Observer, settings: &Settings) -> UResult<()> { if observer.files.no_files_remaining(settings) && !observer.files.only_stdin_remaining() { return Err(USimpleError::new(1, text::NO_FILES_REMAINING.to_string())); diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index 00d23da756..55663fdab2 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -65,6 +65,7 @@ fn dt_to_filename(tm: time::PrimitiveDateTime) -> FileTime { } #[uucore::main] +#[allow(clippy::cognitive_complexity)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args)?; diff --git a/src/uu/unexpand/src/unexpand.rs b/src/uu/unexpand/src/unexpand.rs index da60aa1c2b..dd4471e2d6 100644 --- a/src/uu/unexpand/src/unexpand.rs +++ b/src/uu/unexpand/src/unexpand.rs @@ -318,6 +318,7 @@ fn next_char_info(uflag: bool, buf: &[u8], byte: usize) -> (CharType, usize, usi (ctype, cwidth, nbytes) } +#[allow(clippy::cognitive_complexity)] fn unexpand(options: &Options) -> std::io::Result<()> { let mut output = BufWriter::new(stdout()); let ts = &options.tabstops[..]; diff --git a/src/uu/wc/src/utf8/read.rs b/src/uu/wc/src/utf8/read.rs index eb4684f7f6..1b5bbbe7f7 100644 --- a/src/uu/wc/src/utf8/read.rs +++ b/src/uu/wc/src/utf8/read.rs @@ -60,6 +60,7 @@ impl BufReadDecoder { /// This is similar to `Iterator::next`, /// except that decoded chunks borrow the decoder (~iterator) /// so they need to be handled or copied before the next chunk can start decoding. + #[allow(clippy::cognitive_complexity)] pub fn next_strict(&mut self) -> Option> { enum BytesSource { BufRead(usize), diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 949f05d653..9d7a23d1fb 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -450,6 +450,7 @@ fn word_count_from_reader( } } +#[allow(clippy::cognitive_complexity)] fn word_count_from_reader_specialized< T: WordCountable, const SHOW_CHARS: bool, diff --git a/src/uucore/src/lib/features/fs.rs b/src/uucore/src/lib/features/fs.rs index 6dc371a10c..4de07f5027 100644 --- a/src/uucore/src/lib/features/fs.rs +++ b/src/uucore/src/lib/features/fs.rs @@ -326,6 +326,7 @@ impl<'a> From> for OwningComponent { /// * [`ResolveMode::Logical`] makes this function resolve '..' components /// before symlinks /// +#[allow(clippy::cognitive_complexity)] pub fn canonicalize>( original: P, miss_mode: MissingHandling, @@ -457,6 +458,7 @@ pub fn display_permissions(metadata: &fs::Metadata, display_file_type: bool) -> // The logic below is more readable written this way. #[allow(clippy::if_not_else)] +#[allow(clippy::cognitive_complexity)] #[cfg(unix)] /// Display the permissions of a file on a unix like system pub fn display_permissions_unix(mode: mode_t, display_file_type: bool) -> String { diff --git a/src/uucore/src/lib/features/perms.rs b/src/uucore/src/lib/features/perms.rs index 1103136425..984d6dd402 100644 --- a/src/uucore/src/lib/features/perms.rs +++ b/src/uucore/src/lib/features/perms.rs @@ -203,6 +203,7 @@ impl ChownExecutor { Ok(()) } + #[allow(clippy::cognitive_complexity)] fn traverse>(&self, root: P) -> i32 { let path = root.as_ref(); let meta = match self.obtain_meta(path, self.dereference) { @@ -270,6 +271,7 @@ impl ChownExecutor { } } + #[allow(clippy::cognitive_complexity)] fn dive_into>(&self, root: P) -> i32 { let root = root.as_ref(); @@ -421,6 +423,7 @@ type GidUidFilterParser = fn(&ArgMatches) -> UResult<(Option, Option, /// `parse_gid_uid_and_filter` will be called to obtain the target gid and uid, and the filter, /// from `ArgMatches`. /// `groups_only` determines whether verbose output will only mention the group. +#[allow(clippy::cognitive_complexity)] pub fn chown_base( mut command: Command, args: impl crate::Args, diff --git a/src/uucore/src/lib/features/tokenize/num_format/formatters/float_common.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/float_common.rs index c277e60a69..e0a29217c4 100644 --- a/src/uucore/src/lib/features/tokenize/num_format/formatters/float_common.rs +++ b/src/uucore/src/lib/features/tokenize/num_format/formatters/float_common.rs @@ -40,6 +40,7 @@ fn has_enough_digits( } impl FloatAnalysis { + #[allow(clippy::cognitive_complexity)] pub fn analyze( str_in: &str, initial_prefix: &InitialPrefix, @@ -219,6 +220,7 @@ fn round_terminal_digit( (before_dec, after_dec, false) } +#[allow(clippy::cognitive_complexity)] pub fn get_primitive_dec( initial_prefix: &InitialPrefix, str_in: &str, diff --git a/src/uucore/src/lib/features/tokenize/num_format/formatters/intf.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/intf.rs index e0eb0ffd33..0f6e78de6f 100644 --- a/src/uucore/src/lib/features/tokenize/num_format/formatters/intf.rs +++ b/src/uucore/src/lib/features/tokenize/num_format/formatters/intf.rs @@ -40,6 +40,7 @@ impl Intf { // is_zero: true if number is zero, false otherwise // len_digits: length of digits used to create the int // important, for example, if we run into a non-valid character + #[allow(clippy::cognitive_complexity)] fn analyze(str_in: &str, signed_out: bool, initial_prefix: &InitialPrefix) -> IntAnalysis { // the maximum number of digits we could conceivably // have before the decimal point without exceeding the diff --git a/src/uucore/src/lib/features/tokenize/num_format/num_format.rs b/src/uucore/src/lib/features/tokenize/num_format/num_format.rs index 9aa97f8112..c9b1178b6a 100644 --- a/src/uucore/src/lib/features/tokenize/num_format/num_format.rs +++ b/src/uucore/src/lib/features/tokenize/num_format/num_format.rs @@ -87,6 +87,7 @@ fn get_provided(str_in_opt: Option<&String>) -> Option { // a base, // and an offset for index after all // initial spacing, sign, base prefix, and leading zeroes +#[allow(clippy::cognitive_complexity)] fn get_initial_prefix(str_in: &str, field_type: &FieldType) -> InitialPrefix { let mut str_it = str_in.chars(); let mut ret = InitialPrefix { diff --git a/src/uucore/src/lib/features/tokenize/sub.rs b/src/uucore/src/lib/features/tokenize/sub.rs index af13fb83f8..5bdb24dc63 100644 --- a/src/uucore/src/lib/features/tokenize/sub.rs +++ b/src/uucore/src/lib/features/tokenize/sub.rs @@ -173,6 +173,7 @@ impl SubParser { prefix_char, )) } + #[allow(clippy::cognitive_complexity)] fn sub_vals_retrieved(&mut self, it: &mut PutBackN) -> UResult { if !Self::successfully_eat_prefix(it, &mut self.text_so_far)? { return Ok(false); @@ -342,6 +343,7 @@ impl SubParser { } impl Sub { + #[allow(clippy::cognitive_complexity)] pub(crate) fn write(&self, writer: &mut W, pf_args_it: &mut Peekable>) where W: Write, diff --git a/src/uucore/src/lib/features/tokenize/unescaped_text.rs b/src/uucore/src/lib/features/tokenize/unescaped_text.rs index b4f632901e..29c657ed86 100644 --- a/src/uucore/src/lib/features/tokenize/unescaped_text.rs +++ b/src/uucore/src/lib/features/tokenize/unescaped_text.rs @@ -197,6 +197,7 @@ impl UnescapedText { // and return a wrapper around a Vec of unescaped bytes // break on encounter of sub symbol ('%[^%]') unless called // through %b subst. + #[allow(clippy::cognitive_complexity)] pub fn from_it_core( writer: &mut W, it: &mut PutBackN, From cd688662ec2df3ef18cd6357de8bde4e07d586b5 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 6 May 2023 14:53:28 +0200 Subject: [PATCH 270/477] fix some lines_filter_map_ok clippy warnings --- src/uu/dircolors/src/dircolors.rs | 2 +- src/uucore/src/lib/features/fsext.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index fe78924f43..19c3f7e31c 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -136,7 +136,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { )); } else if files[0].eq("-") { let fin = BufReader::new(std::io::stdin()); - result = parse(fin.lines().filter_map(Result::ok), &out_format, files[0]); + result = parse(fin.lines().map_while(Result::ok), &out_format, files[0]); } else { let path = Path::new(files[0]); if path.is_dir() { diff --git a/src/uucore/src/lib/features/fsext.rs b/src/uucore/src/lib/features/fsext.rs index 1e7f84e6a9..89f1d6e716 100644 --- a/src/uucore/src/lib/features/fsext.rs +++ b/src/uucore/src/lib/features/fsext.rs @@ -409,7 +409,7 @@ pub fn read_fs_list() -> Result, std::io::Error> { let reader = BufReader::new(f); Ok(reader .lines() - .filter_map(|line| line.ok()) + .map_while(Result::ok) .filter_map(|line| { let raw_data = line.split_whitespace().collect::>(); MountInfo::new(file_name, &raw_data) From 1ac31ccfa0db32f40b9600f92554c365fed1c964 Mon Sep 17 00:00:00 2001 From: m11o Date: Sun, 7 May 2023 00:27:16 +0900 Subject: [PATCH 271/477] tty: move help strings to markdown file --- src/uu/tty/src/tty.rs | 6 +++--- src/uu/tty/tty.md | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 src/uu/tty/tty.md diff --git a/src/uu/tty/src/tty.rs b/src/uu/tty/src/tty.rs index e3fc0451ef..e2d9d18470 100644 --- a/src/uu/tty/src/tty.rs +++ b/src/uu/tty/src/tty.rs @@ -14,10 +14,10 @@ use is_terminal::IsTerminal; use std::io::Write; use std::os::unix::io::AsRawFd; use uucore::error::{set_exit_code, UResult}; -use uucore::format_usage; +use uucore::{format_usage, help_about, help_usage}; -static ABOUT: &str = "Print the file name of the terminal connected to standard input."; -const USAGE: &str = "{} [OPTION]..."; +const ABOUT: &str = help_about!("tty.md"); +const USAGE: &str = help_usage!("tty.md"); mod options { pub const SILENT: &str = "silent"; diff --git a/src/uu/tty/tty.md b/src/uu/tty/tty.md new file mode 100644 index 0000000000..230399a206 --- /dev/null +++ b/src/uu/tty/tty.md @@ -0,0 +1,7 @@ +# tty + +``` +tty [OPTION]... +``` + +Print the file name of the terminal connected to standard input. From cad73d2ed3f94a6152ec2181bc7cfb023cf85426 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 May 2023 16:29:49 +0000 Subject: [PATCH 272/477] chore(deps): update rust crate zip to 0.6.5 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0762bb5bd2..05a0940564 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3665,9 +3665,9 @@ checksum = "2a599daf1b507819c1121f0bf87fa37eb19daac6aff3aefefd4e6e2e0f2020fc" [[package]] name = "zip" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef" +checksum = "7e92305c174683d78035cbf1b70e18db6329cc0f1b9cae0a52ca90bf5bfe7125" dependencies = [ "byteorder", "crc32fast", diff --git a/Cargo.toml b/Cargo.toml index ebf3f8ccbd..29f4de0cdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -331,7 +331,7 @@ walkdir = "2.3" winapi-util = "0.1.5" windows-sys = { version="0.45.0", default-features=false } xattr = "1.0.0" -zip = { version = "0.6.4", default_features=false, features=["deflate"] } +zip = { version = "0.6.5", default_features=false, features=["deflate"] } hex = "0.4.3" md-5 = "0.10.5" From b94d10f08028c82fcb06141afa58a615cda1defb Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 6 May 2023 19:35:44 +0200 Subject: [PATCH 273/477] Fix some semicolon_if_nothing_returned --- tests/by-util/test_cp.rs | 16 ++++++++-------- tests/by-util/test_mv.rs | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 8d55a17ca8..0a6e580497 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -255,7 +255,7 @@ fn test_cp_arg_update_none() { .no_stderr() .no_stdout(); - assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n") + assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n"); } #[test] @@ -272,7 +272,7 @@ fn test_cp_arg_update_all() { assert_eq!( at.read(TEST_HOW_ARE_YOU_SOURCE), at.read(TEST_HELLO_WORLD_SOURCE) - ) + ); } #[test] @@ -294,7 +294,7 @@ fn test_cp_arg_update_older_dest_not_older_than_src() { .no_stderr() .no_stdout(); - assert_eq!(at.read(new), "new content\n") + assert_eq!(at.read(new), "new content\n"); } #[test] @@ -319,7 +319,7 @@ fn test_cp_arg_update_older_dest_older_than_src() { .no_stderr() .no_stdout(); - assert_eq!(at.read(old), "new content\n") + assert_eq!(at.read(old), "new content\n"); } #[test] @@ -345,7 +345,7 @@ fn test_cp_arg_update_short_no_overwrite() { .no_stderr() .no_stdout(); - assert_eq!(at.read(new), "new content\n") + assert_eq!(at.read(new), "new content\n"); } #[test] @@ -371,7 +371,7 @@ fn test_cp_arg_update_short_overwrite() { .no_stderr() .no_stdout(); - assert_eq!(at.read(old), "new content\n") + assert_eq!(at.read(old), "new content\n"); } #[test] @@ -399,7 +399,7 @@ fn test_cp_arg_update_none_then_all() { .no_stderr() .no_stdout(); - assert_eq!(at.read(new), "old content\n") + assert_eq!(at.read(new), "old content\n"); } #[test] @@ -427,7 +427,7 @@ fn test_cp_arg_update_all_then_none() { .no_stderr() .no_stdout(); - assert_eq!(at.read(new), "new content\n") + assert_eq!(at.read(new), "new content\n"); } #[test] diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index edeb47a96d..47cbd4a795 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -867,7 +867,7 @@ fn test_mv_arg_update_none_then_all() { .no_stderr() .no_stdout(); - assert_eq!(at.read(new), "old content\n") + assert_eq!(at.read(new), "old content\n"); } #[test] @@ -895,7 +895,7 @@ fn test_mv_arg_update_all_then_none() { .no_stderr() .no_stdout(); - assert_eq!(at.read(new), "new content\n") + assert_eq!(at.read(new), "new content\n"); } #[test] @@ -920,7 +920,7 @@ fn test_mv_arg_update_older_dest_older() { .no_stderr() .no_stdout(); - assert_eq!(at.read(old), new_content) + assert_eq!(at.read(old), new_content); } #[test] @@ -946,7 +946,7 @@ fn test_mv_arg_update_short_overwrite() { .no_stderr() .no_stdout(); - assert_eq!(at.read(old), new_content) + assert_eq!(at.read(old), new_content); } #[test] @@ -972,7 +972,7 @@ fn test_mv_arg_update_short_no_overwrite() { .no_stderr() .no_stdout(); - assert_eq!(at.read(new), new_content) + assert_eq!(at.read(new), new_content); } #[test] From 214c027cfa61e42e07cba5ea7cd65d65e4017752 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 May 2023 19:01:14 +0000 Subject: [PATCH 274/477] fix(deps): update rust crate libc to 0.2.143 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0762bb5bd2..f0b2d4932c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1318,9 +1318,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.142" +version = "0.2.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "edc207893e85c5d6be840e969b496b53d94cec8be2d501b214f50daa97fa8024" [[package]] name = "libloading" diff --git a/Cargo.toml b/Cargo.toml index ebf3f8ccbd..5d1c26feae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -290,7 +290,7 @@ humantime_to_duration = "0.1.3" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" -libc = "0.2.142" +libc = "0.2.143" lscolors = { version = "0.14.0", default-features=false, features = ["nu-ansi-term"] } memchr = "2" nix = { version="0.26", default-features=false } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index d5fe9e54c3..2df32b6145 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -32,7 +32,7 @@ time = { workspace=true, optional=true, features = ["formatting", "local-offset" data-encoding = { version="2.3", optional=true } data-encoding-macro = { version="0.1.12", optional=true } z85 = { version="3.0.5", optional=true } -libc = { version="0.2.142", optional=true } +libc = { version="0.2.143", optional=true } once_cell = { workspace=true } os_display = "0.1.3" From 12e4acaec3740a19cef2c804b25f8a92725ef8a5 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Thu, 23 Feb 2023 22:03:36 -0500 Subject: [PATCH 275/477] dd: add bytes_total to ReadStat Add the `bytes_total` field to the `ReadStat` struct. This lets the main loop of `dd` keep track of the total number of bytes read. --- src/uu/dd/src/dd.rs | 8 ++++++-- src/uu/dd/src/progress.rs | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 836456635c..ea353d6256 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -317,13 +317,13 @@ impl<'a> Input<'a> { _ => break, } } - buf.truncate(bytes_total); Ok(ReadStat { reads_complete, reads_partial, // Records are not truncated when filling. records_truncated: 0, + bytes_total: bytes_total.try_into().unwrap(), }) } @@ -334,6 +334,7 @@ impl<'a> Input<'a> { let mut reads_complete = 0; let mut reads_partial = 0; let mut base_idx = 0; + let mut bytes_total = 0; while base_idx < buf.len() { let next_blk = cmp::min(base_idx + self.settings.ibs, buf.len()); @@ -342,11 +343,13 @@ impl<'a> Input<'a> { match self.read(&mut buf[base_idx..next_blk])? { 0 => break, rlen if rlen < target_len => { + bytes_total += rlen; reads_partial += 1; let padding = vec![pad; target_len - rlen]; buf.splice(base_idx + rlen..next_blk, padding.into_iter()); } - _ => { + rlen => { + bytes_total += rlen; reads_complete += 1; } } @@ -359,6 +362,7 @@ impl<'a> Input<'a> { reads_complete, reads_partial, records_truncated: 0, + bytes_total: bytes_total.try_into().unwrap(), }) } } diff --git a/src/uu/dd/src/progress.rs b/src/uu/dd/src/progress.rs index 51cfa92efd..65af053b84 100644 --- a/src/uu/dd/src/progress.rs +++ b/src/uu/dd/src/progress.rs @@ -79,9 +79,9 @@ impl ProgUpdate { /// ```rust,ignore /// use std::io::Cursor; /// use std::time::Duration; - /// use crate::progress::{ProgUpdate, ReadState, WriteStat}; + /// use crate::progress::{ProgUpdate, ReadStat, WriteStat}; /// - /// let read_stat = ReadStat::new(1, 2, 3); + /// let read_stat = ReadStat::new(1, 2, 3, 999); /// let write_stat = WriteStat::new(4, 5, 6); /// let duration = Duration::new(789, 0); /// let prog_update = ProgUpdate { @@ -121,7 +121,7 @@ impl ProgUpdate { /// ```rust,ignore /// use std::io::Cursor; /// use std::time::Duration; - /// use crate::progress::{ProgUpdate, ReadState, WriteStat}; + /// use crate::progress::ProgUpdate; /// /// let prog_update = ProgUpdate { /// read_stat: Default::default(), @@ -191,7 +191,7 @@ impl ProgUpdate { /// ```rust,ignore /// use std::io::Cursor; /// use std::time::Duration; - /// use crate::progress::{ProgUpdate, ReadState, WriteStat}; + /// use crate::progress::ProgUpdate; /// /// let prog_update = ProgUpdate { /// read_stat: Default::default(), @@ -276,16 +276,20 @@ pub(crate) struct ReadStat { /// /// A truncated record can only occur in `conv=block` mode. pub(crate) records_truncated: u32, + + /// The total number of bytes read. + pub(crate) bytes_total: u64, } impl ReadStat { /// Create a new instance. #[allow(dead_code)] - fn new(complete: u64, partial: u64, truncated: u32) -> Self { + fn new(complete: u64, partial: u64, truncated: u32, bytes_total: u64) -> Self { Self { reads_complete: complete, reads_partial: partial, records_truncated: truncated, + bytes_total, } } @@ -315,6 +319,7 @@ impl std::ops::AddAssign for ReadStat { reads_complete: self.reads_complete + other.reads_complete, reads_partial: self.reads_partial + other.reads_partial, records_truncated: self.records_truncated + other.records_truncated, + bytes_total: self.bytes_total + other.bytes_total, } } } @@ -514,7 +519,7 @@ mod tests { #[test] fn test_read_stat_report() { - let read_stat = ReadStat::new(1, 2, 3); + let read_stat = ReadStat::new(1, 2, 3, 4); let mut cursor = Cursor::new(vec![]); read_stat.report(&mut cursor).unwrap(); assert_eq!(cursor.get_ref(), b"1+2 records in\n"); @@ -530,7 +535,7 @@ mod tests { #[test] fn test_prog_update_write_io_lines() { - let read_stat = ReadStat::new(1, 2, 3); + let read_stat = ReadStat::new(1, 2, 3, 4); let write_stat = WriteStat::new(4, 5, 6); let duration = Duration::new(789, 0); let complete = false; From cc2f97ba0dc61aa4cc3119f55c38e89e5808cb56 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Thu, 23 Feb 2023 22:05:16 -0500 Subject: [PATCH 276/477] dd: add discard_cache() funcs for Input, Output Add the `Input::discard_cache()` and `Output::discard_cache()` functions. These allow discarding the filesystem cache when `dd` no longer needs to access a specified portion of the input or output file, respectively. --- Cargo.lock | 1 + src/uu/dd/Cargo.toml | 3 ++ src/uu/dd/src/dd.rs | 109 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 112 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 9827a78934..caf4946257 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2552,6 +2552,7 @@ dependencies = [ "clap", "gcd", "libc", + "nix", "signal-hook", "uucore", ] diff --git a/src/uu/dd/Cargo.toml b/src/uu/dd/Cargo.toml index b81ef1a8ef..04b60dc311 100644 --- a/src/uu/dd/Cargo.toml +++ b/src/uu/dd/Cargo.toml @@ -20,6 +20,9 @@ gcd = { workspace=true } libc = { workspace=true } uucore = { workspace=true, features=["memo"] } +[target.'cfg(any(target_os = "linux"))'.dependencies] +nix = { workspace=true, features = ["fs"] } + [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] signal-hook = { workspace=true } diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index ea353d6256..43f0da5df3 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -5,7 +5,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rremain, rsofar, rstat, sigusr, wlen, wstat seekable oconv canonicalized +// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rremain, rsofar, rstat, sigusr, wlen, wstat seekable oconv canonicalized fadvise Fadvise FADV DONTNEED ESPIPE mod datastructures; use datastructures::*; @@ -42,9 +42,16 @@ use std::time; use clap::{crate_version, Arg, Command}; use gcd::Gcd; +#[cfg(target_os = "linux")] +use nix::{ + errno::Errno, + fcntl::{posix_fadvise, PosixFadviseAdvice}, +}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult}; use uucore::{format_usage, help_about, help_section, help_usage, show_error}; +#[cfg(target_os = "linux")] +use uucore::{show, show_if_err}; const ABOUT: &str = help_about!("dd.md"); const AFTER_HELP: &str = help_section!("after help", "dd.md"); @@ -131,6 +138,16 @@ impl Source { Self::StdinFile(f) } + /// The length of the data source in number of bytes. + /// + /// If it cannot be determined, then this function returns 0. + fn len(&self) -> std::io::Result { + match self { + Self::File(f) => Ok(f.metadata()?.len().try_into().unwrap_or(i64::MAX)), + _ => Ok(0), + } + } + fn skip(&mut self, n: u64) -> io::Result { match self { #[cfg(not(unix))] @@ -156,6 +173,23 @@ impl Source { Self::Fifo(f) => io::copy(&mut f.take(n), &mut io::sink()), } } + + /// Discard the system file cache for the given portion of the data source. + /// + /// `offset` and `len` specify a contiguous portion of the data + /// source. This function informs the kernel that the specified + /// portion of the source is no longer needed. If not possible, + /// then this function returns an error. + #[cfg(target_os = "linux")] + fn discard_cache(&self, offset: libc::off_t, len: libc::off_t) -> nix::Result<()> { + match self { + Self::File(f) => { + let advice = PosixFadviseAdvice::POSIX_FADV_DONTNEED; + posix_fadvise(f.as_raw_fd(), offset, len, advice) + } + _ => Err(Errno::ESPIPE), // "Illegal seek" + } + } } impl Read for Source { @@ -296,6 +330,29 @@ impl<'a> Read for Input<'a> { } impl<'a> Input<'a> { + /// Discard the system file cache for the given portion of the input. + /// + /// `offset` and `len` specify a contiguous portion of the input. + /// This function informs the kernel that the specified portion of + /// the input file is no longer needed. If not possible, then this + /// function prints an error message to stderr and sets the exit + /// status code to 1. + #[allow(unused_variables)] + fn discard_cache(&self, offset: libc::off_t, len: libc::off_t) { + #[cfg(target_os = "linux")] + { + show_if_err!(self + .src + .discard_cache(offset, len) + .map_err_context(|| "failed to discard cache for: 'standard input'".to_string())); + } + #[cfg(not(target_os = "linux"))] + { + // TODO Is there a way to discard filesystem cache on + // these other operating systems? + } + } + /// Fills a given buffer. /// Reads in increments of 'self.ibs'. /// The start of each ibs-sized read follows the previous one. @@ -451,6 +508,33 @@ impl Dest { _ => Ok(()), } } + + /// Discard the system file cache for the given portion of the destination. + /// + /// `offset` and `len` specify a contiguous portion of the + /// destination. This function informs the kernel that the + /// specified portion of the destination is no longer needed. If + /// not possible, then this function returns an error. + #[cfg(target_os = "linux")] + fn discard_cache(&self, offset: libc::off_t, len: libc::off_t) -> nix::Result<()> { + match self { + Self::File(f, _) => { + let advice = PosixFadviseAdvice::POSIX_FADV_DONTNEED; + posix_fadvise(f.as_raw_fd(), offset, len, advice) + } + _ => Err(Errno::ESPIPE), // "Illegal seek" + } + } + + /// The length of the data destination in number of bytes. + /// + /// If it cannot be determined, then this function returns 0. + fn len(&self) -> std::io::Result { + match self { + Self::File(f, _) => Ok(f.metadata()?.len().try_into().unwrap_or(i64::MAX)), + _ => Ok(0), + } + } } /// Decide whether the given buffer is all zeros. @@ -584,6 +668,29 @@ impl<'a> Output<'a> { Ok(Self { dst, settings }) } + /// Discard the system file cache for the given portion of the output. + /// + /// `offset` and `len` specify a contiguous portion of the output. + /// This function informs the kernel that the specified portion of + /// the output file is no longer needed. If not possible, then + /// this function prints an error message to stderr and sets the + /// exit status code to 1. + #[allow(unused_variables)] + fn discard_cache(&self, offset: libc::off_t, len: libc::off_t) { + #[cfg(target_os = "linux")] + { + show_if_err!(self + .dst + .discard_cache(offset, len) + .map_err_context(|| "failed to discard cache for: 'standard output'".to_string())); + } + #[cfg(target_os = "linux")] + { + // TODO Is there a way to discard filesystem cache on + // these other operating systems? + } + } + /// Write the given bytes one block at a time. /// /// This may write partial blocks (for example, if the underlying From bd18a2a344d67a8b63746cdfa0c9eeba929ada32 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Thu, 23 Feb 2023 22:05:47 -0500 Subject: [PATCH 277/477] dd: support the [io]flag=nocache option Add support for the `iflag=nocache` and `oflag=nocache` to make `dd` discard the filesystem cache for the processed portion of the input or output file. --- src/uu/dd/src/dd.rs | 50 +++++++++++++++++++++++++++ src/uu/dd/src/parseargs.rs | 4 +-- src/uu/dd/src/parseargs/unit_tests.rs | 2 +- tests/by-util/test_dd.rs | 22 ++++++++++++ 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 43f0da5df3..3b8b3addb9 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -785,6 +785,25 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // Optimization: if no blocks are to be written, then don't // bother allocating any buffers. if let Some(Num::Blocks(0) | Num::Bytes(0)) = i.settings.count { + // Even though we are not reading anything from the input + // file, we still need to honor the `nocache` flag, which + // requests that we inform the system that we no longer + // need the contents of the input file in a system cache. + // + // TODO Better error handling for overflowing `len`. + if i.settings.iflags.nocache { + let offset = 0; + let len = i.src.len()?.try_into().unwrap(); + i.discard_cache(offset, len); + } + // Similarly, discard the system cache for the output file. + // + // TODO Better error handling for overflowing `len`. + if i.settings.oflags.nocache { + let offset = 0; + let len = o.dst.len()?.try_into().unwrap(); + o.discard_cache(offset, len); + } return finalize(&mut o, rstat, wstat, start, &prog_tx, output_thread); }; @@ -792,6 +811,13 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // This is the max size needed. let mut buf = vec![BUF_INIT_BYTE; bsize]; + // Index in the input file where we are reading bytes and in + // the output file where we are writing bytes. + // + // These are updated on each iteration of the main loop. + let mut read_offset = 0; + let mut write_offset = 0; + // The main read/write loop. // // Each iteration reads blocks from the input and writes @@ -811,6 +837,30 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { } let wstat_update = o.write_blocks(&buf)?; + // Discard the system file cache for the read portion of + // the input file. + // + // TODO Better error handling for overflowing `offset` and `len`. + let read_len = rstat_update.bytes_total; + if i.settings.iflags.nocache { + let offset = read_offset.try_into().unwrap(); + let len = read_len.try_into().unwrap(); + i.discard_cache(offset, len); + } + read_offset += read_len; + + // Discard the system file cache for the written portion + // of the output file. + // + // TODO Better error handling for overflowing `offset` and `len`. + let write_len = wstat_update.bytes_total; + if o.settings.oflags.nocache { + let offset = write_offset.try_into().unwrap(); + let len = write_len.try_into().unwrap(); + o.discard_cache(offset, len); + } + write_offset += write_len; + // Update the read/write stats and inform the progress thread once per second. // // If the receiver is disconnected, `send()` returns an diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index b9a3baf09a..781934a830 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -304,7 +304,7 @@ impl Parser { "directory" => linux_only!(f, i.directory = true), "dsync" => linux_only!(f, i.dsync = true), "sync" => linux_only!(f, i.sync = true), - "nocache" => return Err(ParseError::Unimplemented(f.to_string())), + "nocache" => linux_only!(f, i.nocache = true), "nonblock" => linux_only!(f, i.nonblock = true), "noatime" => linux_only!(f, i.noatime = true), "noctty" => linux_only!(f, i.noctty = true), @@ -336,7 +336,7 @@ impl Parser { "directory" => linux_only!(f, o.directory = true), "dsync" => linux_only!(f, o.dsync = true), "sync" => linux_only!(f, o.sync = true), - "nocache" => return Err(ParseError::Unimplemented(f.to_string())), + "nocache" => linux_only!(f, o.nocache = true), "nonblock" => linux_only!(f, o.nonblock = true), "noatime" => linux_only!(f, o.noatime = true), "noctty" => linux_only!(f, o.noctty = true), diff --git a/src/uu/dd/src/parseargs/unit_tests.rs b/src/uu/dd/src/parseargs/unit_tests.rs index a135c3572d..54e17b882e 100644 --- a/src/uu/dd/src/parseargs/unit_tests.rs +++ b/src/uu/dd/src/parseargs/unit_tests.rs @@ -55,7 +55,7 @@ fn unimplemented_flags_should_error() { let mut succeeded = Vec::new(); // The following flags are not implemented - for flag in ["cio", "nocache", "nolinks", "text", "binary"] { + for flag in ["cio", "nolinks", "text", "binary"] { let args = vec![format!("iflag={flag}")]; if Parser::new() diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index 99eae48094..a54c473ef0 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1536,3 +1536,25 @@ fn test_multiple_processes_reading_stdin() { .succeeds() .stdout_only("def\n"); } + +/// Test that discarding system file cache fails for stdin. +#[test] +#[cfg(target_os = "linux")] +fn test_nocache_stdin_error() { + new_ucmd!() + .args(&["iflag=nocache", "count=0", "status=noxfer"]) + .fails() + .code_is(1) + .stderr_only("dd: failed to discard cache for: 'standard input': Illegal seek\n0+0 records in\n0+0 records out\n"); +} + +/// Test for discarding system file cache. +#[test] +#[cfg(target_os = "linux")] +fn test_nocache_file() { + let (at, mut ucmd) = at_and_ucmd!(); + at.write_bytes("f", b"a".repeat(1 << 20).as_slice()); + ucmd.args(&["if=f", "of=/dev/null", "iflag=nocache", "status=noxfer"]) + .succeeds() + .stderr_only("2048+0 records in\n2048+0 records out\n"); +} From 916f014ef0fd06ee40bb021252e5972df5f5eacb Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 7 May 2023 18:46:08 +0200 Subject: [PATCH 278/477] dd: fix some clippy warnings 'variable does not need to be mutable' --- src/uu/dd/src/parseargs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index b9a3baf09a..9057b623e0 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -295,7 +295,7 @@ impl Parser { #[allow(clippy::cognitive_complexity)] fn parse_input_flags(&mut self, val: &str) -> Result<(), ParseError> { - let mut i = &mut self.iflag; + let i = &mut self.iflag; for f in val.split(',') { match f { // Common flags @@ -327,7 +327,7 @@ impl Parser { #[allow(clippy::cognitive_complexity)] fn parse_output_flags(&mut self, val: &str) -> Result<(), ParseError> { - let mut o = &mut self.oflag; + let o = &mut self.oflag; for f in val.split(',') { match f { // Common flags @@ -357,7 +357,7 @@ impl Parser { } fn parse_conv_flags(&mut self, val: &str) -> Result<(), ParseError> { - let mut c = &mut self.conv; + let c = &mut self.conv; for f in val.split(',') { match f { // Conversion From 4ff318aee1c28a4a959a35917ca1fa7cec703669 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Sun, 7 May 2023 16:33:21 -0400 Subject: [PATCH 279/477] fixup! dd: support the [io]flag=nocache option --- src/uu/dd/src/dd.rs | 2 ++ tests/by-util/test_dd.rs | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 3b8b3addb9..6727f4bb00 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -793,6 +793,7 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // TODO Better error handling for overflowing `len`. if i.settings.iflags.nocache { let offset = 0; + #[allow(clippy::useless_conversion)] let len = i.src.len()?.try_into().unwrap(); i.discard_cache(offset, len); } @@ -801,6 +802,7 @@ fn dd_copy(mut i: Input, mut o: Output) -> std::io::Result<()> { // TODO Better error handling for overflowing `len`. if i.settings.oflags.nocache { let offset = 0; + #[allow(clippy::useless_conversion)] let len = o.dst.len()?.try_into().unwrap(); o.discard_cache(offset, len); } diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index a54c473ef0..79b1396024 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1541,11 +1541,15 @@ fn test_multiple_processes_reading_stdin() { #[test] #[cfg(target_os = "linux")] fn test_nocache_stdin_error() { + #[cfg(not(target_env = "musl"))] + let detail = "Illegal seek"; + #[cfg(target_env = "musl")] + let detail = "Invalid seek"; new_ucmd!() .args(&["iflag=nocache", "count=0", "status=noxfer"]) .fails() .code_is(1) - .stderr_only("dd: failed to discard cache for: 'standard input': Illegal seek\n0+0 records in\n0+0 records out\n"); + .stderr_only(format!("dd: failed to discard cache for: 'standard input': {detail}\n0+0 records in\n0+0 records out\n")); } /// Test for discarding system file cache. From b7cf825887c23e53e4426a9df929b6482de157b5 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 6 May 2023 00:19:12 +0200 Subject: [PATCH 280/477] uucore::fs add an hardlink detection --- src/uucore/src/lib/features/fs.rs | 75 ++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/src/uucore/src/lib/features/fs.rs b/src/uucore/src/lib/features/fs.rs index 4de07f5027..797be9c2cd 100644 --- a/src/uucore/src/lib/features/fs.rs +++ b/src/uucore/src/lib/features/fs.rs @@ -617,14 +617,47 @@ pub fn is_symlink_loop(path: &Path) -> bool { false } +#[cfg(not(unix))] +// Hard link comparison is not supported on non-Unix platforms +pub fn are_hardlinks_to_same_file(_source: &Path, _target: &Path) -> bool { + false +} + +/// Checks if two paths are hard links to the same file. +/// +/// # Arguments +/// +/// * `source` - A reference to a `Path` representing the source path. +/// * `target` - A reference to a `Path` representing the target path. +/// +/// # Returns +/// +/// * `bool` - Returns `true` if the paths are hard links to the same file, and `false` otherwise. +#[cfg(unix)] +pub fn are_hardlinks_to_same_file(source: &Path, target: &Path) -> bool { + let source_metadata = match fs::metadata(source) { + Ok(metadata) => metadata, + Err(_) => return false, + }; + + let target_metadata = match fs::metadata(target) { + Ok(metadata) => metadata, + Err(_) => return false, + }; + + source_metadata.ino() == target_metadata.ino() && source_metadata.dev() == target_metadata.dev() +} + #[cfg(test)] mod tests { // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; #[cfg(unix)] + use std::io::Write; + #[cfg(unix)] use std::os::unix; #[cfg(unix)] - use tempfile::tempdir; + use tempfile::{tempdir, NamedTempFile}; struct NormalizePathTestCase<'a> { path: &'a str, @@ -769,4 +802,44 @@ mod tests { assert!(is_symlink_loop(&symlink1_path)); } + + #[cfg(unix)] + #[test] + fn test_are_hardlinks_to_same_file_same_file() { + let mut temp_file = NamedTempFile::new().unwrap(); + writeln!(temp_file, "Test content").unwrap(); + + let path1 = temp_file.path(); + let path2 = temp_file.path(); + + assert_eq!(are_hardlinks_to_same_file(&path1, &path2), true); + } + + #[cfg(unix)] + #[test] + fn test_are_hardlinks_to_same_file_different_files() { + let mut temp_file1 = NamedTempFile::new().unwrap(); + writeln!(temp_file1, "Test content 1").unwrap(); + + let mut temp_file2 = NamedTempFile::new().unwrap(); + writeln!(temp_file2, "Test content 2").unwrap(); + + let path1 = temp_file1.path(); + let path2 = temp_file2.path(); + + assert_eq!(are_hardlinks_to_same_file(&path1, &path2), false); + } + + #[cfg(unix)] + #[test] + fn test_are_hardlinks_to_same_file_hard_link() { + let mut temp_file = NamedTempFile::new().unwrap(); + writeln!(temp_file, "Test content").unwrap(); + let path1 = temp_file.path(); + + let path2 = temp_file.path().with_extension("hardlink"); + fs::hard_link(&path1, &path2).unwrap(); + + assert_eq!(are_hardlinks_to_same_file(&path1, &path2), true); + } } From a5a39b6ba81c922a58bffe11a033031d0bfd1dfc Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 6 May 2023 00:24:42 +0200 Subject: [PATCH 281/477] mv: 'mv source hardlink' should fail fixes: tests/mv/force.sh --- src/uu/mv/Cargo.toml | 2 +- src/uu/mv/src/mv.rs | 3 ++- tests/by-util/test_mv.rs | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/uu/mv/Cargo.toml b/src/uu/mv/Cargo.toml index d1f82bf885..5bc660d087 100644 --- a/src/uu/mv/Cargo.toml +++ b/src/uu/mv/Cargo.toml @@ -18,7 +18,7 @@ path = "src/mv.rs" clap = { workspace=true } fs_extra = { workspace=true } indicatif = { workspace=true } -uucore = { workspace=true } +uucore = { workspace=true, features=["fs"] } [[bin]] name = "mv" diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index ed64818637..dfc1129cb4 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -25,6 +25,7 @@ use std::path::{Path, PathBuf}; use uucore::backup_control::{self, BackupMode}; use uucore::display::Quotable; use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError}; +use uucore::fs::are_hardlinks_to_same_file; use uucore::update_control::{self, UpdateMode}; use uucore::{format_usage, help_about, help_section, help_usage, prompt_yes, show}; @@ -268,7 +269,7 @@ fn exec(files: &[OsString], b: &Behavior) -> UResult<()> { } // GNU semantics are: if the source and target are the same, no move occurs and we print an error - if source.eq(target) { + if source.eq(target) || are_hardlinks_to_same_file(source, target) { // Done to match GNU semantics for the dot file if source.eq(Path::new(".")) || source.ends_with("/.") || source.is_file() { return Err(MvError::SameFile( diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index edeb47a96d..93955711d3 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -400,6 +400,23 @@ fn test_mv_same_file() { .stderr_is(format!("mv: '{file_a}' and '{file_a}' are the same file\n",)); } +#[test] +#[cfg(unix)] +fn test_mv_same_hardlink() { + let (at, mut ucmd) = at_and_ucmd!(); + let file_a = "test_mv_same_file_a"; + let file_b = "test_mv_same_file_b"; + at.touch(file_a); + + at.hard_link(file_a, file_b); + + at.touch(file_a); + ucmd.arg(file_a) + .arg(file_b) + .fails() + .stderr_is(format!("mv: '{file_a}' and '{file_b}' are the same file\n",)); +} + #[test] fn test_mv_same_file_not_dot_dir() { let (at, mut ucmd) = at_and_ucmd!(); From 1b99376d95dbf28e9011470421f62cc0f984df5a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 6 May 2023 12:11:01 +0200 Subject: [PATCH 282/477] mv: split exec into smaller functions --- src/uu/mv/src/mv.rs | 151 +++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 78 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index dfc1129cb4..5bbf0eada8 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -238,93 +238,88 @@ fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode { } } -fn exec(files: &[OsString], b: &Behavior) -> UResult<()> { - let paths: Vec = { - let paths = files.iter().map(Path::new); - - // Strip slashes from path, if strip opt present - if b.strip_slashes { - paths - .map(|p| p.components().as_path().to_owned()) - .collect::>() - } else { - paths.map(|p| p.to_owned()).collect::>() - } - }; +fn parse_paths(files: &[OsString], b: &Behavior) -> Vec { + let paths = files.iter().map(Path::new); - if let Some(ref name) = b.target_dir { - return move_files_into_dir(&paths, &PathBuf::from(name), b); + if b.strip_slashes { + paths + .map(|p| p.components().as_path().to_owned()) + .collect::>() + } else { + paths.map(|p| p.to_owned()).collect::>() } - match paths.len() { - /* case 0/1 are not possible thanks to clap */ - 2 => { - let source = &paths[0]; - let target = &paths[1]; - // Here we use the `symlink_metadata()` method instead of `exists()`, - // since it handles dangling symlinks correctly. The method gives an - // `Ok()` results unless the source does not exist, or the user - // lacks permission to access metadata. - if source.symlink_metadata().is_err() { - return Err(MvError::NoSuchFile(source.quote().to_string()).into()); - } +} - // GNU semantics are: if the source and target are the same, no move occurs and we print an error - if source.eq(target) || are_hardlinks_to_same_file(source, target) { - // Done to match GNU semantics for the dot file - if source.eq(Path::new(".")) || source.ends_with("/.") || source.is_file() { - return Err(MvError::SameFile( - source.quote().to_string(), - target.quote().to_string(), - ) - .into()); - } else { - return Err(MvError::SelfSubdirectory(source.display().to_string()).into()); - } - } +fn handle_two_paths(source: &Path, target: &Path, b: &Behavior) -> UResult<()> { + if source.symlink_metadata().is_err() { + return Err(MvError::NoSuchFile(source.quote().to_string()).into()); + } - if target.is_dir() { - if b.no_target_dir { - if source.is_dir() { - rename(source, target, b, None).map_err_context(|| { - format!("cannot move {} to {}", source.quote(), target.quote()) - }) - } else { - Err(MvError::DirectoryToNonDirectory(target.quote().to_string()).into()) - } - } else { - move_files_into_dir(&[source.clone()], target, b) - } - } else if target.exists() && source.is_dir() { - match b.overwrite { - OverwriteMode::NoClobber => return Ok(()), - OverwriteMode::Interactive => { - if !prompt_yes!("overwrite {}? ", target.quote()) { - return Err(io::Error::new(io::ErrorKind::Other, "").into()); - } - } - OverwriteMode::Force => {} - }; - Err(MvError::NonDirectoryToDirectory( - source.quote().to_string(), - target.quote().to_string(), - ) - .into()) + if source.eq(target) || are_hardlinks_to_same_file(source, target) { + if source.eq(Path::new(".")) || source.ends_with("/.") || source.is_file() { + return Err( + MvError::SameFile(source.quote().to_string(), target.quote().to_string()).into(), + ); + } else { + return Err(MvError::SelfSubdirectory(source.display().to_string()).into()); + } + } + + if target.is_dir() { + if b.no_target_dir { + if source.is_dir() { + rename(source, target, b, None).map_err_context(|| { + format!("cannot move {} to {}", source.quote(), target.quote()) + }) } else { - rename(source, target, b, None).map_err(|e| USimpleError::new(1, format!("{e}"))) + Err(MvError::DirectoryToNonDirectory(target.quote().to_string()).into()) } + } else { + move_files_into_dir(&[source.to_path_buf()], target, b) } - _ => { - if b.no_target_dir { - return Err(UUsageError::new( - 1, - format!("mv: extra operand {}", files[2].quote()), - )); + } else if target.exists() && source.is_dir() { + match b.overwrite { + OverwriteMode::NoClobber => return Ok(()), + OverwriteMode::Interactive => { + if !prompt_yes!("overwrite {}? ", target.quote()) { + return Err(io::Error::new(io::ErrorKind::Other, "").into()); + } } - let target_dir = paths.last().unwrap(); - let sources = &paths[..paths.len() - 1]; + OverwriteMode::Force => {} + }; + Err(MvError::NonDirectoryToDirectory( + source.quote().to_string(), + target.quote().to_string(), + ) + .into()) + } else { + rename(source, target, b, None).map_err(|e| USimpleError::new(1, format!("{e}"))) + } +} - move_files_into_dir(sources, target_dir, b) - } +fn handle_multiple_paths(paths: &[PathBuf], b: &Behavior) -> UResult<()> { + if b.no_target_dir { + return Err(UUsageError::new( + 1, + format!("mv: extra operand {}", paths[2].quote()), + )); + } + let target_dir = paths.last().unwrap(); + let sources = &paths[..paths.len() - 1]; + + move_files_into_dir(sources, target_dir, b) +} + +fn exec(files: &[OsString], b: &Behavior) -> UResult<()> { + let paths = parse_paths(files, b); + + if let Some(ref name) = b.target_dir { + return move_files_into_dir(&paths, &PathBuf::from(name), b); + } + + match paths.len() { + 2 => handle_two_paths(&paths[0], &paths[1], b), + _ => handle_multiple_paths(&paths, b), } } From 560ac3d6fbfd5e6d8fa1010c0d5c5b5cb70581ab Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 8 May 2023 07:59:56 +0200 Subject: [PATCH 283/477] dd: fix "unused imports" warning in tests --- tests/by-util/test_dd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index 99eae48094..ecf4f7f4a5 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1,7 +1,7 @@ // spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, availible, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat abcdefghijklm abcdefghi nabcde nabcdefg abcdefg use crate::common::util::TestScenario; -#[cfg(not(windows))] +#[cfg(all(not(windows), feature = "printf"))] use crate::common::util::{UCommand, TESTS_BINARY}; use regex::Regex; From 594f81a88aba0a92abaa6bf6580c50196dfc0974 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 6 May 2023 12:50:58 +0200 Subject: [PATCH 284/477] mv --backup=simple a b on hard links should not fail touch a ln a b ./target/debug/coreutils mv --backup=simple a b GNU: tests/mv/hard-4.sh --- src/uu/mv/src/mv.rs | 4 +++- tests/by-util/test_mv.rs | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 5bbf0eada8..831b362ae7 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -255,7 +255,9 @@ fn handle_two_paths(source: &Path, target: &Path, b: &Behavior) -> UResult<()> { return Err(MvError::NoSuchFile(source.quote().to_string()).into()); } - if source.eq(target) || are_hardlinks_to_same_file(source, target) { + if (source.eq(target) || are_hardlinks_to_same_file(source, target)) + && b.backup != BackupMode::SimpleBackup + { if source.eq(Path::new(".")) || source.ends_with("/.") || source.is_file() { return Err( MvError::SameFile(source.quote().to_string(), target.quote().to_string()).into(), diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 93955711d3..7a1f5cd5b5 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -417,6 +417,23 @@ fn test_mv_same_hardlink() { .stderr_is(format!("mv: '{file_a}' and '{file_b}' are the same file\n",)); } +#[test] +#[cfg(unix)] +fn test_mv_same_hardlink_backup_simple() { + let (at, mut ucmd) = at_and_ucmd!(); + let file_a = "test_mv_same_file_a"; + let file_b = "test_mv_same_file_b"; + at.touch(file_a); + + at.hard_link(file_a, file_b); + + at.touch(file_a); + ucmd.arg(file_a) + .arg(file_b) + .arg("--backup=simple") + .succeeds(); +} + #[test] fn test_mv_same_file_not_dot_dir() { let (at, mut ucmd) = at_and_ucmd!(); From 48b8cfa5956311fbffd3426e773e9853c8ab02f1 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 8 May 2023 15:24:44 +0200 Subject: [PATCH 285/477] mv: adjust the tests - duplicate code + android According to: https://stackoverflow.com/questions/44913985/creating-hardlinks-and-symlinks-in-android hardlink aren't expected to work on android + fat --- tests/by-util/test_mv.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 7a1f5cd5b5..10565493ad 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -401,7 +401,7 @@ fn test_mv_same_file() { } #[test] -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "android")))] fn test_mv_same_hardlink() { let (at, mut ucmd) = at_and_ucmd!(); let file_a = "test_mv_same_file_a"; @@ -418,7 +418,7 @@ fn test_mv_same_hardlink() { } #[test] -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "android")))] fn test_mv_same_hardlink_backup_simple() { let (at, mut ucmd) = at_and_ucmd!(); let file_a = "test_mv_same_file_a"; @@ -427,7 +427,6 @@ fn test_mv_same_hardlink_backup_simple() { at.hard_link(file_a, file_b); - at.touch(file_a); ucmd.arg(file_a) .arg(file_b) .arg("--backup=simple") From caf9bfcadc2e2fdfb10a270d9a846c48d545eb8e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 8 May 2023 15:49:56 +0200 Subject: [PATCH 286/477] doc: show a warning when no tldr example --- src/bin/uudoc.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index 02dafc98ae..b7a2ce5816 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -216,6 +216,10 @@ impl<'a, 'b> MDWriter<'a, 'b> { } else if let Some(f) = get_zip_content(zip, &format!("pages/linux/{}.md", self.name)) { f } else { + println!( + "Warning: Could not find tldr examples for page '{}'", + self.name + ); return Ok(()); }; From 30c166ad405acd83856b816daf8bf3c3c5bc4e3a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 16:28:38 +0000 Subject: [PATCH 287/477] fix(deps): update rust crate libc to 0.2.144 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9827a78934..aa9cfef09b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1318,9 +1318,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.143" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc207893e85c5d6be840e969b496b53d94cec8be2d501b214f50daa97fa8024" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libloading" diff --git a/Cargo.toml b/Cargo.toml index 0623f9e6af..9e87b7a066 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -290,7 +290,7 @@ humantime_to_duration = "0.1.3" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" -libc = "0.2.143" +libc = "0.2.144" lscolors = { version = "0.14.0", default-features=false, features = ["nu-ansi-term"] } memchr = "2" nix = { version="0.26", default-features=false } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 2df32b6145..8693fbfc4f 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -32,7 +32,7 @@ time = { workspace=true, optional=true, features = ["formatting", "local-offset" data-encoding = { version="2.3", optional=true } data-encoding-macro = { version="0.1.12", optional=true } z85 = { version="3.0.5", optional=true } -libc = { version="0.2.143", optional=true } +libc = { version="0.2.144", optional=true } once_cell = { workspace=true } os_display = "0.1.3" From 3f40ec4db758f772869a0bcc91fc506f66ed3697 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 9 May 2023 09:44:48 +0200 Subject: [PATCH 288/477] basenc: add help texts for options --- src/uu/basenc/src/basenc.rs | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/uu/basenc/src/basenc.rs b/src/uu/basenc/src/basenc.rs index afc25c7367..3ec8cede01 100644 --- a/src/uu/basenc/src/basenc.rs +++ b/src/uu/basenc/src/basenc.rs @@ -24,15 +24,33 @@ use uucore::{help_about, help_usage}; const ABOUT: &str = help_about!("basenc.md"); const USAGE: &str = help_usage!("basenc.md"); -const ENCODINGS: &[(&str, Format)] = &[ - ("base64", Format::Base64), - ("base64url", Format::Base64Url), - ("base32", Format::Base32), - ("base32hex", Format::Base32Hex), - ("base16", Format::Base16), - ("base2lsbf", Format::Base2Lsbf), - ("base2msbf", Format::Base2Msbf), - ("z85", Format::Z85), +const ENCODINGS: &[(&str, Format, &str)] = &[ + ("base64", Format::Base64, "same as 'base64' program"), + ("base64url", Format::Base64Url, "file- and url-safe base64"), + ("base32", Format::Base32, "same as 'base32' program"), + ( + "base32hex", + Format::Base32Hex, + "extended hex alphabet base32", + ), + ("base16", Format::Base16, "hex encoding"), + ( + "base2lsbf", + Format::Base2Lsbf, + "bit string with least significant bit (lsb) first", + ), + ( + "base2msbf", + Format::Base2Msbf, + "bit string with most significant bit (msb) first", + ), + ( + "z85", + Format::Z85, + "ascii85-like encoding;\n\ + when encoding, input length must be a multiple of 4;\n\ + when decoding, input length must be a multiple of 5", + ), ]; pub fn uu_app() -> Command { @@ -41,6 +59,7 @@ pub fn uu_app() -> Command { command = command.arg( Arg::new(encoding.0) .long(encoding.0) + .help(encoding.2) .action(ArgAction::SetTrue), ); } From 6247986a529e3b69eaca75c7daf2c53b149e1e1e Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 9 May 2023 10:25:04 +0200 Subject: [PATCH 289/477] docs: add extension (short options with args) --- docs/src/extensions.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/src/extensions.md b/docs/src/extensions.md index 7aaf9db14f..281d8ef2e7 100644 --- a/docs/src/extensions.md +++ b/docs/src/extensions.md @@ -5,6 +5,21 @@ features that are not supported by GNU coreutils. We take care not to introduce features that are incompatible with the GNU coreutils. Below is a list of uutils extensions. +## General + +GNU coreutils provides two ways to define short options taking an argument: + +``` +$ ls -w 80 +$ ls -w80 +``` + +We support a third way: + +``` +$ ls -w=80 +``` + ## `env` `env` has an additional `-f`/`--file` flag that can parse `.env` files and set From 7983e23d535b4603c935a45f340417e0759d67d1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 18:00:46 +0000 Subject: [PATCH 290/477] fix(deps): update rust crate memmap2 to 0.6 --- Cargo.lock | 4 ++-- src/uu/tac/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa9cfef09b..00bede9a30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1404,9 +1404,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "7f9ff02d2efdc645fca1ee55f45545b996e7da776b5b60c4e170334457551693" dependencies = [ "libc", ] diff --git a/src/uu/tac/Cargo.toml b/src/uu/tac/Cargo.toml index 50d83a67cb..0d90569156 100644 --- a/src/uu/tac/Cargo.toml +++ b/src/uu/tac/Cargo.toml @@ -18,7 +18,7 @@ path = "src/tac.rs" [dependencies] memchr = { workspace=true } -memmap2 = "0.5" +memmap2 = "0.6" regex = { workspace=true } clap = { workspace=true } uucore = { workspace=true } From ba6eb392aa44804b1053756df5b93231d49b856f Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 10 May 2023 09:48:32 +0200 Subject: [PATCH 291/477] cksum: split test function into two --- tests/by-util/test_cksum.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 814d4c03a6..2384b2ae27 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -33,7 +33,7 @@ fn test_stdin() { } #[test] -fn test_empty() { +fn test_empty_file() { let (at, mut ucmd) = at_and_ucmd!(); at.touch("a"); @@ -62,25 +62,26 @@ fn test_arg_overrides_stdin() { } #[test] -fn test_invalid_file() { - let ts = TestScenario::new(util_name!()); - let at = ts.fixtures.clone(); +fn test_nonexisting_file() { + let file_name = "asdf"; - let folder_name = "asdf"; - - // First check when file doesn't exist - ts.ucmd() - .arg(folder_name) + new_ucmd!() + .arg(file_name) .fails() .no_stdout() - .stderr_contains("cksum: asdf: No such file or directory"); + .stderr_contains(format!("cksum: {file_name}: No such file or directory")); +} - // Then check when the file is of an invalid type +#[test] +fn test_folder() { + let (at, mut ucmd) = at_and_ucmd!(); + + let folder_name = "a_folder"; at.mkdir(folder_name); - ts.ucmd() - .arg(folder_name) + + ucmd.arg(folder_name) .succeeds() - .stdout_only("4294967295 0 asdf\n"); + .stdout_only(format!("4294967295 0 {folder_name}\n")); } // Make sure crc is correct for files larger than 32 bytes From d8f1f1c16cb132c0c2ec525dd8d3bdc4b56d51cc Mon Sep 17 00:00:00 2001 From: leone Date: Wed, 10 May 2023 18:40:58 +0200 Subject: [PATCH 292/477] date: bugfix test_date_for_no_permission_file (#4544) --- tests/by-util/test_date.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index edad87bd6c..42a94099db 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -282,6 +282,27 @@ fn test_date_for_invalid_file() { } #[test] +#[cfg(unix)] +fn test_date_for_no_permission_file() { + let (at, mut ucmd) = at_and_ucmd!(); + const FILE: &str = "file-no-perm-1"; + + use std::os::unix::fs::PermissionsExt; + let file = std::fs::OpenOptions::new() + .create(true) + .write(true) + .open(at.plus(FILE)) + .unwrap(); + file.set_permissions(std::fs::Permissions::from_mode(0o222)) + .unwrap(); + let result = ucmd.arg("--file").arg(FILE).fails(); + result.no_stdout(); + assert_eq!( + result.stderr_str().trim(), + format!("date: {FILE}: Permission denied") + ); +} + fn test_date_for_dir_as_file() { let result = new_ucmd!().arg("--file").arg("/").fails(); result.no_stdout(); From 452be5a22005a239008874019d9a0c5fb83ba9ab Mon Sep 17 00:00:00 2001 From: SteveLauC Date: Thu, 11 May 2023 18:58:36 +0800 Subject: [PATCH 293/477] ls: device number for BSDs and solarishOS (#4841) --- src/uu/ls/src/ls.rs | 16 ++++++++++++++-- tests/by-util/test_ls.rs | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index db8024c2e7..9219876879 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -41,7 +41,13 @@ use unicode_width::UnicodeWidthStr; target_os = "linux", target_os = "macos", target_os = "android", - target_os = "ios" + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "solaris" ))] use uucore::libc::{dev_t, major, minor}; #[cfg(unix)] @@ -2716,7 +2722,13 @@ fn display_len_or_rdev(metadata: &Metadata, config: &Config) -> SizeOrDeviceId { target_os = "linux", target_os = "macos", target_os = "android", - target_os = "ios" + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "solaris" ))] { let ft = metadata.file_type(); diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 84efb9daa4..61f6d8d8dc 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -3393,3 +3393,44 @@ fn test_tabsize_formatting() { .succeeds() .stdout_is("aaaaaaaa bbbb\ncccc dddddddd"); } + +#[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "solaris" +))] +#[test] +fn test_device_number() { + use std::fs::{metadata, read_dir}; + use std::os::unix::fs::{FileTypeExt, MetadataExt}; + use uucore::libc::{dev_t, major, minor}; + + let dev_dir = read_dir("/dev").unwrap(); + // let's use the first device for test + let blk_dev = dev_dir + .map(|res_entry| res_entry.unwrap()) + .find(|entry| { + entry.file_type().unwrap().is_block_device() + || entry.file_type().unwrap().is_char_device() + }) + .expect("Expect a block/char device"); + let blk_dev_path = blk_dev.path(); + let blk_dev_meta = metadata(blk_dev_path.as_path()).unwrap(); + let blk_dev_number = blk_dev_meta.rdev() as dev_t; + let (major, minor) = unsafe { (major(blk_dev_number), minor(blk_dev_number)) }; + let major_minor_str = format!("{}, {}", major, minor); + + let scene = TestScenario::new(util_name!()); + scene + .ucmd() + .arg("-l") + .arg(blk_dev_path.to_str().expect("should be UTF-8 encoded")) + .succeeds() + .stdout_contains(major_minor_str); +} From 0781ad0a65f1d7dc45e4f6cc163db762ecb97037 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 11 May 2023 08:03:12 +0200 Subject: [PATCH 294/477] cksum: fix output of --algorithm for the algorithms md5, sha[1,224,256,384,512], blake2b, and sm3 from to () = to use the same format as GNU cksum --- src/uu/cksum/src/cksum.rs | 10 +- tests/by-util/test_cksum.rs | 122 +++++++----------- .../cksum/blake2b_multiple_files.expected | 2 + .../cksum/blake2b_single_file.expected | 1 + tests/fixtures/cksum/blake2b_stdin.expected | 1 + ...s.expected => crc_multiple_files.expected} | 0 ...file.expected => crc_single_file.expected} | 0 .../{stdin.expected => crc_stdin.expected} | 0 .../cksum/md5_multiple_files.expected | 2 + tests/fixtures/cksum/md5_single_file.expected | 1 + tests/fixtures/cksum/md5_stdin.expected | 1 + .../cksum/sha1_multiple_files.expected | 2 + .../fixtures/cksum/sha1_single_file.expected | 1 + tests/fixtures/cksum/sha1_stdin.expected | 1 + .../cksum/sha224_multiple_files.expected | 2 + .../cksum/sha224_single_file.expected | 1 + tests/fixtures/cksum/sha224_stdin.expected | 1 + .../cksum/sha256_multiple_files.expected | 2 + .../cksum/sha256_single_file.expected | 1 + tests/fixtures/cksum/sha256_stdin.expected | 1 + .../cksum/sha384_multiple_files.expected | 2 + .../cksum/sha384_single_file.expected | 1 + tests/fixtures/cksum/sha384_stdin.expected | 1 + .../cksum/sha512_multiple_files.expected | 2 + .../cksum/sha512_single_file.expected | 1 + tests/fixtures/cksum/sha512_stdin.expected | 1 + .../cksum/sm3_multiple_files.expected | 2 + tests/fixtures/cksum/sm3_single_file.expected | 1 + tests/fixtures/cksum/sm3_stdin.expected | 1 + 29 files changed, 85 insertions(+), 79 deletions(-) create mode 100644 tests/fixtures/cksum/blake2b_multiple_files.expected create mode 100644 tests/fixtures/cksum/blake2b_single_file.expected create mode 100644 tests/fixtures/cksum/blake2b_stdin.expected rename tests/fixtures/cksum/{multiple_files.expected => crc_multiple_files.expected} (100%) rename tests/fixtures/cksum/{single_file.expected => crc_single_file.expected} (100%) rename tests/fixtures/cksum/{stdin.expected => crc_stdin.expected} (100%) create mode 100644 tests/fixtures/cksum/md5_multiple_files.expected create mode 100644 tests/fixtures/cksum/md5_single_file.expected create mode 100644 tests/fixtures/cksum/md5_stdin.expected create mode 100644 tests/fixtures/cksum/sha1_multiple_files.expected create mode 100644 tests/fixtures/cksum/sha1_single_file.expected create mode 100644 tests/fixtures/cksum/sha1_stdin.expected create mode 100644 tests/fixtures/cksum/sha224_multiple_files.expected create mode 100644 tests/fixtures/cksum/sha224_single_file.expected create mode 100644 tests/fixtures/cksum/sha224_stdin.expected create mode 100644 tests/fixtures/cksum/sha256_multiple_files.expected create mode 100644 tests/fixtures/cksum/sha256_single_file.expected create mode 100644 tests/fixtures/cksum/sha256_stdin.expected create mode 100644 tests/fixtures/cksum/sha384_multiple_files.expected create mode 100644 tests/fixtures/cksum/sha384_single_file.expected create mode 100644 tests/fixtures/cksum/sha384_stdin.expected create mode 100644 tests/fixtures/cksum/sha512_multiple_files.expected create mode 100644 tests/fixtures/cksum/sha512_single_file.expected create mode 100644 tests/fixtures/cksum/sha512_stdin.expected create mode 100644 tests/fixtures/cksum/sm3_multiple_files.expected create mode 100644 tests/fixtures/cksum/sm3_single_file.expected create mode 100644 tests/fixtures/cksum/sm3_stdin.expected diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index 9bddd3d7ab..5a8cec5ea6 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -159,8 +159,14 @@ where div_ceil(sz, options.output_bits), filename.display() ), - (_, true) => println!("{sum} {sz}"), - (_, false) => println!("{sum} {sz} {}", filename.display()), + (ALGORITHM_OPTIONS_CRC, true) => println!("{sum} {sz}"), + (ALGORITHM_OPTIONS_CRC, false) => println!("{sum} {sz} {}", filename.display()), + (ALGORITHM_OPTIONS_BLAKE2B, _) => println!("BLAKE2b ({}) = {sum}", filename.display()), + _ => println!( + "{} ({}) = {sum}", + options.algo_name.to_ascii_uppercase(), + filename.display() + ), } } diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 2384b2ae27..28c978ba6d 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -1,7 +1,11 @@ -// spell-checker:ignore (words) asdf +// spell-checker:ignore (words) asdf algo algos use crate::common::util::TestScenario; +const ALGOS: [&str; 11] = [ + "sysv", "bsd", "crc", "md5", "sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "sm3", +]; + #[test] fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails().code_is(1); @@ -12,7 +16,7 @@ fn test_single_file() { new_ucmd!() .arg("lorem_ipsum.txt") .succeeds() - .stdout_is_fixture("single_file.expected"); + .stdout_is_fixture("crc_single_file.expected"); } #[test] @@ -21,7 +25,7 @@ fn test_multiple_files() { .arg("lorem_ipsum.txt") .arg("alice_in_wonderland.txt") .succeeds() - .stdout_is_fixture("multiple_files.expected"); + .stdout_is_fixture("crc_multiple_files.expected"); } #[test] @@ -29,7 +33,7 @@ fn test_stdin() { new_ucmd!() .pipe_in_fixture("lorem_ipsum.txt") .succeeds() - .stdout_is_fixture("stdin.expected"); + .stdout_is_fixture("crc_stdin.expected"); } #[test] @@ -117,77 +121,41 @@ fn test_stdin_larger_than_128_bytes() { } #[test] -fn test_sha1_single_file() { - new_ucmd!() - .arg("-a=sha1") - .arg("lorem_ipsum.txt") - .succeeds() - .stdout_is("ab1dd0bae1d8883a3d18a66de6afbd28252cfbef 772 lorem_ipsum.txt\n"); -} - -#[test] -fn test_sm3_single_file() { - new_ucmd!() - .arg("-a=sm3") - .arg("lorem_ipsum.txt") - .succeeds() - .stdout_is( - "6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 772 lorem_ipsum.txt\n", - ); -} - -#[test] -fn test_bsd_single_file() { - new_ucmd!() - .arg("-a=bsd") - .arg("lorem_ipsum.txt") - .succeeds() - .stdout_only_fixture("bsd_single_file.expected"); -} - -#[test] -fn test_bsd_multiple_files() { - new_ucmd!() - .arg("-a=bsd") - .arg("lorem_ipsum.txt") - .arg("alice_in_wonderland.txt") - .succeeds() - .stdout_only_fixture("bsd_multiple_files.expected"); -} - -#[test] -fn test_bsd_stdin() { - new_ucmd!() - .arg("-a=bsd") - .pipe_in_fixture("lorem_ipsum.txt") - .succeeds() - .stdout_only_fixture("bsd_stdin.expected"); -} - -#[test] -fn test_sysv_single_file() { - new_ucmd!() - .arg("-a=sysv") - .arg("lorem_ipsum.txt") - .succeeds() - .stdout_only_fixture("sysv_single_file.expected"); -} - -#[test] -fn test_sysv_multiple_files() { - new_ucmd!() - .arg("-a=sysv") - .arg("lorem_ipsum.txt") - .arg("alice_in_wonderland.txt") - .succeeds() - .stdout_only_fixture("sysv_multiple_files.expected"); -} - -#[test] -fn test_sysv_stdin() { - new_ucmd!() - .arg("-a=sysv") - .pipe_in_fixture("lorem_ipsum.txt") - .succeeds() - .stdout_only_fixture("sysv_stdin.expected"); +fn test_algorithm_single_file() { + for algo in ALGOS { + for option in ["-a", "--algorithm"] { + new_ucmd!() + .arg(format!("{option}={algo}")) + .arg("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture(format!("{algo}_single_file.expected")); + } + } +} + +#[test] +fn test_algorithm_multiple_files() { + for algo in ALGOS { + for option in ["-a", "--algorithm"] { + new_ucmd!() + .arg(format!("{option}={algo}")) + .arg("lorem_ipsum.txt") + .arg("alice_in_wonderland.txt") + .succeeds() + .stdout_is_fixture(format!("{algo}_multiple_files.expected")); + } + } +} + +#[test] +fn test_algorithm_stdin() { + for algo in ALGOS { + for option in ["-a", "--algorithm"] { + new_ucmd!() + .arg(format!("{option}={algo}")) + .pipe_in_fixture("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture(format!("{algo}_stdin.expected")); + } + } } diff --git a/tests/fixtures/cksum/blake2b_multiple_files.expected b/tests/fixtures/cksum/blake2b_multiple_files.expected new file mode 100644 index 0000000000..97d06eb6fe --- /dev/null +++ b/tests/fixtures/cksum/blake2b_multiple_files.expected @@ -0,0 +1,2 @@ +BLAKE2b (lorem_ipsum.txt) = 0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 +BLAKE2b (alice_in_wonderland.txt) = 91b8b0f0868e905ad18b8ac35e4a1dacd289857b19258ab5d1e071761af758b0134ec152d4f011fe1825ca889c80c2e072ca70eb50548c25fc49a98937515af4 diff --git a/tests/fixtures/cksum/blake2b_single_file.expected b/tests/fixtures/cksum/blake2b_single_file.expected new file mode 100644 index 0000000000..64ede7ca04 --- /dev/null +++ b/tests/fixtures/cksum/blake2b_single_file.expected @@ -0,0 +1 @@ +BLAKE2b (lorem_ipsum.txt) = 0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 diff --git a/tests/fixtures/cksum/blake2b_stdin.expected b/tests/fixtures/cksum/blake2b_stdin.expected new file mode 100644 index 0000000000..15c34ea775 --- /dev/null +++ b/tests/fixtures/cksum/blake2b_stdin.expected @@ -0,0 +1 @@ +BLAKE2b (-) = 0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 diff --git a/tests/fixtures/cksum/multiple_files.expected b/tests/fixtures/cksum/crc_multiple_files.expected similarity index 100% rename from tests/fixtures/cksum/multiple_files.expected rename to tests/fixtures/cksum/crc_multiple_files.expected diff --git a/tests/fixtures/cksum/single_file.expected b/tests/fixtures/cksum/crc_single_file.expected similarity index 100% rename from tests/fixtures/cksum/single_file.expected rename to tests/fixtures/cksum/crc_single_file.expected diff --git a/tests/fixtures/cksum/stdin.expected b/tests/fixtures/cksum/crc_stdin.expected similarity index 100% rename from tests/fixtures/cksum/stdin.expected rename to tests/fixtures/cksum/crc_stdin.expected diff --git a/tests/fixtures/cksum/md5_multiple_files.expected b/tests/fixtures/cksum/md5_multiple_files.expected new file mode 100644 index 0000000000..54023e7615 --- /dev/null +++ b/tests/fixtures/cksum/md5_multiple_files.expected @@ -0,0 +1,2 @@ +MD5 (lorem_ipsum.txt) = cd724690f7dc61775dfac400a71f2caa +MD5 (alice_in_wonderland.txt) = f6fa7033e16166a9589aa1c0388ffd58 diff --git a/tests/fixtures/cksum/md5_single_file.expected b/tests/fixtures/cksum/md5_single_file.expected new file mode 100644 index 0000000000..5975053d1e --- /dev/null +++ b/tests/fixtures/cksum/md5_single_file.expected @@ -0,0 +1 @@ +MD5 (lorem_ipsum.txt) = cd724690f7dc61775dfac400a71f2caa diff --git a/tests/fixtures/cksum/md5_stdin.expected b/tests/fixtures/cksum/md5_stdin.expected new file mode 100644 index 0000000000..b3b1090bcc --- /dev/null +++ b/tests/fixtures/cksum/md5_stdin.expected @@ -0,0 +1 @@ +MD5 (-) = cd724690f7dc61775dfac400a71f2caa diff --git a/tests/fixtures/cksum/sha1_multiple_files.expected b/tests/fixtures/cksum/sha1_multiple_files.expected new file mode 100644 index 0000000000..f20ea94715 --- /dev/null +++ b/tests/fixtures/cksum/sha1_multiple_files.expected @@ -0,0 +1,2 @@ +SHA1 (lorem_ipsum.txt) = ab1dd0bae1d8883a3d18a66de6afbd28252cfbef +SHA1 (alice_in_wonderland.txt) = 22b54b2520e8b4fa59eb10719028a4e587c12d1e diff --git a/tests/fixtures/cksum/sha1_single_file.expected b/tests/fixtures/cksum/sha1_single_file.expected new file mode 100644 index 0000000000..1b820559f6 --- /dev/null +++ b/tests/fixtures/cksum/sha1_single_file.expected @@ -0,0 +1 @@ +SHA1 (lorem_ipsum.txt) = ab1dd0bae1d8883a3d18a66de6afbd28252cfbef diff --git a/tests/fixtures/cksum/sha1_stdin.expected b/tests/fixtures/cksum/sha1_stdin.expected new file mode 100644 index 0000000000..ced9ce80d4 --- /dev/null +++ b/tests/fixtures/cksum/sha1_stdin.expected @@ -0,0 +1 @@ +SHA1 (-) = ab1dd0bae1d8883a3d18a66de6afbd28252cfbef diff --git a/tests/fixtures/cksum/sha224_multiple_files.expected b/tests/fixtures/cksum/sha224_multiple_files.expected new file mode 100644 index 0000000000..0d6b45b102 --- /dev/null +++ b/tests/fixtures/cksum/sha224_multiple_files.expected @@ -0,0 +1,2 @@ +SHA224 (lorem_ipsum.txt) = 3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 +SHA224 (alice_in_wonderland.txt) = 54c9c7d78458886418ce0845111fc49fe1c628ffd4bf3da14226ffd9 diff --git a/tests/fixtures/cksum/sha224_single_file.expected b/tests/fixtures/cksum/sha224_single_file.expected new file mode 100644 index 0000000000..a08d66bb4e --- /dev/null +++ b/tests/fixtures/cksum/sha224_single_file.expected @@ -0,0 +1 @@ +SHA224 (lorem_ipsum.txt) = 3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 diff --git a/tests/fixtures/cksum/sha224_stdin.expected b/tests/fixtures/cksum/sha224_stdin.expected new file mode 100644 index 0000000000..1bd1386988 --- /dev/null +++ b/tests/fixtures/cksum/sha224_stdin.expected @@ -0,0 +1 @@ +SHA224 (-) = 3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 diff --git a/tests/fixtures/cksum/sha256_multiple_files.expected b/tests/fixtures/cksum/sha256_multiple_files.expected new file mode 100644 index 0000000000..e6fd8beb52 --- /dev/null +++ b/tests/fixtures/cksum/sha256_multiple_files.expected @@ -0,0 +1,2 @@ +SHA256 (lorem_ipsum.txt) = f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 +SHA256 (alice_in_wonderland.txt) = 14ab7e5a0aa3a670222744714bc96961d51012cb216225d965db71824a46e5fe diff --git a/tests/fixtures/cksum/sha256_single_file.expected b/tests/fixtures/cksum/sha256_single_file.expected new file mode 100644 index 0000000000..e16abcb0f3 --- /dev/null +++ b/tests/fixtures/cksum/sha256_single_file.expected @@ -0,0 +1 @@ +SHA256 (lorem_ipsum.txt) = f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 diff --git a/tests/fixtures/cksum/sha256_stdin.expected b/tests/fixtures/cksum/sha256_stdin.expected new file mode 100644 index 0000000000..87bd841953 --- /dev/null +++ b/tests/fixtures/cksum/sha256_stdin.expected @@ -0,0 +1 @@ +SHA256 (-) = f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 diff --git a/tests/fixtures/cksum/sha384_multiple_files.expected b/tests/fixtures/cksum/sha384_multiple_files.expected new file mode 100644 index 0000000000..a5a3324a25 --- /dev/null +++ b/tests/fixtures/cksum/sha384_multiple_files.expected @@ -0,0 +1,2 @@ +SHA384 (lorem_ipsum.txt) = 4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb +SHA384 (alice_in_wonderland.txt) = b7966c97ef84ab5858db2e0cdd33fbaf4fa8346d84de65aba001e738c242598a43272854d0073ad1099404eaa1d93766 diff --git a/tests/fixtures/cksum/sha384_single_file.expected b/tests/fixtures/cksum/sha384_single_file.expected new file mode 100644 index 0000000000..8d673e60b0 --- /dev/null +++ b/tests/fixtures/cksum/sha384_single_file.expected @@ -0,0 +1 @@ +SHA384 (lorem_ipsum.txt) = 4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb diff --git a/tests/fixtures/cksum/sha384_stdin.expected b/tests/fixtures/cksum/sha384_stdin.expected new file mode 100644 index 0000000000..3c0d5c8189 --- /dev/null +++ b/tests/fixtures/cksum/sha384_stdin.expected @@ -0,0 +1 @@ +SHA384 (-) = 4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb diff --git a/tests/fixtures/cksum/sha512_multiple_files.expected b/tests/fixtures/cksum/sha512_multiple_files.expected new file mode 100644 index 0000000000..0f533b27c8 --- /dev/null +++ b/tests/fixtures/cksum/sha512_multiple_files.expected @@ -0,0 +1,2 @@ +SHA512 (lorem_ipsum.txt) = 965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 +SHA512 (alice_in_wonderland.txt) = 251646d5a7eb481e0f3aced7839d78dd5e97153f822dc55938e17059c485990d85d602e2881b528b565ab6262584a69c97b068b26bda81acc9356c53c7c1c96d diff --git a/tests/fixtures/cksum/sha512_single_file.expected b/tests/fixtures/cksum/sha512_single_file.expected new file mode 100644 index 0000000000..e9a02c96a0 --- /dev/null +++ b/tests/fixtures/cksum/sha512_single_file.expected @@ -0,0 +1 @@ +SHA512 (lorem_ipsum.txt) = 965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 diff --git a/tests/fixtures/cksum/sha512_stdin.expected b/tests/fixtures/cksum/sha512_stdin.expected new file mode 100644 index 0000000000..8321c4cc3e --- /dev/null +++ b/tests/fixtures/cksum/sha512_stdin.expected @@ -0,0 +1 @@ +SHA512 (-) = 965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 diff --git a/tests/fixtures/cksum/sm3_multiple_files.expected b/tests/fixtures/cksum/sm3_multiple_files.expected new file mode 100644 index 0000000000..eae2cde2f3 --- /dev/null +++ b/tests/fixtures/cksum/sm3_multiple_files.expected @@ -0,0 +1,2 @@ +SM3 (lorem_ipsum.txt) = 6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 +SM3 (alice_in_wonderland.txt) = d66617ae3c4e87828298dcd836f79efbab488c53b84e09c3e8e83a16c902418d diff --git a/tests/fixtures/cksum/sm3_single_file.expected b/tests/fixtures/cksum/sm3_single_file.expected new file mode 100644 index 0000000000..cf4b8304a3 --- /dev/null +++ b/tests/fixtures/cksum/sm3_single_file.expected @@ -0,0 +1 @@ +SM3 (lorem_ipsum.txt) = 6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 diff --git a/tests/fixtures/cksum/sm3_stdin.expected b/tests/fixtures/cksum/sm3_stdin.expected new file mode 100644 index 0000000000..436fcfb414 --- /dev/null +++ b/tests/fixtures/cksum/sm3_stdin.expected @@ -0,0 +1 @@ +SM3 (-) = 6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 From 7a31d841ba9b2237c5536852395b7c59c6887411 Mon Sep 17 00:00:00 2001 From: John Shin <51249639+shinhs0506@users.noreply.github.com> Date: Thu, 11 May 2023 07:44:23 -0700 Subject: [PATCH 295/477] cp: preserve permission on -p --parents (#4853) --- src/uu/cp/src/cp.rs | 26 ++++++++++++++++++++++++++ tests/by-util/test_cp.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 3e69e5791b..642bbcb145 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -1704,6 +1704,11 @@ fn copy_file( } copy_attributes(source, dest, &options.attributes)?; + if options.parents && should_preserve_attribute(options) { + for (x, y) in aligned_ancestors(source, dest) { + copy_attributes(x, y, &options.attributes)?; + } + } if let Some(progress_bar) = progress_bar { progress_bar.inc(fs::metadata(source)?.len()); @@ -1753,6 +1758,27 @@ fn copy_helper( Ok(()) } +fn should_preserve_attribute(options: &Options) -> bool { + let checks = [ + &options.attributes.mode, + &options.attributes.timestamps, + &options.attributes.links, + &options.attributes.context, + &options.attributes.xattr, + ]; + + #[cfg(unix)] + let checks = [ + checks.as_slice(), + [&options.attributes.ownership].as_slice(), + ] + .concat(); + + checks + .iter() + .any(|attr| matches!(attr, Preserve::Yes { .. })) +} + // "Copies" a FIFO by creating a new one. This workaround is because Rust's // built-in fs::copy does not handle FIFOs (see rust-lang/rust/issues/79390). #[cfg(unix)] diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 0a6e580497..27c996f1b9 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1075,6 +1075,46 @@ fn test_cp_parents_dest_not_directory() { .stderr_contains("with --parents, the destination must be a directory"); } +#[test] +fn test_cp_parents_with_permissions_copy_file() { + let (at, mut ucmd) = at_and_ucmd!(); + + let dir = "dir"; + let file = "p1/p2/file"; + + at.mkdir(dir); + at.mkdir_all("p1/p2"); + at.touch(file); + + let p1_mode = 0o0777; + let p2_mode = 0o0711; + let file_mode = 0o0702; + + #[cfg(unix)] + { + at.set_mode("p1", p1_mode); + at.set_mode("p1/p2", p2_mode); + at.set_mode(file, file_mode); + } + + ucmd.arg("-p") + .arg("--parents") + .arg(file) + .arg(dir) + .succeeds(); + + #[cfg(all(unix, not(target_os = "freebsd")))] + { + let p1_metadata = at.metadata("p1"); + let p2_metadata = at.metadata("p1/p2"); + let file_metadata = at.metadata(file); + + assert_metadata_eq!(p1_metadata, at.metadata("dir/p1")); + assert_metadata_eq!(p2_metadata, at.metadata("dir/p1/p2")); + assert_metadata_eq!(file_metadata, at.metadata("dir/p1/p2/file")); + } +} + #[test] #[cfg(unix)] fn test_cp_writable_special_file_permissions() { From 536d12d20d7ab3ce2237de75eb82342cddb7088c Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 11 May 2023 18:19:49 +0200 Subject: [PATCH 296/477] simplify code Co-authored-by: Daniel Hofstetter --- tests/by-util/test_tee.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_tee.rs b/tests/by-util/test_tee.rs index 41751f2662..51d552d672 100644 --- a/tests/by-util/test_tee.rs +++ b/tests/by-util/test_tee.rs @@ -119,7 +119,7 @@ mod linux_only { let mut fds: [c_int; 2] = [0, 0]; assert!( - !(unsafe { libc::pipe(&mut fds as *mut c_int) } != 0), + (unsafe { libc::pipe(&mut fds as *mut c_int) } == 0), "Failed to create pipe" ); From d98293bdaacedb90afd7a1d61b2a9e83f2678471 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 11 May 2023 18:20:28 +0200 Subject: [PATCH 297/477] bring back the empty line --- tests/by-util/test_cp.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 12dd625c88..22e5fbea29 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1392,6 +1392,7 @@ fn test_cp_target_file_dev_null() { fn test_cp_one_file_system() { use crate::common::util::AtPath; use walkdir::WalkDir; + let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; From 133ff41d813dd171cfef9cbedb3e945cbb8d5879 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 16:56:57 +0000 Subject: [PATCH 298/477] chore(deps): update rust crate humantime_to_duration to 0.2.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 00bede9a30..a92292f645 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1156,9 +1156,9 @@ dependencies = [ [[package]] name = "humantime_to_duration" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46276b15cd421d8262968eb5c3a075ae4a40bd787762ca0ddfead00fd5f6fbce" +checksum = "bcf364c7a07c8beae52fdab733304ceceeb9213f4137d938a17bae365a0136f9" dependencies = [ "regex", "time", diff --git a/Cargo.toml b/Cargo.toml index 9e87b7a066..2434870965 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -286,7 +286,7 @@ fundu = "0.5.1" gcd = "2.3" glob = "0.3.1" half = "2.2" -humantime_to_duration = "0.1.3" +humantime_to_duration = "0.2.0" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" From 9415c6c8cc72aa347c59fb714bec29a9fe3fc871 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 May 2023 14:50:22 +0000 Subject: [PATCH 299/477] chore(deps): update rust crate humantime_to_duration to 0.2.1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c4815bee1..5f8bddf940 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1156,9 +1156,9 @@ dependencies = [ [[package]] name = "humantime_to_duration" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf364c7a07c8beae52fdab733304ceceeb9213f4137d938a17bae365a0136f9" +checksum = "714764645f21cc70c4c151d7798dd158409641f37ad820bed65224aae403cbed" dependencies = [ "regex", "time", diff --git a/Cargo.toml b/Cargo.toml index 2434870965..c5d2a760bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -286,7 +286,7 @@ fundu = "0.5.1" gcd = "2.3" glob = "0.3.1" half = "2.2" -humantime_to_duration = "0.2.0" +humantime_to_duration = "0.2.1" indicatif = "0.17" is-terminal = "0.4.6" itertools = "0.10.5" From a817186e1073b659a5a05b6031d2fa72608ce163 Mon Sep 17 00:00:00 2001 From: John Shin Date: Fri, 12 May 2023 09:19:27 -0700 Subject: [PATCH 300/477] cp: preserve permissions on -r -p --parents --- src/uu/cp/src/copydir.rs | 12 +++++++++++- src/uu/cp/src/cp.rs | 36 ++++++++-------------------------- tests/by-util/test_cp.rs | 42 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/uu/cp/src/copydir.rs b/src/uu/cp/src/copydir.rs index c312b7cbb4..aaeb73f5ac 100644 --- a/src/uu/cp/src/copydir.rs +++ b/src/uu/cp/src/copydir.rs @@ -404,8 +404,18 @@ pub(crate) fn copy_directory( Err(e) => show_error!("{}", e), } } + // Copy the attributes from the root directory to the target directory. - copy_attributes(root, target, &options.attributes)?; + if options.parents { + let dest = target.join(root.file_name().unwrap()); + copy_attributes(root, dest.as_path(), &options.attributes)?; + for (x, y) in aligned_ancestors(root, dest.as_path()) { + copy_attributes(x, y, &options.attributes)?; + } + } else { + copy_attributes(root, target, &options.attributes)?; + } + Ok(()) } diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 642bbcb145..f7069f04f7 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -1151,14 +1151,20 @@ fn copy_source( } else { // Copy as file let dest = construct_dest_path(source_path, target, target_type, options)?; - copy_file( + let res = copy_file( progress_bar, source_path, dest.as_path(), options, symlinked_files, true, - ) + ); + if options.parents { + for (x, y) in aligned_ancestors(source, dest.as_path()) { + copy_attributes(x, y, &options.attributes)?; + } + } + res } } @@ -1704,11 +1710,6 @@ fn copy_file( } copy_attributes(source, dest, &options.attributes)?; - if options.parents && should_preserve_attribute(options) { - for (x, y) in aligned_ancestors(source, dest) { - copy_attributes(x, y, &options.attributes)?; - } - } if let Some(progress_bar) = progress_bar { progress_bar.inc(fs::metadata(source)?.len()); @@ -1758,27 +1759,6 @@ fn copy_helper( Ok(()) } -fn should_preserve_attribute(options: &Options) -> bool { - let checks = [ - &options.attributes.mode, - &options.attributes.timestamps, - &options.attributes.links, - &options.attributes.context, - &options.attributes.xattr, - ]; - - #[cfg(unix)] - let checks = [ - checks.as_slice(), - [&options.attributes.ownership].as_slice(), - ] - .concat(); - - checks - .iter() - .any(|attr| matches!(attr, Preserve::Yes { .. })) -} - // "Copies" a FIFO by creating a new one. This workaround is because Rust's // built-in fs::copy does not handle FIFOs (see rust-lang/rust/issues/79390). #[cfg(unix)] diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 86fbf9dcc0..ef35f6c2de 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1115,6 +1115,48 @@ fn test_cp_parents_with_permissions_copy_file() { } } +#[test] +fn test_cp_parents_with_permissions_copy_dir() { + let (at, mut ucmd) = at_and_ucmd!(); + + let dir1 = "dir"; + let dir2 = "p1/p2"; + let file = "p1/p2/file"; + + at.mkdir(dir1); + at.mkdir_all(dir2); + at.touch(file); + + let p1_mode = 0o0777; + let p2_mode = 0o0711; + let file_mode = 0o0702; + + #[cfg(unix)] + { + at.set_mode("p1", p1_mode); + at.set_mode("p1/p2", p2_mode); + at.set_mode(file, file_mode); + } + + ucmd.arg("-p") + .arg("--parents") + .arg("-r") + .arg(dir2) + .arg(dir1) + .succeeds(); + + #[cfg(all(unix, not(target_os = "freebsd")))] + { + let p1_metadata = at.metadata("p1"); + let p2_metadata = at.metadata("p1/p2"); + let file_metadata = at.metadata(file); + + assert_metadata_eq!(p1_metadata, at.metadata("dir/p1")); + assert_metadata_eq!(p2_metadata, at.metadata("dir/p1/p2")); + assert_metadata_eq!(file_metadata, at.metadata("dir/p1/p2/file")); + } +} + #[test] #[cfg(unix)] fn test_cp_writable_special_file_permissions() { From 690fff2fc9514391d4921a441795445cd2bd0aaa Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 14 May 2023 16:10:46 +0200 Subject: [PATCH 301/477] cksum: implement --untagged --- src/uu/cksum/src/cksum.rs | 35 +++++++--- tests/by-util/test_cksum.rs | 65 +++++++++++++++++++ .../untagged/blake2b_multiple_files.expected | 2 + .../untagged/blake2b_single_file.expected | 1 + .../cksum/untagged/blake2b_stdin.expected | 1 + .../untagged/bsd_multiple_files.expected | 2 + .../cksum/untagged/bsd_single_file.expected | 1 + .../cksum/untagged/bsd_stdin.expected | 1 + .../untagged/crc_multiple_files.expected | 2 + .../cksum/untagged/crc_single_file.expected | 1 + .../cksum/untagged/crc_stdin.expected | 1 + .../untagged/md5_multiple_files.expected | 2 + .../cksum/untagged/md5_single_file.expected | 1 + .../cksum/untagged/md5_stdin.expected | 1 + .../untagged/sha1_multiple_files.expected | 2 + .../cksum/untagged/sha1_single_file.expected | 1 + .../cksum/untagged/sha1_stdin.expected | 1 + .../untagged/sha224_multiple_files.expected | 2 + .../untagged/sha224_single_file.expected | 1 + .../cksum/untagged/sha224_stdin.expected | 1 + .../untagged/sha256_multiple_files.expected | 2 + .../untagged/sha256_single_file.expected | 1 + .../cksum/untagged/sha256_stdin.expected | 1 + .../untagged/sha384_multiple_files.expected | 2 + .../untagged/sha384_single_file.expected | 1 + .../cksum/untagged/sha384_stdin.expected | 1 + .../untagged/sha512_multiple_files.expected | 2 + .../untagged/sha512_single_file.expected | 1 + .../cksum/untagged/sha512_stdin.expected | 1 + .../untagged/sm3_multiple_files.expected | 2 + .../cksum/untagged/sm3_single_file.expected | 1 + .../cksum/untagged/sm3_stdin.expected | 1 + .../untagged/sysv_multiple_files.expected | 2 + .../cksum/untagged/sysv_single_file.expected | 1 + .../cksum/untagged/sysv_stdin.expected | 1 + 35 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 tests/fixtures/cksum/untagged/blake2b_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/blake2b_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/blake2b_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/bsd_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/bsd_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/bsd_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/crc_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/crc_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/crc_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/md5_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/md5_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/md5_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sha1_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sha1_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sha1_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sha224_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sha224_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sha224_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sha256_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sha256_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sha256_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sha384_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sha384_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sha384_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sha512_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sha512_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sha512_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sm3_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sm3_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sm3_stdin.expected create mode 100644 tests/fixtures/cksum/untagged/sysv_multiple_files.expected create mode 100644 tests/fixtures/cksum/untagged/sysv_single_file.expected create mode 100644 tests/fixtures/cksum/untagged/sysv_stdin.expected diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index 5a8cec5ea6..a46f69302a 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -6,7 +6,7 @@ // file that was distributed with this source code. // spell-checker:ignore (ToDO) fname, algo -use clap::{crate_version, Arg, Command}; +use clap::{crate_version, Arg, ArgAction, Command}; use hex::encode; use std::ffi::OsStr; use std::fs::File; @@ -103,6 +103,7 @@ struct Options { algo_name: &'static str, digest: Box, output_bits: usize, + untagged: bool, } /// Calculate checksum @@ -161,12 +162,20 @@ where ), (ALGORITHM_OPTIONS_CRC, true) => println!("{sum} {sz}"), (ALGORITHM_OPTIONS_CRC, false) => println!("{sum} {sz} {}", filename.display()), - (ALGORITHM_OPTIONS_BLAKE2B, _) => println!("BLAKE2b ({}) = {sum}", filename.display()), - _ => println!( - "{} ({}) = {sum}", - options.algo_name.to_ascii_uppercase(), - filename.display() - ), + (ALGORITHM_OPTIONS_BLAKE2B, _) if !options.untagged => { + println!("BLAKE2b ({}) = {sum}", filename.display()); + } + _ => { + if options.untagged { + println!("{sum} {}", filename.display()); + } else { + println!( + "{} ({}) = {sum}", + options.algo_name.to_ascii_uppercase(), + filename.display() + ); + } + } } } @@ -208,8 +217,9 @@ fn digest_read( } mod options { - pub static FILE: &str = "file"; - pub static ALGORITHM: &str = "algorithm"; + pub const ALGORITHM: &str = "algorithm"; + pub const FILE: &str = "file"; + pub const UNTAGGED: &str = "untagged"; } #[uucore::main] @@ -228,6 +238,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { algo_name: name, digest: algo, output_bits: bits, + untagged: matches.get_flag(options::UNTAGGED), }; match matches.get_many::(options::FILE) { @@ -270,5 +281,11 @@ pub fn uu_app() -> Command { ALGORITHM_OPTIONS_SM3, ]), ) + .arg( + Arg::new(options::UNTAGGED) + .long(options::UNTAGGED) + .help("create a reversed style checksum, without digest type") + .action(ArgAction::SetTrue), + ) .after_help(AFTER_HELP) } diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 28c978ba6d..41ddc2ee0b 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -159,3 +159,68 @@ fn test_algorithm_stdin() { } } } + +#[test] +fn test_untagged_single_file() { + new_ucmd!() + .arg("--untagged") + .arg("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture("untagged/crc_single_file.expected"); +} + +#[test] +fn test_untagged_multiple_files() { + new_ucmd!() + .arg("--untagged") + .arg("lorem_ipsum.txt") + .arg("alice_in_wonderland.txt") + .succeeds() + .stdout_is_fixture("untagged/crc_multiple_files.expected"); +} + +#[test] +fn test_untagged_stdin() { + new_ucmd!() + .arg("--untagged") + .pipe_in_fixture("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture("untagged/crc_stdin.expected"); +} + +#[test] +fn test_untagged_algorithm_single_file() { + for algo in ALGOS { + new_ucmd!() + .arg("--untagged") + .arg(format!("--algorithm={algo}")) + .arg("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture(format!("untagged/{algo}_single_file.expected")); + } +} + +#[test] +fn test_untagged_algorithm_multiple_files() { + for algo in ALGOS { + new_ucmd!() + .arg("--untagged") + .arg(format!("--algorithm={algo}")) + .arg("lorem_ipsum.txt") + .arg("alice_in_wonderland.txt") + .succeeds() + .stdout_is_fixture(format!("untagged/{algo}_multiple_files.expected")); + } +} + +#[test] +fn test_untagged_algorithm_stdin() { + for algo in ALGOS { + new_ucmd!() + .arg("--untagged") + .arg(format!("--algorithm={algo}")) + .pipe_in_fixture("lorem_ipsum.txt") + .succeeds() + .stdout_is_fixture(format!("untagged/{algo}_stdin.expected")); + } +} diff --git a/tests/fixtures/cksum/untagged/blake2b_multiple_files.expected b/tests/fixtures/cksum/untagged/blake2b_multiple_files.expected new file mode 100644 index 0000000000..7c68c85733 --- /dev/null +++ b/tests/fixtures/cksum/untagged/blake2b_multiple_files.expected @@ -0,0 +1,2 @@ +0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 lorem_ipsum.txt +91b8b0f0868e905ad18b8ac35e4a1dacd289857b19258ab5d1e071761af758b0134ec152d4f011fe1825ca889c80c2e072ca70eb50548c25fc49a98937515af4 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/blake2b_single_file.expected b/tests/fixtures/cksum/untagged/blake2b_single_file.expected new file mode 100644 index 0000000000..1f5444c87c --- /dev/null +++ b/tests/fixtures/cksum/untagged/blake2b_single_file.expected @@ -0,0 +1 @@ +0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/blake2b_stdin.expected b/tests/fixtures/cksum/untagged/blake2b_stdin.expected new file mode 100644 index 0000000000..0892bff36d --- /dev/null +++ b/tests/fixtures/cksum/untagged/blake2b_stdin.expected @@ -0,0 +1 @@ +0e97a09189e560c3789c0bff1f020166861ef857d1fbfe4574de1842e3c06cabb9575e4af6309a166158c2b408d3c038c1b49d828b35158142cdc0396d1195c3 - diff --git a/tests/fixtures/cksum/untagged/bsd_multiple_files.expected b/tests/fixtures/cksum/untagged/bsd_multiple_files.expected new file mode 100644 index 0000000000..941a2a512f --- /dev/null +++ b/tests/fixtures/cksum/untagged/bsd_multiple_files.expected @@ -0,0 +1,2 @@ +08109 1 lorem_ipsum.txt +01814 1 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/bsd_single_file.expected b/tests/fixtures/cksum/untagged/bsd_single_file.expected new file mode 100644 index 0000000000..293ada3bd6 --- /dev/null +++ b/tests/fixtures/cksum/untagged/bsd_single_file.expected @@ -0,0 +1 @@ +08109 1 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/bsd_stdin.expected b/tests/fixtures/cksum/untagged/bsd_stdin.expected new file mode 100644 index 0000000000..4843ba0824 --- /dev/null +++ b/tests/fixtures/cksum/untagged/bsd_stdin.expected @@ -0,0 +1 @@ +08109 1 diff --git a/tests/fixtures/cksum/untagged/crc_multiple_files.expected b/tests/fixtures/cksum/untagged/crc_multiple_files.expected new file mode 100644 index 0000000000..d7a4f5b4f3 --- /dev/null +++ b/tests/fixtures/cksum/untagged/crc_multiple_files.expected @@ -0,0 +1,2 @@ +378294376 772 lorem_ipsum.txt +3805907707 302 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/crc_single_file.expected b/tests/fixtures/cksum/untagged/crc_single_file.expected new file mode 100644 index 0000000000..e9fc1ca7cf --- /dev/null +++ b/tests/fixtures/cksum/untagged/crc_single_file.expected @@ -0,0 +1 @@ +378294376 772 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/crc_stdin.expected b/tests/fixtures/cksum/untagged/crc_stdin.expected new file mode 100644 index 0000000000..28b37d0bed --- /dev/null +++ b/tests/fixtures/cksum/untagged/crc_stdin.expected @@ -0,0 +1 @@ +378294376 772 diff --git a/tests/fixtures/cksum/untagged/md5_multiple_files.expected b/tests/fixtures/cksum/untagged/md5_multiple_files.expected new file mode 100644 index 0000000000..4b63cbff7f --- /dev/null +++ b/tests/fixtures/cksum/untagged/md5_multiple_files.expected @@ -0,0 +1,2 @@ +cd724690f7dc61775dfac400a71f2caa lorem_ipsum.txt +f6fa7033e16166a9589aa1c0388ffd58 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/md5_single_file.expected b/tests/fixtures/cksum/untagged/md5_single_file.expected new file mode 100644 index 0000000000..ca9eb67859 --- /dev/null +++ b/tests/fixtures/cksum/untagged/md5_single_file.expected @@ -0,0 +1 @@ +cd724690f7dc61775dfac400a71f2caa lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/md5_stdin.expected b/tests/fixtures/cksum/untagged/md5_stdin.expected new file mode 100644 index 0000000000..f4094dcc7e --- /dev/null +++ b/tests/fixtures/cksum/untagged/md5_stdin.expected @@ -0,0 +1 @@ +cd724690f7dc61775dfac400a71f2caa - diff --git a/tests/fixtures/cksum/untagged/sha1_multiple_files.expected b/tests/fixtures/cksum/untagged/sha1_multiple_files.expected new file mode 100644 index 0000000000..1712c74091 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha1_multiple_files.expected @@ -0,0 +1,2 @@ +ab1dd0bae1d8883a3d18a66de6afbd28252cfbef lorem_ipsum.txt +22b54b2520e8b4fa59eb10719028a4e587c12d1e alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sha1_single_file.expected b/tests/fixtures/cksum/untagged/sha1_single_file.expected new file mode 100644 index 0000000000..c8e8ddca6f --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha1_single_file.expected @@ -0,0 +1 @@ +ab1dd0bae1d8883a3d18a66de6afbd28252cfbef lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sha1_stdin.expected b/tests/fixtures/cksum/untagged/sha1_stdin.expected new file mode 100644 index 0000000000..2396ed481e --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha1_stdin.expected @@ -0,0 +1 @@ +ab1dd0bae1d8883a3d18a66de6afbd28252cfbef - diff --git a/tests/fixtures/cksum/untagged/sha224_multiple_files.expected b/tests/fixtures/cksum/untagged/sha224_multiple_files.expected new file mode 100644 index 0000000000..3eb2b500a0 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha224_multiple_files.expected @@ -0,0 +1,2 @@ +3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 lorem_ipsum.txt +54c9c7d78458886418ce0845111fc49fe1c628ffd4bf3da14226ffd9 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sha224_single_file.expected b/tests/fixtures/cksum/untagged/sha224_single_file.expected new file mode 100644 index 0000000000..c5ab1f7d14 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha224_single_file.expected @@ -0,0 +1 @@ +3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sha224_stdin.expected b/tests/fixtures/cksum/untagged/sha224_stdin.expected new file mode 100644 index 0000000000..691e451b37 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha224_stdin.expected @@ -0,0 +1 @@ +3de66fbcad106e1b40ab391be56c51d2007eb1f9c655d0f4e29bfc01 - diff --git a/tests/fixtures/cksum/untagged/sha256_multiple_files.expected b/tests/fixtures/cksum/untagged/sha256_multiple_files.expected new file mode 100644 index 0000000000..a57fa2eaf1 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha256_multiple_files.expected @@ -0,0 +1,2 @@ +f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 lorem_ipsum.txt +14ab7e5a0aa3a670222744714bc96961d51012cb216225d965db71824a46e5fe alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sha256_single_file.expected b/tests/fixtures/cksum/untagged/sha256_single_file.expected new file mode 100644 index 0000000000..1b1be9516b --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha256_single_file.expected @@ -0,0 +1 @@ +f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sha256_stdin.expected b/tests/fixtures/cksum/untagged/sha256_stdin.expected new file mode 100644 index 0000000000..998db6c664 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha256_stdin.expected @@ -0,0 +1 @@ +f7c420501c50e00b309250100d67ea5e910981536b4582fe9c435bd92b3f1f02 - diff --git a/tests/fixtures/cksum/untagged/sha384_multiple_files.expected b/tests/fixtures/cksum/untagged/sha384_multiple_files.expected new file mode 100644 index 0000000000..d309034b4a --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha384_multiple_files.expected @@ -0,0 +1,2 @@ +4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb lorem_ipsum.txt +b7966c97ef84ab5858db2e0cdd33fbaf4fa8346d84de65aba001e738c242598a43272854d0073ad1099404eaa1d93766 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sha384_single_file.expected b/tests/fixtures/cksum/untagged/sha384_single_file.expected new file mode 100644 index 0000000000..88d4da5772 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha384_single_file.expected @@ -0,0 +1 @@ +4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sha384_stdin.expected b/tests/fixtures/cksum/untagged/sha384_stdin.expected new file mode 100644 index 0000000000..cde20b78b9 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha384_stdin.expected @@ -0,0 +1 @@ +4be4b90a0d0d32966992921019f24abc824dcfb8b1c408102f1f6788fb80ba9a9a4c5a7b575a3353a90a8ee719481dcb - diff --git a/tests/fixtures/cksum/untagged/sha512_multiple_files.expected b/tests/fixtures/cksum/untagged/sha512_multiple_files.expected new file mode 100644 index 0000000000..a5dafa7c32 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha512_multiple_files.expected @@ -0,0 +1,2 @@ +965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 lorem_ipsum.txt +251646d5a7eb481e0f3aced7839d78dd5e97153f822dc55938e17059c485990d85d602e2881b528b565ab6262584a69c97b068b26bda81acc9356c53c7c1c96d alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sha512_single_file.expected b/tests/fixtures/cksum/untagged/sha512_single_file.expected new file mode 100644 index 0000000000..adea498d60 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha512_single_file.expected @@ -0,0 +1 @@ +965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sha512_stdin.expected b/tests/fixtures/cksum/untagged/sha512_stdin.expected new file mode 100644 index 0000000000..dd9c968438 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sha512_stdin.expected @@ -0,0 +1 @@ +965464ab2556aad58ebc73d89ad221e559797529ecafc0f466c11795cff6d6e2c60f96a07c542cfd1f426e5e4fe0a48aa15667ba44096b213d0813cd038dfa05 - diff --git a/tests/fixtures/cksum/untagged/sm3_multiple_files.expected b/tests/fixtures/cksum/untagged/sm3_multiple_files.expected new file mode 100644 index 0000000000..de12ab0b9b --- /dev/null +++ b/tests/fixtures/cksum/untagged/sm3_multiple_files.expected @@ -0,0 +1,2 @@ +6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 lorem_ipsum.txt +d66617ae3c4e87828298dcd836f79efbab488c53b84e09c3e8e83a16c902418d alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sm3_single_file.expected b/tests/fixtures/cksum/untagged/sm3_single_file.expected new file mode 100644 index 0000000000..54d5f40d23 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sm3_single_file.expected @@ -0,0 +1 @@ +6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sm3_stdin.expected b/tests/fixtures/cksum/untagged/sm3_stdin.expected new file mode 100644 index 0000000000..6ba002b45b --- /dev/null +++ b/tests/fixtures/cksum/untagged/sm3_stdin.expected @@ -0,0 +1 @@ +6d296b805d060bfed22808df308dbb9b4317794dd4ed6740a10770a782699bc2 - diff --git a/tests/fixtures/cksum/untagged/sysv_multiple_files.expected b/tests/fixtures/cksum/untagged/sysv_multiple_files.expected new file mode 100644 index 0000000000..83a6d6d839 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sysv_multiple_files.expected @@ -0,0 +1,2 @@ +6985 2 lorem_ipsum.txt +27441 1 alice_in_wonderland.txt diff --git a/tests/fixtures/cksum/untagged/sysv_single_file.expected b/tests/fixtures/cksum/untagged/sysv_single_file.expected new file mode 100644 index 0000000000..e0f7252cbe --- /dev/null +++ b/tests/fixtures/cksum/untagged/sysv_single_file.expected @@ -0,0 +1 @@ +6985 2 lorem_ipsum.txt diff --git a/tests/fixtures/cksum/untagged/sysv_stdin.expected b/tests/fixtures/cksum/untagged/sysv_stdin.expected new file mode 100644 index 0000000000..f0fba8c815 --- /dev/null +++ b/tests/fixtures/cksum/untagged/sysv_stdin.expected @@ -0,0 +1 @@ +6985 2 From 3e7594632bbdbcb4a299603acef78818160eac2b Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 14 May 2023 21:47:58 +0200 Subject: [PATCH 302/477] ls: when facing an invalid utf-8, don't panic Fails with ``` thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "invalid-\xE0-"', src/uu/ls/src/ls.rs:1932:53 ``` --- src/uu/ls/src/ls.rs | 10 +++++++++- tests/by-util/test_ls.rs | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 9219876879..5e3a5a0784 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -1997,7 +1997,15 @@ fn should_display(entry: &DirEntry, config: &Config) -> bool { require_literal_separator: false, case_sensitive: true, }; - let file_name = entry.file_name().into_string().unwrap(); + let file_name = entry.file_name(); + // If the decoding fails, still show an incorrect rendering + let file_name = match file_name.to_str() { + Some(s) => s.to_string(), + None => { + let file_name_bytes = file_name.to_string_lossy(); + file_name_bytes.into_owned() + } + }; !config .ignore_patterns .iter() diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index d460952ed9..45ced867a4 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -7,6 +7,10 @@ use crate::common::util::TestScenario; use nix::unistd::{close, dup}; use regex::Regex; use std::collections::HashMap; +#[cfg(target_os = "linux")] +use std::ffi::OsStr; +#[cfg(target_os = "linux")] +use std::os::unix::ffi::OsStrExt; #[cfg(all(unix, feature = "chmod"))] use std::os::unix::io::IntoRawFd; use std::path::Path; @@ -3434,3 +3438,13 @@ fn test_device_number() { .succeeds() .stdout_contains(major_minor_str); } + +#[test] +#[cfg(target_os = "linux")] +fn test_invalid_utf8() { + let (at, mut ucmd) = at_and_ucmd!(); + + let filename = OsStr::from_bytes(b"-\xE0-foo"); + at.touch(filename); + ucmd.succeeds(); +} From 369a2a66314ab6f76e3ac2176edb0c0d6b5e9964 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 15 May 2023 10:12:28 +0200 Subject: [PATCH 303/477] Simplify the declaration Co-authored-by: Daniel Hofstetter --- src/uu/ls/src/ls.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 5e3a5a0784..e5ad4bcd45 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -2001,10 +2001,7 @@ fn should_display(entry: &DirEntry, config: &Config) -> bool { // If the decoding fails, still show an incorrect rendering let file_name = match file_name.to_str() { Some(s) => s.to_string(), - None => { - let file_name_bytes = file_name.to_string_lossy(); - file_name_bytes.into_owned() - } + None => file_name.to_string_lossy().into_owned(), }; !config .ignore_patterns From e6f999a32f03f820081cafa0156203c143d1de78 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 22 Apr 2023 16:25:37 +0200 Subject: [PATCH 304/477] ci: Install pre-built binaries instead of using cargo install --- .github/workflows/CICD.yml | 20 +++++++++----------- .github/workflows/GnuTests.yml | 5 ++--- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 849fb3c670..c0b1363d22 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -52,6 +52,9 @@ jobs: run: | rustup toolchain install nightly --no-self-update --profile minimal rustup default nightly + ## note: requires 'nightly' toolchain b/c `cargo-udeps` uses the `rustc` '-Z save-analysis' option + ## * ... ref: + - uses: taiki-e/install-action@cargo-udeps - uses: Swatinem/rust-cache@v2 - name: Initialize workflow variables id: vars @@ -70,12 +73,6 @@ jobs: CARGO_FEATURES_OPTION='' ; if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi outputs CARGO_FEATURES_OPTION - ## note: requires 'nightly' toolchain b/c `cargo-udeps` uses the `rustc` '-Z save-analysis' option - ## * ... ref: - - name: Install `cargo-udeps` - run: cargo install cargo-udeps - env: - RUSTUP_TOOLCHAIN: stable - name: Detect unused dependencies shell: bash run: | @@ -356,8 +353,8 @@ jobs: ## Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} --profile minimal rustup default ${{ env.RUST_MIN_SRV }} - - uses: Swatinem/rust-cache@v2 - uses: taiki-e/install-action@nextest + - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - name: Initialize workflow variables @@ -765,7 +762,6 @@ jobs: outputs CARGO_CMD # ** pass needed environment into `cross` container (iff `cross` not already configured via "Cross.toml") if [ "${CARGO_CMD}" = 'cross' ] && [ ! -e "Cross.toml" ] ; then - cargo install --version 0.2.1 cross printf "[build.env]\npassthrough = [\"CI\", \"RUST_BACKTRACE\"]\n" > Cross.toml fi # * test only library and/or binaries for arm-type targets @@ -779,6 +775,10 @@ jobs: *-pc-windows-msvc) STRIP="" ;; esac; outputs STRIP + - uses: taiki-e/install-action@v2 + if: steps.vars.outputs.CARGO_CMD == 'cross' + with: + tool: cross@v0.2.1 - name: Create all needed build/work directories shell: bash run: | @@ -1106,6 +1106,7 @@ jobs: rustup toolchain install ${{ matrix.job.toolchain }} --no-self-update --profile minimal rustup default ${{ matrix.job.toolchain }} - uses: taiki-e/install-action@nextest + - uses: taiki-e/install-action@grcov - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -1194,9 +1195,6 @@ jobs: RUSTDOCFLAGS: "-Cpanic=abort" RUST_BACKTRACE: "1" # RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }} - - name: "`grcov` ~ install" - id: build_grcov - run: cargo install grcov - name: Generate coverage data (via `grcov`) id: coverage shell: bash diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 894e29ea8a..f8a7977ddb 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -2,7 +2,7 @@ name: GnuTests # spell-checker:ignore (abbrev/names) CodeCov gnulib GnuTests Swatinem # spell-checker:ignore (jargon) submodules -# spell-checker:ignore (libs/utils) autopoint chksum gperf lcov libexpect pyinotify shopt texinfo valgrind libattr libcap +# spell-checker:ignore (libs/utils) autopoint chksum gperf lcov libexpect pyinotify shopt texinfo valgrind libattr libcap taiki-e # spell-checker:ignore (options) Ccodegen Coverflow Cpanic Zpanic # spell-checker:ignore (people) Dawid Dziurla * dawidd # spell-checker:ignore (vars) FILESET SUBDIRS XPASS @@ -323,6 +323,7 @@ jobs: rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} rustup toolchain install nightly -c rustfmt --profile minimal rustup default nightly + - uses: taiki-e/install-action@grcov - uses: Swatinem/rust-cache@v2 - name: Install dependencies run: | @@ -353,8 +354,6 @@ jobs: UU_MAKE_PROFILE=debug bash util/build-gnu.sh - name: Run GNU tests run: bash uutils/util/run-gnu-test.sh - - name: "`grcov` ~ install" - run: cargo install grcov - name: Generate coverage data (via `grcov`) id: coverage run: | From 2935e5d8f920017ed9699eafc4c4d873f654f40c Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 22 Apr 2023 16:49:49 +0200 Subject: [PATCH 305/477] ci: Use dtolnay/rust-toolchain to install the toolchain instead of the manual setup --- .github/workflows/CICD.yml | 109 ++++++++++++--------------------- .github/workflows/FixPR.yml | 18 ++---- .github/workflows/GnuTests.yml | 22 +++---- 3 files changed, 53 insertions(+), 96 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index c0b1363d22..c182843982 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -3,7 +3,7 @@ name: CICD # spell-checker:ignore (abbrev/names) CICD CodeCOV MacOS MinGW MSVC musl taiki # spell-checker:ignore (env/flags) Awarnings Ccodegen Coverflow Cpanic Dwarnings RUSTDOCFLAGS RUSTFLAGS Zpanic CARGOFLAGS # spell-checker:ignore (jargon) SHAs deps dequote softprops subshell toolchain fuzzers -# spell-checker:ignore (people) Peltoche rivy +# spell-checker:ignore (people) Peltoche rivy dtolnay # spell-checker:ignore (shell/tools) choco clippy dmake dpkg esac fakeroot fdesc fdescfs gmake grcov halium lcov libssl mkdir popd printf pushd rsync rustc rustfmt rustup shopt utmpdump xargs # spell-checker:ignore (misc) aarch alnum armhf bindir busytest coreutils defconfig DESTDIR gecos gnueabihf issuecomment maint multisize nullglob onexitbegin onexitend pell runtest Swatinem tempfile testsuite toybox uutils @@ -48,10 +48,7 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - rustup toolchain install nightly --no-self-update --profile minimal - rustup default nightly + - uses: dtolnay/rust-toolchain@nightly ## note: requires 'nightly' toolchain b/c `cargo-udeps` uses the `rustc` '-Z save-analysis' option ## * ... ref: - uses: taiki-e/install-action@cargo-udeps @@ -95,11 +92,10 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update -c rustfmt --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt - uses: Swatinem/rust-cache@v2 - name: Initialize workflow variables id: vars @@ -136,10 +132,7 @@ jobs: RUN_FOR: 60 steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - rustup toolchain install nightly --no-self-update --profile minimal - rustup default nightly + - uses: dtolnay/rust-toolchain@nightly - name: Install `cargo-fuzz` run: cargo install cargo-fuzz - uses: Swatinem/rust-cache@v2 @@ -183,11 +176,10 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update -c clippy --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: clippy - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -294,11 +286,10 @@ jobs: # - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update -c clippy --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: clippy - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -348,11 +339,10 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) - run: | - ## Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) - rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} --profile minimal - rustup default ${{ env.RUST_MIN_SRV }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_MIN_SRV }} + components: rustfmt - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache @@ -418,11 +408,7 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: "`cargo update` testing" shell: bash @@ -445,11 +431,7 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@stable - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache @@ -492,11 +474,7 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@stable - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache @@ -524,11 +502,7 @@ jobs: - { os: windows-latest , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install nightly --no-self-update --profile minimal - rustup default nightly + - uses: dtolnay/rust-toolchain@nightly - uses: taiki-e/install-action@nextest - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache @@ -553,11 +527,7 @@ jobs: - { os: ubuntu-latest , features: feat_os_unix } steps: - uses: actions/checkout@v3 - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rustup toolchain install stable --no-self-update --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -677,11 +647,10 @@ jobs: - { os: windows-latest , target: x86_64-pc-windows-msvc , features: feat_os_windows } steps: - uses: actions/checkout@v3 - - name: rust toolchain ~ install - run: | - ## rust toolchain ~ install - rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} -t ${{ matrix.job.target }} --profile minimal - rustup default ${{ env.RUST_MIN_SRV }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_MIN_SRV }} + targets: ${{ matrix.job.target }} - uses: Swatinem/rust-cache@v2 with: key: "${{ matrix.job.os }}_${{ matrix.job.target }}" @@ -762,7 +731,7 @@ jobs: outputs CARGO_CMD # ** pass needed environment into `cross` container (iff `cross` not already configured via "Cross.toml") if [ "${CARGO_CMD}" = 'cross' ] && [ ! -e "Cross.toml" ] ; then - printf "[build.env]\npassthrough = [\"CI\", \"RUST_BACKTRACE\"]\n" > Cross.toml + printf "[build.env]\npassthrough = [\"CI\", \"RUST_BACKTRACE\", \"CARGO_TERM_COLOR\"]\n" > Cross.toml fi # * test only library and/or binaries for arm-type targets unset CARGO_TEST_OPTIONS ; case '${{ matrix.job.target }}' in aarch64-* | arm-*) CARGO_TEST_OPTIONS="--bins" ;; esac; @@ -778,7 +747,7 @@ jobs: - uses: taiki-e/install-action@v2 if: steps.vars.outputs.CARGO_CMD == 'cross' with: - tool: cross@v0.2.1 + tool: cross@0.2.1 - name: Create all needed build/work directories shell: bash run: | @@ -1017,11 +986,10 @@ jobs: TEST_SUMMARY_FILE="toybox-result.json" outputs TEST_SUMMARY_FILE - uses: actions/checkout@v3 - - name: rust toolchain ~ install - run: | - ## rust toolchain ~ install - rustup toolchain install --no-self-update ${{ env.RUST_MIN_SRV }} --profile minimal - rustup default ${{ env.RUST_MIN_SRV }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_MIN_SRV }} + components: rustfmt - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 @@ -1100,11 +1068,10 @@ jobs: - { os: windows-latest , features: windows, toolchain: nightly-x86_64-pc-windows-gnu } steps: - uses: actions/checkout@v3 - - name: rust toolchain ~ install - run: | - ## rust toolchain ~ install - rustup toolchain install ${{ matrix.job.toolchain }} --no-self-update --profile minimal - rustup default ${{ matrix.job.toolchain }} + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.job.toolchain }} + components: rustfmt - uses: taiki-e/install-action@nextest - uses: taiki-e/install-action@grcov - uses: Swatinem/rust-cache@v2 diff --git a/.github/workflows/FixPR.yml b/.github/workflows/FixPR.yml index 52561fb368..e1729b1739 100644 --- a/.github/workflows/FixPR.yml +++ b/.github/workflows/FixPR.yml @@ -1,6 +1,6 @@ name: FixPR -# spell-checker:ignore Swatinem +# spell-checker:ignore Swatinem dtolnay # Trigger automated fixes for PRs being merged (with associated commits) @@ -36,11 +36,7 @@ jobs: # surface MSRV from CICD workflow RUST_MIN_SRV=$(grep -P "^\s+RUST_MIN_SRV:" .github/workflows/CICD.yml | grep -Po "(?<=\x22)\d+[.]\d+(?:[.]\d+)?(?=\x22)" ) outputs RUST_MIN_SRV - - name: Install `rust` toolchain (v${{ steps.vars.outputs.RUST_MIN_SRV }}) - run: | - ## Install `rust` toolchain (v${{ steps.vars.outputs.RUST_MIN_SRV }}) - rustup toolchain install ${{ steps.vars.outputs.RUST_MIN_SRV }} --profile minimal - rustup default ${{ steps.vars.outputs.RUST_MIN_SRV }} + - uses: dtolnay/rust-toolchain@${{ steps.vars.outputs.RUST_MIN_SRV }} - uses: Swatinem/rust-cache@v2 - name: Ensure updated 'Cargo.lock' shell: bash @@ -101,12 +97,10 @@ jobs: CARGO_FEATURES_OPTION='' ; if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi outputs CARGO_FEATURES_OPTION - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} - rustup toolchain install stable -c rustfmt --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt - uses: Swatinem/rust-cache@v2 - name: "`cargo fmt`" shell: bash diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index f8a7977ddb..97ba05bafe 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -4,7 +4,7 @@ name: GnuTests # spell-checker:ignore (jargon) submodules # spell-checker:ignore (libs/utils) autopoint chksum gperf lcov libexpect pyinotify shopt texinfo valgrind libattr libcap taiki-e # spell-checker:ignore (options) Ccodegen Coverflow Cpanic Zpanic -# spell-checker:ignore (people) Dawid Dziurla * dawidd +# spell-checker:ignore (people) Dawid Dziurla * dawidd dtolnay # spell-checker:ignore (vars) FILESET SUBDIRS XPASS # * note: to run a single test => `REPO/util/run-gnu-test.sh PATH/TO/TEST/SCRIPT` @@ -58,12 +58,10 @@ jobs: uses: actions/checkout@v3 with: path: '${{ steps.vars.outputs.path_UUTILS }}' - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} - rustup toolchain install stable -c rustfmt --profile minimal - rustup default stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt - uses: Swatinem/rust-cache@v2 - name: Checkout code (GNU coreutils) uses: actions/checkout@v3 @@ -317,12 +315,10 @@ jobs: path: 'gnu' ref: 'v9.3' submodules: recursive - - name: Install `rust` toolchain - run: | - ## Install `rust` toolchain - rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt} - rustup toolchain install nightly -c rustfmt --profile minimal - rustup default nightly + - uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly + components: rustfmt - uses: taiki-e/install-action@grcov - uses: Swatinem/rust-cache@v2 - name: Install dependencies From 4b243ba272fd625a414ea8283fdf30147fa0c5a7 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 22 Apr 2023 18:00:18 +0200 Subject: [PATCH 306/477] ci: Cleanup enviroment variables which are already set by github actions --- .github/workflows/CICD.yml | 7 ------- .github/workflows/GnuTests.yml | 1 - 2 files changed, 8 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index c182843982..fb2300ba9c 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -396,7 +396,6 @@ jobs: env: RUSTFLAGS: "-Awarnings" RUST_BACKTRACE: "1" - CARGO_TERM_COLOR: always deps: name: Dependencies @@ -445,7 +444,6 @@ jobs: run: make nextest CARGOFLAGS="--profile ci --hide-progress-bar" env: RUST_BACKTRACE: "1" - CARGO_TERM_COLOR: "always" - name: "`make install`" shell: bash run: | @@ -483,7 +481,6 @@ jobs: run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: RUST_BACKTRACE: "1" - CARGO_TERM_COLOR: "always" build_rust_nightly: name: Build/nightly @@ -511,7 +508,6 @@ jobs: run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: RUST_BACKTRACE: "1" - CARGO_TERM_COLOR: "always" compute_size: name: Binary sizes @@ -1138,7 +1134,6 @@ jobs: - name: Test uucore run: cargo nextest run --profile ci --hide-progress-bar -p uucore env: - CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" RUSTDOCFLAGS: "-Cpanic=abort" @@ -1147,7 +1142,6 @@ jobs: - name: Test run: cargo nextest run --profile ci --hide-progress-bar ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: - CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" RUSTDOCFLAGS: "-Cpanic=abort" @@ -1156,7 +1150,6 @@ jobs: - name: Test individual utilities run: cargo nextest run --profile ci --hide-progress-bar ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} env: - CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" RUSTDOCFLAGS: "-Cpanic=abort" diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 97ba05bafe..4bde3ff6ee 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -341,7 +341,6 @@ jobs: locale -a - name: Build binaries env: - CARGO_INCREMENTAL: "0" RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" RUSTDOCFLAGS: "-Cpanic=abort" run: | From a569f6167ec945a6c77285ae0102289aa56465a7 Mon Sep 17 00:00:00 2001 From: Joining7943 <111500881+Joining7943@users.noreply.github.com> Date: Sat, 22 Apr 2023 15:59:01 +0200 Subject: [PATCH 307/477] ci/gnu tests: Fix Swatinem/rust-cache action to use the correct workspace --- .github/workflows/GnuTests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 894e29ea8a..964775580a 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -65,6 +65,8 @@ jobs: rustup toolchain install stable -c rustfmt --profile minimal rustup default stable - uses: Swatinem/rust-cache@v2 + with: + workspaces: "./${{ steps.vars.outputs.path_UUTILS }} -> target" - name: Checkout code (GNU coreutils) uses: actions/checkout@v3 with: @@ -324,6 +326,8 @@ jobs: rustup toolchain install nightly -c rustfmt --profile minimal rustup default nightly - uses: Swatinem/rust-cache@v2 + with: + workspaces: "./uutils -> target" - name: Install dependencies run: | ## Install dependencies From 3870ee252ae884cc1dba53d57ee74b34c8703467 Mon Sep 17 00:00:00 2001 From: Jed Denlea Date: Sun, 14 May 2023 15:29:54 -0700 Subject: [PATCH 308/477] yes: support non-UTF-8 args Also, tighten the creation of the output buffer. Rather than copy "y\n" 8192 times, or any other input some number of times, it can be doubled in place using Vec::extend_from_within. --- Cargo.lock | 1 + src/uu/yes/Cargo.toml | 1 + src/uu/yes/src/yes.rs | 161 ++++++++++++++++++++++++++++++++------ tests/by-util/test_yes.rs | 26 +++++- 4 files changed, 161 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f8bddf940..6abb5014a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3379,6 +3379,7 @@ name = "uu_yes" version = "0.0.18" dependencies = [ "clap", + "itertools", "nix", "uucore", ] diff --git a/src/uu/yes/Cargo.toml b/src/uu/yes/Cargo.toml index fd3d9ddc0b..9d661fb0d9 100644 --- a/src/uu/yes/Cargo.toml +++ b/src/uu/yes/Cargo.toml @@ -16,6 +16,7 @@ path = "src/yes.rs" [dependencies] clap = { workspace=true } +itertools = { workspace=true } [target.'cfg(unix)'.dependencies] uucore = { workspace=true, features=["pipes", "signals"] } diff --git a/src/uu/yes/src/yes.rs b/src/uu/yes/src/yes.rs index 41bfeddca6..fd51240646 100644 --- a/src/uu/yes/src/yes.rs +++ b/src/uu/yes/src/yes.rs @@ -7,8 +7,11 @@ /* last synced with: yes (GNU coreutils) 8.13 */ -use clap::{Arg, ArgAction, Command}; -use std::borrow::Cow; +// cSpell:ignore strs + +use clap::{builder::ValueParser, Arg, ArgAction, Command}; +use std::error::Error; +use std::ffi::OsString; use std::io::{self, Write}; use uucore::error::{UResult, USimpleError}; #[cfg(unix)] @@ -28,19 +31,11 @@ const BUF_SIZE: usize = 16 * 1024; pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args)?; - let string = if let Some(values) = matches.get_many::("STRING") { - let mut result = values.fold(String::new(), |res, s| res + s + " "); - result.pop(); - result.push('\n'); - Cow::from(result) - } else { - Cow::from("y\n") - }; + let mut buffer = Vec::with_capacity(BUF_SIZE); + args_into_buffer(&mut buffer, matches.get_many::("STRING")).unwrap(); + prepare_buffer(&mut buffer); - let mut buffer = [0; BUF_SIZE]; - let bytes = prepare_buffer(&string, &mut buffer); - - match exec(bytes) { + match exec(&buffer) { Ok(()) => Ok(()), Err(err) if err.kind() == io::ErrorKind::BrokenPipe => Ok(()), Err(err) => Err(USimpleError::new(1, format!("standard output: {err}"))), @@ -51,21 +46,73 @@ pub fn uu_app() -> Command { Command::new(uucore::util_name()) .about(ABOUT) .override_usage(format_usage(USAGE)) - .arg(Arg::new("STRING").action(ArgAction::Append)) + .arg( + Arg::new("STRING") + .value_parser(ValueParser::os_string()) + .action(ArgAction::Append), + ) .infer_long_args(true) } -fn prepare_buffer<'a>(input: &'a str, buffer: &'a mut [u8; BUF_SIZE]) -> &'a [u8] { - if input.len() < BUF_SIZE / 2 { - let mut size = 0; - while size < BUF_SIZE - input.len() { - let (_, right) = buffer.split_at_mut(size); - right[..input.len()].copy_from_slice(input.as_bytes()); - size += input.len(); - } - &buffer[..size] +// Copies words from `i` into `buf`, separated by spaces. +fn args_into_buffer<'a>( + buf: &mut Vec, + i: Option>, +) -> Result<(), Box> { + // TODO: this should be replaced with let/else once available in the MSRV. + let i = if let Some(i) = i { + i } else { - input.as_bytes() + buf.extend_from_slice(b"y\n"); + return Ok(()); + }; + + // On Unix (and wasi), OsStrs are just &[u8]'s underneath... + #[cfg(any(unix, target_os = "wasi"))] + { + #[cfg(unix)] + use std::os::unix::ffi::OsStrExt; + #[cfg(target_os = "wasi")] + use std::os::wasi::ffi::OsStrExt; + + for part in itertools::intersperse(i.map(|a| a.as_bytes()), b" ") { + buf.extend_from_slice(part); + } + } + + // But, on Windows, we must hop through a String. + #[cfg(not(any(unix, target_os = "wasi")))] + { + for part in itertools::intersperse(i.map(|a| a.to_str()), Some(" ")) { + let bytes = match part { + Some(part) => part.as_bytes(), + None => return Err("arguments contain invalid UTF-8".into()), + }; + buf.extend_from_slice(bytes); + } + } + + buf.push(b'\n'); + + Ok(()) +} + +// Assumes buf holds a single output line forged from the command line arguments, copies it +// repeatedly until the buffer holds as many copies as it can under BUF_SIZE. +fn prepare_buffer(buf: &mut Vec) { + if buf.len() * 2 > BUF_SIZE { + return; + } + + assert!(!buf.is_empty()); + + let line_len = buf.len(); + let target_size = line_len * (BUF_SIZE / line_len); + + while buf.len() < target_size { + let to_copy = std::cmp::min(target_size - buf.len(), buf.len()); + debug_assert_eq!(to_copy % line_len, 0); + buf.extend_from_within(..to_copy); } } @@ -88,3 +135,67 @@ pub fn exec(bytes: &[u8]) -> io::Result<()> { stdout.write_all(bytes)?; } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_prepare_buffer() { + let tests = [ + (150, 16350), + (1000, 16000), + (4093, 16372), + (4099, 12297), + (4111, 12333), + (2, 16384), + (3, 16383), + (4, 16384), + (5, 16380), + (8192, 16384), + (8191, 16382), + (8193, 8193), + (10000, 10000), + (15000, 15000), + (25000, 25000), + ]; + + for (line, final_len) in tests { + let mut v = std::iter::repeat(b'a').take(line).collect::>(); + prepare_buffer(&mut v); + assert_eq!(v.len(), final_len); + } + } + + #[test] + fn test_args_into_buf() { + { + let mut v = Vec::with_capacity(BUF_SIZE); + args_into_buffer(&mut v, None::>).unwrap(); + assert_eq!(String::from_utf8(v).unwrap(), "y\n"); + } + + { + let mut v = Vec::with_capacity(BUF_SIZE); + args_into_buffer(&mut v, Some([OsString::from("foo")].iter())).unwrap(); + assert_eq!(String::from_utf8(v).unwrap(), "foo\n"); + } + + { + let mut v = Vec::with_capacity(BUF_SIZE); + args_into_buffer( + &mut v, + Some( + [ + OsString::from("foo"), + OsString::from("bar baz"), + OsString::from("qux"), + ] + .iter(), + ), + ) + .unwrap(); + assert_eq!(String::from_utf8(v).unwrap(), "foo bar baz qux\n"); + } + } +} diff --git a/tests/by-util/test_yes.rs b/tests/by-util/test_yes.rs index c054a6e5f3..89a68e7e1c 100644 --- a/tests/by-util/test_yes.rs +++ b/tests/by-util/test_yes.rs @@ -1,3 +1,4 @@ +use std::ffi::OsStr; use std::process::{ExitStatus, Stdio}; #[cfg(unix)] @@ -15,8 +16,10 @@ fn check_termination(result: ExitStatus) { assert!(result.success(), "yes did not exit successfully"); } +const NO_ARGS: &[&str] = &[]; + /// Run `yes`, capture some of the output, close the pipe, and verify it. -fn run(args: &[&str], expected: &[u8]) { +fn run(args: &[impl AsRef], expected: &[u8]) { let mut cmd = new_ucmd!(); let mut child = cmd.args(args).set_stdout(Stdio::piped()).run_no_wait(); let buf = child.stdout_exact_bytes(expected.len()); @@ -34,7 +37,7 @@ fn test_invalid_arg() { #[test] fn test_simple() { - run(&[], b"y\ny\ny\ny\n"); + run(NO_ARGS, b"y\ny\ny\ny\n"); } #[test] @@ -44,7 +47,7 @@ fn test_args() { #[test] fn test_long_output() { - run(&[], "y\n".repeat(512 * 1024).as_bytes()); + run(NO_ARGS, "y\n".repeat(512 * 1024).as_bytes()); } /// Test with an output that seems likely to get mangled in case of incomplete writes. @@ -88,3 +91,20 @@ fn test_piped_to_dev_full() { } } } + +#[test] +#[cfg(any(unix, target_os = "wasi"))] +fn test_non_utf8() { + #[cfg(unix)] + use std::os::unix::ffi::OsStrExt; + #[cfg(target_os = "wasi")] + use std::os::wasi::ffi::OsStrExt; + + run( + &[ + OsStr::from_bytes(b"\xbf\xff\xee"), + OsStr::from_bytes(b"bar"), + ], + &b"\xbf\xff\xee bar\n".repeat(5000), + ); +} From a1a136650b2048071bcbeadc69a5a9dabb420eb8 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 15 May 2023 21:46:07 +0200 Subject: [PATCH 309/477] remaining-gnu-error.py: split SKIP & ERROR --- util/remaining-gnu-error.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/util/remaining-gnu-error.py b/util/remaining-gnu-error.py index eda37094dd..5fd47300ab 100755 --- a/util/remaining-gnu-error.py +++ b/util/remaining-gnu-error.py @@ -19,7 +19,8 @@ types = ("/*/*.sh", "/*/*.pl", "/*/*.xpl") tests = [] -error_or_skip_tests = [] +error_tests = [] +skip_tests = [] for files in types: tests.extend(glob.glob(base + files)) @@ -58,14 +59,23 @@ def show_list(l): print("Could not find test '%s'. Maybe update the GNU repo?" % a) sys.exit(1) - # if it is SKIP or ERROR, show it - if data[d][e] in ("SKIP", "ERROR"): + # if it is SKIP, show it + if data[d][e] == "SKIP": list_of_files.remove(a) - error_or_skip_tests.append(a) + skip_tests.append(a) + # if it is ERROR, show it + if data[d][e] == "ERROR": + list_of_files.remove(a) + error_tests.append(a) -print("SKIP and ERROR tests:") -show_list(error_or_skip_tests) +print("===============") +print("SKIP tests:") +show_list(skip_tests) +print("") +print("===============") +print("ERROR tests:") +show_list(error_tests) print("") print("===============") print("FAIL tests:") From 6c1552cc202e982af3393208bb1b458f073c8597 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 15 May 2023 23:08:49 +0200 Subject: [PATCH 310/477] Document why tests are skipped --- util/why-skip.txt | 96 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 util/why-skip.txt diff --git a/util/why-skip.txt b/util/why-skip.txt new file mode 100644 index 0000000000..9f72ad7e07 --- /dev/null +++ b/util/why-skip.txt @@ -0,0 +1,96 @@ += trapping SIGPIPE is not supported = +tests/tail-2/pipe-f.sh +tests/misc/seq-epipe.sh +tests/misc/printf-surprise.sh +tests/misc/env-signal-handler.sh + += skipped test: breakpoint not hit = +tests/tail-2/inotify-race2.sh +tail-2/inotify-race.sh + += internal test failure: maybe LD_PRELOAD doesn't work? = +tests/rm/rm-readdir-fail.sh +tests/rm/r-root.sh +tests/df/skip-duplicates.sh +tests/df/no-mtab-status.sh + += LD_PRELOAD was ineffective? = +tests/cp/nfs-removal-race.sh + += failed to create hfs file system = +tests/mv/hardlink-case.sh + += temporarily disabled = +tests/mkdir/writable-under-readonly.sh + += this system lacks SMACK support = +tests/mkdir/smack-root.sh +tests/mkdir/smack-no-root.sh +tests/id/smack.sh + += this system lacks SELinux support = +tests/mkdir/selinux.sh +tests/mkdir/restorecon.sh +tests/misc/selinux.sh +tests/misc/chcon.sh +tests/install/install-Z-selinux.sh +tests/install/install-C-selinux.sh +tests/id/no-context.sh +tests/id/context.sh +tests/cp/no-ctx.sh +tests/cp/cp-a-selinux.sh + += failed to set xattr of file = +tests/misc/xattr.sh + += timeout returned 142. SIGALRM not handled? = +tests/misc/timeout-group.sh + += FULL_PARTITION_TMPDIR not defined = +tests/misc/tac-continue.sh + += can't get window size = +tests/misc/stty-row-col.sh + += The Swedish locale with blank thousands separator is unavailable. = +tests/misc/sort-h-thousands-sep.sh + += this shell lacks ulimit support = +tests/misc/csplit-heap.sh + += multicall binary is disabled = +tests/misc/coreutils.sh + += your ls doesn't call capget = +tests/ls/no-cap.sh + + += not running on GNU/Hurd = +tests/id/gnu-zero-uids.sh + += file system cannot represent big timestamps = +tests/du/bigtime.sh + += no rootfs in mtab = +tests/df/skip-rootfs.sh + += insufficient mount/ext2 support = +tests/df/problematic-chars.sh +tests/cp/cp-mv-enotsup-xattr.sh + += 512 byte aligned O_DIRECT is not supported on this (file) system = +tests/dd/direct.sh + += skipped test: /usr/bin/touch -m -d '1998-01-15 23:00' didn't work = +tests/misc/ls-time.sh + += requires controlling input terminal = +tests/misc/stty-pairs.sh +tests/misc/stty.sh +tests/misc/stty-invalid.sh + += insufficient SEEK_DATA support = +tests/cp/sparse-perf.sh +tests/cp/sparse-extents.sh +tests/cp/sparse-extents-2.sh +tests/cp/sparse-2.sh From 354cb0341c09fe8bd9fd5c9f96b634f71a275f0c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 10:35:39 +0000 Subject: [PATCH 311/477] chore(deps): update rust crate zip to 0.6.6 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6abb5014a6..2a189c8193 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3667,9 +3667,9 @@ checksum = "2a599daf1b507819c1121f0bf87fa37eb19daac6aff3aefefd4e6e2e0f2020fc" [[package]] name = "zip" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e92305c174683d78035cbf1b70e18db6329cc0f1b9cae0a52ca90bf5bfe7125" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" dependencies = [ "byteorder", "crc32fast", diff --git a/Cargo.toml b/Cargo.toml index c5d2a760bd..24bbafab2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -331,7 +331,7 @@ walkdir = "2.3" winapi-util = "0.1.5" windows-sys = { version="0.45.0", default-features=false } xattr = "1.0.0" -zip = { version = "0.6.5", default_features=false, features=["deflate"] } +zip = { version = "0.6.6", default_features=false, features=["deflate"] } hex = "0.4.3" md-5 = "0.10.5" From 11b72d3849745cbdd3fb0c05c4811c94f841b30e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 11:30:17 +0000 Subject: [PATCH 312/477] chore(deps): update rust crate sm3 to 0.4.2 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a189c8193..a9f9532b65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2158,9 +2158,9 @@ dependencies = [ [[package]] name = "sm3" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f943a7c5e3089f2bd046221d1e9f4fa59396bf0fe966360983649683086215da" +checksum = "ebb9a3b702d0a7e33bc4d85a14456633d2b165c2ad839c5fd9a8417c1ab15860" dependencies = [ "digest", ] diff --git a/Cargo.toml b/Cargo.toml index 24bbafab2a..8f62a87f6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -340,7 +340,7 @@ sha2 = "0.10.6" sha3 = "0.10.8" blake2b_simd = "1.0.1" blake3 = "1.3.3" -sm3 = "0.4.1" +sm3 = "0.4.2" digest = "0.10.6" uucore = { version=">=0.0.18", package="uucore", path="src/uucore" } From 5b715b4085005d13b014456debd932e9f625d0db Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 16 May 2023 16:10:18 +0200 Subject: [PATCH 313/477] Add "spell-checker:ignore" line --- util/why-skip.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/why-skip.txt b/util/why-skip.txt index 9f72ad7e07..c790311c13 100644 --- a/util/why-skip.txt +++ b/util/why-skip.txt @@ -1,3 +1,5 @@ +# spell-checker:ignore epipe readdir restorecon SIGALRM capget bigtime rootfs enotsup + = trapping SIGPIPE is not supported = tests/tail-2/pipe-f.sh tests/misc/seq-epipe.sh From b676875c0c92ae84f74c03d551c7e6fdf2eb43d1 Mon Sep 17 00:00:00 2001 From: Ideflop Date: Wed, 17 May 2023 20:38:03 +0200 Subject: [PATCH 314/477] more: add arguments print over and clean print --- src/uu/more/src/more.rs | 81 +++++++++++++++++++++++++++----------- tests/by-util/test_more.rs | 9 +++++ 2 files changed, 67 insertions(+), 23 deletions(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 6cf9df1ab1..2b6bde9dab 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -14,13 +14,14 @@ use std::{ time::Duration, }; -use clap::{crate_version, Arg, ArgAction, Command}; +use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; use crossterm::event::KeyEventKind; use crossterm::{ + cursor::MoveTo, event::{self, Event, KeyCode, KeyEvent, KeyModifiers}, execute, queue, style::Attribute, - terminal, + terminal::{self, Clear, ClearType}, }; use is_terminal::IsTerminal; @@ -51,12 +52,34 @@ pub mod options { const MULTI_FILE_TOP_PROMPT: &str = "::::::::::::::\n{}\n::::::::::::::\n"; +struct Options { + silent: bool, + clean_print: bool, + print_over: bool, +} + +impl Options { + fn from(matches: &ArgMatches) -> Self { + Self { + silent: matches.get_flag(options::SILENT), + clean_print: matches.get_flag(options::CLEAN_PRINT), + print_over: matches.get_flag(options::PRINT_OVER), + } + } +} + #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let matches = uu_app().get_matches_from(args); + let args = args.collect_lossy(); + let matches = match uu_app().try_get_matches_from(&args) { + Ok(m) => m, + Err(e) => return Err(e.into()), + }; + + let options = Options::from(&matches); let mut buff = String::new(); - let silent = matches.get_flag(options::SILENT); + if let Some(files) = matches.get_many::(options::FILES) { let mut stdout = setup_term(); let length = files.len(); @@ -83,14 +106,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } let mut reader = BufReader::new(File::open(file).unwrap()); reader.read_to_string(&mut buff).unwrap(); - more(&buff, &mut stdout, next_file.copied(), silent)?; + more(&buff, &mut stdout, next_file.copied(), &options)?; buff.clear(); } reset_term(&mut stdout); } else if !std::io::stdin().is_terminal() { stdin().read_to_string(&mut buff).unwrap(); let mut stdout = setup_term(); - more(&buff, &mut stdout, None, silent)?; + more(&buff, &mut stdout, None, &options)?; reset_term(&mut stdout); } else { return Err(UUsageError::new(1, "bad usage")); @@ -104,6 +127,13 @@ pub fn uu_app() -> Command { .override_usage(format_usage(USAGE)) .version(crate_version!()) .infer_long_args(true) + .arg( + Arg::new(options::PRINT_OVER) + .short('c') + .long(options::PRINT_OVER) + .help("Do not scroll, display text and clean line ends") + .action(ArgAction::SetTrue), + ) .arg( Arg::new(options::SILENT) .short('d') @@ -111,6 +141,13 @@ pub fn uu_app() -> Command { .help("Display help instead of ringing bell") .action(ArgAction::SetTrue), ) + .arg( + Arg::new(options::CLEAN_PRINT) + .short('p') + .long(options::CLEAN_PRINT) + .help("Do not scroll, clean screen and display text") + .action(ArgAction::SetTrue), + ) // The commented arguments below are unimplemented: /* .arg( @@ -125,18 +162,6 @@ pub fn uu_app() -> Command { .long(options::NO_PAUSE) .help("Suppress pause after form feed"), ) - .arg( - Arg::new(options::PRINT_OVER) - .short('c') - .long(options::PRINT_OVER) - .help("Do not scroll, display text and clean line ends"), - ) - .arg( - Arg::new(options::CLEAN_PRINT) - .short('p') - .long(options::CLEAN_PRINT) - .help("Do not scroll, clean screen and display text"), - ) .arg( Arg::new(options::SQUEEZE) .short('s') @@ -209,7 +234,7 @@ fn setup_term() -> usize { fn reset_term(stdout: &mut std::io::Stdout) { terminal::disable_raw_mode().unwrap(); // Clear the prompt - queue!(stdout, terminal::Clear(terminal::ClearType::CurrentLine)).unwrap(); + queue!(stdout, terminal::Clear(ClearType::CurrentLine)).unwrap(); // Move cursor to the beginning without printing new line print!("\r"); stdout.flush().unwrap(); @@ -219,11 +244,16 @@ fn reset_term(stdout: &mut std::io::Stdout) { #[inline(always)] fn reset_term(_: &mut usize) {} -fn more(buff: &str, stdout: &mut Stdout, next_file: Option<&str>, silent: bool) -> UResult<()> { +fn more( + buff: &str, + stdout: &mut Stdout, + next_file: Option<&str>, + options: &Options, +) -> UResult<()> { let (cols, rows) = terminal::size().unwrap(); let lines = break_buff(buff, usize::from(cols)); - let mut pager = Pager::new(rows, lines, next_file, silent); + let mut pager = Pager::new(rows, lines, next_file, options); pager.draw(stdout, None); if pager.should_close() { return Ok(()); @@ -303,6 +333,11 @@ fn more(buff: &str, stdout: &mut Stdout, next_file: Option<&str>, silent: bool) _ => continue, } + if options.clean_print { + execute!(std::io::stdout(), Clear(ClearType::Purge), MoveTo(0, 0)).unwrap(); + } else if options.print_over { + execute!(std::io::stdout(), Clear(ClearType::All), MoveTo(0, 0)).unwrap(); + } pager.draw(stdout, wrong_key); } } @@ -320,7 +355,7 @@ struct Pager<'a> { } impl<'a> Pager<'a> { - fn new(rows: u16, lines: Vec, next_file: Option<&'a str>, silent: bool) -> Self { + fn new(rows: u16, lines: Vec, next_file: Option<&'a str>, options: &Options) -> Self { let line_count = lines.len(); Self { upper_mark: 0, @@ -328,7 +363,7 @@ impl<'a> Pager<'a> { lines, next_file, line_count, - silent, + silent: options.silent, } } diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index bdf80a27c1..5b4fa1ca3b 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -10,6 +10,15 @@ fn test_more_no_arg() { } } +#[test] +fn test_valid_arg() { + new_ucmd!().arg("-c").succeeds().code_is(0); + new_ucmd!().arg("--print-over").succeeds().code_is(0); + + new_ucmd!().arg("-p").succeeds().code_is(0); + new_ucmd!().arg("--clean-print").succeeds().code_is(0); +} + #[test] fn test_more_dir_arg() { // Run the test only if there's a valid terminal, else do nothing From db5696f64b8743b2b908bc26ae5fbd7e3c42895f Mon Sep 17 00:00:00 2001 From: Jed Denlea Date: Tue, 16 May 2023 19:20:24 -0700 Subject: [PATCH 315/477] rm: support non-UTF-8 paths Addresses #4868. --- src/uu/rm/src/rm.rs | 12 +++++++----- tests/by-util/test_rm.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 7937faf745..2a8a57be06 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -7,8 +7,9 @@ // spell-checker:ignore (path) eacces -use clap::{crate_version, parser::ValueSource, Arg, ArgAction, Command}; +use clap::{builder::ValueParser, crate_version, parser::ValueSource, Arg, ArgAction, Command}; use std::collections::VecDeque; +use std::ffi::{OsStr, OsString}; use std::fs::{self, File, Metadata}; use std::io::ErrorKind; use std::ops::BitOr; @@ -59,9 +60,9 @@ static ARG_FILES: &str = "files"; pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; - let files: Vec = matches - .get_many::(ARG_FILES) - .map(|v| v.map(ToString::to_string).collect()) + let files: Vec<&OsStr> = matches + .get_many::(ARG_FILES) + .map(|v| v.map(OsString::as_os_str).collect()) .unwrap_or_default(); let force_flag = matches.get_flag(OPT_FORCE); @@ -231,13 +232,14 @@ pub fn uu_app() -> Command { .arg( Arg::new(ARG_FILES) .action(ArgAction::Append) + .value_parser(ValueParser::os_string()) .num_args(1..) .value_hint(clap::ValueHint::AnyPath), ) } // TODO: implement one-file-system (this may get partially implemented in walkdir) -fn remove(files: &[String], options: &Options) -> bool { +fn remove(files: &[&OsStr], options: &Options) -> bool { let mut had_err = false; for filename in files { diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 3a2ee0b44d..a5c342ffe7 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -54,6 +54,8 @@ fn test_rm_interactive() { at.touch(file_a); at.touch(file_b); + assert!(at.file_exists(file_a)); + assert!(at.file_exists(file_b)); scene .ucmd() @@ -84,6 +86,11 @@ fn test_rm_force() { let file_a = "test_rm_force_a"; let file_b = "test_rm_force_b"; + at.touch(file_a); + at.touch(file_b); + assert!(at.file_exists(file_a)); + assert!(at.file_exists(file_b)); + ucmd.arg("-f") .arg(file_a) .arg(file_b) @@ -100,6 +107,11 @@ fn test_rm_force_multiple() { let file_a = "test_rm_force_a"; let file_b = "test_rm_force_b"; + at.touch(file_a); + at.touch(file_b); + assert!(at.file_exists(file_a)); + assert!(at.file_exists(file_b)); + ucmd.arg("-f") .arg("-f") .arg("-f") @@ -578,3 +590,24 @@ fn test_fifo_removal() { .timeout(Duration::from_secs(2)) .succeeds(); } + +#[test] +#[cfg(any(unix, target_os = "wasi"))] +#[cfg(not(target_os = "macos"))] +fn test_non_utf8() { + use std::ffi::OsStr; + #[cfg(unix)] + use std::os::unix::ffi::OsStrExt; + #[cfg(target_os = "wasi")] + use std::os::wasi::ffi::OsStrExt; + + let file = OsStr::from_bytes(b"not\xffutf8"); // spell-checker:disable-line + + let (at, mut ucmd) = at_and_ucmd!(); + + at.touch(file); + assert!(at.file_exists(file)); + + ucmd.arg(file).succeeds(); + assert!(!at.file_exists(file)); +} From 1a12ffaa796e3d57d90a784ff3d276b5e4ae335c Mon Sep 17 00:00:00 2001 From: Ideflop Date: Thu, 18 May 2023 09:18:33 +0200 Subject: [PATCH 316/477] Add check for terminal in test_valid_arg() function --- tests/by-util/test_more.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index 5b4fa1ca3b..80d3c3da4c 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -12,11 +12,14 @@ fn test_more_no_arg() { #[test] fn test_valid_arg() { - new_ucmd!().arg("-c").succeeds().code_is(0); - new_ucmd!().arg("--print-over").succeeds().code_is(0); + if std::io::stdout().is_terminal() { + new_ucmd!().arg("-c").succeeds().code_is(0); + new_ucmd!().arg("--print-over").succeeds().code_is(0); - new_ucmd!().arg("-p").succeeds().code_is(0); - new_ucmd!().arg("--clean-print").succeeds().code_is(0); + new_ucmd!().arg("-p").succeeds().code_is(0); + new_ucmd!().arg("--clean-print").succeeds().code_is(0); + } else { + } } #[test] From 35b5fd6a40db2037a9bf36de848ccc2dd05b6cdf Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 5 May 2023 13:44:50 +0200 Subject: [PATCH 317/477] mktemp -t foo.XXXX should create in TMPDIR --- src/uu/mktemp/src/mktemp.rs | 7 ++++++- tests/by-util/test_mktemp.rs | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 6a3f6f21b1..997c11dce3 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -191,7 +191,12 @@ impl Options { (tmpdir, template.to_string()) } Some(template) => { - let tmpdir = matches.get_one::(OPT_TMPDIR).map(String::from); + let tmpdir = if matches.get_flag(OPT_T) { + // mktemp -t foo.xxx should export in TMPDIR + Some(env::temp_dir().display().to_string()) + } else { + matches.get_one::(OPT_TMPDIR).map(String::from) + }; (tmpdir, template.to_string()) } } diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 907f8cf1de..fecbe98cee 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -857,3 +857,18 @@ fn test_default_missing_value() { let scene = TestScenario::new(util_name!()); scene.ucmd().arg("-d").arg("--tmpdir").succeeds(); } + +#[test] +fn test_default_issue_4821_t_tmpdir() { + let scene = TestScenario::new(util_name!()); + let pathname = scene.fixtures.as_string(); + let result = scene + .ucmd() + .env(TMPDIR, &pathname) + .arg("-t") + .arg("foo.XXXX") + .succeeds(); + let stdout = result.stdout_str(); + println!("stdout = {stdout}"); + assert!(stdout.contains(&pathname)); +} From cd189b239189e155f8ee84fc2b51cab6ba2e7224 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 15 May 2023 21:32:35 +0200 Subject: [PATCH 318/477] Fix mktemp -t -p ~/projects/playground foo.XXXX --- src/uu/mktemp/src/mktemp.rs | 4 +++- tests/by-util/test_mktemp.rs | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 997c11dce3..20498337ae 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -191,7 +191,9 @@ impl Options { (tmpdir, template.to_string()) } Some(template) => { - let tmpdir = if matches.get_flag(OPT_T) { + let tmpdir = if matches.contains_id(OPT_TMPDIR) { + matches.get_one::(OPT_TMPDIR).map(String::from) + } else if matches.get_flag(OPT_T) { // mktemp -t foo.xxx should export in TMPDIR Some(env::temp_dir().display().to_string()) } else { diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index fecbe98cee..788f1f14a1 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -872,3 +872,19 @@ fn test_default_issue_4821_t_tmpdir() { println!("stdout = {stdout}"); assert!(stdout.contains(&pathname)); } + +#[test] +fn test_default_issue_4821_t_tmpdir_p() { + let scene = TestScenario::new(util_name!()); + let pathname = scene.fixtures.as_string(); + let result = scene + .ucmd() + .arg("-t") + .arg("-p") + .arg(&pathname) + .arg("foo.XXXX") + .succeeds(); + let stdout = result.stdout_str(); + println!("stdout = {stdout}"); + assert!(stdout.contains(&pathname)); +} From 932f44d3dcbc80294f3f4daf91957472aead9d49 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 18 May 2023 15:24:49 +0200 Subject: [PATCH 319/477] more: support PageDown/PageUp keys --- src/uu/more/src/more.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 6cf9df1ab1..52d181b792 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -257,6 +257,11 @@ fn more(buff: &str, stdout: &mut Stdout, next_file: Option<&str>, silent: bool) modifiers: KeyModifiers::NONE, .. }) + | Event::Key(KeyEvent { + code: KeyCode::PageDown, + modifiers: KeyModifiers::NONE, + .. + }) | Event::Key(KeyEvent { code: KeyCode::Char(' '), modifiers: KeyModifiers::NONE, @@ -272,6 +277,11 @@ fn more(buff: &str, stdout: &mut Stdout, next_file: Option<&str>, silent: bool) code: KeyCode::Up, modifiers: KeyModifiers::NONE, .. + }) + | Event::Key(KeyEvent { + code: KeyCode::PageUp, + modifiers: KeyModifiers::NONE, + .. }) => { pager.page_up(); } From b05c05eb4592533a35b21f79c522b8c87878cbf7 Mon Sep 17 00:00:00 2001 From: John Shin Date: Thu, 18 May 2023 18:25:41 -0700 Subject: [PATCH 320/477] mkdir: chmod of parent directories created by -p --- src/uu/mkdir/src/mkdir.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index 9f490ecf9b..f48f53bee3 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -20,7 +20,7 @@ use uucore::mode; use uucore::{display::Quotable, fs::dir_strip_dot_for_creation}; use uucore::{format_usage, help_about, help_section, help_usage, show, show_if_err}; -static DEFAULT_PERM: u32 = 0o755; +static DEFAULT_PERM: u32 = 0o777; const ABOUT: &str = help_about!("mkdir.md"); const USAGE: &str = help_usage!("mkdir.md"); @@ -41,7 +41,7 @@ fn get_mode(_matches: &ArgMatches, _mode_had_minus_prefix: bool) -> Result Result { let digits: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; - // Translate a ~str in octal form to u16, default to 755 + // Translate a ~str in octal form to u16, default to 777 // Not tested on Windows let mut new_mode = DEFAULT_PERM; match matches.get_one::(options::MODE) { @@ -158,7 +158,7 @@ fn exec(dirs: ValuesRef, recursive: bool, mode: u32, verbose: bool) -> } fn mkdir(path: &Path, recursive: bool, mode: u32, verbose: bool) -> UResult<()> { - create_dir(path, recursive, verbose)?; + create_dir(path, recursive, verbose, false)?; chmod(path, mode) } @@ -179,7 +179,7 @@ fn chmod(_path: &Path, _mode: u32) -> UResult<()> { Ok(()) } -fn create_dir(path: &Path, recursive: bool, verbose: bool) -> UResult<()> { +fn create_dir(path: &Path, recursive: bool, verbose: bool, is_parent: bool) -> UResult<()> { if path.exists() && !recursive { return Err(USimpleError::new( 1, @@ -192,7 +192,7 @@ fn create_dir(path: &Path, recursive: bool, verbose: bool) -> UResult<()> { if recursive { match path.parent() { - Some(p) => create_dir(p, recursive, verbose)?, + Some(p) => create_dir(p, recursive, verbose, true)?, None => { USimpleError::new(1, "failed to create whole tree"); } @@ -207,6 +207,11 @@ fn create_dir(path: &Path, recursive: bool, verbose: bool) -> UResult<()> { path.quote() ); } + if is_parent { + // directories created by -p have permission bits set to '=rwx,u+wx', + // which is umask modified by 'u+wx' + chmod(path, (!mode::get_umask() & 0o0777) | 0o0300)?; + } Ok(()) } Err(_) if path.is_dir() => Ok(()), From 5e1a6c1f137f986a3fd089e5d08ce7696aceba33 Mon Sep 17 00:00:00 2001 From: John Shin Date: Thu, 18 May 2023 19:12:38 -0700 Subject: [PATCH 321/477] mkdir: add test for checking mode of parent dirs with -p --- tests/by-util/test_mkdir.rs | 68 ++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index e2ac763b44..08b3cb1ede 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -71,6 +71,72 @@ fn test_mkdir_dup_dir_parent() { scene.ucmd().arg("-p").arg(TEST_DIR6).succeeds(); } +#[cfg(not(windows))] +#[test] +fn test_mkdir_parent_mode() { + let (at, mut ucmd) = at_and_ucmd!(); + + let default_umask: mode_t = 0o022; + let original_umask = unsafe { umask(default_umask) }; + + ucmd.arg("-p").arg("a/b").succeeds().no_stderr().no_stdout(); + + assert!(at.dir_exists("a")); + // parents created by -p have permissions set to "=rwx,u+wx" + assert_eq!( + at.metadata("a").permissions().mode(), + ((!default_umask & 0o777) | 0o300) + 0o40000 + ); + assert!(at.dir_exists("a/b")); + // sub directory's permission is determined only by the umask + assert_eq!( + at.metadata("a/b").permissions().mode(), + (!default_umask & 0o777) + 0o40000 + ); + + unsafe { + umask(original_umask); + } +} + +#[cfg(not(windows))] +#[test] +fn test_mkdir_parent_mode_check_existing_parent() { + let (at, mut ucmd) = at_and_ucmd!(); + + let default_umask: mode_t = 0o022; + let original_umask = unsafe { umask(default_umask) }; + + at.mkdir("a"); + + ucmd.arg("-p") + .arg("a/b/c") + .succeeds() + .no_stderr() + .no_stdout(); + + assert!(at.dir_exists("a")); + // parent dirs that already exist do not get their permissions modified + assert_eq!( + at.metadata("a").permissions().mode(), + (!default_umask & 0o777) + 0o40000 + ); + assert!(at.dir_exists("a/b")); + assert_eq!( + at.metadata("a/b").permissions().mode(), + ((!default_umask & 0o777) | 0o300) + 0o40000 + ); + assert!(at.dir_exists("a/b/c")); + assert_eq!( + at.metadata("a/b/c").permissions().mode(), + (!default_umask & 0o777) + 0o40000 + ); + + unsafe { + umask(original_umask); + } +} + #[test] fn test_mkdir_dup_file() { let scene = TestScenario::new(util_name!()); @@ -98,7 +164,7 @@ fn test_symbolic_alteration() { ucmd.arg("-m").arg("-w").arg(TEST_DIR1).succeeds(); let perms = at.metadata(TEST_DIR1).permissions().mode(); - assert_eq!(perms, 0o40555); + assert_eq!(perms, 0o40577); } #[test] From f592dff46a1e226480a19635abdadb18287ce7a1 Mon Sep 17 00:00:00 2001 From: John Shin Date: Thu, 18 May 2023 19:23:08 -0700 Subject: [PATCH 322/477] mkdir: skip setting dir permissions on windows --- src/uu/mkdir/src/mkdir.rs | 2 ++ tests/by-util/test_mkdir.rs | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index f48f53bee3..04281a4554 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -179,6 +179,7 @@ fn chmod(_path: &Path, _mode: u32) -> UResult<()> { Ok(()) } +#[allow(unused_variables)] fn create_dir(path: &Path, recursive: bool, verbose: bool, is_parent: bool) -> UResult<()> { if path.exists() && !recursive { return Err(USimpleError::new( @@ -207,6 +208,7 @@ fn create_dir(path: &Path, recursive: bool, verbose: bool, is_parent: bool) -> U path.quote() ); } + #[cfg(not(windows))] if is_parent { // directories created by -p have permission bits set to '=rwx,u+wx', // which is umask modified by 'u+wx' diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index 08b3cb1ede..409334c2eb 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -84,13 +84,13 @@ fn test_mkdir_parent_mode() { assert!(at.dir_exists("a")); // parents created by -p have permissions set to "=rwx,u+wx" assert_eq!( - at.metadata("a").permissions().mode(), + at.metadata("a").permissions().mode() as mode_t, ((!default_umask & 0o777) | 0o300) + 0o40000 ); assert!(at.dir_exists("a/b")); // sub directory's permission is determined only by the umask assert_eq!( - at.metadata("a/b").permissions().mode(), + at.metadata("a/b").permissions().mode() as mode_t, (!default_umask & 0o777) + 0o40000 ); @@ -118,17 +118,17 @@ fn test_mkdir_parent_mode_check_existing_parent() { assert!(at.dir_exists("a")); // parent dirs that already exist do not get their permissions modified assert_eq!( - at.metadata("a").permissions().mode(), + at.metadata("a").permissions().mode() as mode_t, (!default_umask & 0o777) + 0o40000 ); assert!(at.dir_exists("a/b")); assert_eq!( - at.metadata("a/b").permissions().mode(), + at.metadata("a/b").permissions().mode() as mode_t, ((!default_umask & 0o777) | 0o300) + 0o40000 ); assert!(at.dir_exists("a/b/c")); assert_eq!( - at.metadata("a/b/c").permissions().mode(), + at.metadata("a/b/c").permissions().mode() as mode_t, (!default_umask & 0o777) + 0o40000 ); From 5be5f850434029cb27d2c87d47f739eb088caa81 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 19 May 2023 10:38:04 +0200 Subject: [PATCH 323/477] mktemp: simplify test_default_missing_value() --- tests/by-util/test_mktemp.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 788f1f14a1..57562ba0b8 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -854,8 +854,7 @@ fn test_nonexistent_dir_prefix() { #[test] fn test_default_missing_value() { - let scene = TestScenario::new(util_name!()); - scene.ucmd().arg("-d").arg("--tmpdir").succeeds(); + new_ucmd!().arg("-d").arg("--tmpdir").succeeds(); } #[test] From a01dc20c30da066f9e2785b7043d5fe0d09ad175 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 19 May 2023 10:42:52 +0200 Subject: [PATCH 324/477] mktemp: remove TEST_TEMPLATE9 --- tests/by-util/test_mktemp.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 57562ba0b8..f26f82bc25 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -23,7 +23,6 @@ static TEST_TEMPLATE7: &str = "XXXtemplate"; // spell-checker:disable-line static TEST_TEMPLATE8: &str = "tempXXXl/ate"; #[cfg(windows)] static TEST_TEMPLATE8: &str = "tempXXXl\\ate"; -static TEST_TEMPLATE9: &str = "a.XXXX"; #[cfg(not(windows))] const TMPDIR: &str = "TMPDIR"; @@ -573,9 +572,7 @@ fn test_template_path_separator() { /// Test that a prefix with a point is valid. #[test] fn test_prefix_template_separator() { - new_ucmd!() - .args(&["-p", ".", "-t", TEST_TEMPLATE9]) - .succeeds(); + new_ucmd!().args(&["-p", ".", "-t", "a.XXXX"]).succeeds(); } #[test] From 9e8575dadd6501117147499728711211c1626a03 Mon Sep 17 00:00:00 2001 From: John Shin Date: Fri, 19 May 2023 08:13:33 -0700 Subject: [PATCH 325/477] mkdir: add documentation for the use of allow attribute --- src/uu/mkdir/src/mkdir.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index 04281a4554..a94439af5a 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -179,6 +179,7 @@ fn chmod(_path: &Path, _mode: u32) -> UResult<()> { Ok(()) } +// `is_parent` argument is not used on windows #[allow(unused_variables)] fn create_dir(path: &Path, recursive: bool, verbose: bool, is_parent: bool) -> UResult<()> { if path.exists() && !recursive { From 698fafad68b1d2ecb4fd807660e2641711913a24 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 19 May 2023 16:53:20 +0200 Subject: [PATCH 326/477] mktemp: prioritize TMPDIR over -p when using -t --- src/uu/mktemp/src/mktemp.rs | 9 ++++++++- tests/by-util/test_mktemp.rs | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 20498337ae..fc360d0f5a 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -42,6 +42,11 @@ static OPT_T: &str = "t"; static ARG_TEMPLATE: &str = "template"; +#[cfg(not(windows))] +const TMPDIR_ENV_VAR: &str = "TMPDIR"; +#[cfg(windows)] +const TMPDIR_ENV_VAR: &str = "TMP"; + #[derive(Debug)] enum MkTempError { PersistError(PathBuf), @@ -191,7 +196,9 @@ impl Options { (tmpdir, template.to_string()) } Some(template) => { - let tmpdir = if matches.contains_id(OPT_TMPDIR) { + let tmpdir = if env::var(TMPDIR_ENV_VAR).is_ok() && matches.get_flag(OPT_T) { + env::var(TMPDIR_ENV_VAR).ok() + } else if matches.contains_id(OPT_TMPDIR) { matches.get_one::(OPT_TMPDIR).map(String::from) } else if matches.get_flag(OPT_T) { // mktemp -t foo.xxx should export in TMPDIR diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index f26f82bc25..6bcb37f459 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -884,3 +884,20 @@ fn test_default_issue_4821_t_tmpdir_p() { println!("stdout = {stdout}"); assert!(stdout.contains(&pathname)); } + +#[test] +fn test_t_ensure_tmpdir_has_higher_priority_than_p() { + let scene = TestScenario::new(util_name!()); + let pathname = scene.fixtures.as_string(); + let result = scene + .ucmd() + .env(TMPDIR, &pathname) + .arg("-t") + .arg("-p") + .arg("should_not_attempt_to_write_in_this_nonexisting_dir") + .arg("foo.XXXX") + .succeeds(); + let stdout = result.stdout_str(); + println!("stdout = {stdout}"); + assert!(stdout.contains(&pathname)); +} From 2d1a9f6709c631319f379fcf4a03c7f3aeba7112 Mon Sep 17 00:00:00 2001 From: Ideflop <94184575+Ideflop@users.noreply.github.com> Date: Sat, 20 May 2023 08:56:50 +0200 Subject: [PATCH 327/477] fix behavior of -c and -p commands --- src/uu/more/src/more.rs | 11 ++++++++--- tests/by-util/test_more.rs | 8 ++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 2b6bde9dab..08e6fdd70c 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -333,9 +333,14 @@ fn more( _ => continue, } - if options.clean_print { - execute!(std::io::stdout(), Clear(ClearType::Purge), MoveTo(0, 0)).unwrap(); - } else if options.print_over { + if options.print_over { + execute!( + std::io::stdout(), + MoveTo(0, 0), + Clear(ClearType::FromCursorDown) + ) + .unwrap(); + } else if options.clean_print { execute!(std::io::stdout(), Clear(ClearType::All), MoveTo(0, 0)).unwrap(); } pager.draw(stdout, wrong_key); diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index 80d3c3da4c..bffa88cab5 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -13,11 +13,11 @@ fn test_more_no_arg() { #[test] fn test_valid_arg() { if std::io::stdout().is_terminal() { - new_ucmd!().arg("-c").succeeds().code_is(0); - new_ucmd!().arg("--print-over").succeeds().code_is(0); + new_ucmd!().arg("-c").succeeds(); + new_ucmd!().arg("--print-over").succeeds(); - new_ucmd!().arg("-p").succeeds().code_is(0); - new_ucmd!().arg("--clean-print").succeeds().code_is(0); + new_ucmd!().arg("-p").succeeds(); + new_ucmd!().arg("--clean-print").succeeds(); } else { } } From e844bdfebec58d1d791b91b36468f666a3c177bb Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 20 May 2023 16:26:11 +0200 Subject: [PATCH 328/477] more: remove empty "else"-branches in tests --- tests/by-util/test_more.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index bffa88cab5..cb12343fa0 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -6,7 +6,6 @@ fn test_more_no_arg() { // Reading from stdin is now supported, so this must succeed if std::io::stdout().is_terminal() { new_ucmd!().succeeds(); - } else { } } @@ -18,7 +17,6 @@ fn test_valid_arg() { new_ucmd!().arg("-p").succeeds(); new_ucmd!().arg("--clean-print").succeeds(); - } else { } } @@ -32,6 +30,5 @@ fn test_more_dir_arg() { .arg(".") .fails() .usage_error("'.' is a directory."); - } else { } } From c3b06e10a65da393ae7d82153f7acaca6ad1eef5 Mon Sep 17 00:00:00 2001 From: Jed Denlea Date: Fri, 31 Mar 2023 19:18:45 -0700 Subject: [PATCH 329/477] wc: clean up of settings The Settings object did not need a QuotingStyle member, it was basically a static. --- src/uu/wc/src/wc.rs | 134 +++++++++++++++++++++++--------------------- 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 9d7a23d1fb..c697cb33b7 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -42,23 +42,36 @@ struct Settings { show_words: bool, show_max_line_length: bool, files0_from_stdin_mode: bool, - title_quoting_style: QuotingStyle, total_when: TotalWhen, } +impl Default for Settings { + fn default() -> Self { + // Defaults if none of -c, -m, -l, -w, nor -L are specified. + Self { + show_bytes: true, + show_chars: false, + show_lines: true, + show_words: true, + show_max_line_length: false, + files0_from_stdin_mode: false, + total_when: TotalWhen::default(), + } + } +} + impl Settings { fn new(matches: &ArgMatches) -> Self { - let title_quoting_style = QuotingStyle::Shell { - escape: true, - always_quote: false, - show_control: false, - }; - let files0_from_stdin_mode = match matches.get_one::(options::FILES0_FROM) { Some(files_0_from) => files_0_from == STDIN_REPR, None => false, }; + let total_when = matches + .get_one::(options::TOTAL) + .map(Into::into) + .unwrap_or_default(); + let settings = Self { show_bytes: matches.get_flag(options::BYTES), show_chars: matches.get_flag(options::CHAR), @@ -66,46 +79,38 @@ impl Settings { show_words: matches.get_flag(options::WORDS), show_max_line_length: matches.get_flag(options::MAX_LINE_LENGTH), files0_from_stdin_mode, - title_quoting_style, - total_when: matches.get_one::(options::TOTAL).unwrap().into(), + total_when, }; - if settings.show_bytes - || settings.show_chars - || settings.show_lines - || settings.show_words - || settings.show_max_line_length - { - return settings; - } - - Self { - show_bytes: true, - show_chars: false, - show_lines: true, - show_words: true, - show_max_line_length: false, - files0_from_stdin_mode, - title_quoting_style: settings.title_quoting_style, - total_when: settings.total_when, + if settings.number_enabled() > 0 { + settings + } else { + Self { + files0_from_stdin_mode, + total_when, + ..Default::default() + } } } fn number_enabled(&self) -> u32 { - let mut result = 0; - result += self.show_bytes as u32; - result += self.show_chars as u32; - result += self.show_lines as u32; - result += self.show_max_line_length as u32; - result += self.show_words as u32; - result + [ + self.show_bytes, + self.show_chars, + self.show_lines, + self.show_max_line_length, + self.show_words, + ] + .into_iter() + .map(Into::::into) + .sum() } } const ABOUT: &str = help_about!("wc.md"); const USAGE: &str = help_usage!("wc.md"); -pub mod options { +mod options { pub static BYTES: &str = "bytes"; pub static CHAR: &str = "chars"; pub static FILES0_FROM: &str = "files0-from"; @@ -118,6 +123,12 @@ pub mod options { static ARG_FILES: &str = "files"; static STDIN_REPR: &str = "-"; +static QS_ESCAPE: &QuotingStyle = &QuotingStyle::Shell { + escape: true, + always_quote: false, + show_control: false, +}; + enum StdinKind { /// Stdin specified on command-line with "-". Explicit, @@ -147,35 +158,34 @@ impl From<&OsStr> for Input { impl Input { /// Converts input to title that appears in stats. - fn to_title(&self, quoting_style: &QuotingStyle) -> Option { + fn to_title(&self) -> Option { match self { - Self::Path(path) => Some(escape_name(&path.clone().into_os_string(), quoting_style)), - Self::Stdin(StdinKind::Explicit) => { - Some(escape_name(OsStr::new(STDIN_REPR), quoting_style)) - } + Self::Path(path) => Some(escape_name(path.as_os_str(), QS_ESCAPE)), + Self::Stdin(StdinKind::Explicit) => Some(STDIN_REPR.into()), Self::Stdin(StdinKind::Implicit) => None, } } - fn path_display(&self, quoting_style: &QuotingStyle) -> String { + fn path_display(&self) -> String { match self { - Self::Path(path) => escape_name(&path.clone().into_os_string(), quoting_style), - Self::Stdin(_) => escape_name(OsStr::new("standard input"), quoting_style), + Self::Path(path) => escape_name(OsStr::new(&path), QS_ESCAPE), + Self::Stdin(_) => escape_name(OsStr::new("standard input"), QS_ESCAPE), } } } /// When to show the "total" line -#[derive(PartialEq)] +#[derive(Clone, Copy, Default, PartialEq)] enum TotalWhen { + #[default] Auto, Always, Only, Never, } -impl From<&String> for TotalWhen { - fn from(s: &String) -> Self { +impl> From for TotalWhen { + fn from(s: T) -> Self { match s.as_ref() { "auto" => Self::Auto, "always" => Self::Always, @@ -261,11 +271,11 @@ pub fn uu_app() -> Command { Arg::new(options::FILES0_FROM) .long(options::FILES0_FROM) .value_name("F") - .help( - "read input from the files specified by - NUL-terminated names in file F; - If F is - then read names from standard input", - ) + .help(concat!( + "read input from the files specified by\n", + " NUL-terminated names in file F;\n", + " If F is - then read names from standard input" + )) .value_hint(clap::ValueHint::FilePath), ) .arg( @@ -286,10 +296,12 @@ pub fn uu_app() -> Command { Arg::new(options::TOTAL) .long(options::TOTAL) .value_parser(["auto", "always", "only", "never"]) - .default_value("auto") - .hide_default_value(true) .value_name("WHEN") - .help("when to print a line with total counts"), + .hide_possible_values(true) + .help(concat!( + "when to print a line with total counts;\n", + " WHEN can be: auto, always, only, never" + )), ) .arg( Arg::new(options::WORDS) @@ -627,28 +639,20 @@ fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> { CountResult::Interrupted(word_count, error) => { show!(USimpleError::new( 1, - format!( - "{}: {}", - input.path_display(&settings.title_quoting_style), - error - ) + format!("{}: {}", input.path_display(), error) )); word_count } CountResult::Failure(error) => { show!(USimpleError::new( 1, - format!( - "{}: {}", - input.path_display(&settings.title_quoting_style), - error - ) + format!("{}: {}", input.path_display(), error) )); continue; } }; total_word_count += word_count; - let result = word_count.with_title(input.to_title(&settings.title_quoting_style)); + let result = word_count.with_title(input.to_title()); if are_stats_visible { if let Err(err) = print_stats(settings, &result, number_width) { From 38b4825e7f484683ea54da995f1a7529e6b2aced Mon Sep 17 00:00:00 2001 From: Jed Denlea Date: Fri, 31 Mar 2023 19:52:52 -0700 Subject: [PATCH 330/477] wc: avoid excess String allocations print_stats will now take advantage of the buffer built into io::stdout(). We can also waste fewer lines on show! by making a helper macro. --- src/uu/wc/src/wc.rs | 103 ++++++++++++++---------------------- src/uu/wc/src/word_count.rs | 16 ------ tests/by-util/test_wc.rs | 5 +- 3 files changed, 42 insertions(+), 82 deletions(-) diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index c697cb33b7..60f2a5800c 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -17,7 +17,7 @@ use countable::WordCountable; use unicode_width::UnicodeWidthChar; use utf8::{BufReadDecoder, BufReadDecoderError}; use uucore::{format_usage, help_about, help_usage, show}; -use word_count::{TitledWordCount, WordCount}; +use word_count::WordCount; use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; @@ -29,7 +29,7 @@ use std::fs::{self, File}; use std::io::{self, Read, Write}; use std::path::PathBuf; -use uucore::error::{UError, UResult, USimpleError}; +use uucore::error::{FromIo, UError, UResult}; use uucore::quoting_style::{escape_name, QuotingStyle}; /// The minimum character width for formatting counts when reading from stdin. @@ -621,93 +621,72 @@ fn compute_number_width(inputs: &[Input], settings: &Settings) -> usize { fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> { let mut total_word_count = WordCount::default(); - let (number_width, are_stats_visible, total_row_title) = - if settings.total_when == TotalWhen::Only { - (1, false, None) - } else { - let number_width = compute_number_width(inputs, settings); - let title = Some(String::from("total")); - - (number_width, true, title) - }; - + let (number_width, are_stats_visible) = match settings.total_when { + TotalWhen::Only => (1, false), + _ => (compute_number_width(inputs, settings), true), + }; let is_total_row_visible = settings.total_when.is_total_row_visible(inputs.len()); for input in inputs { let word_count = match word_count_from_input(input, settings) { CountResult::Success(word_count) => word_count, - CountResult::Interrupted(word_count, error) => { - show!(USimpleError::new( - 1, - format!("{}: {}", input.path_display(), error) - )); + CountResult::Interrupted(word_count, err) => { + show!(err.map_err_context(|| input.path_display())); word_count } - CountResult::Failure(error) => { - show!(USimpleError::new( - 1, - format!("{}: {}", input.path_display(), error) - )); + CountResult::Failure(err) => { + show!(err.map_err_context(|| input.path_display())); continue; } }; total_word_count += word_count; - let result = word_count.with_title(input.to_title()); - if are_stats_visible { - if let Err(err) = print_stats(settings, &result, number_width) { - show!(USimpleError::new( - 1, - format!( - "failed to print result for {}: {}", - &result.title.unwrap_or_else(|| String::from("")), - err, - ), - )); + let maybe_title = input.to_title(); + let maybe_title_str = maybe_title.as_deref(); + if let Err(err) = print_stats(settings, &word_count, maybe_title_str, number_width) { + let title = maybe_title_str.unwrap_or(""); + show!(err.map_err_context(|| format!("failed to print result for {title}"))); } } } if is_total_row_visible { - let total_result = total_word_count.with_title(total_row_title); - if let Err(err) = print_stats(settings, &total_result, number_width) { - show!(USimpleError::new( - 1, - format!("failed to print total: {err}") - )); + let title = are_stats_visible.then_some("total"); + if let Err(err) = print_stats(settings, &total_word_count, title, number_width) { + show!(err.map_err_context(|| "failed to print total".into())); } } - // Although this appears to be returning `Ok`, the exit code may - // have been set to a non-zero value by a call to `show!()` above. + // Although this appears to be returning `Ok`, the exit code may have been set to a non-zero + // value by a call to `record_error!()` above. Ok(()) } fn print_stats( settings: &Settings, - result: &TitledWordCount, + result: &WordCount, + title: Option<&str>, number_width: usize, ) -> io::Result<()> { - let mut columns = Vec::new(); - - if settings.show_lines { - columns.push(format!("{:1$}", result.count.lines, number_width)); - } - if settings.show_words { - columns.push(format!("{:1$}", result.count.words, number_width)); - } - if settings.show_chars { - columns.push(format!("{:1$}", result.count.chars, number_width)); - } - if settings.show_bytes { - columns.push(format!("{:1$}", result.count.bytes, number_width)); - } - if settings.show_max_line_length { - columns.push(format!("{:1$}", result.count.max_line_length, number_width)); - } - if let Some(title) = &result.title { - columns.push(title.clone()); + let mut stdout = io::stdout().lock(); + + let maybe_cols = [ + (settings.show_lines, result.lines), + (settings.show_words, result.words), + (settings.show_chars, result.chars), + (settings.show_bytes, result.bytes), + (settings.show_max_line_length, result.max_line_length), + ]; + + let mut space = ""; + for (_, num) in maybe_cols.iter().filter(|(show, _)| *show) { + write!(stdout, "{space}{num:number_width$}")?; + space = " "; } - writeln!(io::stdout().lock(), "{}", columns.join(" ")) + if let Some(title) = title { + writeln!(stdout, "{space}{title}") + } else { + writeln!(stdout) + } } diff --git a/src/uu/wc/src/word_count.rs b/src/uu/wc/src/word_count.rs index b2dd704502..cf839175f9 100644 --- a/src/uu/wc/src/word_count.rs +++ b/src/uu/wc/src/word_count.rs @@ -29,19 +29,3 @@ impl AddAssign for WordCount { *self = *self + other; } } - -impl WordCount { - pub fn with_title(self, title: Option) -> TitledWordCount { - TitledWordCount { title, count: self } - } -} - -/// This struct supplements the actual word count with an optional title that is -/// displayed to the user at the end of the program. -/// The reason we don't simply include title in the `WordCount` struct is that -/// it would result in unnecessary copying of `String`. -#[derive(Debug, Default, Clone)] -pub struct TitledWordCount { - pub title: Option, - pub count: WordCount, -} diff --git a/tests/by-util/test_wc.rs b/tests/by-util/test_wc.rs index 64e3b70da8..1ce27f18d8 100644 --- a/tests/by-util/test_wc.rs +++ b/tests/by-util/test_wc.rs @@ -375,7 +375,7 @@ fn test_read_from_directory_error() { #[cfg(not(windows))] const STDERR: &str = ".: Is a directory"; #[cfg(windows)] - const STDERR: &str = ".: Access is denied"; + const STDERR: &str = ".: Permission denied"; #[cfg(not(windows))] const STDOUT: &str = " 0 0 0 .\n"; @@ -392,10 +392,7 @@ fn test_read_from_directory_error() { /// Test that getting counts from nonexistent file is an error. #[test] fn test_read_from_nonexistent_file() { - #[cfg(not(windows))] const MSG: &str = "bogusfile: No such file or directory"; - #[cfg(windows)] - const MSG: &str = "bogusfile: The system cannot find the file specified"; new_ucmd!() .args(&["bogusfile"]) .fails() From 36b45e2249dcd6e9ec9d60dc7131147a888c6e57 Mon Sep 17 00:00:00 2001 From: Jed Denlea Date: Fri, 31 Mar 2023 22:58:49 -0700 Subject: [PATCH 331/477] wc: touch up errors, quote more like GNU WcError should not hold Strings which are clones of `&'static str`s. thiserror provides a convenient API to declare errors with their Display messages. wc quotes the --files0-from source slightly differently when reporting errors about empty file names. --- Cargo.lock | 1 + src/uu/wc/Cargo.toml | 1 + src/uu/wc/src/wc.rs | 160 ++++++++++++++++++++++++------------------- 3 files changed, 93 insertions(+), 69 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9f9532b65..c219fa3bcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3352,6 +3352,7 @@ dependencies = [ "clap", "libc", "nix", + "thiserror", "unicode-width", "uucore", ] diff --git a/src/uu/wc/Cargo.toml b/src/uu/wc/Cargo.toml index 1b1bd41d31..2b42affb58 100644 --- a/src/uu/wc/Cargo.toml +++ b/src/uu/wc/Cargo.toml @@ -18,6 +18,7 @@ path = "src/wc.rs" clap = { workspace=true } uucore = { workspace=true, features=["pipes"] } bytecount = { workspace=true } +thiserror = { workspace=true } unicode-width = { workspace=true } [target.'cfg(unix)'.dependencies] diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 60f2a5800c..00f8988683 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -11,26 +11,33 @@ mod count_fast; mod countable; mod utf8; mod word_count; -use clap::builder::ValueParser; -use count_fast::{count_bytes_chars_and_lines_fast, count_bytes_fast}; -use countable::WordCountable; + +use std::{ + borrow::Cow, + cmp::max, + ffi::{OsStr, OsString}, + fs::{self, File}, + io::{self, Read, Write}, + path::{Path, PathBuf}, +}; + +use clap::{builder::ValueParser, crate_version, Arg, ArgAction, ArgMatches, Command}; +use thiserror::Error; use unicode_width::UnicodeWidthChar; use utf8::{BufReadDecoder, BufReadDecoderError}; -use uucore::{format_usage, help_about, help_usage, show}; -use word_count::WordCount; - -use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; -use std::cmp::max; -use std::error::Error; -use std::ffi::{OsStr, OsString}; -use std::fmt::Display; -use std::fs::{self, File}; -use std::io::{self, Read, Write}; -use std::path::PathBuf; +use uucore::{ + error::{FromIo, UError, UResult}, + format_usage, help_about, help_usage, + quoting_style::{escape_name, QuotingStyle}, + show, +}; -use uucore::error::{FromIo, UError, UResult}; -use uucore::quoting_style::{escape_name, QuotingStyle}; +use crate::{ + count_fast::{count_bytes_chars_and_lines_fast, count_bytes_fast}, + countable::WordCountable, + word_count::WordCount, +}; /// The minimum character width for formatting counts when reading from stdin. const MINIMUM_WIDTH: usize = 7; @@ -41,7 +48,7 @@ struct Settings { show_lines: bool, show_words: bool, show_max_line_length: bool, - files0_from_stdin_mode: bool, + files0_from_path: Option, total_when: TotalWhen, } @@ -54,7 +61,7 @@ impl Default for Settings { show_lines: true, show_words: true, show_max_line_length: false, - files0_from_stdin_mode: false, + files0_from_path: None, total_when: TotalWhen::default(), } } @@ -62,10 +69,9 @@ impl Default for Settings { impl Settings { fn new(matches: &ArgMatches) -> Self { - let files0_from_stdin_mode = match matches.get_one::(options::FILES0_FROM) { - Some(files_0_from) => files_0_from == STDIN_REPR, - None => false, - }; + let files0_from_path = matches + .get_one::(options::FILES0_FROM) + .map(Into::into); let total_when = matches .get_one::(options::TOTAL) @@ -78,7 +84,7 @@ impl Settings { show_lines: matches.get_flag(options::LINES), show_words: matches.get_flag(options::WORDS), show_max_line_length: matches.get_flag(options::MAX_LINE_LENGTH), - files0_from_stdin_mode, + files0_from_path, total_when, }; @@ -86,7 +92,7 @@ impl Settings { settings } else { Self { - files0_from_stdin_mode, + files0_from_path: settings.files0_from_path, total_when, ..Default::default() } @@ -119,7 +125,6 @@ mod options { pub static TOTAL: &str = "total"; pub static WORDS: &str = "words"; } - static ARG_FILES: &str = "files"; static STDIN_REPR: &str = "-"; @@ -128,12 +133,16 @@ static QS_ESCAPE: &QuotingStyle = &QuotingStyle::Shell { always_quote: false, show_control: false, }; +static QS_QUOTE_ESCAPE: &QuotingStyle = &QuotingStyle::Shell { + escape: true, + always_quote: true, + show_control: false, +}; enum StdinKind { - /// Stdin specified on command-line with "-". + /// Specified on command-line with "-" (STDIN_REPR) Explicit, - - /// Stdin implicitly specified on command-line by not passing any positional argument. + /// Implied by the lack of any arguments Implicit, } @@ -158,18 +167,22 @@ impl From<&OsStr> for Input { impl Input { /// Converts input to title that appears in stats. - fn to_title(&self) -> Option { + fn to_title(&self) -> Option> { match self { - Self::Path(path) => Some(escape_name(path.as_os_str(), QS_ESCAPE)), - Self::Stdin(StdinKind::Explicit) => Some(STDIN_REPR.into()), + Self::Path(path) => Some(match path.to_str() { + Some(s) if !s.contains('\n') => Cow::Borrowed(s), + _ => Cow::Owned(escape_name(path.as_os_str(), QS_ESCAPE)), + }), + Self::Stdin(StdinKind::Explicit) => Some(Cow::Borrowed(STDIN_REPR)), Self::Stdin(StdinKind::Implicit) => None, } } + /// Converts input into the form that appears in errors. fn path_display(&self) -> String { match self { - Self::Path(path) => escape_name(OsStr::new(&path), QS_ESCAPE), - Self::Stdin(_) => escape_name(OsStr::new("standard input"), QS_ESCAPE), + Self::Path(path) => escape_name(path.as_os_str(), QS_ESCAPE), + Self::Stdin(_) => String::from("standard input"), } } } @@ -206,33 +219,33 @@ impl TotalWhen { } } -#[derive(Debug)] +#[derive(Debug, Error)] enum WcError { - FilesDisabled(String), - StdinReprNotAllowed(String), + #[error("file operands cannot be combined with --files0-from")] + FilesDisabled, + #[error("when reading file names from stdin, no file name of '-' allowed")] + StdinReprNotAllowed, + #[error("invalid zero-length file name")] + ZeroLengthFileName, + #[error("{path}:{idx}: invalid zero-length file name")] + ZeroLengthFileNameCtx { path: String, idx: usize }, } -impl UError for WcError { - fn code(&self) -> i32 { - match self { - Self::FilesDisabled(_) | Self::StdinReprNotAllowed(_) => 1, +impl WcError { + fn zero_len(ctx: Option<(&Path, usize)>) -> Self { + match ctx { + Some((path, idx)) => { + let path = escape_name(path.as_os_str(), QS_ESCAPE); + Self::ZeroLengthFileNameCtx { path, idx } + } + None => Self::ZeroLengthFileName, } } - - fn usage(&self) -> bool { - matches!(self, Self::FilesDisabled(_)) - } } -impl Error for WcError {} - -impl Display for WcError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::FilesDisabled(message) | Self::StdinReprNotAllowed(message) => { - write!(f, "{message}") - } - } +impl UError for WcError { + fn usage(&self) -> bool { + matches!(self, Self::FilesDisabled) } } @@ -276,6 +289,7 @@ pub fn uu_app() -> Command { " NUL-terminated names in file F;\n", " If F is - then read names from standard input" )) + .value_parser(ValueParser::os_string()) .value_hint(clap::ValueHint::FilePath), ) .arg( @@ -322,38 +336,39 @@ fn inputs(matches: &ArgMatches) -> UResult> { match matches.get_many::(ARG_FILES) { Some(os_values) => { if matches.contains_id(options::FILES0_FROM) { - return Err(WcError::FilesDisabled( - "file operands cannot be combined with --files0-from".into(), - ) - .into()); + return Err(WcError::FilesDisabled.into()); } Ok(os_values.map(|s| Input::from(s.as_os_str())).collect()) } - None => match matches.get_one::(options::FILES0_FROM) { - Some(files_0_from) => create_paths_from_files0(files_0_from), + None => match matches.get_one::(options::FILES0_FROM) { + Some(files_0_from) => create_paths_from_files0(Path::new(files_0_from)), None => Ok(vec![Input::Stdin(StdinKind::Implicit)]), }, } } -fn create_paths_from_files0(files_0_from: &str) -> UResult> { +fn create_paths_from_files0(files_0_from: &Path) -> UResult> { let mut paths = String::new(); - let read_from_stdin = files_0_from == STDIN_REPR; + let read_from_stdin = files_0_from.as_os_str() == STDIN_REPR; if read_from_stdin { io::stdin().lock().read_to_string(&mut paths)?; } else { - File::open(files_0_from)?.read_to_string(&mut paths)?; + File::open(files_0_from) + .map_err_context(|| { + format!( + "cannot open {} for reading", + escape_name(files_0_from.as_os_str(), QS_QUOTE_ESCAPE) + ) + })? + .read_to_string(&mut paths)?; } let paths: Vec<&str> = paths.split_terminator('\0').collect(); if read_from_stdin && paths.contains(&STDIN_REPR) { - return Err(WcError::StdinReprNotAllowed( - "when reading file names from stdin, no file name of '-' allowed".into(), - ) - .into()); + return Err(WcError::StdinReprNotAllowed.into()); } Ok(paths.iter().map(OsStr::new).map(Input::from).collect()) @@ -589,8 +604,10 @@ fn word_count_from_input(input: &Input, settings: &Settings) -> CountResult { /// is close enough to pass the GNU test suite. fn compute_number_width(inputs: &[Input], settings: &Settings) -> usize { if inputs.is_empty() - || (inputs.len() == 1 && settings.number_enabled() == 1) - || (settings.files0_from_stdin_mode && settings.number_enabled() == 1) + || settings.number_enabled() == 1 + && (inputs.len() == 1 + || settings.files0_from_path.as_ref().map(|p| p.as_os_str()) + == Some(OsStr::new(STDIN_REPR))) { return 1; } @@ -627,7 +644,12 @@ fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> { }; let is_total_row_visible = settings.total_when.is_total_row_visible(inputs.len()); - for input in inputs { + for (idx, input) in inputs.iter().enumerate() { + if matches!(input, Input::Path(p) if p.as_os_str().is_empty()) { + let err = WcError::zero_len(settings.files0_from_path.as_deref().map(|s| (s, idx))); + show!(err); + continue; + } let word_count = match word_count_from_input(input, settings) { CountResult::Success(word_count) => word_count, CountResult::Interrupted(word_count, err) => { From d58ee5a28a5ffbf7da142a233104d75fe48d96ff Mon Sep 17 00:00:00 2001 From: Jed Denlea Date: Mon, 24 Apr 2023 23:41:59 -0700 Subject: [PATCH 332/477] wc: skip String to measure number length Sadly ilog10 isn't available until we use 1.67, but we can get close in the meantime. --- src/uu/wc/src/wc.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 00f8988683..2ed43e16ae 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -5,7 +5,7 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -// cSpell:ignore wc wc's +// cSpell:ignore ilog wc wc's mod count_fast; mod countable; @@ -632,7 +632,14 @@ fn compute_number_width(inputs: &[Input], settings: &Settings) -> usize { } } - max(minimum_width, total.to_string().len()) + if total == 0 { + minimum_width + } else { + let total_width = (1 + ilog10_u64(total)) + .try_into() + .expect("ilog of a u64 should fit into a usize"); + max(total_width, minimum_width) + } } fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> { @@ -712,3 +719,29 @@ fn print_stats( writeln!(stdout) } } + +// TODO: remove and just use usize::ilog10 once the MSRV is >= 1.67. +fn ilog10_u64(mut u: u64) -> u32 { + if u == 0 { + panic!("cannot compute log of 0") + } + let mut log = 0; + if u >= 10_000_000_000 { + log += 10; + u /= 10_000_000_000; + } + if u >= 100_000 { + log += 5; + u /= 100_000; + } + // Rust's standard library in versions >= 1.67 does something even more clever than this, but + // this should work just fine for the time being. + log + match u { + 1..=9 => 0, + 10..=99 => 1, + 100..=999 => 2, + 1000..=9999 => 3, + 10000..=99999 => 4, + _ => unreachable!(), + } +} From 0130a07579b737a28c307801232b09ed9f211258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mo=C3=AFse=20Valvassori?= Date: Sun, 21 May 2023 17:54:32 +0200 Subject: [PATCH 333/477] chown: show message if file doesn't exist * print the message "failed to change ownership of" when we try to change a non existing file. * replace the 4-tuple returned by parse_gid_uid_and_filter by GidUidOwnerFilter struct. * chain the test in one expression. * chown: remove unused var "result" in test --------- Co-authored-by: Daniel Hofstetter --- src/uu/chgrp/src/chgrp.rs | 19 ++++++++++++++---- src/uu/chown/src/chown.rs | 29 +++++++++++++++++++++------ src/uucore/src/lib/features/perms.rs | 30 ++++++++++++++++++++++++---- tests/by-util/test_chown.rs | 12 +++++------ 4 files changed, 70 insertions(+), 20 deletions(-) diff --git a/src/uu/chgrp/src/chgrp.rs b/src/uu/chgrp/src/chgrp.rs index e63dd9eb7d..bd01e132b4 100644 --- a/src/uu/chgrp/src/chgrp.rs +++ b/src/uu/chgrp/src/chgrp.rs @@ -10,7 +10,7 @@ use uucore::display::Quotable; pub use uucore::entries; use uucore::error::{FromIo, UResult, USimpleError}; -use uucore::perms::{chown_base, options, IfFrom}; +use uucore::perms::{chown_base, options, GidUidOwnerFilter, IfFrom}; use uucore::{format_usage, help_about, help_usage}; use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; @@ -21,16 +21,22 @@ use std::os::unix::fs::MetadataExt; const ABOUT: &str = help_about!("chgrp.md"); const USAGE: &str = help_usage!("chgrp.md"); -fn parse_gid_and_uid(matches: &ArgMatches) -> UResult<(Option, Option, IfFrom)> { +fn parse_gid_and_uid(matches: &ArgMatches) -> UResult { + let mut raw_group: String = String::new(); let dest_gid = if let Some(file) = matches.get_one::(options::REFERENCE) { fs::metadata(file) - .map(|meta| Some(meta.gid())) + .map(|meta| { + let gid = meta.gid(); + raw_group = entries::gid2grp(gid).unwrap_or_else(|_| gid.to_string()); + Some(gid) + }) .map_err_context(|| format!("failed to get attributes of {}", file.quote()))? } else { let group = matches .get_one::(options::ARG_GROUP) .map(|s| s.as_str()) .unwrap_or_default(); + raw_group = group.to_string(); if group.is_empty() { None } else { @@ -45,7 +51,12 @@ fn parse_gid_and_uid(matches: &ArgMatches) -> UResult<(Option, Option, } } }; - Ok((dest_gid, None, IfFrom::All)) + Ok(GidUidOwnerFilter { + dest_gid, + dest_uid: None, + raw_owner: raw_group, + filter: IfFrom::All, + }) } #[uucore::main] diff --git a/src/uu/chown/src/chown.rs b/src/uu/chown/src/chown.rs index 2d810564e3..67e71b815b 100644 --- a/src/uu/chown/src/chown.rs +++ b/src/uu/chown/src/chown.rs @@ -9,7 +9,7 @@ use uucore::display::Quotable; pub use uucore::entries::{self, Group, Locate, Passwd}; -use uucore::perms::{chown_base, options, IfFrom}; +use uucore::perms::{chown_base, options, GidUidOwnerFilter, IfFrom}; use uucore::{format_usage, help_about, help_usage}; use uucore::error::{FromIo, UResult, USimpleError}; @@ -23,7 +23,7 @@ static ABOUT: &str = help_about!("chown.md"); const USAGE: &str = help_usage!("chown.md"); -fn parse_gid_uid_and_filter(matches: &ArgMatches) -> UResult<(Option, Option, IfFrom)> { +fn parse_gid_uid_and_filter(matches: &ArgMatches) -> UResult { let filter = if let Some(spec) = matches.get_one::(options::FROM) { match parse_spec(spec, ':')? { (Some(uid), None) => IfFrom::User(uid), @@ -37,17 +37,34 @@ fn parse_gid_uid_and_filter(matches: &ArgMatches) -> UResult<(Option, Optio let dest_uid: Option; let dest_gid: Option; + let raw_owner: String; if let Some(file) = matches.get_one::(options::REFERENCE) { let meta = fs::metadata(file) .map_err_context(|| format!("failed to get attributes of {}", file.quote()))?; - dest_gid = Some(meta.gid()); - dest_uid = Some(meta.uid()); + let gid = meta.gid(); + let uid = meta.uid(); + dest_gid = Some(gid); + dest_uid = Some(uid); + raw_owner = format!( + "{}:{}", + entries::uid2usr(uid).unwrap_or_else(|_| uid.to_string()), + entries::gid2grp(gid).unwrap_or_else(|_| gid.to_string()) + ); } else { - let (u, g) = parse_spec(matches.get_one::(options::ARG_OWNER).unwrap(), ':')?; + raw_owner = matches + .get_one::(options::ARG_OWNER) + .unwrap() + .into(); + let (u, g) = parse_spec(&raw_owner, ':')?; dest_uid = u; dest_gid = g; } - Ok((dest_gid, dest_uid, filter)) + Ok(GidUidOwnerFilter { + dest_gid, + dest_uid, + raw_owner, + filter, + }) } #[uucore::main] diff --git a/src/uucore/src/lib/features/perms.rs b/src/uucore/src/lib/features/perms.rs index 984d6dd402..6383477371 100644 --- a/src/uucore/src/lib/features/perms.rs +++ b/src/uucore/src/lib/features/perms.rs @@ -182,6 +182,7 @@ pub enum TraverseSymlinks { pub struct ChownExecutor { pub dest_uid: Option, pub dest_gid: Option, + pub raw_owner: String, // The owner of the file as input by the user in the command line. pub traverse_symlinks: TraverseSymlinks, pub verbosity: Verbosity, pub filter: IfFrom, @@ -208,7 +209,16 @@ impl ChownExecutor { let path = root.as_ref(); let meta = match self.obtain_meta(path, self.dereference) { Some(m) => m, - _ => return 1, + _ => { + if self.verbosity.level == VerbosityLevel::Verbose { + println!( + "failed to change ownership of {} to {}", + path.quote(), + self.raw_owner + ); + } + return 1; + } }; // Prohibit only if: @@ -414,7 +424,13 @@ pub mod options { pub const ARG_FILES: &str = "FILE"; } -type GidUidFilterParser = fn(&ArgMatches) -> UResult<(Option, Option, IfFrom)>; +pub struct GidUidOwnerFilter { + pub dest_gid: Option, + pub dest_uid: Option, + pub raw_owner: String, + pub filter: IfFrom, +} +type GidUidFilterOwnerParser = fn(&ArgMatches) -> UResult; /// Base implementation for `chgrp` and `chown`. /// @@ -428,7 +444,7 @@ pub fn chown_base( mut command: Command, args: impl crate::Args, add_arg_if_not_reference: &'static str, - parse_gid_uid_and_filter: GidUidFilterParser, + parse_gid_uid_and_filter: GidUidFilterOwnerParser, groups_only: bool, ) -> UResult<()> { let args: Vec<_> = args.collect(); @@ -511,12 +527,18 @@ pub fn chown_base( } else { VerbosityLevel::Normal }; - let (dest_gid, dest_uid, filter) = parse_gid_uid_and_filter(&matches)?; + let GidUidOwnerFilter { + dest_gid, + dest_uid, + raw_owner, + filter, + } = parse_gid_uid_and_filter(&matches)?; let executor = ChownExecutor { traverse_symlinks, dest_gid, dest_uid, + raw_owner, verbosity: Verbosity { groups_only, level: verbosity_level, diff --git a/tests/by-util/test_chown.rs b/tests/by-util/test_chown.rs index fce4fa6359..fd7e377224 100644 --- a/tests/by-util/test_chown.rs +++ b/tests/by-util/test_chown.rs @@ -730,15 +730,15 @@ fn test_chown_file_notexisting() { let user_name = String::from(result.stdout_str().trim()); assert!(!user_name.is_empty()); - let _result = scene + scene .ucmd() - .arg(user_name) + .arg(&user_name) .arg("--verbose") .arg("not_existing") - .fails(); - - // TODO: uncomment once "failed to change ownership of '{}' to {}" added to stdout - // result.stderr_contains("retained as"); + .fails() + .stdout_contains(format!( + "failed to change ownership of 'not_existing' to {user_name}" + )); // TODO: uncomment once message changed from "cannot dereference" to "cannot access" // result.stderr_contains("cannot access 'not_existing': No such file or directory"); } From 33ac653ce54790e2a245bfaae3b05ed09835c0e2 Mon Sep 17 00:00:00 2001 From: John Shin Date: Sun, 21 May 2023 19:31:04 -0700 Subject: [PATCH 334/477] mkdir: correctly set umask so that tests fail without the fix --- tests/by-util/test_mkdir.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index 409334c2eb..efa7c3248d 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -76,7 +76,7 @@ fn test_mkdir_dup_dir_parent() { fn test_mkdir_parent_mode() { let (at, mut ucmd) = at_and_ucmd!(); - let default_umask: mode_t = 0o022; + let default_umask: mode_t = 0o160; let original_umask = unsafe { umask(default_umask) }; ucmd.arg("-p").arg("a/b").succeeds().no_stderr().no_stdout(); @@ -104,11 +104,11 @@ fn test_mkdir_parent_mode() { fn test_mkdir_parent_mode_check_existing_parent() { let (at, mut ucmd) = at_and_ucmd!(); - let default_umask: mode_t = 0o022; - let original_umask = unsafe { umask(default_umask) }; - at.mkdir("a"); + let default_umask: mode_t = 0o160; + let original_umask = unsafe { umask(default_umask) }; + ucmd.arg("-p") .arg("a/b/c") .succeeds() @@ -119,7 +119,7 @@ fn test_mkdir_parent_mode_check_existing_parent() { // parent dirs that already exist do not get their permissions modified assert_eq!( at.metadata("a").permissions().mode() as mode_t, - (!default_umask & 0o777) + 0o40000 + (!original_umask & 0o777) + 0o40000 ); assert!(at.dir_exists("a/b")); assert_eq!( From c4b53a44b5629b17fb85a0818c803a475a6071ea Mon Sep 17 00:00:00 2001 From: Jed Denlea Date: Fri, 31 Mar 2023 23:57:53 -0700 Subject: [PATCH 335/477] wc: make --files0-from work with streams --- src/uu/wc/src/countable.rs | 1 + src/uu/wc/src/wc.rs | 444 +++++++++++++++++++++++++------------ tests/by-util/test_wc.rs | 22 +- 3 files changed, 313 insertions(+), 154 deletions(-) diff --git a/src/uu/wc/src/countable.rs b/src/uu/wc/src/countable.rs index 5596decb3e..b86b96fa2f 100644 --- a/src/uu/wc/src/countable.rs +++ b/src/uu/wc/src/countable.rs @@ -28,6 +28,7 @@ impl WordCountable for StdinLock<'_> { self } } + impl WordCountable for File { type Buffered = BufReader; diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 2ed43e16ae..08d00db188 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -13,11 +13,12 @@ mod utf8; mod word_count; use std::{ - borrow::Cow, + borrow::{Borrow, Cow}, cmp::max, - ffi::{OsStr, OsString}, + ffi::OsString, fs::{self, File}, - io::{self, Read, Write}, + io::{self, Write}, + iter, path::{Path, PathBuf}, }; @@ -42,17 +43,17 @@ use crate::{ /// The minimum character width for formatting counts when reading from stdin. const MINIMUM_WIDTH: usize = 7; -struct Settings { +struct Settings<'a> { show_bytes: bool, show_chars: bool, show_lines: bool, show_words: bool, show_max_line_length: bool, - files0_from_path: Option, + files0_from: Option>, total_when: TotalWhen, } -impl Default for Settings { +impl Default for Settings<'_> { fn default() -> Self { // Defaults if none of -c, -m, -l, -w, nor -L are specified. Self { @@ -61,15 +62,15 @@ impl Default for Settings { show_lines: true, show_words: true, show_max_line_length: false, - files0_from_path: None, + files0_from: None, total_when: TotalWhen::default(), } } } -impl Settings { - fn new(matches: &ArgMatches) -> Self { - let files0_from_path = matches +impl<'a> Settings<'a> { + fn new(matches: &'a ArgMatches) -> Self { + let files0_from = matches .get_one::(options::FILES0_FROM) .map(Into::into); @@ -84,7 +85,7 @@ impl Settings { show_lines: matches.get_flag(options::LINES), show_words: matches.get_flag(options::WORDS), show_max_line_length: matches.get_flag(options::MAX_LINE_LENGTH), - files0_from_path, + files0_from, total_when, }; @@ -92,7 +93,7 @@ impl Settings { settings } else { Self { - files0_from_path: settings.files0_from_path, + files0_from: settings.files0_from, total_when, ..Default::default() } @@ -139,6 +140,74 @@ static QS_QUOTE_ESCAPE: &QuotingStyle = &QuotingStyle::Shell { show_control: false, }; +/// Supported inputs. +#[derive(Debug)] +enum Inputs<'a> { + /// Default Standard input, i.e. no arguments. + Stdin, + /// Files; "-" means stdin, possibly multiple times! + Paths(Vec>), + /// --files0-from; "-" means stdin. + Files0From(Input<'a>), +} + +impl<'a> Inputs<'a> { + fn new(matches: &'a ArgMatches) -> UResult { + let arg_files = matches.get_many::(ARG_FILES); + let files0_from = matches.get_one::(options::FILES0_FROM); + + match (arg_files, files0_from) { + (None, None) => Ok(Self::Stdin), + (Some(files), None) => Ok(Self::Paths(files.map(Into::into).collect())), + (None, Some(path)) => { + // If path is a file, and the file isn't too large, we'll load it ahead + // of time. Every path within the file will have its length checked to + // hopefully better align the output columns. + let input = Input::from(path); + match input.try_as_files0()? { + Some(paths) => Ok(Self::Paths(paths)), + None => Ok(Self::Files0From(input)), + } + } + (Some(_), Some(_)) => Err(WcError::FilesDisabled.into()), + } + } + + // Creates an iterator which yields values borrowed from the command line arguments. + // Returns an error if the file specified in --files0-from cannot be opened. + fn try_iter( + &'a self, + settings: &'a Settings<'a>, + ) -> UResult>> { + let base: Box> = match self { + Self::Stdin => Box::new(iter::once(Ok(Input::Stdin(StdinKind::Implicit)))), + Self::Paths(inputs) => Box::new(inputs.iter().map(|i| Ok(i.as_borrowed()))), + Self::Files0From(input) => match input { + Input::Path(path) => Box::new(files0_iter_file(path)?), + Input::Stdin(_) => Box::new(files0_iter_stdin()), + }, + }; + + // The index of each yielded item must be tracked for error reporting. + let mut with_idx = base.enumerate(); + let files0_from_path = settings.files0_from.as_ref().map(|i| i.as_borrowed()); + + let iter = iter::from_fn(move || { + let (idx, next) = with_idx.next()?; + match next { + // filter zero length file names... + Ok(Input::Path(p)) if p.as_os_str().is_empty() => Some(Err({ + let maybe_ctx = files0_from_path.as_ref().map(|p| (p, idx)); + WcError::zero_len(maybe_ctx).into() + })), + _ => Some(next), + } + }); + Ok(iter) + } +} + +#[derive(Clone, Copy, Debug)] enum StdinKind { /// Specified on command-line with "-" (STDIN_REPR) Explicit, @@ -146,26 +215,44 @@ enum StdinKind { Implicit, } -/// Supported inputs. -enum Input { - /// A regular file. - Path(PathBuf), - - /// Standard input. +/// Represents a single input, either to be counted or processed for other files names via +/// --files0-from. +#[derive(Debug)] +enum Input<'a> { + Path(Cow<'a, Path>), Stdin(StdinKind), } -impl From<&OsStr> for Input { - fn from(input: &OsStr) -> Self { - if input == STDIN_REPR { +impl From for Input<'_> { + fn from(p: PathBuf) -> Self { + if p.as_os_str() == STDIN_REPR { + Self::Stdin(StdinKind::Explicit) + } else { + Self::Path(Cow::Owned(p)) + } + } +} + +impl<'a, T: AsRef + ?Sized> From<&'a T> for Input<'a> { + fn from(p: &'a T) -> Self { + let p = p.as_ref(); + if p.as_os_str() == STDIN_REPR { Self::Stdin(StdinKind::Explicit) } else { - Self::Path(input.into()) + Self::Path(Cow::Borrowed(p)) } } } -impl Input { +impl<'a> Input<'a> { + /// Translates Path(Cow::Owned(_)) to Path(Cow::Borrowed(_)). + fn as_borrowed(&'a self) -> Self { + match self { + Self::Path(p) => Self::Path(Cow::Borrowed(p.borrow())), + Self::Stdin(k) => Self::Stdin(*k), + } + } + /// Converts input to title that appears in stats. fn to_title(&self) -> Option> { match self { @@ -185,6 +272,56 @@ impl Input { Self::Stdin(_) => String::from("standard input"), } } + + /// When given --files0-from, we may be given a path or stdin. Either may be a stream or + /// a regular file. If given a file less than 10 MiB, it will be consumed and turned into + /// a Vec of Input::Paths which can be scanned to determine the widths of the columns that + /// will ultimately be printed. + fn try_as_files0(&self) -> UResult>>> { + match self { + Self::Path(path) => match fs::metadata(path) { + Ok(meta) if meta.is_file() && meta.len() <= (10 << 20) => Ok(Some( + files0_iter_file(path)?.collect::, _>>()?, + )), + _ => Ok(None), + }, + Self::Stdin(_) if is_stdin_small_file() => { + Ok(Some(files0_iter_stdin().collect::, _>>()?)) + } + Self::Stdin(_) => Ok(None), + } + } +} + +#[cfg(unix)] +fn is_stdin_small_file() -> bool { + use std::os::unix::io::{AsRawFd, FromRawFd}; + // Safety: we'll rely on Rust to give us a valid RawFd for stdin with which we can attempt to + // open a File, but only for the sake of fetching .metadata(). ManuallyDrop will ensure we + // don't do anything else to the FD if anything unexpected happens. + let f = std::mem::ManuallyDrop::new(unsafe { File::from_raw_fd(io::stdin().as_raw_fd()) }); + matches!(f.metadata(), Ok(meta) if meta.is_file() && meta.len() <= (10 << 20)) +} + +#[cfg(windows)] +fn is_stdin_small_file() -> bool { + use std::os::windows::io::{AsRawHandle, FromRawHandle}; + // Safety: we'll rely on Rust to give us a valid RawHandle for stdin with which we can attempt + // to open a File, but only for the sake of fetching .metadata(). ManuallyDrop will ensure we + // don't do anything else to the FD if anything unexpected happens. + let f = std::mem::ManuallyDrop::new(unsafe { + let h = io::stdin().as_raw_handle(); + if h.is_null() { + return false; + } + File::from_raw_handle(h) + }); + matches!(f.metadata(), Ok(meta) if meta.is_file() && meta.len() <= (10 << 20)) +} + +#[cfg(not(any(unix, windows)))] +fn is_stdin_small_file() -> bool { + false } /// When to show the "total" line @@ -228,14 +365,17 @@ enum WcError { #[error("invalid zero-length file name")] ZeroLengthFileName, #[error("{path}:{idx}: invalid zero-length file name")] - ZeroLengthFileNameCtx { path: String, idx: usize }, + ZeroLengthFileNameCtx { path: Cow<'static, str>, idx: usize }, } impl WcError { - fn zero_len(ctx: Option<(&Path, usize)>) -> Self { + fn zero_len(ctx: Option<(&Input, usize)>) -> Self { match ctx { - Some((path, idx)) => { - let path = escape_name(path.as_os_str(), QS_ESCAPE); + Some((input, idx)) => { + let path = match input { + Input::Stdin(_) => STDIN_REPR.into(), + Input::Path(path) => escape_name(path.as_os_str(), QS_ESCAPE).into(), + }; Self::ZeroLengthFileNameCtx { path, idx } } None => Self::ZeroLengthFileName, @@ -253,9 +393,8 @@ impl UError for WcError { pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args)?; - let inputs = inputs(&matches)?; - let settings = Settings::new(&matches); + let inputs = Inputs::new(&matches)?; wc(&inputs, &settings) } @@ -332,48 +471,6 @@ pub fn uu_app() -> Command { ) } -fn inputs(matches: &ArgMatches) -> UResult> { - match matches.get_many::(ARG_FILES) { - Some(os_values) => { - if matches.contains_id(options::FILES0_FROM) { - return Err(WcError::FilesDisabled.into()); - } - - Ok(os_values.map(|s| Input::from(s.as_os_str())).collect()) - } - None => match matches.get_one::(options::FILES0_FROM) { - Some(files_0_from) => create_paths_from_files0(Path::new(files_0_from)), - None => Ok(vec![Input::Stdin(StdinKind::Implicit)]), - }, - } -} - -fn create_paths_from_files0(files_0_from: &Path) -> UResult> { - let mut paths = String::new(); - let read_from_stdin = files_0_from.as_os_str() == STDIN_REPR; - - if read_from_stdin { - io::stdin().lock().read_to_string(&mut paths)?; - } else { - File::open(files_0_from) - .map_err_context(|| { - format!( - "cannot open {} for reading", - escape_name(files_0_from.as_os_str(), QS_QUOTE_ESCAPE) - ) - })? - .read_to_string(&mut paths)?; - } - - let paths: Vec<&str> = paths.split_terminator('\0').collect(); - - if read_from_stdin && paths.contains(&STDIN_REPR) { - return Err(WcError::StdinReprNotAllowed.into()); - } - - Ok(paths.iter().map(OsStr::new).map(Input::from).collect()) -} - fn word_count_from_reader( mut reader: T, settings: &Settings, @@ -555,109 +652,166 @@ enum CountResult { Failure(io::Error), } -/// If we fail opening a file we only show the error. If we fail reading it -/// we show a count for what we managed to read. +/// If we fail opening a file, we only show the error. If we fail reading the +/// file, we show a count for what we managed to read. /// -/// Therefore the reading implementations always return a total and sometimes +/// Therefore, the reading implementations always return a total and sometimes /// return an error: (WordCount, Option). -fn word_count_from_input(input: &Input, settings: &Settings) -> CountResult { - match input { - Input::Stdin(_) => { - let stdin = io::stdin(); - let stdin_lock = stdin.lock(); - let count = word_count_from_reader(stdin_lock, settings); - match count { - (total, Some(error)) => CountResult::Interrupted(total, error), - (total, None) => CountResult::Success(total), - } - } +fn word_count_from_input(input: &Input<'_>, settings: &Settings) -> CountResult { + let (total, maybe_err) = match input { + Input::Stdin(_) => word_count_from_reader(io::stdin().lock(), settings), Input::Path(path) => match File::open(path) { - Err(error) => CountResult::Failure(error), - Ok(file) => match word_count_from_reader(file, settings) { - (total, Some(error)) => CountResult::Interrupted(total, error), - (total, None) => CountResult::Success(total), - }, + Ok(f) => word_count_from_reader(f, settings), + Err(err) => return CountResult::Failure(err), }, + }; + match maybe_err { + None => CountResult::Success(total), + Some(err) => CountResult::Interrupted(total, err), } } /// Compute the number of digits needed to represent all counts in all inputs. /// -/// `inputs` may include zero or more [`Input::Stdin`] entries, each of -/// which represents reading from `stdin`. The presence of any such -/// entry causes this function to return a width that is at least -/// [`MINIMUM_WIDTH`]. +/// For [`Inputs::Stdin`], [`MINIMUM_WIDTH`] is returned, unless there is only one counter number +/// to be printed, in which case 1 is returned. /// -/// If `input` is empty, or if only one number needs to be printed (for just -/// one file) then this function is optimized to return 1 without making any -/// calls to get file metadata. +/// For [`Inputs::Files0From`], [`MINIMUM_WIDTH`] is returned. /// -/// If file metadata could not be read from any of the [`Input::Path`] input, -/// that input does not affect number width computation +/// An [`Inputs::Paths`] may include zero or more "-" entries, each of which represents reading +/// from `stdin`. The presence of any such entry causes this function to return a width that is at +/// least [`MINIMUM_WIDTH`]. /// -/// Otherwise, the file sizes in the file metadata are summed and the number of -/// digits in that total size is returned as the number width +/// If an [`Inputs::Paths`] contains only one path and only one number needs to be printed then +/// this function is optimized to return 1 without making any calls to get file metadata. /// -/// To mirror GNU wc's behavior a special case is added. If --files0-from is -/// used and input is read from stdin and there is only one calculation enabled -/// columns will not be aligned. This is not exactly GNU wc's behavior, but it -/// is close enough to pass the GNU test suite. -fn compute_number_width(inputs: &[Input], settings: &Settings) -> usize { - if inputs.is_empty() - || settings.number_enabled() == 1 - && (inputs.len() == 1 - || settings.files0_from_path.as_ref().map(|p| p.as_os_str()) - == Some(OsStr::new(STDIN_REPR))) - { - return 1; - } - - let mut minimum_width = 1; - let mut total = 0; - - for input in inputs { - match input { - Input::Stdin(_) => { - minimum_width = MINIMUM_WIDTH; +/// If file metadata could not be read from any of the [`Input::Path`] input, that input does not +/// affect number width computation. Otherwise, the file sizes from the files' metadata are summed +/// and the number of digits in that total size is returned. +fn compute_number_width(inputs: &Inputs, settings: &Settings) -> usize { + match inputs { + Inputs::Stdin if settings.number_enabled() == 1 => 1, + Inputs::Stdin => MINIMUM_WIDTH, + Inputs::Files0From(_) => 1, + Inputs::Paths(inputs) => { + if settings.number_enabled() == 1 && inputs.len() == 1 { + return 1; } - Input::Path(path) => { - if let Ok(meta) = fs::metadata(path) { - if meta.is_file() { - total += meta.len(); - } else { - minimum_width = MINIMUM_WIDTH; + + let mut minimum_width = 1; + let mut total: u64 = 0; + for input in inputs.iter() { + match input { + Input::Stdin(_) => minimum_width = MINIMUM_WIDTH, + Input::Path(path) => { + if let Ok(meta) = fs::metadata(path) { + if meta.is_file() { + total += meta.len(); + } else { + minimum_width = MINIMUM_WIDTH; + } + } } } } + + if total == 0 { + minimum_width + } else { + let total_width = (1 + ilog10_u64(total)) + .try_into() + .expect("ilog of a u64 should fit into a usize"); + max(total_width, minimum_width) + } } } +} - if total == 0 { - minimum_width - } else { - let total_width = (1 + ilog10_u64(total)) - .try_into() - .expect("ilog of a u64 should fit into a usize"); - max(total_width, minimum_width) +type InputIterItem<'a> = Result, Box>; + +/// To be used with `--files0-from=-`, this applies a filter on the results of files0_iter to +/// translate '-' into the appropriate error. +fn files0_iter_stdin<'a>() -> impl Iterator> { + files0_iter(io::stdin().lock(), STDIN_REPR.into()).map(|i| match i { + Ok(Input::Stdin(_)) => Err(WcError::StdinReprNotAllowed.into()), + _ => i, + }) +} + +fn files0_iter_file<'a>(path: &Path) -> UResult>> { + match File::open(path) { + Ok(f) => Ok(files0_iter(f, path.into())), + Err(e) => Err(e.map_err_context(|| { + format!( + "cannot open {} for reading", + escape_name(path.as_os_str(), QS_QUOTE_ESCAPE) + ) + })), } } -fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> { +fn files0_iter<'a>( + r: impl io::Read + 'static, + err_path: OsString, +) -> impl Iterator> { + use std::io::BufRead; + let mut i = Some( + io::BufReader::new(r) + .split(b'\0') + .map(move |res| match res { + Ok(p) if p == STDIN_REPR.as_bytes() => Ok(Input::Stdin(StdinKind::Explicit)), + Ok(p) => { + // On Unix systems, OsStrings are just strings of bytes, not necessarily UTF-8. + #[cfg(unix)] + { + use std::os::unix::ffi::OsStringExt; + Ok(Input::Path(PathBuf::from(OsString::from_vec(p)).into())) + } + + // ...Windows does not, we must go through Strings. + #[cfg(not(unix))] + { + let s = String::from_utf8(p) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; + Ok(Input::Path(PathBuf::from(s).into())) + } + } + Err(e) => Err(e.map_err_context(|| { + format!("{}: read error", escape_name(&err_path, QS_ESCAPE)) + }) as Box), + }), + ); + // Loop until there is an error; yield that error and then nothing else. + std::iter::from_fn(move || { + let next = i.as_mut().and_then(Iterator::next); + if matches!(next, Some(Err(_)) | None) { + i = None; + } + next + }) +} + +fn wc(inputs: &Inputs, settings: &Settings) -> UResult<()> { let mut total_word_count = WordCount::default(); + let mut num_inputs: usize = 0; let (number_width, are_stats_visible) = match settings.total_when { TotalWhen::Only => (1, false), _ => (compute_number_width(inputs, settings), true), }; - let is_total_row_visible = settings.total_when.is_total_row_visible(inputs.len()); - for (idx, input) in inputs.iter().enumerate() { - if matches!(input, Input::Path(p) if p.as_os_str().is_empty()) { - let err = WcError::zero_len(settings.files0_from_path.as_deref().map(|s| (s, idx))); - show!(err); - continue; - } - let word_count = match word_count_from_input(input, settings) { + for maybe_input in inputs.try_iter(settings)? { + num_inputs += 1; + + let input = match maybe_input { + Ok(input) => input, + Err(err) => { + show!(err); + continue; + } + }; + + let word_count = match word_count_from_input(&input, settings) { CountResult::Success(word_count) => word_count, CountResult::Interrupted(word_count, err) => { show!(err.map_err_context(|| input.path_display())); @@ -679,7 +833,7 @@ fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> { } } - if is_total_row_visible { + if settings.total_when.is_total_row_visible(num_inputs) { let title = are_stats_visible.then_some("total"); if let Err(err) = print_stats(settings, &total_word_count, title, number_width) { show!(err.map_err_context(|| "failed to print total".into())); diff --git a/tests/by-util/test_wc.rs b/tests/by-util/test_wc.rs index 1ce27f18d8..01c36b7c0d 100644 --- a/tests/by-util/test_wc.rs +++ b/tests/by-util/test_wc.rs @@ -424,10 +424,12 @@ fn test_files0_from() { new_ucmd!() .args(&["--files0-from=files0_list.txt"]) .run() - .stdout_is( - " 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 5 57 302 \ - alice_in_wonderland.txt\n 36 370 2189 total\n", - ); + .stdout_is(concat!( + " 13 109 772 lorem_ipsum.txt\n", + " 18 204 1115 moby_dick.txt\n", + " 5 57 302 alice_in_wonderland.txt\n", + " 36 370 2189 total\n", + )); } #[test] @@ -436,7 +438,7 @@ fn test_files0_from_with_stdin() { .args(&["--files0-from=-"]) .pipe_in("lorem_ipsum.txt") .run() - .stdout_is(" 13 109 772 lorem_ipsum.txt\n"); + .stdout_is("13 109 772 lorem_ipsum.txt\n"); } #[test] @@ -445,10 +447,12 @@ fn test_files0_from_with_stdin_in_file() { .args(&["--files0-from=files0_list_with_stdin.txt"]) .pipe_in_fixture("alice_in_wonderland.txt") .run() - .stdout_is( - " 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 5 57 302 \ - -\n 36 370 2189 total\n", - ); + .stdout_is(concat!( + " 13 109 772 lorem_ipsum.txt\n", + " 18 204 1115 moby_dick.txt\n", + " 5 57 302 -\n", + " 36 370 2189 total\n", + )); } #[test] From d1d64049e324f1bcf6e61cd1196752b6adaf5591 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 07:34:09 +0000 Subject: [PATCH 336/477] chore(deps): update rust crate clap_complete to 4.3 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9f9532b65..edf17c2c14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -298,9 +298,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c22dcfb410883764b29953103d9ef7bb8fe21b3fa1158bc99986c2067294bd" +checksum = "a04ddfaacc3bc9e6ea67d024575fafc2a813027cf374b8f24f7bc233c6b6be12" dependencies = [ "clap", ] diff --git a/Cargo.toml b/Cargo.toml index 8f62a87f6c..37e548c81f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -270,7 +270,7 @@ bytecount = "0.6.3" byteorder = "1.4.3" chrono = { version="^0.4.24", default-features=false, features=["std", "alloc", "clock"]} clap = { version = "4.2", features = ["wrap_help", "cargo"] } -clap_complete = "4.2" +clap_complete = "4.3" clap_mangen = "0.2" compare = "0.1.0" coz = { version = "0.1.3" } From e5b46ea3eb2a5bd5c17b8dd0ef2af476bd8f5842 Mon Sep 17 00:00:00 2001 From: Jed Denlea Date: Sat, 29 Apr 2023 19:47:49 -0700 Subject: [PATCH 337/477] wc: more tests and fixes My previous commits meant to bring our wc's output and behavior in line with GNU's. There should be tests that check for these changes! I found a stupid bug in my own changes, I was not adding 1 to the indexes produced by .enumerate() when printing errors. --- src/uu/wc/src/wc.rs | 26 +-- tests/by-util/test_wc.rs | 203 ++++++++++++++++-- tests/fixtures/wc/alice in wonderland.txt | 5 + tests/fixtures/wc/dir with spaces/.keep | 0 tests/fixtures/wc/files0 with nonexistent.txt | Bin 0 -> 94 bytes 5 files changed, 199 insertions(+), 35 deletions(-) create mode 100644 tests/fixtures/wc/alice in wonderland.txt create mode 100644 tests/fixtures/wc/dir with spaces/.keep create mode 100644 tests/fixtures/wc/files0 with nonexistent.txt diff --git a/src/uu/wc/src/wc.rs b/src/uu/wc/src/wc.rs index 08d00db188..9fb8ca7a63 100644 --- a/src/uu/wc/src/wc.rs +++ b/src/uu/wc/src/wc.rs @@ -188,9 +188,9 @@ impl<'a> Inputs<'a> { }, }; - // The index of each yielded item must be tracked for error reporting. - let mut with_idx = base.enumerate(); - let files0_from_path = settings.files0_from.as_ref().map(|i| i.as_borrowed()); + // The 1-based index of each yielded item must be tracked for error reporting. + let mut with_idx = base.enumerate().map(|(i, v)| (i + 1, v)); + let files0_from_path = settings.files0_from.as_ref().map(|p| p.as_borrowed()); let iter = iter::from_fn(move || { let (idx, next) = with_idx.next()?; @@ -303,23 +303,9 @@ fn is_stdin_small_file() -> bool { matches!(f.metadata(), Ok(meta) if meta.is_file() && meta.len() <= (10 << 20)) } -#[cfg(windows)] -fn is_stdin_small_file() -> bool { - use std::os::windows::io::{AsRawHandle, FromRawHandle}; - // Safety: we'll rely on Rust to give us a valid RawHandle for stdin with which we can attempt - // to open a File, but only for the sake of fetching .metadata(). ManuallyDrop will ensure we - // don't do anything else to the FD if anything unexpected happens. - let f = std::mem::ManuallyDrop::new(unsafe { - let h = io::stdin().as_raw_handle(); - if h.is_null() { - return false; - } - File::from_raw_handle(h) - }); - matches!(f.metadata(), Ok(meta) if meta.is_file() && meta.len() <= (10 << 20)) -} - -#[cfg(not(any(unix, windows)))] +#[cfg(not(unix))] +// Windows presents a piped stdin as a "normal file" with a length equal to however many bytes +// have been buffered at the time it's checked. To be safe, we must never assume it's a file. fn is_stdin_small_file() -> bool { false } diff --git a/tests/by-util/test_wc.rs b/tests/by-util/test_wc.rs index 01c36b7c0d..aba5ed350a 100644 --- a/tests/by-util/test_wc.rs +++ b/tests/by-util/test_wc.rs @@ -268,12 +268,16 @@ fn test_multiple_default() { "lorem_ipsum.txt", "moby_dick.txt", "alice_in_wonderland.txt", + "alice in wonderland.txt", ]) .run() - .stdout_is( - " 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 5 57 302 \ - alice_in_wonderland.txt\n 36 370 2189 total\n", - ); + .stdout_is(concat!( + " 13 109 772 lorem_ipsum.txt\n", + " 18 204 1115 moby_dick.txt\n", + " 5 57 302 alice_in_wonderland.txt\n", + " 5 57 302 alice in wonderland.txt\n", + " 41 427 2491 total\n", + )); } /// Test for an empty file. @@ -352,17 +356,24 @@ fn test_file_bytes_dictate_width() { new_ucmd!() .args(&["-lwc", "alice_in_wonderland.txt", "lorem_ipsum.txt"]) .run() - .stdout_is( - " 5 57 302 alice_in_wonderland.txt\n 13 109 772 \ - lorem_ipsum.txt\n 18 166 1074 total\n", - ); + .stdout_is(concat!( + " 5 57 302 alice_in_wonderland.txt\n", + " 13 109 772 lorem_ipsum.txt\n", + " 18 166 1074 total\n", + )); // . is a directory, so minimum_width should get set to 7 #[cfg(not(windows))] - const STDOUT: &str = " 0 0 0 emptyfile.txt\n 0 0 0 \ - .\n 0 0 0 total\n"; + const STDOUT: &str = concat!( + " 0 0 0 emptyfile.txt\n", + " 0 0 0 .\n", + " 0 0 0 total\n", + ); #[cfg(windows)] - const STDOUT: &str = " 0 0 0 emptyfile.txt\n 0 0 0 total\n"; + const STDOUT: &str = concat!( + " 0 0 0 emptyfile.txt\n", + " 0 0 0 total\n", + ); new_ucmd!() .args(&["-lwc", "emptyfile.txt", "."]) .run() @@ -392,12 +403,10 @@ fn test_read_from_directory_error() { /// Test that getting counts from nonexistent file is an error. #[test] fn test_read_from_nonexistent_file() { - const MSG: &str = "bogusfile: No such file or directory"; new_ucmd!() .args(&["bogusfile"]) .fails() - .stderr_contains(MSG) - .stdout_is(""); + .stderr_only("wc: bogusfile: No such file or directory\n"); } #[test] @@ -421,15 +430,30 @@ fn test_files0_disabled_files_argument() { #[test] fn test_files0_from() { + // file new_ucmd!() .args(&["--files0-from=files0_list.txt"]) .run() + .success() .stdout_is(concat!( " 13 109 772 lorem_ipsum.txt\n", " 18 204 1115 moby_dick.txt\n", " 5 57 302 alice_in_wonderland.txt\n", " 36 370 2189 total\n", )); + + // stream + new_ucmd!() + .args(&["--files0-from=-"]) + .pipe_in_fixture("files0_list.txt") + .run() + .success() + .stdout_is(concat!( + "13 109 772 lorem_ipsum.txt\n", + "18 204 1115 moby_dick.txt\n", + "5 57 302 alice_in_wonderland.txt\n", + "36 370 2189 total\n", + )); } #[test] @@ -450,7 +474,7 @@ fn test_files0_from_with_stdin_in_file() { .stdout_is(concat!( " 13 109 772 lorem_ipsum.txt\n", " 18 204 1115 moby_dick.txt\n", - " 5 57 302 -\n", + " 5 57 302 -\n", // alice_in_wonderland.txt " 36 370 2189 total\n", )); } @@ -531,3 +555,152 @@ fn test_total_only() { .run() .stdout_is("31 313 1887\n"); } + +#[test] +fn test_zero_length_files() { + // A trailing zero is ignored, but otherwise empty file names are an error... + const LIST: &str = "\0moby_dick.txt\0\0alice_in_wonderland.txt\0\0lorem_ipsum.txt\0"; + + // Try with and without the last \0 + for l in [LIST.len(), LIST.len() - 1] { + new_ucmd!() + .args(&["--files0-from=-"]) + .pipe_in(&LIST[..l]) + .run() + .failure() + .stdout_is(concat!( + "18 204 1115 moby_dick.txt\n", + "5 57 302 alice_in_wonderland.txt\n", + "13 109 772 lorem_ipsum.txt\n", + "36 370 2189 total\n", + )) + .stderr_is(concat!( + "wc: -:1: invalid zero-length file name\n", + "wc: -:3: invalid zero-length file name\n", + "wc: -:5: invalid zero-length file name\n", + )); + } + + // But, just as important, a zero-length file name may still be at the end... + new_ucmd!() + .args(&["--files0-from=-"]) + .pipe_in( + LIST.as_bytes() + .iter() + .chain(b"\0") + .copied() + .collect::>(), + ) + .run() + .failure() + .stdout_is(concat!( + "18 204 1115 moby_dick.txt\n", + "5 57 302 alice_in_wonderland.txt\n", + "13 109 772 lorem_ipsum.txt\n", + "36 370 2189 total\n", + )) + .stderr_is(concat!( + "wc: -:1: invalid zero-length file name\n", + "wc: -:3: invalid zero-length file name\n", + "wc: -:5: invalid zero-length file name\n", + "wc: -:7: invalid zero-length file name\n", + )); +} + +#[test] +fn test_files0_errors_quoting() { + new_ucmd!() + .args(&["--files0-from=files0 with nonexistent.txt"]) + .run() + .failure() + .stderr_is(concat!( + "wc: this_file_does_not_exist.txt: No such file or directory\n", + "wc: 'files0 with nonexistent.txt':2: invalid zero-length file name\n", + "wc: 'this file does not exist.txt': No such file or directory\n", + "wc: \"this files doesn't exist either.txt\": No such file or directory\n", + )) + .stdout_is("0 0 0 total\n"); +} + +#[test] +fn test_files0_progressive_stream() { + use std::process::Stdio; + // You should be able to run wc and have a back-and-forth exchange with wc... + let mut child = new_ucmd!() + .args(&["--files0-from=-"]) + .set_stdin(Stdio::piped()) + .set_stdout(Stdio::piped()) + .set_stderr(Stdio::piped()) + .run_no_wait(); + + macro_rules! chk { + ($fn:ident, $exp:literal) => { + assert_eq!(child.$fn($exp.len()), $exp.as_bytes()); + }; + } + + // File in, count out... + child.write_in("moby_dick.txt\0"); + chk!(stdout_exact_bytes, "18 204 1115 moby_dick.txt\n"); + child.write_in("lorem_ipsum.txt\0"); + chk!(stdout_exact_bytes, "13 109 772 lorem_ipsum.txt\n"); + + // Introduce an error! + child.write_in("\0"); + chk!( + stderr_exact_bytes, + "wc: -:3: invalid zero-length file name\n" + ); + + // wc is quick to forgive, let's move on... + child.write_in("alice_in_wonderland.txt\0"); + chk!(stdout_exact_bytes, "5 57 302 alice_in_wonderland.txt\n"); + + // Fin. + child + .wait() + .expect("wc should finish") + .failure() + .stdout_only("36 370 2189 total\n"); +} + +#[test] +fn files0_from_dir() { + // On Unix, `read(open("."))` fails. On Windows, `open(".")` fails. Thus, the errors happen in + // different contexts. + #[cfg(not(windows))] + macro_rules! dir_err { + ($p:literal) => { + concat!("wc: ", $p, ": read error: Is a directory\n") + }; + } + #[cfg(windows)] + macro_rules! dir_err { + ($p:literal) => { + concat!("wc: cannot open ", $p, " for reading: Permission denied\n") + }; + } + + new_ucmd!() + .args(&["--files0-from=dir with spaces"]) + .fails() + .stderr_only(dir_err!("'dir with spaces'")); + + // Those contexts have different rules about quoting in errors... + #[cfg(windows)] + const DOT_ERR: &str = dir_err!("'.'"); + #[cfg(not(windows))] + const DOT_ERR: &str = dir_err!("."); + new_ucmd!() + .args(&["--files0-from=."]) + .fails() + .stderr_only(DOT_ERR); + + // That also means you cannot `< . wc --files0-from=-` on Windows. + #[cfg(not(windows))] + new_ucmd!() + .args(&["--files0-from=-"]) + .set_stdin(std::fs::File::open(".").unwrap()) + .fails() + .stderr_only(dir_err!("-")); +} diff --git a/tests/fixtures/wc/alice in wonderland.txt b/tests/fixtures/wc/alice in wonderland.txt new file mode 100644 index 0000000000..a95562a1ce --- /dev/null +++ b/tests/fixtures/wc/alice in wonderland.txt @@ -0,0 +1,5 @@ +Alice was beginning to get very tired of sitting by +her sister on the bank, and of having nothing to do: once or twice +she had peeped into the book her sister was reading, but it had no +pictures or conversations in it, "and what is the use of a book," +thought Alice "without pictures or conversation?" diff --git a/tests/fixtures/wc/dir with spaces/.keep b/tests/fixtures/wc/dir with spaces/.keep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/fixtures/wc/files0 with nonexistent.txt b/tests/fixtures/wc/files0 with nonexistent.txt new file mode 100644 index 0000000000000000000000000000000000000000..00c00b705b1675852a0f3f72509aed19b4eb851c GIT binary patch literal 94 zcmXTP$SjUe%gjlQPsvX$j?c?4iBGM_EH2S2sVHG!C;`eUfMgXwvI;<11%xbIvKTCz Rrw)}=NX;zCNG$@H005vrBUS(a literal 0 HcmV?d00001 From 66224cdbf8d57fc8bda12fb891a9667b5cbe9c5e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 11:32:58 +0000 Subject: [PATCH 338/477] fix(deps): update rust crate data-encoding to 2.4 --- Cargo.lock | 4 ++-- src/uucore/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9f9532b65..fdbdcebc62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -761,9 +761,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.3.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "data-encoding-macro" diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 8693fbfc4f..2ed0b89892 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -29,7 +29,7 @@ itertools = { version="0.10.5", optional=true } thiserror = { workspace=true, optional=true } time = { workspace=true, optional=true, features = ["formatting", "local-offset", "macros"] } # * "problem" dependencies (pinned) -data-encoding = { version="2.3", optional=true } +data-encoding = { version="2.4", optional=true } data-encoding-macro = { version="0.1.12", optional=true } z85 = { version="3.0.5", optional=true } libc = { version="0.2.144", optional=true } From cda52ebce655c6e3e673317094e6608daa85d00d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 12:36:42 +0000 Subject: [PATCH 339/477] fix(deps): update rust crate data-encoding-macro to 0.1.13 --- Cargo.lock | 8 ++++---- src/uucore/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 456f909ad0..829939c971 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -767,9 +767,9 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "data-encoding-macro" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -777,9 +777,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5bbed42daaa95e780b60a50546aa345b8413a1e46f9a40a12907d3598f038db" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" dependencies = [ "data-encoding", "syn", diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 2ed0b89892..ea7fb44f3c 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -30,7 +30,7 @@ thiserror = { workspace=true, optional=true } time = { workspace=true, optional=true, features = ["formatting", "local-offset", "macros"] } # * "problem" dependencies (pinned) data-encoding = { version="2.4", optional=true } -data-encoding-macro = { version="0.1.12", optional=true } +data-encoding-macro = { version="0.1.13", optional=true } z85 = { version="3.0.5", optional=true } libc = { version="0.2.144", optional=true } once_cell = { workspace=true } From 8ffc33429e6ed32b84443202830f7c9734770efc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 12:49:11 +0000 Subject: [PATCH 340/477] chore(deps): update rust crate digest to 0.10.7 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 456f909ad0..5972a6cd96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -793,9 +793,9 @@ checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", diff --git a/Cargo.toml b/Cargo.toml index 37e548c81f..0fdf76e31c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -341,7 +341,7 @@ sha3 = "0.10.8" blake2b_simd = "1.0.1" blake3 = "1.3.3" sm3 = "0.4.2" -digest = "0.10.6" +digest = "0.10.7" uucore = { version=">=0.0.18", package="uucore", path="src/uucore" } uucore_procs = { version=">=0.0.18", package="uucore_procs", path="src/uucore_procs" } From 19aacbdc409af5afe4dd949589c293e7fd08aba1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 15:52:38 +0000 Subject: [PATCH 341/477] chore(deps): update rust crate bstr to 1.5 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e9b3d281f..79dc58af8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,9 +200,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09" +checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5" dependencies = [ "memchr", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index 0fdf76e31c..d792e76424 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -265,7 +265,7 @@ test = [ "uu_test" ] [workspace.dependencies] bigdecimal = "0.3" binary-heap-plus = "0.5.0" -bstr = "1.4" +bstr = "1.5" bytecount = "0.6.3" byteorder = "1.4.3" chrono = { version="^0.4.24", default-features=false, features=["std", "alloc", "clock"]} From d41777c52c34d5c772d5e200710a73ba5b96ca3b Mon Sep 17 00:00:00 2001 From: tpeters Date: Mon, 22 May 2023 20:07:14 +0200 Subject: [PATCH 342/477] more: change file unwrap to match --- src/uu/more/src/more.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 64683a1bec..b9d9c8272c 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -104,7 +104,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if length > 1 { buff.push_str(&MULTI_FILE_TOP_PROMPT.replace("{}", file.to_str().unwrap())); } - let mut reader = BufReader::new(File::open(file).unwrap()); + let opened_file = match File::open(file) { + Err(why) => { + return Err(UUsageError::new( + 1, + format!("cannot open {}: {}", file.quote(), why.kind()), + )) + } + Ok(opened_file) => opened_file, + }; + let mut reader = BufReader::new(opened_file); reader.read_to_string(&mut buff).unwrap(); more(&buff, &mut stdout, next_file.copied(), &options)?; buff.clear(); From 92f4849b605f6d070c3fd035bdea4c55747ae750 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 22 May 2023 23:29:55 +0200 Subject: [PATCH 343/477] date: bring back the test --- tests/by-util/test_date.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index 42a94099db..4dc02ef6f3 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -303,6 +303,7 @@ fn test_date_for_no_permission_file() { ); } +#[test] fn test_date_for_dir_as_file() { let result = new_ucmd!().arg("--file").arg("/").fails(); result.no_stdout(); From 78909fdd392ce4513c87b29f81cf05776384ee4d Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 22 May 2023 21:11:47 -0700 Subject: [PATCH 344/477] rm: allow empty when for --interactive arg --- src/uu/rm/src/rm.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 2a8a57be06..2d875bdd96 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -169,6 +169,9 @@ pub fn uu_app() -> Command { prompts always", ) .value_name("WHEN") + .num_args(0..=1) + .require_equals(true) + .default_missing_value("always") .overrides_with_all([OPT_PROMPT, OPT_PROMPT_MORE]), ) .arg( From eeb3341101f9bcb500f51e4b242850bbd831e5cd Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 22 May 2023 21:23:44 -0700 Subject: [PATCH 345/477] rm: add tests for --interactive with empty when --- tests/by-util/test_rm.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index a5c342ffe7..85d96d2ee7 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -361,6 +361,26 @@ fn test_rm_interactive_never() { assert!(!at.file_exists(file_2)); } +#[test] +fn test_rm_interactive_missing_value() { + // `--interactive` is equivalent to `--interactive=always` or `-i` + let (at, mut ucmd) = at_and_ucmd!(); + + let file1 = "test_rm_interactive_missing_value_file1"; + let file2 = "test_rm_interactive_missing_value_file2"; + + at.touch(file1); + at.touch(file2); + + ucmd.arg("--interactive") + .arg(file1) + .arg(file2) + .pipe_in("y\ny") + .succeeds(); + + assert!(!at.file_exists(file1)); + assert!(!at.file_exists(file2)); +} #[test] fn test_rm_descend_directory() { // This test descends into each directory and deletes the files and folders inside of them From e50b84035fc54063e57dbc9e13757ae4986b8d22 Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 22 May 2023 21:26:52 -0700 Subject: [PATCH 346/477] rm: fix prompt when --interactive is once --- src/uu/rm/src/rm.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 2d875bdd96..f2e2050d9f 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -115,11 +115,20 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { verbose: matches.get_flag(OPT_VERBOSE), }; if options.interactive == InteractiveMode::Once && (options.recursive || files.len() > 3) { - let msg = if options.recursive { - "Remove all arguments recursively?" - } else { - "Remove all arguments?" - }; + let msg: String = format!( + "remove {} {}{}", + files.len(), + if files.len() > 1 { + "arguments" + } else { + "argument" + }, + if options.recursive { + " recursively?" + } else { + "?" + } + ); if !prompt_yes!("{}", msg) { return Ok(()); } From 421b2f258152112fae0ea34cdb6faecae4dfba4b Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 22 May 2023 21:27:43 -0700 Subject: [PATCH 347/477] rm: test prompts when --interactive is once --- tests/by-util/test_rm.rs | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 85d96d2ee7..737c4fa79b 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -381,6 +381,54 @@ fn test_rm_interactive_missing_value() { assert!(!at.file_exists(file1)); assert!(!at.file_exists(file2)); } + +#[test] +fn test_rm_interactive_once_prompt() { + let (at, mut ucmd) = at_and_ucmd!(); + + let file1 = "test_rm_interactive_once_recursive_prompt_file1"; + let file2 = "test_rm_interactive_once_recursive_prompt_file2"; + let file3 = "test_rm_interactive_once_recursive_prompt_file3"; + let file4 = "test_rm_interactive_once_recursive_prompt_file4"; + + at.touch(file1); + at.touch(file2); + at.touch(file3); + at.touch(file4); + + ucmd.arg("--interactive=once") + .arg(file1) + .arg(file2) + .arg(file3) + .arg(file4) + .pipe_in("y") + .succeeds() + .stderr_contains("remove 4 arguments?"); + + assert!(!at.file_exists(file1)); + assert!(!at.file_exists(file2)); + assert!(!at.file_exists(file3)); + assert!(!at.file_exists(file4)); +} + +#[test] +fn test_rm_interactive_once_recursive_prompt() { + let (at, mut ucmd) = at_and_ucmd!(); + + let file1 = "test_rm_interactive_once_recursive_prompt_file1"; + + at.touch(file1); + + ucmd.arg("--interactive=once") + .arg("-r") + .arg(file1) + .pipe_in("y") + .succeeds() + .stderr_contains("remove 1 argument recursively?"); + + assert!(!at.file_exists(file1)); +} + #[test] fn test_rm_descend_directory() { // This test descends into each directory and deletes the files and folders inside of them From 2f4b57ca973c4ab9036d63ef0fcbc211f0b79fcc Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 23 May 2023 07:23:42 +0200 Subject: [PATCH 348/477] mv: add missing semicolons to tests --- tests/by-util/test_mv.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 5c1d6c747e..39eaed1e72 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -825,7 +825,7 @@ fn test_mv_arg_update_none() { .no_stderr() .no_stdout(); - assert_eq!(at.read(file2), file2_content) + assert_eq!(at.read(file2), file2_content); } #[test] @@ -847,7 +847,7 @@ fn test_mv_arg_update_all() { .no_stderr() .no_stdout(); - assert_eq!(at.read(file2), file1_content) + assert_eq!(at.read(file2), file1_content); } #[test] @@ -872,7 +872,7 @@ fn test_mv_arg_update_older_dest_not_older() { .no_stderr() .no_stdout(); - assert_eq!(at.read(new), new_content) + assert_eq!(at.read(new), new_content); } #[test] From 465b245a1c624b7c914960b8ed6e1e8c95f50ab9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 06:24:59 +0000 Subject: [PATCH 349/477] chore(deps): update rust crate regex to 1.8.2 --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79dc58af8e..35713129ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1899,9 +1899,9 @@ checksum = "f1bfbf25d7eb88ddcbb1ec3d755d0634da8f7657b2cb8b74089121409ab8228f" [[package]] name = "regex" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +checksum = "d1a59b5d8e97dee33696bf13c5ba8ab85341c002922fba050069326b9c498974" dependencies = [ "aho-corasick 1.0.1", "memchr", @@ -1916,9 +1916,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "rlimit" diff --git a/Cargo.toml b/Cargo.toml index d792e76424..9abc28bc26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -311,7 +311,7 @@ rand = { version = "0.8", features = ["small_rng"] } rand_core = "0.6" rayon = "1.7" redox_syscall = "0.2" -regex = "1.8.1" +regex = "1.8.2" rstest = "0.17.0" rust-ini = "0.18.0" same-file = "1.0.6" From 9e0a63fae7d32736c871a33a46084bd1df51693d Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 23 May 2023 10:34:06 +0200 Subject: [PATCH 350/477] Bump crossbeam(-channel, -epoch, -utils) crates crossbeam-channel from 0.5.6 to 0.5.8 crossbeam-epoch from 0.9.12 to 0.9.14 crossbeam-utils from 0.8.13 to 0.8.15 --- Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 35713129ab..12a3baec4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -607,9 +607,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if", "crossbeam-utils", @@ -628,9 +628,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.12" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bf8df95e795db1a4aca2957ad884a2df35413b24bbeb3114422f3cc21498e8" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if", @@ -641,9 +641,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.13" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422f23e724af1240ec469ea1e834d87a4b59ce2efe2c6a96256b0c47e2fd86aa" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] @@ -1413,9 +1413,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] From 50bff30c67cff3a87bb956ae52d2f5e91948c91b Mon Sep 17 00:00:00 2001 From: tpeters Date: Tue, 23 May 2023 18:03:25 +0200 Subject: [PATCH 351/477] more: add test and change error type --- src/uu/more/src/more.rs | 2 +- tests/by-util/test_more.rs | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index b9d9c8272c..b5487ef871 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -106,7 +106,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } let opened_file = match File::open(file) { Err(why) => { - return Err(UUsageError::new( + return Err(USimpleError::new( 1, format!("cannot open {}: {}", file.quote(), why.kind()), )) diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index cb12343fa0..75f0eed779 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -1,5 +1,7 @@ use crate::common::util::TestScenario; use is_terminal::IsTerminal; +use std::fs::{set_permissions, Permissions}; +use std::os::unix::fs::PermissionsExt; #[test] fn test_more_no_arg() { @@ -32,3 +34,14 @@ fn test_more_dir_arg() { .usage_error("'.' is a directory."); } } + +#[test] +fn test_more_invalid_file_perms() { + let (at, mut ucmd) = at_and_ucmd!(); + let permissions = Permissions::from_mode(0o244); + at.make_file("invalid-perms.txt").metadata().unwrap(); + set_permissions(at.plus("invalid-perms.txt"), permissions).unwrap(); + ucmd.arg("invalid-perms.txt").fails(); + //.code_is(1) + //.stderr_is("more: cannot open 'invalid-perms.txt': permission denied"); +} From c561074425cef41265266fd9056f9ac853f5f20e Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 23 May 2023 15:45:04 -0700 Subject: [PATCH 352/477] mkdir: explicitly set umask when testing mode --- tests/by-util/test_mkdir.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index efa7c3248d..ba29c31ca5 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -162,9 +162,14 @@ fn test_symbolic_mode() { fn test_symbolic_alteration() { let (at, mut ucmd) = at_and_ucmd!(); + let default_umask = 0o022; + let original_umask = unsafe { umask(default_umask) }; + ucmd.arg("-m").arg("-w").arg(TEST_DIR1).succeeds(); let perms = at.metadata(TEST_DIR1).permissions().mode(); assert_eq!(perms, 0o40577); + + unsafe { umask(original_umask) }; } #[test] From f8a5dbc41c6e117c34ce5ca7132674c7627a8748 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 23 May 2023 15:56:51 -0700 Subject: [PATCH 353/477] mkdir: run tests sequentially by adding a mutex --- tests/by-util/test_mkdir.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index ba29c31ca5..308df48057 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -1,8 +1,12 @@ use crate::common::util::TestScenario; #[cfg(not(windows))] use libc::{mode_t, umask}; +use once_cell::sync::Lazy; #[cfg(not(windows))] use std::os::unix::fs::PermissionsExt; +use std::sync::Mutex; + +static TEST_MUTEX: Lazy> = Lazy::new(|| Mutex::new(())); static TEST_DIR1: &str = "mkdir_test1"; static TEST_DIR2: &str = "mkdir_test2"; @@ -20,16 +24,19 @@ static TEST_DIR12: &str = "mkdir_test12"; #[test] fn test_invalid_arg() { + let _guard = TEST_MUTEX.lock(); new_ucmd!().arg("--definitely-invalid").fails().code_is(1); } #[test] fn test_mkdir_mkdir() { + let _guard = TEST_MUTEX.lock(); new_ucmd!().arg(TEST_DIR1).succeeds(); } #[test] fn test_mkdir_verbose() { + let _guard = TEST_MUTEX.lock(); let expected = "mkdir: created directory 'mkdir_test1'\n"; new_ucmd!() .arg(TEST_DIR1) @@ -40,6 +47,7 @@ fn test_mkdir_verbose() { #[test] fn test_mkdir_dup_dir() { + let _guard = TEST_MUTEX.lock(); let scene = TestScenario::new(util_name!()); scene.ucmd().arg(TEST_DIR2).succeeds(); scene.ucmd().arg(TEST_DIR2).fails(); @@ -47,11 +55,13 @@ fn test_mkdir_dup_dir() { #[test] fn test_mkdir_mode() { + let _guard = TEST_MUTEX.lock(); new_ucmd!().arg("-m").arg("755").arg(TEST_DIR3).succeeds(); } #[test] fn test_mkdir_parent() { + let _guard = TEST_MUTEX.lock(); let scene = TestScenario::new(util_name!()); scene.ucmd().arg("-p").arg(TEST_DIR4).succeeds(); scene.ucmd().arg("-p").arg(TEST_DIR4).succeeds(); @@ -61,11 +71,13 @@ fn test_mkdir_parent() { #[test] fn test_mkdir_no_parent() { + let _guard = TEST_MUTEX.lock(); new_ucmd!().arg(TEST_DIR5).fails(); } #[test] fn test_mkdir_dup_dir_parent() { + let _guard = TEST_MUTEX.lock(); let scene = TestScenario::new(util_name!()); scene.ucmd().arg(TEST_DIR6).succeeds(); scene.ucmd().arg("-p").arg(TEST_DIR6).succeeds(); @@ -74,6 +86,7 @@ fn test_mkdir_dup_dir_parent() { #[cfg(not(windows))] #[test] fn test_mkdir_parent_mode() { + let _guard = TEST_MUTEX.lock(); let (at, mut ucmd) = at_and_ucmd!(); let default_umask: mode_t = 0o160; @@ -102,6 +115,7 @@ fn test_mkdir_parent_mode() { #[cfg(not(windows))] #[test] fn test_mkdir_parent_mode_check_existing_parent() { + let _guard = TEST_MUTEX.lock(); let (at, mut ucmd) = at_and_ucmd!(); at.mkdir("a"); @@ -139,6 +153,7 @@ fn test_mkdir_parent_mode_check_existing_parent() { #[test] fn test_mkdir_dup_file() { + let _guard = TEST_MUTEX.lock(); let scene = TestScenario::new(util_name!()); scene.fixtures.touch(TEST_FILE7); scene.ucmd().arg(TEST_FILE7).fails(); @@ -150,6 +165,7 @@ fn test_mkdir_dup_file() { #[test] #[cfg(not(windows))] fn test_symbolic_mode() { + let _guard = TEST_MUTEX.lock(); let (at, mut ucmd) = at_and_ucmd!(); ucmd.arg("-m").arg("a=rwx").arg(TEST_DIR1).succeeds(); @@ -160,6 +176,7 @@ fn test_symbolic_mode() { #[test] #[cfg(not(windows))] fn test_symbolic_alteration() { + let _guard = TEST_MUTEX.lock(); let (at, mut ucmd) = at_and_ucmd!(); let default_umask = 0o022; @@ -175,6 +192,7 @@ fn test_symbolic_alteration() { #[test] #[cfg(not(windows))] fn test_multi_symbolic() { + let _guard = TEST_MUTEX.lock(); let (at, mut ucmd) = at_and_ucmd!(); ucmd.arg("-m") @@ -187,6 +205,7 @@ fn test_multi_symbolic() { #[test] fn test_recursive_reporting() { + let _guard = TEST_MUTEX.lock(); new_ucmd!() .arg("-p") .arg("-v") @@ -208,6 +227,7 @@ fn test_recursive_reporting() { #[test] fn test_mkdir_trailing_dot() { + let _guard = TEST_MUTEX.lock(); let scene2 = TestScenario::new("ls"); new_ucmd!() .arg("-p") @@ -236,6 +256,7 @@ fn test_mkdir_trailing_dot() { #[cfg(not(windows))] fn test_umask_compliance() { fn test_single_case(umask_set: mode_t) { + let _guard = TEST_MUTEX.lock(); let (at, mut ucmd) = at_and_ucmd!(); let original_umask = unsafe { umask(umask_set) }; From b29f8b011b55dc96891cd7d59c18a743a0f4c7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mo=C3=AFse=20Valvassori?= Date: Wed, 24 May 2023 09:45:19 +0200 Subject: [PATCH 354/477] chown: show "ownership of 'foo' retained" message * Display a message when the owner is not changed. * Display a message when the current user/group doesn't match those specified in the `--from` args. * print messages to stdout * Show the message "ownership of 'foo' retained as 'bar'" for every path entry when `chown -v -R --from=` * fix chown tests: test stdout and not stderr * factorize duplicate code in a function * Display a message when the owner is not changed. * Display a message when the current user/group doesn't match those specified in the `--from` args. * print messages to stdout * Show the message "ownership of 'foo' retained as 'bar'" for every path entry when `chown -v -R --from=` * fix chown tests: test stdout and not stderr * factorize duplicate code in a function * display the retained ownership details according to the destination ownership. --- src/uucore/src/lib/features/perms.rs | 39 ++++ tests/by-util/test_chown.rs | 260 +++++++++++++++++++++++++++ 2 files changed, 299 insertions(+) diff --git a/src/uucore/src/lib/features/perms.rs b/src/uucore/src/lib/features/perms.rs index 6383477371..5384b52a18 100644 --- a/src/uucore/src/lib/features/perms.rs +++ b/src/uucore/src/lib/features/perms.rs @@ -271,6 +271,11 @@ impl ChownExecutor { } } } else { + self.print_verbose_ownership_retained_as( + path, + meta.uid(), + self.dest_gid.map(|_| meta.gid()), + ); 0 }; @@ -332,6 +337,11 @@ impl ChownExecutor { }; if !self.matched(meta.uid(), meta.gid()) { + self.print_verbose_ownership_retained_as( + path, + meta.uid(), + self.dest_gid.map(|_| meta.gid()), + ); continue; } @@ -393,6 +403,35 @@ impl ChownExecutor { IfFrom::UserGroup(u, g) => u == uid && g == gid, } } + + fn print_verbose_ownership_retained_as(&self, path: &Path, uid: u32, gid: Option) { + if self.verbosity.level == VerbosityLevel::Verbose { + match (self.dest_uid, self.dest_gid, gid) { + (Some(_), Some(_), Some(gid)) => { + println!( + "ownership of {} retained as {}:{}", + path.quote(), + entries::uid2usr(uid).unwrap_or_else(|_| uid.to_string()), + entries::gid2grp(gid).unwrap_or_else(|_| gid.to_string()), + ); + } + (None, Some(_), Some(gid)) => { + println!( + "ownership of {} retained as {}", + path.quote(), + entries::gid2grp(gid).unwrap_or_else(|_| gid.to_string()), + ); + } + (_, _, _) => { + println!( + "ownership of {} retained as {}", + path.quote(), + entries::uid2usr(uid).unwrap_or_else(|_| uid.to_string()), + ); + } + } + } + } } pub mod options { diff --git a/tests/by-util/test_chown.rs b/tests/by-util/test_chown.rs index fd7e377224..191e4a86b3 100644 --- a/tests/by-util/test_chown.rs +++ b/tests/by-util/test_chown.rs @@ -742,3 +742,263 @@ fn test_chown_file_notexisting() { // TODO: uncomment once message changed from "cannot dereference" to "cannot access" // result.stderr_contains("cannot access 'not_existing': No such file or directory"); } + +#[test] +fn test_chown_no_change_to_user_from_user() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let result = scene.cmd("whoami").run(); + if skipping_test_is_okay(&result, "whoami: cannot find name for user ID") { + return; + } + let user_name = String::from(result.stdout_str().trim()); + assert!(!user_name.is_empty()); + + let file = "f"; + at.touch(file); + scene + .ucmd() + .arg("-v") + .arg("--from=42") + .arg("43") + .arg(file) + .succeeds() + .stdout_only(format!("ownership of '{file}' retained as {user_name}\n")); +} + +#[test] +fn test_chown_no_change_to_user_from_group() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let result = scene.cmd("whoami").run(); + if skipping_test_is_okay(&result, "whoami: cannot find name for user ID") { + return; + } + let user_name = String::from(result.stdout_str().trim()); + assert!(!user_name.is_empty()); + + let file = "f"; + at.touch(file); + scene + .ucmd() + .arg("-v") + .arg("--from=:42") + .arg("43") + .arg(file) + .succeeds() + .stdout_only(format!("ownership of '{file}' retained as {user_name}\n")); +} + +#[test] +fn test_chown_no_change_to_user_from_user_group() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let result = scene.cmd("whoami").run(); + if skipping_test_is_okay(&result, "whoami: cannot find name for user ID") { + return; + } + let user_name = String::from(result.stdout_str().trim()); + assert!(!user_name.is_empty()); + + let file = "f"; + at.touch(file); + scene + .ucmd() + .arg("-v") + .arg("--from=42:42") + .arg("43") + .arg(file) + .succeeds() + .stdout_only(format!("ownership of '{file}' retained as {user_name}\n")); +} + +#[test] +fn test_chown_no_change_to_group_from_user() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let result = scene.cmd("whoami").run(); + if skipping_test_is_okay(&result, "whoami: cannot find name for user ID") { + return; + } + let user_name = String::from(result.stdout_str().trim()); + assert!(!user_name.is_empty()); + + let result = scene.cmd("id").arg("-ng").run(); + if skipping_test_is_okay(&result, "id: cannot find name for group ID") { + return; + } + let group_name = String::from(result.stdout_str().trim()); + assert!(!group_name.is_empty()); + + let file = "f"; + at.touch(file); + scene + .ucmd() + .arg("-v") + .arg("--from=42") + .arg(":43") + .arg(file) + .succeeds() + .stdout_only(format!("ownership of '{file}' retained as {group_name}\n")); +} + +#[test] +fn test_chown_no_change_to_group_from_group() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let result = scene.cmd("whoami").run(); + if skipping_test_is_okay(&result, "whoami: cannot find name for user ID") { + return; + } + let user_name = String::from(result.stdout_str().trim()); + assert!(!user_name.is_empty()); + let result = scene.cmd("id").arg("-ng").run(); + if skipping_test_is_okay(&result, "id: cannot find name for group ID") { + return; + } + let group_name = String::from(result.stdout_str().trim()); + assert!(!group_name.is_empty()); + + let file = "f"; + at.touch(file); + scene + .ucmd() + .arg("-v") + .arg("--from=:42") + .arg(":43") + .arg(file) + .succeeds() + .stdout_only(format!("ownership of '{file}' retained as {group_name}\n")); +} + +#[test] +fn test_chown_no_change_to_group_from_user_group() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let result = scene.cmd("whoami").run(); + if skipping_test_is_okay(&result, "whoami: cannot find name for user ID") { + return; + } + let user_name = String::from(result.stdout_str().trim()); + assert!(!user_name.is_empty()); + let result = scene.cmd("id").arg("-ng").run(); + if skipping_test_is_okay(&result, "id: cannot find name for group ID") { + return; + } + let group_name = String::from(result.stdout_str().trim()); + assert!(!group_name.is_empty()); + + let file = "f"; + at.touch(file); + scene + .ucmd() + .arg("-v") + .arg("--from=42:42") + .arg(":43") + .arg(file) + .succeeds() + .stdout_only(format!("ownership of '{file}' retained as {group_name}\n")); +} + +#[test] +fn test_chown_no_change_to_user_group_from_user() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let result = scene.cmd("whoami").run(); + if skipping_test_is_okay(&result, "whoami: cannot find name for user ID") { + return; + } + let user_name = String::from(result.stdout_str().trim()); + assert!(!user_name.is_empty()); + + let result = scene.cmd("id").arg("-ng").run(); + if skipping_test_is_okay(&result, "id: cannot find name for group ID") { + return; + } + let group_name = String::from(result.stdout_str().trim()); + assert!(!group_name.is_empty()); + + let file = "f"; + at.touch(file); + scene + .ucmd() + .arg("-v") + .arg("--from=42") + .arg("43:43") + .arg(file) + .succeeds() + .stdout_only(format!( + "ownership of '{file}' retained as {user_name}:{group_name}\n" + )); +} + +#[test] +fn test_chown_no_change_to_user_group_from_group() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let result = scene.cmd("whoami").run(); + if skipping_test_is_okay(&result, "whoami: cannot find name for user ID") { + return; + } + let user_name = String::from(result.stdout_str().trim()); + assert!(!user_name.is_empty()); + let result = scene.cmd("id").arg("-ng").run(); + if skipping_test_is_okay(&result, "id: cannot find name for group ID") { + return; + } + let group_name = String::from(result.stdout_str().trim()); + assert!(!group_name.is_empty()); + + let file = "f"; + at.touch(file); + scene + .ucmd() + .arg("-v") + .arg("--from=:42") + .arg("43:43") + .arg(file) + .succeeds() + .stdout_only(format!( + "ownership of '{file}' retained as {user_name}:{group_name}\n" + )); +} + +#[test] +fn test_chown_no_change_to_user_group_from_user_group() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let result = scene.cmd("whoami").run(); + if skipping_test_is_okay(&result, "whoami: cannot find name for user ID") { + return; + } + let user_name = String::from(result.stdout_str().trim()); + assert!(!user_name.is_empty()); + let result = scene.cmd("id").arg("-ng").run(); + if skipping_test_is_okay(&result, "id: cannot find name for group ID") { + return; + } + let group_name = String::from(result.stdout_str().trim()); + assert!(!group_name.is_empty()); + + let file = "f"; + at.touch(file); + scene + .ucmd() + .arg("-v") + .arg("--from=42:42") + .arg("43:43") + .arg(file) + .succeeds() + .stdout_only(format!( + "ownership of '{file}' retained as {user_name}:{group_name}\n" + )); +} From eed916a0760e80225e73caecf1a4b4ab9855ddb1 Mon Sep 17 00:00:00 2001 From: tpeters Date: Wed, 24 May 2023 12:30:28 +0200 Subject: [PATCH 355/477] more: disable raw mode on error --- src/uu/more/src/more.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index b5487ef871..8c6cdf6e2a 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -106,10 +106,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } let opened_file = match File::open(file) { Err(why) => { + terminal::disable_raw_mode().unwrap(); return Err(USimpleError::new( 1, format!("cannot open {}: {}", file.quote(), why.kind()), - )) + )); } Ok(opened_file) => opened_file, }; From 53ffd55bdfa9ac929023754679e7849610f9e667 Mon Sep 17 00:00:00 2001 From: tpeters Date: Wed, 24 May 2023 13:28:30 +0200 Subject: [PATCH 356/477] more: run test only on unix systems --- tests/by-util/test_more.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index 75f0eed779..7753aa0ca8 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -1,6 +1,10 @@ use crate::common::util::TestScenario; use is_terminal::IsTerminal; + +//Both following includes are only needed inside the test_more_invalid_file_perms() +#[cfg(target_family = "unix")] use std::fs::{set_permissions, Permissions}; +#[cfg(target_family = "unix")] use std::os::unix::fs::PermissionsExt; #[test] @@ -36,12 +40,13 @@ fn test_more_dir_arg() { } #[test] +#[cfg(target_family = "unix")] fn test_more_invalid_file_perms() { - let (at, mut ucmd) = at_and_ucmd!(); - let permissions = Permissions::from_mode(0o244); - at.make_file("invalid-perms.txt").metadata().unwrap(); - set_permissions(at.plus("invalid-perms.txt"), permissions).unwrap(); - ucmd.arg("invalid-perms.txt").fails(); - //.code_is(1) - //.stderr_is("more: cannot open 'invalid-perms.txt': permission denied"); + if std::io::stdout().is_terminal() { + let (at, mut ucmd) = at_and_ucmd!(); + let permissions = Permissions::from_mode(0o244); + at.make_file("invalid-perms.txt").metadata().unwrap(); + set_permissions(at.plus("invalid-perms.txt"), permissions).unwrap(); + ucmd.arg("invalid-perms.txt").fails(); + } } From ccdb76aef7b57cd2dd2251bc821cf5533e2deaf3 Mon Sep 17 00:00:00 2001 From: Ludmuterol <45458713+Ludmuterol@users.noreply.github.com> Date: Wed, 24 May 2023 15:57:55 +0200 Subject: [PATCH 357/477] more: Update tests/by-util/test_more.rs Co-authored-by: Daniel Hofstetter --- tests/by-util/test_more.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index 7753aa0ca8..7171ca4fe0 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -45,7 +45,7 @@ fn test_more_invalid_file_perms() { if std::io::stdout().is_terminal() { let (at, mut ucmd) = at_and_ucmd!(); let permissions = Permissions::from_mode(0o244); - at.make_file("invalid-perms.txt").metadata().unwrap(); + at.make_file("invalid-perms.txt"); set_permissions(at.plus("invalid-perms.txt"), permissions).unwrap(); ucmd.arg("invalid-perms.txt").fails(); } From 7cad501c2c6883327911eaedf44876ca25fa6a6c Mon Sep 17 00:00:00 2001 From: tpeters Date: Wed, 24 May 2023 16:32:29 +0200 Subject: [PATCH 358/477] more: add output check to test --- tests/by-util/test_more.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index 7171ca4fe0..97353deb8a 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -1,12 +1,6 @@ use crate::common::util::TestScenario; use is_terminal::IsTerminal; -//Both following includes are only needed inside the test_more_invalid_file_perms() -#[cfg(target_family = "unix")] -use std::fs::{set_permissions, Permissions}; -#[cfg(target_family = "unix")] -use std::os::unix::fs::PermissionsExt; - #[test] fn test_more_no_arg() { // Reading from stdin is now supported, so this must succeed @@ -42,11 +36,17 @@ fn test_more_dir_arg() { #[test] #[cfg(target_family = "unix")] fn test_more_invalid_file_perms() { + use std::fs::{set_permissions, Permissions}; + use std::os::unix::fs::PermissionsExt; + if std::io::stdout().is_terminal() { let (at, mut ucmd) = at_and_ucmd!(); let permissions = Permissions::from_mode(0o244); at.make_file("invalid-perms.txt"); set_permissions(at.plus("invalid-perms.txt"), permissions).unwrap(); - ucmd.arg("invalid-perms.txt").fails(); + ucmd.arg("invalid-perms.txt") + .fails() + .code_is(1) + .stderr_contains("permission denied"); } } From 90ed91608eabae6fbab01e42f333a685934d2cc5 Mon Sep 17 00:00:00 2001 From: John Shin Date: Wed, 24 May 2023 16:50:08 -0700 Subject: [PATCH 359/477] mkdir: document why a mutex is necessary --- tests/by-util/test_mkdir.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index 308df48057..425be8c35c 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -6,6 +6,10 @@ use once_cell::sync::Lazy; use std::os::unix::fs::PermissionsExt; use std::sync::Mutex; +// tests in `test_mkdir.rs` cannot run in parallel since some tests alter the umask. This may cause +// other tests to run under a wrong set of permissions +// +// when writing a test case, acquire this mutex before proceeding with the main logic of the test static TEST_MUTEX: Lazy> = Lazy::new(|| Mutex::new(())); static TEST_DIR1: &str = "mkdir_test1"; From 9f56e47e1d8b39f1474044cfebf1aa990b9bc09b Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 25 May 2023 13:23:20 +0200 Subject: [PATCH 360/477] Remove unused "num_cpus" dependency --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9abc28bc26..b891354644 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -296,7 +296,6 @@ memchr = "2" nix = { version="0.26", default-features=false } nom = "7.1.3" notify = { version = "=5.1.0", features=["macos_kqueue"]} -num_cpus = "1.15" num-bigint = "0.4.3" num-traits = "0.2.15" number_prefix = "0.4" From 2d15b01c8b8f0d9306f8ffe3c28047e6ec489e9e Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 25 May 2023 15:21:45 +0200 Subject: [PATCH 361/477] Bump rustix from 0.36.8 to 0.36.14 --- Cargo.lock | 25 +++++++------------------ deny.toml | 2 +- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12a3baec4d..a498797adb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -848,17 +848,6 @@ dependencies = [ "regex", ] -[[package]] -name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] - [[package]] name = "errno" version = "0.3.0" @@ -1792,7 +1781,7 @@ dependencies = [ "byteorder", "hex", "lazy_static", - "rustix 0.36.8", + "rustix 0.36.14", ] [[package]] @@ -1988,12 +1977,12 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.8" +version = "0.36.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +checksum = "14e4d67015953998ad0eb82887a0eb0129e18a7e2f3b7b0f6c422fddcd503d62" dependencies = [ "bitflags", - "errno 0.2.8", + "errno", "io-lifetimes", "libc", "linux-raw-sys 0.1.4", @@ -2007,7 +1996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" dependencies = [ "bitflags", - "errno 0.3.0", + "errno", "io-lifetimes", "libc", "linux-raw-sys 0.3.0", @@ -2225,7 +2214,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall", - "rustix 0.36.8", + "rustix 0.36.14", "windows-sys 0.42.0", ] @@ -2253,7 +2242,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c9afddd2cec1c0909f06b00ef33f94ab2cc0578c4a610aa208ddfec8aa2b43a" dependencies = [ - "rustix 0.36.8", + "rustix 0.36.14", "windows-sys 0.45.0", ] diff --git a/deny.toml b/deny.toml index 31a1707546..efa057f53e 100644 --- a/deny.toml +++ b/deny.toml @@ -62,7 +62,7 @@ skip = [ # is-terminal { name = "hermit-abi", version = "0.3.1" }, # is-terminal - { name = "rustix", version = "0.36.8" }, + { name = "rustix", version = "0.36.14" }, # is-terminal (via rustix) { name = "io-lifetimes", version = "1.0.5" }, # is-terminal From d69d6ebb13e2563f417a92da9d26ffcb777ece3a Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 25 May 2023 15:31:23 +0200 Subject: [PATCH 362/477] Bump rustix from 0.37.3 to 0.37.7 --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a498797adb..48852a88bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1236,7 +1236,7 @@ checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", - "rustix 0.37.3", + "rustix 0.37.7", "windows-sys 0.45.0", ] @@ -1991,9 +1991,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.3" +version = "0.37.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" +checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" dependencies = [ "bitflags", "errno", From 97f5ea3ac21c8f1a8dab40d214f0040054579be8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 May 2023 04:46:14 +0000 Subject: [PATCH 363/477] chore(deps): update rust crate regex to 1.8.3 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12a3baec4d..98b1470b73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1899,9 +1899,9 @@ checksum = "f1bfbf25d7eb88ddcbb1ec3d755d0634da8f7657b2cb8b74089121409ab8228f" [[package]] name = "regex" -version = "1.8.2" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1a59b5d8e97dee33696bf13c5ba8ab85341c002922fba050069326b9c498974" +checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" dependencies = [ "aho-corasick 1.0.1", "memchr", diff --git a/Cargo.toml b/Cargo.toml index b891354644..1d62c58e76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -310,7 +310,7 @@ rand = { version = "0.8", features = ["small_rng"] } rand_core = "0.6" rayon = "1.7" redox_syscall = "0.2" -regex = "1.8.2" +regex = "1.8.3" rstest = "0.17.0" rust-ini = "0.18.0" same-file = "1.0.6" From 03dec5128c172c7aa3749532d70d1d82bdfe0f95 Mon Sep 17 00:00:00 2001 From: Ideflop <94184575+Ideflop@users.noreply.github.com> Date: Sat, 27 May 2023 00:04:04 +0200 Subject: [PATCH 364/477] more: implement argument -s / --squeeze --- src/uu/more/src/more.rs | 82 +++++++++++++++++++++++++++++++------- tests/by-util/test_more.rs | 3 ++ 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 8c6cdf6e2a..996a1dc615 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -56,14 +56,16 @@ struct Options { silent: bool, clean_print: bool, print_over: bool, + squeeze: bool, } impl Options { fn from(matches: &ArgMatches) -> Self { Self { - silent: matches.get_flag(options::SILENT), clean_print: matches.get_flag(options::CLEAN_PRINT), print_over: matches.get_flag(options::PRINT_OVER), + silent: matches.get_flag(options::SILENT), + squeeze: matches.get_flag(options::SQUEEZE), } } } @@ -158,6 +160,13 @@ pub fn uu_app() -> Command { .help("Do not scroll, clean screen and display text") .action(ArgAction::SetTrue), ) + .arg( + Arg::new(options::SQUEEZE) + .short('s') + .long(options::SQUEEZE) + .help("Squeeze multiple blank lines into one") + .action(ArgAction::SetTrue), + ) // The commented arguments below are unimplemented: /* .arg( @@ -172,12 +181,6 @@ pub fn uu_app() -> Command { .long(options::NO_PAUSE) .help("Suppress pause after form feed"), ) - .arg( - Arg::new(options::SQUEEZE) - .short('s') - .long(options::SQUEEZE) - .help("Squeeze multiple blank lines into one"), - ) .arg( Arg::new(options::PLAIN) .short('u') @@ -377,6 +380,8 @@ struct Pager<'a> { next_file: Option<&'a str>, line_count: usize, silent: bool, + squeeze: bool, + line_squeezed: usize, } impl<'a> Pager<'a> { @@ -389,6 +394,8 @@ impl<'a> Pager<'a> { next_file, line_count, silent: options.silent, + squeeze: options.squeeze, + line_squeezed: 0, } } @@ -414,7 +421,21 @@ impl<'a> Pager<'a> { } fn page_up(&mut self) { - self.upper_mark = self.upper_mark.saturating_sub(self.content_rows.into()); + let content_row_usize: usize = self.content_rows.into(); + self.upper_mark = self + .upper_mark + .saturating_sub(content_row_usize.saturating_add(self.line_squeezed)); + + if self.squeeze { + let iter = self.lines.iter().take(self.upper_mark).rev(); + for line in iter { + if line.is_empty() { + self.upper_mark = self.upper_mark.saturating_sub(1); + } else { + break; + } + } + } } fn next_line(&mut self) { @@ -430,7 +451,7 @@ impl<'a> Pager<'a> { self.content_rows = row.saturating_sub(1); } - fn draw(&self, stdout: &mut std::io::Stdout, wrong_key: Option) { + fn draw(&mut self, stdout: &mut std::io::Stdout, wrong_key: Option) { let lower_mark = self .line_count .min(self.upper_mark.saturating_add(self.content_rows.into())); @@ -439,13 +460,44 @@ impl<'a> Pager<'a> { stdout.flush().unwrap(); } - fn draw_lines(&self, stdout: &mut std::io::Stdout) { + fn draw_lines(&mut self, stdout: &mut std::io::Stdout) { execute!(stdout, terminal::Clear(terminal::ClearType::CurrentLine)).unwrap(); - let displayed_lines = self - .lines - .iter() - .skip(self.upper_mark) - .take(self.content_rows.into()); + + self.line_squeezed = 0; + let mut previous_line_blank = false; + let mut displayed_lines = Vec::new(); + let mut iter = self.lines.iter().skip(self.upper_mark); + + while displayed_lines.len() < self.content_rows as usize { + match iter.next() { + Some(line) => { + if self.squeeze { + match (line.is_empty(), previous_line_blank) { + (true, false) => { + previous_line_blank = true; + displayed_lines.push(line); + } + (false, true) => { + previous_line_blank = false; + displayed_lines.push(line); + } + (false, false) => displayed_lines.push(line), + (true, true) => { + self.line_squeezed += 1; + self.upper_mark += 1; + } + } + } else { + displayed_lines.push(line); + } + } + // if none the end of the file is reached + None => { + self.upper_mark = self.line_count; + break; + } + } + } for line in displayed_lines { stdout.write_all(format!("\r{line}\n").as_bytes()).unwrap(); diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index 97353deb8a..43f405d9a8 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -17,6 +17,9 @@ fn test_valid_arg() { new_ucmd!().arg("-p").succeeds(); new_ucmd!().arg("--clean-print").succeeds(); + + new_ucmd!().arg("-s").succeeds(); + new_ucmd!().arg("--squeeze").succeeds(); } } From b248b9d34c56b4dfe3d34227d6279b8545d5c912 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 27 May 2023 08:02:03 +0200 Subject: [PATCH 365/477] tail: disable some tests on Android --- tests/by-util/test_tail.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index 7a812dc74e..b7740f6140 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -1536,6 +1536,7 @@ fn test_retry8() { #[test] #[cfg(all( not(target_vendor = "apple"), + not(target_os = "android"), not(target_os = "windows"), not(target_os = "freebsd") ))] // FIXME: for currently not working platforms @@ -1616,6 +1617,7 @@ fn test_retry9() { #[test] #[cfg(all( not(target_vendor = "apple"), + not(target_os = "android"), not(target_os = "windows"), not(target_os = "freebsd") ))] // FIXME: for currently not working platforms @@ -1678,6 +1680,7 @@ fn test_follow_descriptor_vs_rename1() { #[test] #[cfg(all( not(target_vendor = "apple"), + not(target_os = "android"), not(target_os = "windows"), not(target_os = "freebsd") ))] // FIXME: for currently not working platforms @@ -2118,6 +2121,7 @@ fn test_follow_name_move_create1() { #[test] #[cfg(all( not(target_vendor = "apple"), + not(target_os = "android"), not(target_os = "windows"), not(target_os = "freebsd") ))] // FIXME: for currently not working platforms From c6e79fa3f8f8b25eb0b820174e19397dbdc9df78 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 27 May 2023 08:05:08 +0200 Subject: [PATCH 366/477] Bump notify from 5.1.0 to 5.2.0 --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6902deb470..9be88e701e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1460,9 +1460,9 @@ dependencies = [ [[package]] name = "notify" -version = "5.1.0" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ea850aa68a06e48fdb069c0ec44d0d64c8dbffa49bf3b6f7f0a901fdea1ba9" +checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486" dependencies = [ "bitflags", "crossbeam-channel", @@ -1473,7 +1473,7 @@ dependencies = [ "libc", "mio", "walkdir", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1d62c58e76..525e9ab38f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -295,7 +295,7 @@ lscolors = { version = "0.14.0", default-features=false, features = ["nu-ansi-te memchr = "2" nix = { version="0.26", default-features=false } nom = "7.1.3" -notify = { version = "=5.1.0", features=["macos_kqueue"]} +notify = { version = "=5.2.0", features=["macos_kqueue"]} num-bigint = "0.4.3" num-traits = "0.2.15" number_prefix = "0.4" From 382ea38ace7670623ae607e3037415735e23a727 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 27 May 2023 08:31:04 +0000 Subject: [PATCH 367/477] chore(deps): update rust crate notify to v6 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9be88e701e..2c78c112eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1460,9 +1460,9 @@ dependencies = [ [[package]] name = "notify" -version = "5.2.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486" +checksum = "4d9ba6c734de18ca27c8cef5cd7058aa4ac9f63596131e4c7e41e579319032a2" dependencies = [ "bitflags", "crossbeam-channel", diff --git a/Cargo.toml b/Cargo.toml index 525e9ab38f..8e64fbaa71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -295,7 +295,7 @@ lscolors = { version = "0.14.0", default-features=false, features = ["nu-ansi-te memchr = "2" nix = { version="0.26", default-features=false } nom = "7.1.3" -notify = { version = "=5.2.0", features=["macos_kqueue"]} +notify = { version = "=6.0.0", features=["macos_kqueue"]} num-bigint = "0.4.3" num-traits = "0.2.15" number_prefix = "0.4" From 81a854a13eed85cc2dc44d32b9189d3360517bfd Mon Sep 17 00:00:00 2001 From: jaggededgedjustice Date: Sat, 27 May 2023 14:41:12 +0100 Subject: [PATCH 368/477] date: Catch format string that is not supported by chrono (#4244) * Catch format string that is not supported by chrono Co-authored-by: Sylvestre Ledru --- src/uu/date/src/date.rs | 7 +++++++ tests/by-util/test_date.rs | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index a94ffd65fd..381619f06f 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -262,6 +262,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Ok(date) => { // GNU `date` uses `%N` for nano seconds, however crate::chrono uses `%f` let format_string = &format_string.replace("%N", "%f"); + // Refuse to pass this string to chrono as it is crashing in this crate + if format_string.contains("%#z") { + return Err(USimpleError::new( + 1, + format!("invalid format {}", format_string.replace("%f", "%N")), + )); + } // Hack to work around panic in chrono, // TODO - remove when a fix for https://github.com/chronotope/chrono/issues/623 is released let format_items = StrftimeItems::new(format_string); diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index 4dc02ef6f3..c8c33aa890 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -356,6 +356,13 @@ fn test_invalid_format_string() { assert!(result.stderr_str().starts_with("date: invalid format ")); } +#[test] +fn test_unsupported_format() { + let result = new_ucmd!().arg("+%#z").fails(); + result.no_stdout(); + assert!(result.stderr_str().starts_with("date: invalid format %#z")); +} + #[test] fn test_date_string_human() { let date_formats = vec![ From 7fb9a9b0c40108e5ae8e8b60434966fbaf6b98fc Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 27 May 2023 16:01:15 +0200 Subject: [PATCH 369/477] Bump console from 0.15.5 to 0.15.7 --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c78c112eb..04bec342e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -354,15 +354,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.5" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] From 7d2d56785877ab8954e34c766e2c245da46460ba Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 27 May 2023 16:04:52 +0200 Subject: [PATCH 370/477] Bump ctrlc from 3.2.4 to 3.2.5 --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04bec342e6..ce6c8f792f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -701,12 +701,12 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.2.4" +version = "3.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1631ca6e3c59112501a9d87fd86f21591ff77acd31331e8a73f8d80a65bbdd71" +checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639" dependencies = [ "nix", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] From cdadb3880705d0483a9a90b55d04797b087b90dc Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 27 May 2023 16:07:03 +0200 Subject: [PATCH 371/477] Bump filetime from 0.2.18 to 0.2.20 --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce6c8f792f..9aa6c262f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -898,14 +898,14 @@ checksum = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" [[package]] name = "filetime" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3" +checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412" dependencies = [ "cfg-if", "libc", "redox_syscall", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] From 9d39b137a77b24ede515c446b7ff5f642d6764da Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 27 May 2023 16:10:23 +0200 Subject: [PATCH 372/477] Bump mio from 0.8.5 to 0.8.6 --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9aa6c262f1..07a3ea6e5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1426,14 +1426,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", "wasi", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] From f0b5cd98a614b9e7ab0de6180119579b73043b4d Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 27 May 2023 16:11:16 +0200 Subject: [PATCH 373/477] Bump parking_lot_core from 0.9.4 to 0.9.7 --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07a3ea6e5d..ce9f763012 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1631,15 +1631,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] From f0fe7b3bba87da56d34b658352e9cf460392f156 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 27 May 2023 16:16:18 +0200 Subject: [PATCH 374/477] Bump tempfile from 3.4.0 to 3.5.0 --- Cargo.lock | 88 +++++++++++++++++++++++++----------------------------- deny.toml | 2 ++ 2 files changed, 43 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce9f763012..e792745a3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,7 +95,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" dependencies = [ "anstyle", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -349,7 +349,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" dependencies = [ - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -362,7 +362,7 @@ dependencies = [ "lazy_static", "libc", "unicode-width", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -706,7 +706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639" dependencies = [ "nix", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -856,7 +856,7 @@ checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -904,8 +904,8 @@ checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412" dependencies = [ "cfg-if", "libc", - "redox_syscall", - "windows-sys 0.45.0", + "redox_syscall 0.2.16", + "windows-sys", ] [[package]] @@ -1225,7 +1225,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" dependencies = [ "libc", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1237,7 +1237,7 @@ dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", "rustix 0.37.7", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1433,7 +1433,7 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1473,7 +1473,7 @@ dependencies = [ "libc", "mio", "walkdir", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1482,7 +1482,7 @@ version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df031e117bca634c262e9bd3173776844b6c17a90b3741c9163663b4385af76" dependencies = [ - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1637,9 +1637,9 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1880,6 +1880,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "reference-counted-singleton" version = "0.1.2" @@ -1986,7 +1995,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys 0.1.4", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -2000,7 +2009,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys 0.3.0", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -2207,15 +2216,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", - "rustix 0.36.14", - "windows-sys 0.42.0", + "redox_syscall 0.3.5", + "rustix 0.37.7", + "windows-sys", ] [[package]] @@ -2243,7 +2252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c9afddd2cec1c0909f06b00ef33f94ab2cc0578c4a610aa208ddfec8aa2b43a" dependencies = [ "rustix 0.36.14", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -2531,7 +2540,7 @@ dependencies = [ "libc", "time", "uucore", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -2588,7 +2597,7 @@ dependencies = [ "clap", "glob", "uucore", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -2711,7 +2720,7 @@ dependencies = [ "clap", "hostname", "uucore", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -3013,7 +3022,7 @@ dependencies = [ "libc", "uucore", "walkdir", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -3158,7 +3167,7 @@ dependencies = [ "libc", "nix", "uucore", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -3186,7 +3195,7 @@ dependencies = [ "same-file", "uucore", "winapi-util", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -3204,7 +3213,7 @@ version = "0.0.18" dependencies = [ "clap", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "uucore", ] @@ -3227,7 +3236,7 @@ dependencies = [ "humantime_to_duration", "time", "uucore", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -3360,7 +3369,7 @@ dependencies = [ "clap", "libc", "uucore", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -3405,7 +3414,7 @@ dependencies = [ "walkdir", "wild", "winapi-util", - "windows-sys 0.45.0", + "windows-sys", "z85", ] @@ -3552,21 +3561,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - [[package]] name = "windows-sys" version = "0.45.0" diff --git a/deny.toml b/deny.toml index efa057f53e..f554862471 100644 --- a/deny.toml +++ b/deny.toml @@ -69,6 +69,8 @@ skip = [ { name = "linux-raw-sys", version = "0.1.4" }, # is-terminal { name = "windows-sys", version = "0.45.0" }, + # tempfile + { name = "redox_syscall", version = "0.3.5" }, # cpp_macros { name = "aho-corasick", version = "0.7.19" }, ] From 82f9abc50b007ab1fbe746e3dda38b0184fd0c53 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 27 May 2023 18:56:22 +0000 Subject: [PATCH 375/477] chore(deps): update rust crate redox_syscall to 0.3 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e792745a3a..5280303ba4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3213,7 +3213,7 @@ version = "0.0.18" dependencies = [ "clap", "libc", - "redox_syscall 0.2.16", + "redox_syscall 0.3.5", "uucore", ] diff --git a/Cargo.toml b/Cargo.toml index 8e64fbaa71..99875183a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -309,7 +309,7 @@ quick-error = "2.0.1" rand = { version = "0.8", features = ["small_rng"] } rand_core = "0.6" rayon = "1.7" -redox_syscall = "0.2" +redox_syscall = "0.3" regex = "1.8.3" rstest = "0.17.0" rust-ini = "0.18.0" From c92ca96b18b0cb9c5ab07c056d80d9d817cabb88 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 27 May 2023 18:58:28 +0000 Subject: [PATCH 376/477] chore(deps): update rust crate tempfile to 3.5.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8e64fbaa71..8941fae57d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -317,7 +317,7 @@ same-file = "1.0.6" selinux = "0.4" signal-hook = "0.3.15" smallvec = { version = "1.10", features = ["union"] } -tempfile = "3.4.0" +tempfile = "3.5.0" term_grid = "0.1.5" terminal_size = "0.2.5" textwrap = { version="0.16.0", features=["terminal_size"] } From 07434647ad4a09b48d0c8729245814d7eb850c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Sat, 27 May 2023 23:56:15 +0200 Subject: [PATCH 377/477] fix: Correctly detect format when using md5sum with check flag (#4645) --- src/uu/hashsum/src/hashsum.rs | 70 +++++++++++++---- tests/by-util/test_hashsum.rs | 138 ++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 14 deletions(-) diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index af05ddbd99..7b571efcd5 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -14,6 +14,7 @@ use clap::crate_version; use clap::ArgAction; use clap::{Arg, ArgMatches, Command}; use hex::encode; +use regex::Captures; use regex::Regex; use std::cmp::Ordering; use std::error::Error; @@ -604,22 +605,65 @@ where // regular expression, otherwise we use the `{n}` modifier, // where `n` is the number of bytes. let bytes = options.digest.output_bits() / 4; - let modifier = if bytes > 0 { + let bytes_marker = if bytes > 0 { format!("{{{bytes}}}") } else { "+".to_string() }; - let gnu_re = Regex::new(&format!( - r"^(?P[a-fA-F0-9]{modifier}) (?P[ \*])(?P.*)", - )) - .map_err(|_| HashsumError::InvalidRegex)?; + // BSD reversed mode format is similar to the default mode, but doesn’t use a character to distinguish binary and text modes. + let mut bsd_reversed = None; + + /// Creates a Regex for parsing lines based on the given format. + /// The default value of `gnu_re` created with this function has to be recreated + /// after the initial line has been parsed, as this line dictates the format + /// for the rest of them, and mixing of formats is disallowed. + fn gnu_re_template( + bytes_marker: &str, + format_marker: &str, + ) -> Result { + Regex::new(&format!( + r"^(?P[a-fA-F0-9]{bytes_marker}) {format_marker}(?P.*)" + )) + .map_err(|_| HashsumError::InvalidRegex) + } + let mut gnu_re = gnu_re_template(&bytes_marker, r"(?P[ \*])?")?; let bsd_re = Regex::new(&format!( r"^{algorithm} \((?P.*)\) = (?P[a-fA-F0-9]{digest_size})", algorithm = options.algoname, - digest_size = modifier, + digest_size = bytes_marker, )) .map_err(|_| HashsumError::InvalidRegex)?; + fn handle_captures( + caps: &Captures, + bytes_marker: &str, + bsd_reversed: &mut Option, + gnu_re: &mut Regex, + ) -> Result<(String, String, bool), HashsumError> { + if bsd_reversed.is_none() { + let is_bsd_reversed = caps.name("binary").is_none(); + let format_marker = if is_bsd_reversed { + "" + } else { + r"(?P[ \*])" + } + .to_string(); + + *bsd_reversed = Some(is_bsd_reversed); + *gnu_re = gnu_re_template(bytes_marker, &format_marker)?; + } + + Ok(( + caps.name("fileName").unwrap().as_str().to_string(), + caps.name("digest").unwrap().as_str().to_ascii_lowercase(), + if *bsd_reversed == Some(false) { + caps.name("binary").unwrap().as_str() == "*" + } else { + false + }, + )) + } + let buffer = file; for (i, maybe_line) in buffer.lines().enumerate() { let line = match maybe_line { @@ -627,14 +671,12 @@ where Err(e) => return Err(e.map_err_context(|| "failed to read file".to_string())), }; let (ck_filename, sum, binary_check) = match gnu_re.captures(&line) { - Some(caps) => ( - caps.name("fileName").unwrap().as_str(), - caps.name("digest").unwrap().as_str().to_ascii_lowercase(), - caps.name("binary").unwrap().as_str() == "*", - ), + Some(caps) => { + handle_captures(&caps, &bytes_marker, &mut bsd_reversed, &mut gnu_re)? + } None => match bsd_re.captures(&line) { Some(caps) => ( - caps.name("fileName").unwrap().as_str(), + caps.name("fileName").unwrap().as_str().to_string(), caps.name("digest").unwrap().as_str().to_ascii_lowercase(), true, ), @@ -655,7 +697,7 @@ where } }, }; - let f = match File::open(ck_filename) { + let f = match File::open(ck_filename.clone()) { Err(_) => { failed_open_file += 1; println!( @@ -706,7 +748,7 @@ where ) .map_err_context(|| "failed to read input".to_string())?; if options.tag { - println!("{} ({}) = {}", options.algoname, filename.display(), sum); + println!("{} ({:?}) = {}", options.algoname, filename.display(), sum); } else if options.nonames { println!("{sum}"); } else if options.zero { diff --git a/tests/by-util/test_hashsum.rs b/tests/by-util/test_hashsum.rs index 645f11ef2c..3650047b21 100644 --- a/tests/by-util/test_hashsum.rs +++ b/tests/by-util/test_hashsum.rs @@ -209,6 +209,144 @@ fn test_check_file_not_found_warning() { .stderr_is("sha1sum: warning: 1 listed file could not be read\n"); } +// Asterisk `*` is a reserved paths character on win32, nor the path can end with a whitespace. +// ref: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions +#[test] +fn test_check_md5sum() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + #[cfg(not(windows))] + { + for f in &["a", " b", "*c", "dd", " "] { + at.write(f, &format!("{f}\n")); + } + at.write( + "check.md5sum", + "60b725f10c9c85c70d97880dfe8191b3 a\n\ + bf35d7536c785cf06730d5a40301eba2 b\n\ + f5b61709718c1ecf8db1aea8547d4698 *c\n\ + b064a020db8018f18ff5ae367d01b212 dd\n\ + d784fa8b6d98d27699781bd9a7cf19f0 ", + ); + scene + .ccmd("md5sum") + .arg("--strict") + .arg("-c") + .arg("check.md5sum") + .succeeds() + .stdout_is("a: OK\n b: OK\n*c: OK\ndd: OK\n : OK\n") + .stderr_is(""); + } + #[cfg(windows)] + { + for f in &["a", " b", "dd"] { + at.write(f, &format!("{f}\n")); + } + at.write( + "check.md5sum", + "60b725f10c9c85c70d97880dfe8191b3 a\n\ + bf35d7536c785cf06730d5a40301eba2 b\n\ + b064a020db8018f18ff5ae367d01b212 dd", + ); + scene + .ccmd("md5sum") + .arg("--strict") + .arg("-c") + .arg("check.md5sum") + .succeeds() + .stdout_is("a: OK\n b: OK\ndd: OK\n") + .stderr_is(""); + } +} + +#[test] +fn test_check_md5sum_reverse_bsd() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + #[cfg(not(windows))] + { + for f in &["a", " b", "*c", "dd", " "] { + at.write(f, &format!("{f}\n")); + } + at.write( + "check.md5sum", + "60b725f10c9c85c70d97880dfe8191b3 a\n\ + bf35d7536c785cf06730d5a40301eba2 b\n\ + f5b61709718c1ecf8db1aea8547d4698 *c\n\ + b064a020db8018f18ff5ae367d01b212 dd\n\ + d784fa8b6d98d27699781bd9a7cf19f0 ", + ); + scene + .ccmd("md5sum") + .arg("--strict") + .arg("-c") + .arg("check.md5sum") + .succeeds() + .stdout_is("a: OK\n b: OK\n*c: OK\ndd: OK\n : OK\n") + .stderr_is(""); + } + #[cfg(windows)] + { + for f in &["a", " b", "dd"] { + at.write(f, &format!("{f}\n")); + } + at.write( + "check.md5sum", + "60b725f10c9c85c70d97880dfe8191b3 a\n\ + bf35d7536c785cf06730d5a40301eba2 b\n\ + b064a020db8018f18ff5ae367d01b212 dd", + ); + scene + .ccmd("md5sum") + .arg("--strict") + .arg("-c") + .arg("check.md5sum") + .succeeds() + .stdout_is("a: OK\n b: OK\ndd: OK\n") + .stderr_is(""); + } +} + +#[test] +fn test_check_md5sum_mixed_format() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + #[cfg(not(windows))] + { + for f in &[" b", "*c", "dd", " "] { + at.write(f, &format!("{f}\n")); + } + at.write( + "check.md5sum", + "bf35d7536c785cf06730d5a40301eba2 b\n\ + f5b61709718c1ecf8db1aea8547d4698 *c\n\ + b064a020db8018f18ff5ae367d01b212 dd\n\ + d784fa8b6d98d27699781bd9a7cf19f0 ", + ); + } + #[cfg(windows)] + { + for f in &[" b", "dd"] { + at.write(f, &format!("{f}\n")); + } + at.write( + "check.md5sum", + "bf35d7536c785cf06730d5a40301eba2 b\n\ + b064a020db8018f18ff5ae367d01b212 dd", + ); + } + scene + .ccmd("md5sum") + .arg("--strict") + .arg("-c") + .arg("check.md5sum") + .fails() + .code_is(1); +} + #[test] fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails().code_is(1); From d6562b2b5fee55d97b228eb92fb6e9265e1c8f0e Mon Sep 17 00:00:00 2001 From: Jed Denlea Date: Sun, 28 May 2023 17:24:13 -0700 Subject: [PATCH 378/477] uniq: non-UTF-8 file names and fewer copies uniq ought to be able to work with files whose names are not UTF-8. I've also taken the chance to remove some unnecessary String allocations. Additionally, both open_input_file and open_output_file were returning items with two implie levels of `Box` that were not necessary. In the case of stdin as input, it was not necessary to wrap stdin with a BufReader, StdinLock implements BufRead itself. --- src/uu/uniq/src/uniq.rs | 83 ++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/src/uu/uniq/src/uniq.rs b/src/uu/uniq/src/uniq.rs index 16b4ab2c49..89141f35fb 100644 --- a/src/uu/uniq/src/uniq.rs +++ b/src/uu/uniq/src/uniq.rs @@ -5,10 +5,10 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; +use clap::{builder::ValueParser, crate_version, Arg, ArgAction, ArgMatches, Command}; +use std::ffi::{OsStr, OsString}; use std::fs::File; -use std::io::{self, stdin, stdout, BufRead, BufReader, BufWriter, Read, Write}; -use std::path::Path; +use std::io::{self, stdin, stdout, BufRead, BufReader, BufWriter, Write}; use std::str::FromStr; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; @@ -64,11 +64,7 @@ macro_rules! write_line_terminator { } impl Uniq { - pub fn print_uniq( - &self, - reader: &mut BufReader, - writer: &mut BufWriter, - ) -> UResult<()> { + pub fn print_uniq(&self, reader: impl BufRead, mut writer: impl Write) -> UResult<()> { let mut first_line_printed = false; let mut group_count = 1; let line_terminator = self.get_line_terminator(); @@ -78,6 +74,8 @@ impl Uniq { None => return Ok(()), }; + let writer = &mut writer; + // compare current `line` with consecutive lines (`next_line`) of the input // and if needed, print `line` based on the command line options provided for next_line in lines { @@ -122,7 +120,6 @@ impl Uniq { } match char_indices.find(|(_, c)| c.is_whitespace()) { None => return "", - Some((next_field_i, _)) => i = next_field_i, } } @@ -195,9 +192,9 @@ impl Uniq { || self.delimiters == Delimiters::Both) } - fn print_line( + fn print_line( &self, - writer: &mut BufWriter, + writer: &mut impl Write, line: &str, count: usize, first_line_printed: bool, @@ -209,7 +206,7 @@ impl Uniq { } if self.show_counts { - writer.write_all(format!("{count:7} {line}").as_bytes()) + write!(writer, "{count:7} {line}") } else { writer.write_all(line.as_bytes()) } @@ -245,19 +242,12 @@ fn opt_parsed(opt_name: &str, matches: &ArgMatches) -> UResult UResult<()> { let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; - let files: Vec = matches - .get_many::(ARG_FILES) - .map(|v| v.map(ToString::to_string).collect()) - .unwrap_or_default(); + let files = matches.get_many::(ARG_FILES); - let (in_file_name, out_file_name) = match files.len() { - 0 => ("-".to_owned(), "-".to_owned()), - 1 => (files[0].clone(), "-".to_owned()), - 2 => (files[0].clone(), files[1].clone()), - _ => { - unreachable!() // Cannot happen as clap will fail earlier - } - }; + let (in_file_name, out_file_name) = files + .map(|fi| fi.map(AsRef::as_ref)) + .map(|mut fi| (fi.next(), fi.next())) + .unwrap_or_default(); let uniq = Uniq { repeats_only: matches.get_flag(options::REPEATED) @@ -282,8 +272,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } uniq.print_uniq( - &mut open_input_file(&in_file_name)?, - &mut open_output_file(&out_file_name)?, + open_input_file(in_file_name)?, + open_output_file(out_file_name)?, ) } @@ -387,6 +377,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(ARG_FILES) .action(ArgAction::Append) + .value_parser(ValueParser::os_string()) .num_args(0..=2) .value_hint(clap::ValueHint::FilePath), ) @@ -412,26 +403,26 @@ fn get_delimiter(matches: &ArgMatches) -> Delimiters { } } -fn open_input_file(in_file_name: &str) -> UResult>> { - let in_file = if in_file_name == "-" { - Box::new(stdin()) as Box - } else { - let path = Path::new(in_file_name); - let in_file = File::open(path) - .map_err_context(|| format!("Could not open {}", in_file_name.maybe_quote()))?; - Box::new(in_file) as Box - }; - Ok(BufReader::new(in_file)) +// None or "-" means stdin. +fn open_input_file(in_file_name: Option<&OsStr>) -> UResult> { + Ok(match in_file_name { + Some(path) if path != "-" => { + let in_file = File::open(path) + .map_err_context(|| format!("Could not open {}", path.maybe_quote()))?; + Box::new(BufReader::new(in_file)) + } + _ => Box::new(stdin().lock()), + }) } -fn open_output_file(out_file_name: &str) -> UResult>> { - let out_file = if out_file_name == "-" { - Box::new(stdout()) as Box - } else { - let path = Path::new(out_file_name); - let out_file = File::create(path) - .map_err_context(|| format!("Could not create {}", out_file_name.maybe_quote()))?; - Box::new(out_file) as Box - }; - Ok(BufWriter::new(out_file)) +// None or "-" means stdout. +fn open_output_file(out_file_name: Option<&OsStr>) -> UResult> { + Ok(match out_file_name { + Some(path) if path != "-" => { + let out_file = File::create(path) + .map_err_context(|| format!("Could not open {}", path.maybe_quote()))?; + Box::new(BufWriter::new(out_file)) + } + _ => Box::new(stdout().lock()), + }) } From 4cc569f5f046edf635d99c9d31fc30554375759d Mon Sep 17 00:00:00 2001 From: GaryDev <112358055+garydev10@users.noreply.github.com> Date: Mon, 29 May 2023 13:34:19 +0800 Subject: [PATCH 379/477] whoami: add test to improve coverage * tests/whoami: add windows test for issue #4614 * tests/whoami issue #4614: add all platform test --- tests/by-util/test_whoami.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/by-util/test_whoami.rs b/tests/by-util/test_whoami.rs index cbcf86028a..9e6c35be6e 100644 --- a/tests/by-util/test_whoami.rs +++ b/tests/by-util/test_whoami.rs @@ -50,3 +50,8 @@ fn test_normal_compare_env() { println!("test skipped:"); } } + +#[test] +fn test_succeeds_on_all_platforms() { + new_ucmd!().succeeds().no_stderr(); +} From d75e15fbca9078d2c577cb547be5a634a143c5f0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 10:29:34 +0000 Subject: [PATCH 380/477] chore(deps): update rust crate chrono to ^0.4.25 --- Cargo.lock | 12 +++++++++--- Cargo.toml | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87fdcdd76f..df518b91f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -251,12 +257,12 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "fdbc37d37da9e5bce8173f3a41b71d9bf3c674deebbaceacd0ebdabde76efb03" dependencies = [ + "android-tzdata", "iana-time-zone", - "num-integer", "num-traits", "winapi", ] diff --git a/Cargo.toml b/Cargo.toml index 8442faf5fe..e784cbe542 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -268,7 +268,7 @@ binary-heap-plus = "0.5.0" bstr = "1.5" bytecount = "0.6.3" byteorder = "1.4.3" -chrono = { version="^0.4.24", default-features=false, features=["std", "alloc", "clock"]} +chrono = { version="^0.4.25", default-features=false, features=["std", "alloc", "clock"]} clap = { version = "4.2", features = ["wrap_help", "cargo"] } clap_complete = "4.3" clap_mangen = "0.2" From af90bbd2d39193aaacf430107c81bdaceafbad2b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 10:29:39 +0000 Subject: [PATCH 381/477] chore(deps): update rust crate once_cell to 1.17.2 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87fdcdd76f..f077165e0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1542,9 +1542,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "once_cell" -version = "1.17.1" +version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" [[package]] name = "onig" diff --git a/Cargo.toml b/Cargo.toml index 8442faf5fe..10d20b47e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -299,7 +299,7 @@ notify = { version = "=6.0.0", features=["macos_kqueue"]} num-bigint = "0.4.3" num-traits = "0.2.15" number_prefix = "0.4" -once_cell = "1.17.1" +once_cell = "1.17.2" onig = { version = "~6.4", default-features = false } ouroboros = "0.15.6" phf = "0.11.1" From 6c98b23e80d73f051de94d3f85129af94c96a2e3 Mon Sep 17 00:00:00 2001 From: Ideflop <94184575+Ideflop@users.noreply.github.com> Date: Mon, 29 May 2023 14:36:18 +0200 Subject: [PATCH 382/477] more: implement arguments -n/--lines and --number --- src/uu/more/src/more.rs | 73 ++++++++++++++++++++++++++------------ tests/by-util/test_more.rs | 14 ++++++++ 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 996a1dc615..9be9b55767 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -14,10 +14,10 @@ use std::{ time::Duration, }; -use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; +use clap::{crate_version, value_parser, Arg, ArgAction, ArgMatches, Command}; use crossterm::event::KeyEventKind; use crossterm::{ - cursor::MoveTo, + cursor::{MoveTo, MoveUp}, event::{self, Event, KeyCode, KeyEvent, KeyModifiers}, execute, queue, style::Attribute, @@ -53,16 +53,28 @@ pub mod options { const MULTI_FILE_TOP_PROMPT: &str = "::::::::::::::\n{}\n::::::::::::::\n"; struct Options { - silent: bool, clean_print: bool, + lines: Option, print_over: bool, + silent: bool, squeeze: bool, } impl Options { fn from(matches: &ArgMatches) -> Self { + let lines = match ( + matches.get_one::(options::LINES).copied(), + matches.get_one::(options::NUMBER).copied(), + ) { + // We add 1 to the number of lines to display because the last line + // is used for the banner + (Some(number), _) if number > 0 => Some(number + 1), + (None, Some(number)) if number > 0 => Some(number + 1), + (_, _) => None, + }; Self { clean_print: matches.get_flag(options::CLEAN_PRINT), + lines, print_over: matches.get_flag(options::PRINT_OVER), silent: matches.get_flag(options::SILENT), squeeze: matches.get_flag(options::SQUEEZE), @@ -167,6 +179,23 @@ pub fn uu_app() -> Command { .help("Squeeze multiple blank lines into one") .action(ArgAction::SetTrue), ) + .arg( + Arg::new(options::LINES) + .short('n') + .long(options::LINES) + .value_name("number") + .num_args(1) + .value_parser(value_parser!(u16).range(0..)) + .help("The number of lines per screen full"), + ) + .arg( + Arg::new(options::NUMBER) + .long(options::NUMBER) + .required(false) + .num_args(1) + .value_parser(value_parser!(u16).range(0..)) + .help("Same as --lines"), + ) // The commented arguments below are unimplemented: /* .arg( @@ -187,22 +216,6 @@ pub fn uu_app() -> Command { .long(options::PLAIN) .help("Suppress underlining and bold"), ) - .arg( - Arg::new(options::LINES) - .short('n') - .long(options::LINES) - .value_name("number") - .takes_value(true) - .help("The number of lines per screen full"), - ) - .arg( - Arg::new(options::NUMBER) - .allow_hyphen_values(true) - .long(options::NUMBER) - .required(false) - .takes_value(true) - .help("Same as --lines"), - ) .arg( Arg::new(options::FROM_LINE) .short('F') @@ -263,7 +276,11 @@ fn more( next_file: Option<&str>, options: &Options, ) -> UResult<()> { - let (cols, rows) = terminal::size().unwrap(); + let (cols, mut rows) = terminal::size().unwrap(); + if let Some(number) = options.lines { + rows = number; + } + let lines = break_buff(buff, usize::from(cols)); let mut pager = Pager::new(rows, lines, next_file, options); @@ -327,6 +344,7 @@ fn more( .. }) => { pager.page_up(); + paging_add_back_message(options, stdout); } Event::Key(KeyEvent { code: KeyCode::Char('j'), @@ -347,7 +365,7 @@ fn more( pager.prev_line(); } Event::Resize(col, row) => { - pager.page_resize(col, row); + pager.page_resize(col, row, options.lines); } Event::Key(KeyEvent { code: KeyCode::Char(k), @@ -447,8 +465,10 @@ impl<'a> Pager<'a> { } // TODO: Deal with column size changes. - fn page_resize(&mut self, _: u16, row: u16) { - self.content_rows = row.saturating_sub(1); + fn page_resize(&mut self, _: u16, row: u16, option_line: Option) { + if option_line.is_none() { + self.content_rows = row.saturating_sub(1); + }; } fn draw(&mut self, stdout: &mut std::io::Stdout, wrong_key: Option) { @@ -536,6 +556,13 @@ impl<'a> Pager<'a> { } } +fn paging_add_back_message(options: &Options, stdout: &mut std::io::Stdout) { + if options.lines.is_some() { + execute!(stdout, MoveUp(1)).unwrap(); + stdout.write_all("\n\r...back 1 page\n".as_bytes()).unwrap(); + } +} + // Break the lines on the cols of the terminal fn break_buff(buff: &str, cols: usize) -> Vec { let mut lines = Vec::with_capacity(buff.lines().count()); diff --git a/tests/by-util/test_more.rs b/tests/by-util/test_more.rs index 43f405d9a8..95a4818b52 100644 --- a/tests/by-util/test_more.rs +++ b/tests/by-util/test_more.rs @@ -20,6 +20,20 @@ fn test_valid_arg() { new_ucmd!().arg("-s").succeeds(); new_ucmd!().arg("--squeeze").succeeds(); + + new_ucmd!().arg("-n").arg("10").succeeds(); + new_ucmd!().arg("--lines").arg("0").succeeds(); + new_ucmd!().arg("--number").arg("0").succeeds(); + } +} + +#[test] +fn test_invalid_arg() { + if std::io::stdout().is_terminal() { + new_ucmd!().arg("--invalid").fails(); + + new_ucmd!().arg("--lines").arg("-10").fails(); + new_ucmd!().arg("--number").arg("-10").fails(); } } From d303af31b78862644e291b71e747d4089102ee26 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 29 May 2023 00:08:11 +0200 Subject: [PATCH 383/477] cp: Accept --preserve=link Used for example in: tests/mv/hard-3.sh --- src/uu/cp/src/cp.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index f7069f04f7..f8087c7f04 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -278,14 +278,22 @@ static PRESERVABLE_ATTRIBUTES: &[&str] = &[ "ownership", "timestamps", "context", + "link", "links", "xattr", "all", ]; #[cfg(not(unix))] -static PRESERVABLE_ATTRIBUTES: &[&str] = - &["mode", "timestamps", "context", "links", "xattr", "all"]; +static PRESERVABLE_ATTRIBUTES: &[&str] = &[ + "mode", + "timestamps", + "context", + "link", + "links", + "xattr", + "all", +]; pub fn uu_app() -> Command { const MODE_ARGS: &[&str] = &[ @@ -713,7 +721,7 @@ impl Attributes { "ownership" => self.ownership = preserve_yes_required, "timestamps" => self.timestamps = preserve_yes_required, "context" => self.context = preserve_yes_required, - "links" => self.links = preserve_yes_required, + "link" | "links" => self.links = preserve_yes_required, "xattr" => self.xattr = preserve_yes_required, _ => { return Err(Error::InvalidArgument(format!( From d38797bb5032ba96aad0fb2c1bf62a5f2ee2901e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 26 May 2023 18:53:30 +0200 Subject: [PATCH 384/477] mv: Show 'skipped' when a file isn't overwriten Should fix tests/mv/mv-n.sh --- src/uu/mv/src/mv.rs | 14 ++++++++++---- tests/by-util/test_mv.rs | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 831b362ae7..5ca677c696 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -440,13 +440,19 @@ fn rename( match b.overwrite { OverwriteMode::NoClobber => { - return Err(io::Error::new( - io::ErrorKind::Other, - format!("not replacing {}", to.quote()), - )); + let err_msg = if b.verbose { + println!("skipped {}", to.quote()); + String::new() + } else { + format!("not replacing {}", to.quote()) + }; + return Err(io::Error::new(io::ErrorKind::Other, err_msg)); } OverwriteMode::Interactive => { if !prompt_yes!("overwrite {}?", to.quote()) { + if b.verbose { + println!("skipped {}", to.quote()); + } return Err(io::Error::new(io::ErrorKind::Other, "")); } } diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 39eaed1e72..f73d3249d4 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -1243,6 +1243,29 @@ fn test_mv_info_self() { .stderr_contains("mv: cannot move 'dir2' to a subdirectory of itself, 'dir2/dir2'"); } +#[test] +fn test_mv_arg_interactive_skipped() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("a"); + at.touch("b"); + ucmd.args(&["-vi", "a", "b"]) + .pipe_in("N\n") + .ignore_stdin_write_error() + .fails() + .stderr_is("mv: overwrite 'b'? ") + .stdout_is("skipped 'b'\n"); +} + +#[test] +fn test_mv_arg_interactive_skipped_vin() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("a"); + at.touch("b"); + ucmd.args(&["-vin", "a", "b"]) + .fails() + .stdout_is("skipped 'b'\n"); +} + #[test] fn test_mv_into_self_data() { let scene = TestScenario::new(util_name!()); From 63d8039d55c0526abcaadff95e012b3de38c58b6 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 29 May 2023 16:40:24 +0200 Subject: [PATCH 385/477] Bump windows-targets from 0.42.1 to 0.42.2 --- Cargo.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8014c0dbdc..ffb9982664 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3579,9 +3579,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -3594,45 +3594,45 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "xattr" From d1349b30fa98b7541b5199fdb0006280242954e6 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 29 May 2023 16:51:28 +0200 Subject: [PATCH 386/477] Add windows-targets & its deps to deny.toml --- deny.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/deny.toml b/deny.toml index f554862471..c4d83c513a 100644 --- a/deny.toml +++ b/deny.toml @@ -69,6 +69,15 @@ skip = [ { name = "linux-raw-sys", version = "0.1.4" }, # is-terminal { name = "windows-sys", version = "0.45.0" }, + { name = "windows-targets", version = "0.42.2" }, + { name = "windows_aarch64_gnullvm", version = "0.42.2" }, + { name = "windows_aarch64_msvc", version = "0.42.2" }, + { name = "windows_i686_gnu", version = "0.42.2" }, + { name = "windows_i686_msvc", version = "0.42.2" }, + { name = "windows_x86_64_gnu", version = "0.42.2" }, + { name = "windows_x86_64_gnullvm", version = "0.42.2" }, + { name = "windows_x86_64_msvc", version = "0.42.2" }, + # tempfile { name = "redox_syscall", version = "0.3.5" }, # cpp_macros From f2006a9a6b95c1ca327421a67c659435c3a91130 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 22 May 2023 23:03:54 +0200 Subject: [PATCH 387/477] cp: add support of cp --debug --- src/uu/cp/src/cp.rs | 85 ++++++++++- src/uu/cp/src/platform/linux.rs | 41 ++++- src/uu/cp/src/platform/macos.rs | 12 +- src/uu/cp/src/platform/other.rs | 12 +- tests/by-util/test_cp.rs | 257 ++++++++++++++++++++++++++++++++ 5 files changed, 391 insertions(+), 16 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index f7069f04f7..a1cbd4aecb 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -229,10 +229,79 @@ pub struct Options { backup_suffix: String, target_dir: Option, update: UpdateMode, + debug: bool, verbose: bool, progress_bar: bool, } +/// Enum representing various debug states of the offload and reflink actions. +#[derive(Debug)] +#[allow(dead_code)] // All of them are used on Linux +enum OffloadReflinkDebug { + Unknown, + No, + Yes, + Avoided, + Unsupported, +} + +/// Enum representing various debug states of the sparse detection. +#[derive(Debug)] +#[allow(dead_code)] // silent for now until we use them +enum SparseDebug { + Unknown, + No, + Zeros, + SeekHole, + SeekHoleZeros, + Unsupported, +} + +/// Struct that contains the debug state for each action in a file copy operation. +#[derive(Debug)] +struct CopyDebug { + offload: OffloadReflinkDebug, + reflink: OffloadReflinkDebug, + sparse_detection: SparseDebug, +} + +impl OffloadReflinkDebug { + fn to_string(&self) -> &'static str { + match self { + Self::No => "no", + Self::Yes => "yes", + Self::Avoided => "avoided", + Self::Unsupported => "unsupported", + Self::Unknown => "unknown", + } + } +} + +impl SparseDebug { + fn to_string(&self) -> &'static str { + match self { + Self::No => "no", + Self::Zeros => "zeros", + Self::SeekHole => "SEEK_HOLE", + Self::SeekHoleZeros => "SEEK_HOLE + zeros", + Self::Unsupported => "unsupported", + Self::Unknown => "unknown", + } + } +} + +/// This function prints the debug information of a file copy operation if +/// no hard link or symbolic link is required, and data copy is required. +/// It prints the debug information of the offload, reflink, and sparse detection actions. +fn show_debug(copy_debug: &CopyDebug) { + println!( + "copy offload: {}, reflink: {}, sparse detection: {}", + copy_debug.offload.to_string(), + copy_debug.reflink.to_string(), + copy_debug.sparse_detection.to_string(), + ); +} + const ABOUT: &str = help_about!("cp.md"); const USAGE: &str = help_usage!("cp.md"); const AFTER_HELP: &str = help_section!("after help", "cp.md"); @@ -269,6 +338,7 @@ mod options { pub const STRIP_TRAILING_SLASHES: &str = "strip-trailing-slashes"; pub const SYMBOLIC_LINK: &str = "symbolic-link"; pub const TARGET_DIRECTORY: &str = "target-directory"; + pub const DEBUG: &str = "debug"; pub const VERBOSE: &str = "verbose"; } @@ -361,6 +431,12 @@ pub fn uu_app() -> Command { .help("remove any trailing slashes from each SOURCE argument") .action(ArgAction::SetTrue), ) + .arg( + Arg::new(options::DEBUG) + .long(options::DEBUG) + .help("explain how a file is copied. Implies -v") + .action(ArgAction::SetTrue), + ) .arg( Arg::new(options::VERBOSE) .short('v') @@ -831,7 +907,8 @@ impl Options { one_file_system: matches.get_flag(options::ONE_FILE_SYSTEM), parents: matches.get_flag(options::PARENTS), update: update_mode, - verbose: matches.get_flag(options::VERBOSE), + debug: matches.get_flag(options::DEBUG), + verbose: matches.get_flag(options::VERBOSE) || matches.get_flag(options::DEBUG), strip_trailing_slashes: matches.get_flag(options::STRIP_TRAILING_SLASHES), reflink_mode: { if let Some(reflink) = matches.get_one::(options::REFLINK) { @@ -1745,7 +1822,7 @@ fn copy_helper( } else if source_is_symlink { copy_link(source, dest, symlinked_files)?; } else { - copy_on_write( + let copy_debug = copy_on_write( source, dest, options.reflink_mode, @@ -1754,6 +1831,10 @@ fn copy_helper( #[cfg(any(target_os = "linux", target_os = "android", target_os = "macos"))] source_is_fifo, )?; + + if !options.attributes_only && options.debug { + show_debug(©_debug); + } } Ok(()) diff --git a/src/uu/cp/src/platform/linux.rs b/src/uu/cp/src/platform/linux.rs index 7d97813dd4..18f2520a2a 100644 --- a/src/uu/cp/src/platform/linux.rs +++ b/src/uu/cp/src/platform/linux.rs @@ -13,7 +13,7 @@ use quick_error::ResultExt; use uucore::mode::get_umask; -use crate::{CopyResult, ReflinkMode, SparseMode}; +use crate::{CopyDebug, CopyResult, OffloadReflinkDebug, ReflinkMode, SparseDebug, SparseMode}; // From /usr/include/linux/fs.h: // #define FICLONE _IOW(0x94, 9, int) @@ -145,24 +145,51 @@ pub(crate) fn copy_on_write( sparse_mode: SparseMode, context: &str, source_is_fifo: bool, -) -> CopyResult<()> { +) -> CopyResult { + let mut copy_debug = CopyDebug { + offload: OffloadReflinkDebug::Unknown, + reflink: OffloadReflinkDebug::Unsupported, + sparse_detection: SparseDebug::No, + }; + let result = match (reflink_mode, sparse_mode) { - (ReflinkMode::Never, SparseMode::Always) => sparse_copy(source, dest), - (ReflinkMode::Never, _) => std::fs::copy(source, dest).map(|_| ()), - (ReflinkMode::Auto, SparseMode::Always) => sparse_copy(source, dest), + (ReflinkMode::Never, SparseMode::Always) => { + copy_debug.sparse_detection = SparseDebug::Zeros; + copy_debug.offload = OffloadReflinkDebug::Avoided; + copy_debug.reflink = OffloadReflinkDebug::No; + sparse_copy(source, dest) + } + (ReflinkMode::Never, _) => { + copy_debug.sparse_detection = SparseDebug::No; + copy_debug.reflink = OffloadReflinkDebug::No; + std::fs::copy(source, dest).map(|_| ()) + } + (ReflinkMode::Auto, SparseMode::Always) => { + copy_debug.offload = OffloadReflinkDebug::Avoided; + copy_debug.sparse_detection = SparseDebug::Zeros; + copy_debug.reflink = OffloadReflinkDebug::Unsupported; + sparse_copy(source, dest) + } (ReflinkMode::Auto, _) => { + copy_debug.sparse_detection = SparseDebug::No; + copy_debug.reflink = OffloadReflinkDebug::Unsupported; if source_is_fifo { copy_fifo_contents(source, dest).map(|_| ()) } else { clone(source, dest, CloneFallback::FSCopy) } } - (ReflinkMode::Always, SparseMode::Auto) => clone(source, dest, CloneFallback::Error), + (ReflinkMode::Always, SparseMode::Auto) => { + copy_debug.sparse_detection = SparseDebug::No; + copy_debug.reflink = OffloadReflinkDebug::Yes; + + clone(source, dest, CloneFallback::Error) + } (ReflinkMode::Always, _) => { return Err("`--reflink=always` can be used only with --sparse=auto".into()) } }; result.context(context)?; - Ok(()) + Ok(copy_debug) } diff --git a/src/uu/cp/src/platform/macos.rs b/src/uu/cp/src/platform/macos.rs index 4407e0edf9..b173aa9591 100644 --- a/src/uu/cp/src/platform/macos.rs +++ b/src/uu/cp/src/platform/macos.rs @@ -11,7 +11,7 @@ use std::path::Path; use quick_error::ResultExt; -use crate::{CopyResult, ReflinkMode, SparseMode}; +use crate::{CopyDebug, CopyResult, OffloadReflinkDebug, ReflinkMode, SparseDebug, SparseMode}; /// Copies `source` to `dest` using copy-on-write if possible. /// @@ -24,10 +24,15 @@ pub(crate) fn copy_on_write( sparse_mode: SparseMode, context: &str, source_is_fifo: bool, -) -> CopyResult<()> { +) -> CopyResult { if sparse_mode != SparseMode::Auto { return Err("--sparse is only supported on linux".to_string().into()); } + let mut copy_debug = CopyDebug { + offload: OffloadReflinkDebug::Unknown, + reflink: OffloadReflinkDebug::Unsupported, + sparse_detection: SparseDebug::Unsupported, + }; // Extract paths in a form suitable to be passed to a syscall. // The unwrap() is safe because they come from the command-line and so contain non nul @@ -72,6 +77,7 @@ pub(crate) fn copy_on_write( return Err(format!("failed to clone {source:?} from {dest:?}: {error}").into()) } _ => { + copy_debug.reflink = OffloadReflinkDebug::Yes; if source_is_fifo { let mut src_file = File::open(source)?; let mut dst_file = File::create(dest)?; @@ -83,5 +89,5 @@ pub(crate) fn copy_on_write( }; } - Ok(()) + Ok(copy_debug) } diff --git a/src/uu/cp/src/platform/other.rs b/src/uu/cp/src/platform/other.rs index b70da2f234..f5882f75ea 100644 --- a/src/uu/cp/src/platform/other.rs +++ b/src/uu/cp/src/platform/other.rs @@ -8,7 +8,7 @@ use std::path::Path; use quick_error::ResultExt; -use crate::{CopyResult, ReflinkMode, SparseMode}; +use crate::{CopyDebug, CopyResult, OffloadReflinkDebug, ReflinkMode, SparseDebug, SparseMode}; /// Copies `source` to `dest` for systems without copy-on-write pub(crate) fn copy_on_write( @@ -17,7 +17,7 @@ pub(crate) fn copy_on_write( reflink_mode: ReflinkMode, sparse_mode: SparseMode, context: &str, -) -> CopyResult<()> { +) -> CopyResult { if reflink_mode != ReflinkMode::Never { return Err("--reflink is only supported on linux and macOS" .to_string() @@ -26,8 +26,12 @@ pub(crate) fn copy_on_write( if sparse_mode != SparseMode::Auto { return Err("--sparse is only supported on linux".to_string().into()); } - + let copy_debug = CopyDebug { + offload: OffloadReflinkDebug::Unsupported, + reflink: OffloadReflinkDebug::Unsupported, + sparse_detection: SparseDebug::Unsupported, + }; fs::copy(source, dest).context(context)?; - Ok(()) + Ok(copy_debug) } diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index ef35f6c2de..1feeb0edee 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -2909,3 +2909,260 @@ fn test_cp_archive_on_directory_ending_dot() { ucmd.args(&["-a", "dir1/.", "dir2"]).succeeds(); assert!(at.file_exists("dir2/file")); } + +#[test] +fn test_cp_debug_default() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + at.touch("a"); + let result = ts.ucmd().arg("--debug").arg("a").arg("b").succeeds(); + + let stdout_str = result.stdout_str(); + #[cfg(target_os = "macos")] + if !stdout_str + .contains("copy offload: unknown, reflink: unsupported, sparse detection: unsupported") + { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } + #[cfg(target_os = "linux")] + if !stdout_str.contains("copy offload: unknown, reflink: unsupported, sparse detection: no") { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } + + #[cfg(windows)] + if !stdout_str + .contains("copy offload: unsupported, reflink: unsupported, sparse detection: unsupported") + { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } +} + +#[test] +fn test_cp_debug_multiple_default() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + let dir = "dir"; + at.touch("a"); + at.touch("b"); + at.mkdir(dir); + let result = ts + .ucmd() + .arg("--debug") + .arg("a") + .arg("b") + .arg(dir) + .succeeds(); + + let stdout_str = result.stdout_str(); + + #[cfg(target_os = "macos")] + { + if !stdout_str + .contains("copy offload: unknown, reflink: unsupported, sparse detection: unsupported") + { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } + + // two files, two occurrences + assert_eq!( + result + .stdout_str() + .matches( + "copy offload: unknown, reflink: unsupported, sparse detection: unsupported" + ) + .count(), + 2 + ); + } + + #[cfg(target_os = "linux")] + { + if !stdout_str.contains("copy offload: unknown, reflink: unsupported, sparse detection: no") + { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } + + // two files, two occurrences + assert_eq!( + result + .stdout_str() + .matches("copy offload: unknown, reflink: unsupported, sparse detection: no") + .count(), + 2 + ); + } + + #[cfg(target_os = "windows")] + { + if !stdout_str.contains( + "copy offload: unsupported, reflink: unsupported, sparse detection: unsupported", + ) { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } + + // two files, two occurrences + assert_eq!( + result + .stdout_str() + .matches("copy offload: unsupported, reflink: unsupported, sparse detection: unsupported") + .count(), + 2 + ); + } +} + +#[test] +#[cfg(target_os = "linux")] +fn test_cp_debug_sparse_reflink() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + at.touch("a"); + let result = ts + .ucmd() + .arg("--debug") + .arg("--sparse=always") + .arg("--reflink=never") + .arg("a") + .arg("b") + .succeeds(); + + let stdout_str = result.stdout_str(); + if !stdout_str.contains("copy offload: avoided, reflink: no, sparse detection: zeros") { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } +} + +#[test] +#[cfg(target_os = "linux")] +fn test_cp_debug_sparse_always() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + at.touch("a"); + let result = ts + .ucmd() + .arg("--debug") + .arg("--sparse=always") + .arg("a") + .arg("b") + .succeeds(); + let stdout_str = result.stdout_str(); + if !stdout_str.contains("copy offload: avoided, reflink: unsupported, sparse detection: zeros") + { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } +} + +#[test] +#[cfg(target_os = "linux")] +fn test_cp_debug_sparse_never() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + at.touch("a"); + let result = ts + .ucmd() + .arg("--debug") + .arg("--sparse=never") + .arg("a") + .arg("b") + .succeeds(); + let stdout_str = result.stdout_str(); + if !stdout_str.contains("copy offload: unknown, reflink: unsupported, sparse detection: no") { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } +} + +#[test] +fn test_cp_debug_sparse_auto() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + at.touch("a"); + let result = ts + .ucmd() + .arg("--debug") + .arg("--sparse=auto") + .arg("a") + .arg("b") + .succeeds(); + let stdout_str = result.stdout_str(); + + #[cfg(target_os = "macos")] + if !stdout_str + .contains("copy offload: unknown, reflink: unsupported, sparse detection: unsupported") + { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } + + #[cfg(target_os = "linux")] + if !stdout_str.contains("copy offload: unknown, reflink: unsupported, sparse detection: no") { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } +} + +#[test] +#[cfg(any(target_os = "linux", target_os = "android", target_os = "macos"))] +fn test_cp_debug_reflink_auto() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + at.touch("a"); + let result = ts + .ucmd() + .arg("--debug") + .arg("--reflink=auto") + .arg("a") + .arg("b") + .succeeds(); + + #[cfg(target_os = "linux")] + { + let stdout_str = result.stdout_str(); + if !stdout_str.contains("copy offload: unknown, reflink: unsupported, sparse detection: no") + { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } + } + + #[cfg(target_os = "macos")] + { + let stdout_str = result.stdout_str(); + if !stdout_str + .contains("copy offload: unknown, reflink: unsupported, sparse detection: unsupported") + { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } + } +} + +#[test] +#[cfg(target_os = "linux")] +fn test_cp_debug_sparse_always_reflink_auto() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + at.touch("a"); + let result = ts + .ucmd() + .arg("--debug") + .arg("--sparse=always") + .arg("--reflink=auto") + .arg("a") + .arg("b") + .succeeds(); + let stdout_str = result.stdout_str(); + if !stdout_str.contains("copy offload: avoided, reflink: unsupported, sparse detection: zeros") + { + println!("Failure: stdout was \n{stdout_str}"); + assert!(false); + } +} From 2b3594a5f536496035215bf2bf7fee46d06c9452 Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 29 May 2023 19:13:33 -0700 Subject: [PATCH 388/477] core: add octal and hex size parse support --- src/uucore/src/lib/parser/parse_size.rs | 126 ++++++++++++++++++++---- 1 file changed, 106 insertions(+), 20 deletions(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index 60209d8493..70b94fbccd 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -25,6 +25,12 @@ pub struct Parser<'parser> { pub default_unit: Option<&'parser str>, } +enum NumberSystem { + Decimal, + Octal, + Hexadecimal, +} + impl<'parser> Parser<'parser> { pub fn with_allow_list(&mut self, allow_list: &'parser [&str]) -> &mut Self { self.allow_list = Some(allow_list); @@ -62,32 +68,42 @@ impl<'parser> Parser<'parser> { /// assert_eq!(Ok(123), parse_size("123")); /// assert_eq!(Ok(9 * 1000), parse_size("9kB")); // kB is 1000 /// assert_eq!(Ok(2 * 1024), parse_size("2K")); // K is 1024 + /// assert_eq!(Ok(44251 * 1024), parse_size("0xACDBK")); /// ``` pub fn parse(&self, size: &str) -> Result { if size.is_empty() { return Err(ParseSizeError::parse_failure(size)); } - // Get the numeric part of the size argument. For example, if the - // argument is "123K", then the numeric part is "123". - let numeric_string: String = size.chars().take_while(|c| c.is_ascii_digit()).collect(); - let number: u64 = if numeric_string.is_empty() { - 1 - } else { - match numeric_string.parse() { - Ok(n) => n, - Err(_) => return Err(ParseSizeError::parse_failure(size)), + + let number_system: NumberSystem = self.determine_number_system(size); + + // Split the size argument into numeric and unit parts + // For example, if the argument is "123K", the numeric part is "123", and + // the unit is "K" + let (numeric_string, unit) = match number_system { + NumberSystem::Hexadecimal => { + let numeric_string: String = size + .chars() + .take(2) + .chain(size.chars().skip(2).take_while(|c| c.is_ascii_hexdigit())) + .collect(); + let unit: String = size.chars().skip(numeric_string.len()).collect(); + + (numeric_string, unit) + } + _ => { + let mut unit: String = size + .chars() + .rev() + .take_while(|c| c.is_alphabetic()) + .collect(); + unit = unit.chars().rev().collect(); + let numeric_string = size.chars().take(size.len() - unit.len()).collect(); + + (numeric_string, unit) } }; - - // Get the alphabetic units part of the size argument and compute - // the factor it represents. For example, if the argument is "123K", - // then the unit part is "K" and the factor is 1024. This may be the - // empty string, in which case, the factor is 1. - // - // The lowercase "b" (used by `od`, `head`, `tail`, etc.) means - // "block" and the Posix block size is 512. The uppercase "B" - // means "byte". - let mut unit: &str = &size[numeric_string.len()..]; + let mut unit: &str = unit.as_str(); if let Some(default_unit) = self.default_unit { // Check if `unit` is empty then assigns `default_unit` to `unit` @@ -115,6 +131,12 @@ impl<'parser> Parser<'parser> { } } + // Compute the factor the unit represents. + // empty string means the factor is 1. + // + // The lowercase "b" (used by `od`, `head`, `tail`, etc.) means + // "block" and the Posix block size is 512. The uppercase "B" + // means "byte". let (base, exponent): (u128, u32) = match unit { "" => (1, 0), "B" if self.capital_b_bytes => (1, 0), @@ -142,10 +164,60 @@ impl<'parser> Parser<'parser> { Ok(n) => n, Err(_) => return Err(ParseSizeError::size_too_big(size)), }; + + // parse string into u64 + let number: u64 = match number_system { + NumberSystem::Decimal => { + if numeric_string.is_empty() { + 1 + } else { + match numeric_string.parse() { + Ok(n) => n, + Err(_) => return Err(ParseSizeError::parse_failure(size)), + } + } + } + NumberSystem::Octal => { + let trimmed_string = numeric_string.trim_start_matches("0"); + match u64::from_str_radix(trimmed_string, 8) { + Ok(res) => res, + Err(_) => return Err(ParseSizeError::parse_failure(size)), + } + } + NumberSystem::Hexadecimal => { + let trimmed_string = numeric_string.trim_start_matches("0x"); + match u64::from_str_radix(trimmed_string, 16) { + Ok(res) => res, + Err(_) => return Err(ParseSizeError::parse_failure(size)), + } + } + }; + number .checked_mul(factor) .ok_or_else(|| ParseSizeError::size_too_big(size)) } + + fn determine_number_system(&self, size: &str) -> NumberSystem { + if size.len() <= 1 { + return NumberSystem::Decimal; + } + + if size.starts_with("0x") { + return NumberSystem::Hexadecimal; + } + + let num_digits: usize = size + .chars() + .take_while(|c| c.is_ascii_digit()) + .collect::() + .len(); + if size.starts_with("0") && num_digits > 1 { + return NumberSystem::Octal; + } + + NumberSystem::Decimal + } } /// Parse a size string into a number of bytes. @@ -336,7 +408,7 @@ mod tests { #[test] fn invalid_suffix() { - let test_strings = ["328hdsf3290", "5mib", "1e2", "1H", "1.2"]; + let test_strings = ["5mib", "1eb", "1H"]; for &test_string in &test_strings { assert_eq!( parse_size(test_string).unwrap_err(), @@ -450,4 +522,18 @@ mod tests { assert!(parser.parse("1B").is_err()); assert!(parser.parse("B").is_err()); } + + #[test] + fn parse_octal_size() { + assert_eq!(Ok(63), parse_size("077")); + assert_eq!(Ok(528), parse_size("01020")); + assert_eq!(Ok(668 * 1024), parse_size("01234K")); + } + + #[test] + fn parse_hex_size() { + assert_eq!(Ok(10), parse_size("0xA")); + assert_eq!(Ok(94722), parse_size("0x17202")); + assert_eq!(Ok(44251 * 1024), parse_size("0xACDBK")); + } } From f8a46196ef42bc404040173ad9bc93ae25d15ac4 Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 29 May 2023 20:10:16 -0700 Subject: [PATCH 389/477] shred: add support for hex and octal size --- src/uu/shred/src/shred.rs | 42 ++++++++++--------------------------- tests/by-util/test_shred.rs | 11 ++++++++++ 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 89f857b19f..1ceffe9957 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -19,6 +19,7 @@ use std::os::unix::prelude::PermissionsExt; use std::path::{Path, PathBuf}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; +use uucore::parse_size::parse_size; use uucore::{format_usage, help_about, help_section, help_usage, show, show_error, show_if_err}; const ABOUT: &str = help_about!("shred.md"); @@ -318,38 +319,17 @@ pub fn uu_app() -> Command { ) } -// TODO: Add support for all postfixes here up to and including EiB -// http://www.gnu.org/software/coreutils/manual/coreutils.html#Block-size fn get_size(size_str_opt: Option) -> Option { - size_str_opt.as_ref()?; - - let mut size_str = size_str_opt.as_ref().unwrap().clone(); - // Immutably look at last character of size string - let unit = match size_str.chars().last().unwrap() { - 'K' => { - size_str.pop(); - 1024u64 - } - 'M' => { - size_str.pop(); - (1024 * 1024) as u64 - } - 'G' => { - size_str.pop(); - (1024 * 1024 * 1024) as u64 - } - _ => 1u64, - }; - - let coefficient = match size_str.parse::() { - Ok(u) => u, - Err(_) => { - show_error!("{}: Invalid file size", size_str_opt.unwrap().maybe_quote()); - std::process::exit(1); - } - }; - - Some(coefficient * unit) + match size_str_opt { + Some(size) => match parse_size(size.as_str()) { + Ok(res) => Some(res), + Err(_) => { + show_error!("invalid file size: {}", size.quote()); + std::process::exit(1) + } + }, + None => None, + } } fn pass_name(pass_type: &PassType) -> String { diff --git a/tests/by-util/test_shred.rs b/tests/by-util/test_shred.rs index 58db09cbd6..a34345aeee 100644 --- a/tests/by-util/test_shred.rs +++ b/tests/by-util/test_shred.rs @@ -51,3 +51,14 @@ fn test_shred_force() { // file_a was deleted. assert!(!at.file_exists(file)); } + +#[test] +fn test_hex() { + let (at, mut ucmd) = at_and_ucmd!(); + + let file = "test_hex"; + + at.touch(file); + + ucmd.arg("--size=0x10").arg(file).succeeds(); +} From 6233ad6dd7e9a0fa4552cec788265a75dac5fecf Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 29 May 2023 20:59:21 -0700 Subject: [PATCH 390/477] core: fix clippy warning for size parser --- src/uucore/src/lib/parser/parse_size.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index 70b94fbccd..be642ef8bb 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -178,7 +178,7 @@ impl<'parser> Parser<'parser> { } } NumberSystem::Octal => { - let trimmed_string = numeric_string.trim_start_matches("0"); + let trimmed_string = numeric_string.trim_start_matches('0'); match u64::from_str_radix(trimmed_string, 8) { Ok(res) => res, Err(_) => return Err(ParseSizeError::parse_failure(size)), @@ -212,7 +212,7 @@ impl<'parser> Parser<'parser> { .take_while(|c| c.is_ascii_digit()) .collect::() .len(); - if size.starts_with("0") && num_digits > 1 { + if size.starts_with('0') && num_digits > 1 { return NumberSystem::Octal; } From d98c81802fb419f1bef412f1c70dad207b6c4c94 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 05:21:01 +0000 Subject: [PATCH 391/477] chore(deps): update rust crate clap to 4.3 --- Cargo.lock | 190 ++++++++++++++++++++++++++++++++++++----------------- Cargo.toml | 2 +- 2 files changed, 129 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ffb9982664..1d7f927243 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,42 +66,51 @@ dependencies = [ [[package]] name = "anstream" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", + "anstyle-query", "anstyle-wincon", - "concolor-override", - "concolor-query", + "colorchoice", "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "0.3.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" [[package]] name = "anstyle-parse" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" dependencies = [ "utf8parse", ] +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "anstyle-wincon" -version = "0.2.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -280,18 +289,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6efb5f0a41b5ef5b50c5da28c07609c20091df0c1fc33d418fa2a7e693c2b624" +checksum = "93aae7a4192245f70fe75dd9157fc7b4a5bf53e88d30bd4396f7d8f9284d5acc" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671fcaa5debda4b9a84aa7fde49c907c8986c0e6ab927e04217c9cb74e7c8bc9" +checksum = "4f423e341edefb78c9caba2d9c7f7687d0e72e89df3ce3394554754393ac3990" dependencies = [ "anstream", "anstyle", @@ -313,9 +322,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "clap_mangen" @@ -338,25 +347,16 @@ dependencies = [ ] [[package]] -name = "compare" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120133d4db2ec47efe2e26502ee984747630c67f51974fca0b6c1340cf2368d3" - -[[package]] -name = "concolor-override" +name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] -name = "concolor-query" -version = "0.3.3" +name = "compare" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" -dependencies = [ - "windows-sys", -] +checksum = "120133d4db2ec47efe2e26502ee984747630c67f51974fca0b6c1340cf2368d3" [[package]] name = "console" @@ -368,7 +368,7 @@ dependencies = [ "lazy_static", "libc", "unicode-width", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -712,7 +712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639" dependencies = [ "nix", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -862,7 +862,7 @@ checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -911,7 +911,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall 0.2.16", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1231,7 +1231,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1243,7 +1243,7 @@ dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", "rustix 0.37.7", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1439,7 +1439,7 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1479,7 +1479,7 @@ dependencies = [ "libc", "mio", "walkdir", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1488,7 +1488,7 @@ version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df031e117bca634c262e9bd3173776844b6c17a90b3741c9163663b4385af76" dependencies = [ - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1645,7 +1645,7 @@ dependencies = [ "libc", "redox_syscall 0.2.16", "smallvec", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -2001,7 +2001,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys 0.1.4", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -2015,7 +2015,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys 0.3.0", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -2230,7 +2230,7 @@ dependencies = [ "fastrand", "redox_syscall 0.3.5", "rustix 0.37.7", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -2258,7 +2258,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c9afddd2cec1c0909f06b00ef33f94ab2cc0578c4a610aa208ddfec8aa2b43a" dependencies = [ "rustix 0.36.14", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -2546,7 +2546,7 @@ dependencies = [ "libc", "time", "uucore", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -2603,7 +2603,7 @@ dependencies = [ "clap", "glob", "uucore", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -2726,7 +2726,7 @@ dependencies = [ "clap", "hostname", "uucore", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -3028,7 +3028,7 @@ dependencies = [ "libc", "uucore", "walkdir", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -3173,7 +3173,7 @@ dependencies = [ "libc", "nix", "uucore", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -3201,7 +3201,7 @@ dependencies = [ "same-file", "uucore", "winapi-util", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -3242,7 +3242,7 @@ dependencies = [ "humantime_to_duration", "time", "uucore", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -3376,7 +3376,7 @@ dependencies = [ "clap", "libc", "uucore", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -3421,7 +3421,7 @@ dependencies = [ "walkdir", "wild", "winapi-util", - "windows-sys", + "windows-sys 0.45.0", "z85", ] @@ -3574,7 +3574,16 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] @@ -3583,13 +3592,28 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -3598,42 +3622,84 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "xattr" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 1621eca86e..595be01f46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -269,7 +269,7 @@ bstr = "1.5" bytecount = "0.6.3" byteorder = "1.4.3" chrono = { version="^0.4.25", default-features=false, features=["std", "alloc", "clock"]} -clap = { version = "4.2", features = ["wrap_help", "cargo"] } +clap = { version = "4.3", features = ["wrap_help", "cargo"] } clap_complete = "4.3" clap_mangen = "0.2" compare = "0.1.0" From f02b2345ee289b8aafcbd2d5759a690e44fcb96e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 06:36:45 +0000 Subject: [PATCH 392/477] chore(deps): update rust crate is-terminal to 0.4.7 --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d7f927243..d29da51457 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1236,14 +1236,14 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", "rustix 0.37.7", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 595be01f46..29e4244b8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -288,7 +288,7 @@ glob = "0.3.1" half = "2.2" humantime_to_duration = "0.2.1" indicatif = "0.17" -is-terminal = "0.4.6" +is-terminal = "0.4.7" itertools = "0.10.5" libc = "0.2.144" lscolors = { version = "0.14.0", default-features=false, features = ["nu-ansi-term"] } From 2e070224a53a7066920827a5dc0b0a4a811805f6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 06:36:49 +0000 Subject: [PATCH 393/477] chore(deps): update rust crate terminal_size to 0.2.6 --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d7f927243..49744bcf07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2253,12 +2253,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9afddd2cec1c0909f06b00ef33f94ab2cc0578c4a610aa208ddfec8aa2b43a" +checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" dependencies = [ - "rustix 0.36.14", - "windows-sys 0.45.0", + "rustix 0.37.7", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 595be01f46..0dccdbc756 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -319,7 +319,7 @@ signal-hook = "0.3.15" smallvec = { version = "1.10", features = ["union"] } tempfile = "3.5.0" term_grid = "0.1.5" -terminal_size = "0.2.5" +terminal_size = "0.2.6" textwrap = { version="0.16.0", features=["terminal_size"] } thiserror = "1.0" time = { version="0.3" } From 8f9a328c6a4564a29408ec09bc2ada6647b384e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 06:36:57 +0000 Subject: [PATCH 394/477] fix(deps): update rust crate windows-sys to 0.48.0 --- Cargo.lock | 18 +++++++++--------- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d7f927243..ba1a705fc4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2546,7 +2546,7 @@ dependencies = [ "libc", "time", "uucore", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -2603,7 +2603,7 @@ dependencies = [ "clap", "glob", "uucore", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -2726,7 +2726,7 @@ dependencies = [ "clap", "hostname", "uucore", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -3028,7 +3028,7 @@ dependencies = [ "libc", "uucore", "walkdir", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -3173,7 +3173,7 @@ dependencies = [ "libc", "nix", "uucore", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -3201,7 +3201,7 @@ dependencies = [ "same-file", "uucore", "winapi-util", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -3242,7 +3242,7 @@ dependencies = [ "humantime_to_duration", "time", "uucore", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -3376,7 +3376,7 @@ dependencies = [ "clap", "libc", "uucore", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -3421,7 +3421,7 @@ dependencies = [ "walkdir", "wild", "winapi-util", - "windows-sys 0.45.0", + "windows-sys 0.48.0", "z85", ] diff --git a/Cargo.toml b/Cargo.toml index 595be01f46..ab191d47ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -328,7 +328,7 @@ unicode-width = "0.1.10" utf-8 = "0.7.6" walkdir = "2.3" winapi-util = "0.1.5" -windows-sys = { version="0.45.0", default-features=false } +windows-sys = { version="0.48.0", default-features=false } xattr = "1.0.0" zip = { version = "0.6.6", default_features=false, features=["deflate"] } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index ea7fb44f3c..491e98868a 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -58,7 +58,7 @@ tempfile = { workspace=true } [target.'cfg(target_os = "windows")'.dependencies] winapi-util = { version= "0.1.5", optional=true } -windows-sys = { version = "0.45.0", optional = true, default-features = false, features = ["Win32_Storage_FileSystem", "Win32_Foundation", "Win32_System_WindowsProgramming"] } +windows-sys = { version = "0.48.0", optional = true, default-features = false, features = ["Win32_Storage_FileSystem", "Win32_Foundation", "Win32_System_WindowsProgramming"] } [features] default = [] From 2ec70dc05dddc31ecf94abe57bb68ba7c808ef9b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 06:37:02 +0000 Subject: [PATCH 395/477] fix(deps): update rust crate dns-lookup to v2 --- Cargo.lock | 12 ++++++------ src/uucore/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d7f927243..9e79da98a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -816,14 +816,14 @@ checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" [[package]] name = "dns-lookup" -version = "1.0.8" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53ecafc952c4528d9b51a458d1a8904b81783feff9fde08ab6ed2545ff396872" +checksum = "8f332aa79f9e9de741ac013237294ef42ce2e9c6394dc7d766725812f1238812" dependencies = [ "cfg-if", "libc", "socket2", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -2183,12 +2183,12 @@ checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" [[package]] name = "socket2" -version = "0.4.7" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index ea7fb44f3c..2c02ad3d30 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -20,7 +20,7 @@ path="src/lib/lib.rs" [dependencies] clap = { workspace=true } uucore_procs = { workspace=true } -dns-lookup = { version="1.0.8", optional=true } +dns-lookup = { version="2.0.2", optional=true } dunce = "1.0.4" wild = "2.1" glob = "0.3.1" From f1c943ed31d9d44cc1316f05042ec9f0505edec7 Mon Sep 17 00:00:00 2001 From: Ideflop <94184575+Ideflop@users.noreply.github.com> Date: Tue, 30 May 2023 09:03:00 +0200 Subject: [PATCH 396/477] more: error handling for write_all in function paging_add_back_message --- src/uu/more/src/more.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 9be9b55767..a43489566c 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -344,7 +344,7 @@ fn more( .. }) => { pager.page_up(); - paging_add_back_message(options, stdout); + paging_add_back_message(options, stdout)?; } Event::Key(KeyEvent { code: KeyCode::Char('j'), @@ -556,11 +556,12 @@ impl<'a> Pager<'a> { } } -fn paging_add_back_message(options: &Options, stdout: &mut std::io::Stdout) { +fn paging_add_back_message(options: &Options, stdout: &mut std::io::Stdout) -> UResult<()> { if options.lines.is_some() { - execute!(stdout, MoveUp(1)).unwrap(); - stdout.write_all("\n\r...back 1 page\n".as_bytes()).unwrap(); + execute!(stdout, MoveUp(1))?; + stdout.write_all("\n\r...back 1 page\n".as_bytes())?; } + Ok(()) } // Break the lines on the cols of the terminal From af528ba84e91a36005e2d6f4c82e92107a4937b5 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 30 May 2023 00:26:17 -0700 Subject: [PATCH 397/477] core: refactor num and unit split --- src/uucore/src/lib/parser/parse_size.rs | 31 +++++++------------------ 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index be642ef8bb..716cf8d793 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -80,30 +80,15 @@ impl<'parser> Parser<'parser> { // Split the size argument into numeric and unit parts // For example, if the argument is "123K", the numeric part is "123", and // the unit is "K" - let (numeric_string, unit) = match number_system { - NumberSystem::Hexadecimal => { - let numeric_string: String = size - .chars() - .take(2) - .chain(size.chars().skip(2).take_while(|c| c.is_ascii_hexdigit())) - .collect(); - let unit: String = size.chars().skip(numeric_string.len()).collect(); - - (numeric_string, unit) - } - _ => { - let mut unit: String = size - .chars() - .rev() - .take_while(|c| c.is_alphabetic()) - .collect(); - unit = unit.chars().rev().collect(); - let numeric_string = size.chars().take(size.len() - unit.len()).collect(); - - (numeric_string, unit) - } + let numeric_string: String = match number_system { + NumberSystem::Hexadecimal => size + .chars() + .take(2) + .chain(size.chars().skip(2).take_while(|c| c.is_ascii_hexdigit())) + .collect(), + _ => size.chars().take_while(|c| c.is_ascii_digit()).collect(), }; - let mut unit: &str = unit.as_str(); + let mut unit: &str = &size[numeric_string.len()..]; if let Some(default_unit) = self.default_unit { // Check if `unit` is empty then assigns `default_unit` to `unit` From aed8a5759a42ffe6b7f94dc8d6750e18c623df65 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 30 May 2023 00:27:09 -0700 Subject: [PATCH 398/477] core: size parser treat 000 as decimal --- src/uucore/src/lib/parser/parse_size.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index 716cf8d793..af4cf990df 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -197,7 +197,8 @@ impl<'parser> Parser<'parser> { .take_while(|c| c.is_ascii_digit()) .collect::() .len(); - if size.starts_with('0') && num_digits > 1 { + let all_zeros = size.chars().all(|c| c == '0'); + if size.starts_with('0') && num_digits > 1 && !all_zeros { return NumberSystem::Octal; } From 81871d54a2bc3b765d5c3bee219b3d7725e2d362 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 30 May 2023 00:33:14 -0700 Subject: [PATCH 399/477] core: refactor parse_number in size parser --- src/uucore/src/lib/parser/parse_size.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index af4cf990df..c6a02dfaea 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -156,25 +156,16 @@ impl<'parser> Parser<'parser> { if numeric_string.is_empty() { 1 } else { - match numeric_string.parse() { - Ok(n) => n, - Err(_) => return Err(ParseSizeError::parse_failure(size)), - } + self.parse_number(&numeric_string, 10, size)? } } NumberSystem::Octal => { let trimmed_string = numeric_string.trim_start_matches('0'); - match u64::from_str_radix(trimmed_string, 8) { - Ok(res) => res, - Err(_) => return Err(ParseSizeError::parse_failure(size)), - } + self.parse_number(trimmed_string, 8, size)? } NumberSystem::Hexadecimal => { let trimmed_string = numeric_string.trim_start_matches("0x"); - match u64::from_str_radix(trimmed_string, 16) { - Ok(res) => res, - Err(_) => return Err(ParseSizeError::parse_failure(size)), - } + self.parse_number(trimmed_string, 16, size)? } }; @@ -204,6 +195,16 @@ impl<'parser> Parser<'parser> { NumberSystem::Decimal } + + fn parse_number( + &self, + numeric_string: &str, + radix: u32, + original_size: &str, + ) -> Result { + u64::from_str_radix(numeric_string, radix) + .map_err(|_| ParseSizeError::ParseFailure(original_size.to_string())) + } } /// Parse a size string into a number of bytes. From b1cfa224559921e0d26ef44d10f248819788b143 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 10:01:25 +0000 Subject: [PATCH 400/477] chore(deps): update rust crate ctrlc to 3.3 --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d7f927243..27609935d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -707,12 +707,12 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.2.5" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639" +checksum = "7394a21d012ce5c850497fb774b167d81b99f060025fbf06ee92b9848bd97eb2" dependencies = [ "nix", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 595be01f46..e2f4cb9a14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -275,7 +275,7 @@ clap_mangen = "0.2" compare = "0.1.0" coz = { version = "0.1.3" } crossterm = ">=0.26.1" -ctrlc = { version = "3.2", features = ["termination"] } +ctrlc = { version = "3.3", features = ["termination"] } exacl = "0.10.0" file_diff = "1.0.0" filetime = "0.2" From 6278c6f2d6bcd923c2ce294b13b822853a529030 Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 29 May 2023 19:13:33 -0700 Subject: [PATCH 401/477] core: add octal and hex size parse support --- src/uucore/src/lib/parser/parse_size.rs | 126 ++++++++++++++++++++---- 1 file changed, 106 insertions(+), 20 deletions(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index 60209d8493..70b94fbccd 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -25,6 +25,12 @@ pub struct Parser<'parser> { pub default_unit: Option<&'parser str>, } +enum NumberSystem { + Decimal, + Octal, + Hexadecimal, +} + impl<'parser> Parser<'parser> { pub fn with_allow_list(&mut self, allow_list: &'parser [&str]) -> &mut Self { self.allow_list = Some(allow_list); @@ -62,32 +68,42 @@ impl<'parser> Parser<'parser> { /// assert_eq!(Ok(123), parse_size("123")); /// assert_eq!(Ok(9 * 1000), parse_size("9kB")); // kB is 1000 /// assert_eq!(Ok(2 * 1024), parse_size("2K")); // K is 1024 + /// assert_eq!(Ok(44251 * 1024), parse_size("0xACDBK")); /// ``` pub fn parse(&self, size: &str) -> Result { if size.is_empty() { return Err(ParseSizeError::parse_failure(size)); } - // Get the numeric part of the size argument. For example, if the - // argument is "123K", then the numeric part is "123". - let numeric_string: String = size.chars().take_while(|c| c.is_ascii_digit()).collect(); - let number: u64 = if numeric_string.is_empty() { - 1 - } else { - match numeric_string.parse() { - Ok(n) => n, - Err(_) => return Err(ParseSizeError::parse_failure(size)), + + let number_system: NumberSystem = self.determine_number_system(size); + + // Split the size argument into numeric and unit parts + // For example, if the argument is "123K", the numeric part is "123", and + // the unit is "K" + let (numeric_string, unit) = match number_system { + NumberSystem::Hexadecimal => { + let numeric_string: String = size + .chars() + .take(2) + .chain(size.chars().skip(2).take_while(|c| c.is_ascii_hexdigit())) + .collect(); + let unit: String = size.chars().skip(numeric_string.len()).collect(); + + (numeric_string, unit) + } + _ => { + let mut unit: String = size + .chars() + .rev() + .take_while(|c| c.is_alphabetic()) + .collect(); + unit = unit.chars().rev().collect(); + let numeric_string = size.chars().take(size.len() - unit.len()).collect(); + + (numeric_string, unit) } }; - - // Get the alphabetic units part of the size argument and compute - // the factor it represents. For example, if the argument is "123K", - // then the unit part is "K" and the factor is 1024. This may be the - // empty string, in which case, the factor is 1. - // - // The lowercase "b" (used by `od`, `head`, `tail`, etc.) means - // "block" and the Posix block size is 512. The uppercase "B" - // means "byte". - let mut unit: &str = &size[numeric_string.len()..]; + let mut unit: &str = unit.as_str(); if let Some(default_unit) = self.default_unit { // Check if `unit` is empty then assigns `default_unit` to `unit` @@ -115,6 +131,12 @@ impl<'parser> Parser<'parser> { } } + // Compute the factor the unit represents. + // empty string means the factor is 1. + // + // The lowercase "b" (used by `od`, `head`, `tail`, etc.) means + // "block" and the Posix block size is 512. The uppercase "B" + // means "byte". let (base, exponent): (u128, u32) = match unit { "" => (1, 0), "B" if self.capital_b_bytes => (1, 0), @@ -142,10 +164,60 @@ impl<'parser> Parser<'parser> { Ok(n) => n, Err(_) => return Err(ParseSizeError::size_too_big(size)), }; + + // parse string into u64 + let number: u64 = match number_system { + NumberSystem::Decimal => { + if numeric_string.is_empty() { + 1 + } else { + match numeric_string.parse() { + Ok(n) => n, + Err(_) => return Err(ParseSizeError::parse_failure(size)), + } + } + } + NumberSystem::Octal => { + let trimmed_string = numeric_string.trim_start_matches("0"); + match u64::from_str_radix(trimmed_string, 8) { + Ok(res) => res, + Err(_) => return Err(ParseSizeError::parse_failure(size)), + } + } + NumberSystem::Hexadecimal => { + let trimmed_string = numeric_string.trim_start_matches("0x"); + match u64::from_str_radix(trimmed_string, 16) { + Ok(res) => res, + Err(_) => return Err(ParseSizeError::parse_failure(size)), + } + } + }; + number .checked_mul(factor) .ok_or_else(|| ParseSizeError::size_too_big(size)) } + + fn determine_number_system(&self, size: &str) -> NumberSystem { + if size.len() <= 1 { + return NumberSystem::Decimal; + } + + if size.starts_with("0x") { + return NumberSystem::Hexadecimal; + } + + let num_digits: usize = size + .chars() + .take_while(|c| c.is_ascii_digit()) + .collect::() + .len(); + if size.starts_with("0") && num_digits > 1 { + return NumberSystem::Octal; + } + + NumberSystem::Decimal + } } /// Parse a size string into a number of bytes. @@ -336,7 +408,7 @@ mod tests { #[test] fn invalid_suffix() { - let test_strings = ["328hdsf3290", "5mib", "1e2", "1H", "1.2"]; + let test_strings = ["5mib", "1eb", "1H"]; for &test_string in &test_strings { assert_eq!( parse_size(test_string).unwrap_err(), @@ -450,4 +522,18 @@ mod tests { assert!(parser.parse("1B").is_err()); assert!(parser.parse("B").is_err()); } + + #[test] + fn parse_octal_size() { + assert_eq!(Ok(63), parse_size("077")); + assert_eq!(Ok(528), parse_size("01020")); + assert_eq!(Ok(668 * 1024), parse_size("01234K")); + } + + #[test] + fn parse_hex_size() { + assert_eq!(Ok(10), parse_size("0xA")); + assert_eq!(Ok(94722), parse_size("0x17202")); + assert_eq!(Ok(44251 * 1024), parse_size("0xACDBK")); + } } From 3ca003846dc2d272d56a27043cf73c9b5dc6b427 Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 29 May 2023 20:10:16 -0700 Subject: [PATCH 402/477] shred: add support for hex and octal size --- src/uu/shred/src/shred.rs | 42 ++++++++++--------------------------- tests/by-util/test_shred.rs | 11 ++++++++++ 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 89f857b19f..1ceffe9957 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -19,6 +19,7 @@ use std::os::unix::prelude::PermissionsExt; use std::path::{Path, PathBuf}; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError, UUsageError}; +use uucore::parse_size::parse_size; use uucore::{format_usage, help_about, help_section, help_usage, show, show_error, show_if_err}; const ABOUT: &str = help_about!("shred.md"); @@ -318,38 +319,17 @@ pub fn uu_app() -> Command { ) } -// TODO: Add support for all postfixes here up to and including EiB -// http://www.gnu.org/software/coreutils/manual/coreutils.html#Block-size fn get_size(size_str_opt: Option) -> Option { - size_str_opt.as_ref()?; - - let mut size_str = size_str_opt.as_ref().unwrap().clone(); - // Immutably look at last character of size string - let unit = match size_str.chars().last().unwrap() { - 'K' => { - size_str.pop(); - 1024u64 - } - 'M' => { - size_str.pop(); - (1024 * 1024) as u64 - } - 'G' => { - size_str.pop(); - (1024 * 1024 * 1024) as u64 - } - _ => 1u64, - }; - - let coefficient = match size_str.parse::() { - Ok(u) => u, - Err(_) => { - show_error!("{}: Invalid file size", size_str_opt.unwrap().maybe_quote()); - std::process::exit(1); - } - }; - - Some(coefficient * unit) + match size_str_opt { + Some(size) => match parse_size(size.as_str()) { + Ok(res) => Some(res), + Err(_) => { + show_error!("invalid file size: {}", size.quote()); + std::process::exit(1) + } + }, + None => None, + } } fn pass_name(pass_type: &PassType) -> String { diff --git a/tests/by-util/test_shred.rs b/tests/by-util/test_shred.rs index 58db09cbd6..a34345aeee 100644 --- a/tests/by-util/test_shred.rs +++ b/tests/by-util/test_shred.rs @@ -51,3 +51,14 @@ fn test_shred_force() { // file_a was deleted. assert!(!at.file_exists(file)); } + +#[test] +fn test_hex() { + let (at, mut ucmd) = at_and_ucmd!(); + + let file = "test_hex"; + + at.touch(file); + + ucmd.arg("--size=0x10").arg(file).succeeds(); +} From 6cadffc8f1879ba1174d30d10cadc9ac273498a3 Mon Sep 17 00:00:00 2001 From: John Shin Date: Mon, 29 May 2023 20:59:21 -0700 Subject: [PATCH 403/477] core: fix clippy warning for size parser --- src/uucore/src/lib/parser/parse_size.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index 70b94fbccd..be642ef8bb 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -178,7 +178,7 @@ impl<'parser> Parser<'parser> { } } NumberSystem::Octal => { - let trimmed_string = numeric_string.trim_start_matches("0"); + let trimmed_string = numeric_string.trim_start_matches('0'); match u64::from_str_radix(trimmed_string, 8) { Ok(res) => res, Err(_) => return Err(ParseSizeError::parse_failure(size)), @@ -212,7 +212,7 @@ impl<'parser> Parser<'parser> { .take_while(|c| c.is_ascii_digit()) .collect::() .len(); - if size.starts_with("0") && num_digits > 1 { + if size.starts_with('0') && num_digits > 1 { return NumberSystem::Octal; } From 8ef926c6e863c0b274df9c33b326d45e7e24b10e Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 30 May 2023 00:26:17 -0700 Subject: [PATCH 404/477] core: refactor num and unit split --- src/uucore/src/lib/parser/parse_size.rs | 31 +++++++------------------ 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index be642ef8bb..716cf8d793 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -80,30 +80,15 @@ impl<'parser> Parser<'parser> { // Split the size argument into numeric and unit parts // For example, if the argument is "123K", the numeric part is "123", and // the unit is "K" - let (numeric_string, unit) = match number_system { - NumberSystem::Hexadecimal => { - let numeric_string: String = size - .chars() - .take(2) - .chain(size.chars().skip(2).take_while(|c| c.is_ascii_hexdigit())) - .collect(); - let unit: String = size.chars().skip(numeric_string.len()).collect(); - - (numeric_string, unit) - } - _ => { - let mut unit: String = size - .chars() - .rev() - .take_while(|c| c.is_alphabetic()) - .collect(); - unit = unit.chars().rev().collect(); - let numeric_string = size.chars().take(size.len() - unit.len()).collect(); - - (numeric_string, unit) - } + let numeric_string: String = match number_system { + NumberSystem::Hexadecimal => size + .chars() + .take(2) + .chain(size.chars().skip(2).take_while(|c| c.is_ascii_hexdigit())) + .collect(), + _ => size.chars().take_while(|c| c.is_ascii_digit()).collect(), }; - let mut unit: &str = unit.as_str(); + let mut unit: &str = &size[numeric_string.len()..]; if let Some(default_unit) = self.default_unit { // Check if `unit` is empty then assigns `default_unit` to `unit` From 0465553f6ebd36cebf4d0d71a476b957cb2b29fc Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 30 May 2023 00:27:09 -0700 Subject: [PATCH 405/477] core: size parser treat 000 as decimal --- src/uucore/src/lib/parser/parse_size.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index 716cf8d793..af4cf990df 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -197,7 +197,8 @@ impl<'parser> Parser<'parser> { .take_while(|c| c.is_ascii_digit()) .collect::() .len(); - if size.starts_with('0') && num_digits > 1 { + let all_zeros = size.chars().all(|c| c == '0'); + if size.starts_with('0') && num_digits > 1 && !all_zeros { return NumberSystem::Octal; } From a3979201836e97cea203eee0f328d89ff75d8a7b Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 30 May 2023 00:33:14 -0700 Subject: [PATCH 406/477] core: refactor parse_number in size parser --- src/uucore/src/lib/parser/parse_size.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index af4cf990df..c6a02dfaea 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -156,25 +156,16 @@ impl<'parser> Parser<'parser> { if numeric_string.is_empty() { 1 } else { - match numeric_string.parse() { - Ok(n) => n, - Err(_) => return Err(ParseSizeError::parse_failure(size)), - } + self.parse_number(&numeric_string, 10, size)? } } NumberSystem::Octal => { let trimmed_string = numeric_string.trim_start_matches('0'); - match u64::from_str_radix(trimmed_string, 8) { - Ok(res) => res, - Err(_) => return Err(ParseSizeError::parse_failure(size)), - } + self.parse_number(trimmed_string, 8, size)? } NumberSystem::Hexadecimal => { let trimmed_string = numeric_string.trim_start_matches("0x"); - match u64::from_str_radix(trimmed_string, 16) { - Ok(res) => res, - Err(_) => return Err(ParseSizeError::parse_failure(size)), - } + self.parse_number(trimmed_string, 16, size)? } }; @@ -204,6 +195,16 @@ impl<'parser> Parser<'parser> { NumberSystem::Decimal } + + fn parse_number( + &self, + numeric_string: &str, + radix: u32, + original_size: &str, + ) -> Result { + u64::from_str_radix(numeric_string, radix) + .map_err(|_| ParseSizeError::ParseFailure(original_size.to_string())) + } } /// Parse a size string into a number of bytes. From 58bf9989199c0713ed6d4e385a594f0424e100cc Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 30 May 2023 15:49:53 +0200 Subject: [PATCH 407/477] Ignore some words --- src/uucore/src/lib/parser/parse_size.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uucore/src/lib/parser/parse_size.rs b/src/uucore/src/lib/parser/parse_size.rs index c6a02dfaea..2ea84e389b 100644 --- a/src/uucore/src/lib/parser/parse_size.rs +++ b/src/uucore/src/lib/parser/parse_size.rs @@ -3,7 +3,7 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -// spell-checker:ignore (ToDO) hdsf ghead gtail +// spell-checker:ignore (ToDO) hdsf ghead gtail ACDBK hexdigit use std::error::Error; use std::fmt; From f830b6e68f984c47f90dba68f6d12b7873a1d3a1 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 23 May 2023 11:14:47 +0200 Subject: [PATCH 408/477] update to platform-info 2.0.1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/uu/arch/src/arch.rs | 7 ++++--- src/uu/uname/src/uname.rs | 19 +++++++++---------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d7f927243..529e1ec358 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1712,9 +1712,9 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "platform-info" -version = "1.0.2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7c23cfae725ae06d9e43010153fa77bdfa8c827bf08fe4beeb2a3514e6be12" +checksum = "827dc4f7a81331d48c8abf11b5ac18673b390d33e9632327e286d940289aefab" dependencies = [ "libc", "winapi", diff --git a/Cargo.toml b/Cargo.toml index 595be01f46..0992677092 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -304,7 +304,7 @@ onig = { version = "~6.4", default-features = false } ouroboros = "0.15.6" phf = "0.11.1" phf_codegen = "0.11.1" -platform-info = "1.0.2" +platform-info = "2.0.1" quick-error = "2.0.1" rand = { version = "0.8", features = ["small_rng"] } rand_core = "0.6" diff --git a/src/uu/arch/src/arch.rs b/src/uu/arch/src/arch.rs index a2208d8b03..96eba1ef94 100644 --- a/src/uu/arch/src/arch.rs +++ b/src/uu/arch/src/arch.rs @@ -9,7 +9,7 @@ use platform_info::*; use clap::{crate_version, Command}; -use uucore::error::{FromIo, UResult}; +use uucore::error::{UResult, USimpleError}; use uucore::{help_about, help_section}; static ABOUT: &str = help_about!("arch.md"); @@ -19,8 +19,9 @@ static SUMMARY: &str = help_section!("after help", "arch.md"); pub fn uumain(args: impl uucore::Args) -> UResult<()> { uu_app().try_get_matches_from(args)?; - let uts = PlatformInfo::new().map_err_context(|| "cannot get system name".to_string())?; - println!("{}", uts.machine().trim()); + let uts = PlatformInfo::new().map_err(|_e| USimpleError::new(1, "cannot get system name"))?; + + println!("{}", uts.machine().to_string_lossy().trim()); Ok(()) } diff --git a/src/uu/uname/src/uname.rs b/src/uu/uname/src/uname.rs index df744dd850..8b86792345 100644 --- a/src/uu/uname/src/uname.rs +++ b/src/uu/uname/src/uname.rs @@ -13,7 +13,7 @@ use clap::{crate_version, Arg, ArgAction, Command}; use platform_info::*; use uucore::{ - error::{FromIo, UResult}, + error::{UResult, USimpleError}, format_usage, help_about, help_usage, }; @@ -36,8 +36,8 @@ pub mod options { pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().try_get_matches_from(args)?; - let uname = - PlatformInfo::new().map_err_context(|| "failed to create PlatformInfo".to_string())?; + let uname = PlatformInfo::new().map_err(|_e| USimpleError::new(1, "cannot get system name"))?; + let mut output = String::new(); let all = matches.get_flag(options::ALL); @@ -61,33 +61,32 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { || hardware_platform); if kernel_name || all || none { - output.push_str(&uname.sysname()); + output.push_str(&uname.sysname().to_string_lossy()); output.push(' '); } if nodename || all { - // maint: [2023-01-14; rivy] remove `.trim_end_matches('\0')` when platform-info nodename-NUL bug is fixed (see GH:uutils/platform-info/issues/32) - output.push_str(uname.nodename().trim_end_matches('\0')); + output.push_str(&uname.nodename().to_string_lossy()); output.push(' '); } if kernel_release || all { - output.push_str(&uname.release()); + output.push_str(&uname.release().to_string_lossy()); output.push(' '); } if kernel_version || all { - output.push_str(&uname.version()); + output.push_str(&uname.version().to_string_lossy()); output.push(' '); } if machine || all { - output.push_str(&uname.machine()); + output.push_str(&uname.machine().to_string_lossy()); output.push(' '); } if os || all { - output.push_str(&uname.osname()); + output.push_str(&uname.osname().to_string_lossy()); output.push(' '); } From abff446691e2fb320b9ad9268d5d6d339411635a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 18:41:48 +0000 Subject: [PATCH 409/477] chore(deps): update rust crate ctrlc to 3.4 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 37ac460763..e185df39ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -707,9 +707,9 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7394a21d012ce5c850497fb774b167d81b99f060025fbf06ee92b9848bd97eb2" +checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" dependencies = [ "nix", "windows-sys 0.48.0", diff --git a/Cargo.toml b/Cargo.toml index d033ac75c9..be30a43582 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -275,7 +275,7 @@ clap_mangen = "0.2" compare = "0.1.0" coz = { version = "0.1.3" } crossterm = ">=0.26.1" -ctrlc = { version = "3.3", features = ["termination"] } +ctrlc = { version = "3.4", features = ["termination"] } exacl = "0.10.0" file_diff = "1.0.0" filetime = "0.2" From f10faf21bc328fb5704cdb0361c5084e20e84d7a Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 30 May 2023 11:26:39 -0700 Subject: [PATCH 410/477] head: interpret size as decimal --- src/uu/head/src/parse.rs | 8 +++++++- tests/by-util/test_head.rs | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/uu/head/src/parse.rs b/src/uu/head/src/parse.rs index b24b6591ef..56c359a0c7 100644 --- a/src/uu/head/src/parse.rs +++ b/src/uu/head/src/parse.rs @@ -114,7 +114,13 @@ pub fn parse_num(src: &str) -> Result<(u64, bool), ParseSizeError> { return Err(ParseSizeError::ParseFailure(src.to_string())); } - parse_size(size_string).map(|n| (n, all_but_last)) + // remove leading zeros so that size is interpreted as decimal, not octal + let trimmed_string = size_string.trim_start_matches('0'); + if trimmed_string.is_empty() { + Ok((0, all_but_last)) + } else { + parse_size(trimmed_string).map(|n| (n, all_but_last)) + } } #[cfg(test)] diff --git a/tests/by-util/test_head.rs b/tests/by-util/test_head.rs index 571bfb3a89..0e1eafc860 100644 --- a/tests/by-util/test_head.rs +++ b/tests/by-util/test_head.rs @@ -189,6 +189,15 @@ fn test_no_such_file_or_directory() { .stderr_contains("cannot open 'no_such_file.toml' for reading: No such file or directory"); } +#[test] +fn test_lines_leading_zeros() { + new_ucmd!() + .arg("--lines=010") + .pipe_in("\n\n\n\n\n\n\n\n\n\n\n\n") + .succeeds() + .stdout_is("\n\n\n\n\n\n\n\n\n\n"); +} + /// Test that each non-existent files gets its own error message printed. #[test] fn test_multiple_nonexistent_files() { From b93bae2964ce52ad24dbd16ee110593096efb944 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 30 May 2023 13:34:00 -0700 Subject: [PATCH 411/477] tail: fix parsing logic and add quote --- src/uu/tail/src/args.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/uu/tail/src/args.rs b/src/uu/tail/src/args.rs index 5fb5ef2b3e..955a9d8f6a 100644 --- a/src/uu/tail/src/args.rs +++ b/src/uu/tail/src/args.rs @@ -80,7 +80,7 @@ impl FilterMode { Err(e) => { return Err(USimpleError::new( 1, - format!("invalid number of bytes: {e}"), + format!("invalid number of bytes: '{e}'"), )) } } @@ -415,16 +415,17 @@ fn parse_num(src: &str) -> Result { starting_with = true; } } - } else { - return Err(ParseSizeError::ParseFailure(src.to_string())); } - parse_size(size_string).map(|n| match (n, starting_with) { - (0, true) => Signum::PlusZero, - (0, false) => Signum::MinusZero, - (n, true) => Signum::Positive(n), - (n, false) => Signum::Negative(n), - }) + match parse_size(size_string) { + Ok(n) => match (n, starting_with) { + (0, true) => Ok(Signum::PlusZero), + (0, false) => Ok(Signum::MinusZero), + (n, true) => Ok(Signum::Positive(n)), + (n, false) => Ok(Signum::Negative(n)), + }, + Err(_) => Err(ParseSizeError::ParseFailure(size_string.to_string())), + } } pub fn parse_args(args: impl uucore::Args) -> UResult { From f10059db026cdda3def757ee6a430b122e59bd83 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 30 May 2023 13:40:41 -0700 Subject: [PATCH 412/477] shred: refactor get_size --- src/uu/shred/src/shred.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 1ceffe9957..47c3ff6ec5 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -320,16 +320,16 @@ pub fn uu_app() -> Command { } fn get_size(size_str_opt: Option) -> Option { - match size_str_opt { - Some(size) => match parse_size(size.as_str()) { - Ok(res) => Some(res), - Err(_) => { + size_str_opt + .as_ref() + .and_then(|size| parse_size(size.as_str()).ok()) + .or_else(|| { + if let Some(size) = size_str_opt { show_error!("invalid file size: {}", size.quote()); - std::process::exit(1) + std::process::exit(1); } - }, - None => None, - } + None + }) } fn pass_name(pass_type: &PassType) -> String { From a4baca01c990dfb31eb82eb53a7d340eb54f1aee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 21:02:52 +0000 Subject: [PATCH 413/477] chore(deps): update rust crate chrono to ^0.4.26 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 37ac460763..1a6ad23ba4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -266,9 +266,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.25" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbc37d37da9e5bce8173f3a41b71d9bf3c674deebbaceacd0ebdabde76efb03" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/Cargo.toml b/Cargo.toml index d033ac75c9..08fb3b44d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -268,7 +268,7 @@ binary-heap-plus = "0.5.0" bstr = "1.5" bytecount = "0.6.3" byteorder = "1.4.3" -chrono = { version="^0.4.25", default-features=false, features=["std", "alloc", "clock"]} +chrono = { version="^0.4.26", default-features=false, features=["std", "alloc", "clock"]} clap = { version = "4.3", features = ["wrap_help", "cargo"] } clap_complete = "4.3" clap_mangen = "0.2" From 4b09b917cd3e4687da28fb91b6d3d3eef0ffea54 Mon Sep 17 00:00:00 2001 From: John Shin Date: Tue, 30 May 2023 15:08:22 -0700 Subject: [PATCH 414/477] shred: use exact if size is given --- src/uu/shred/src/shred.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 47c3ff6ec5..5ec1d12135 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -239,7 +239,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { .get_one::(options::SIZE) .map(|s| s.to_string()); let size = get_size(size_arg); - let exact = matches.get_flag(options::EXACT) && size.is_none(); // if -s is given, ignore -x + let exact = matches.get_flag(options::EXACT) || size.is_some(); let zero = matches.get_flag(options::ZERO); let verbose = matches.get_flag(options::VERBOSE); From 77e183955b73951047db10ac37d2747b428863c9 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Wed, 31 May 2023 20:09:26 +0200 Subject: [PATCH 415/477] head: use OsStringExt::from_vec instead of std::from_utf8_unchecked This no longer triggers the `invalid_from_utf8_unchecked` lint. It is also a bit cleaner and no longer requires `unsafe` because OsString is not guaranteed to be valid UTF-8. --- src/uu/head/src/head.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/uu/head/src/head.rs b/src/uu/head/src/head.rs index 2ccf20904e..a336c91d4b 100644 --- a/src/uu/head/src/head.rs +++ b/src/uu/head/src/head.rs @@ -622,12 +622,10 @@ mod tests { #[test] #[cfg(target_os = "linux")] fn test_arg_iterate_bad_encoding() { - #[allow(clippy::invalid_utf8_in_unchecked)] - let invalid = unsafe { std::str::from_utf8_unchecked(b"\x80\x81") }; + use std::os::unix::ffi::OsStringExt; + let invalid = OsString::from_vec(vec![b'\x80', b'\x81']); // this arises from a conversion from OsString to &str - assert!( - arg_iterate(vec![OsString::from("head"), OsString::from(invalid)].into_iter()).is_err() - ); + assert!(arg_iterate(vec![OsString::from("head"), invalid].into_iter()).is_err()); } #[test] fn read_early_exit() { From 7a706d37197d6dadfc4fda56f436bfad2ca686d8 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 30 May 2023 16:41:48 +0200 Subject: [PATCH 416/477] deny.toml: remove io-lifetimes from skip list --- deny.toml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/deny.toml b/deny.toml index c4d83c513a..14470b9b0d 100644 --- a/deny.toml +++ b/deny.toml @@ -61,13 +61,10 @@ highlight = "all" skip = [ # is-terminal { name = "hermit-abi", version = "0.3.1" }, - # is-terminal + # procfs { name = "rustix", version = "0.36.14" }, - # is-terminal (via rustix) - { name = "io-lifetimes", version = "1.0.5" }, - # is-terminal - { name = "linux-raw-sys", version = "0.1.4" }, - # is-terminal + { name = "linux-raw-sys", version = "0.1.4" }, + # various crates { name = "windows-sys", version = "0.45.0" }, { name = "windows-targets", version = "0.42.2" }, { name = "windows_aarch64_gnullvm", version = "0.42.2" }, @@ -77,7 +74,6 @@ skip = [ { name = "windows_x86_64_gnu", version = "0.42.2" }, { name = "windows_x86_64_gnullvm", version = "0.42.2" }, { name = "windows_x86_64_msvc", version = "0.42.2" }, - # tempfile { name = "redox_syscall", version = "0.3.5" }, # cpp_macros From 0b4a91744d73daea683a1385d160f281b361e242 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 30 May 2023 16:47:40 +0200 Subject: [PATCH 417/477] Bump io-lifetimes from 1.0.5 to 1.0.11 --- Cargo.lock | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7a1f5b9b3..c38199dca5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1226,12 +1226,13 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.5" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ + "hermit-abi 0.3.1", "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] From 7a449feaa0a414f5cac208fcbe552f4b3e87f879 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 1 Jun 2023 10:43:09 +0200 Subject: [PATCH 418/477] Bump fundu from 0.5.1 to 1.0.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c38199dca5..b657c84fed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -957,9 +957,9 @@ dependencies = [ [[package]] name = "fundu" -version = "0.5.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a37cfff04a32112c22c5497b20b0b09100fca406e76afd47b2ba5ab33d7a851" +checksum = "47af3b646bdd738395be2db903fc11a5923b5e206016b8d4ad6db890bcae9bd5" [[package]] name = "futures" diff --git a/Cargo.toml b/Cargo.toml index ebd9a4bf40..409b03159e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -282,7 +282,7 @@ filetime = "0.2" fnv = "1.0.7" fs_extra = "1.3.0" fts-sys = "0.2" -fundu = "0.5.1" +fundu = "1.0.0" gcd = "2.3" glob = "0.3.1" half = "2.2" From ccee02f0257b44ab376c8fb5a3377099ca713b20 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 1 Jun 2023 10:57:54 +0200 Subject: [PATCH 419/477] sleep: fix compile error due to fundu update --- src/uu/sleep/src/sleep.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/uu/sleep/src/sleep.rs b/src/uu/sleep/src/sleep.rs index 009986095f..8acb7724f8 100644 --- a/src/uu/sleep/src/sleep.rs +++ b/src/uu/sleep/src/sleep.rs @@ -14,7 +14,7 @@ use uucore::{ }; use clap::{crate_version, Arg, ArgAction, Command}; -use fundu::{self, DurationParser, ParseError}; +use fundu::{self, DurationParser, ParseError, SaturatingInto}; static ABOUT: &str = help_about!("sleep.md"); const USAGE: &str = help_usage!("sleep.md"); @@ -63,7 +63,7 @@ pub fn uu_app() -> Command { fn sleep(args: &[&str]) -> UResult<()> { let mut arg_error = false; - use fundu::TimeUnit::*; + use fundu::TimeUnit::{Day, Hour, Minute, Second}; let parser = DurationParser::with_time_units(&[Second, Minute, Hour, Day]); let sleep_dur = args @@ -91,7 +91,9 @@ fn sleep(args: &[&str]) -> UResult<()> { None } }) - .fold(Duration::ZERO, |acc, n| acc.saturating_add(n)); + .fold(Duration::ZERO, |acc, n| { + acc.saturating_add(SaturatingInto::::saturating_into(n)) + }); if arg_error { return Err(UUsageError::new(1, "")); From b6c02c1a236d83d6f538d045eb02e6ce3eddf8eb Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 1 Jun 2023 15:30:43 +0200 Subject: [PATCH 420/477] tail: fix compile error due to fundu update --- src/uu/tail/src/args.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/uu/tail/src/args.rs b/src/uu/tail/src/args.rs index 5fb5ef2b3e..c054017c22 100644 --- a/src/uu/tail/src/args.rs +++ b/src/uu/tail/src/args.rs @@ -9,7 +9,7 @@ use crate::paths::Input; use crate::{parse, platform, Quotable}; use clap::crate_version; use clap::{Arg, ArgAction, ArgMatches, Command}; -use fundu::DurationParser; +use fundu::{DurationParser, SaturatingInto}; use is_terminal::IsTerminal; use same_file::Handle; use std::collections::VecDeque; @@ -235,12 +235,15 @@ impl Settings { // `DURATION::MAX` or `infinity` was given // * not applied here but it supports customizable time units and provides better error // messages - settings.sleep_sec = - DurationParser::without_time_units() - .parse(source) - .map_err(|_| { - UUsageError::new(1, format!("invalid number of seconds: '{source}'")) - })?; + settings.sleep_sec = match DurationParser::without_time_units().parse(source) { + Ok(duration) => SaturatingInto::::saturating_into(duration), + Err(_) => { + return Err(UUsageError::new( + 1, + format!("invalid number of seconds: '{source}'"), + )) + } + } } if let Some(s) = matches.get_one::(options::MAX_UNCHANGED_STATS) { From 4eb1e847e984f6293e0d919109a1f5cdd16b2f7a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 31 May 2023 23:53:21 +0200 Subject: [PATCH 421/477] cp --no-clobber should fail --- src/uu/cp/src/cp.rs | 15 ++++++--------- tests/by-util/test_cp.rs | 6 +++--- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 513fb8380a..e9fb56ef31 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -1102,23 +1102,21 @@ fn preserve_hardlinks( } /// When handling errors, we don't always want to show them to the user. This function handles that. -/// If the error is printed, returns true, false otherwise. -fn show_error_if_needed(error: &Error) -> bool { +fn show_error_if_needed(error: &Error) { match error { // When using --no-clobber, we don't want to show // an error message - Error::NotAllFilesCopied => (), + Error::NotAllFilesCopied => { + // Need to return an error code + } Error::Skipped => { // touch a b && echo "n"|cp -i a b && echo $? // should return an error from GNU 9.2 - return true; } _ => { show_error!("{}", error); - return true; } } - false } /// Copy all `sources` to `target`. Returns an @@ -1175,9 +1173,8 @@ fn copy(sources: &[Source], target: &TargetSlice, options: &Options) -> CopyResu options, &mut symlinked_files, ) { - if show_error_if_needed(&error) { - non_fatal_errors = true; - } + show_error_if_needed(&error); + non_fatal_errors = true; } } seen_sources.insert(source); diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 1feeb0edee..690aa8b4eb 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -487,7 +487,7 @@ fn test_cp_arg_no_clobber() { ucmd.arg(TEST_HELLO_WORLD_SOURCE) .arg(TEST_HOW_ARE_YOU_SOURCE) .arg("--no-clobber") - .succeeds(); + .fails(); assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n"); } @@ -498,7 +498,7 @@ fn test_cp_arg_no_clobber_inferred_arg() { ucmd.arg(TEST_HELLO_WORLD_SOURCE) .arg(TEST_HOW_ARE_YOU_SOURCE) .arg("--no-clob") - .succeeds(); + .fails(); assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n"); } @@ -525,7 +525,7 @@ fn test_cp_arg_no_clobber_twice() { .arg("--no-clobber") .arg("source.txt") .arg("dest.txt") - .succeeds(); + .fails(); assert_eq!(at.read("source.txt"), "some-content"); // Should be empty as the "no-clobber" should keep From 20ce7accf250b07a4e0fe2f1bfe29f6363581cd6 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Jun 2023 00:23:34 +0200 Subject: [PATCH 422/477] cp: -i prompts in the right place Should fix tests/cp/cp-i.sh --- src/uu/cp/src/cp.rs | 25 ++++++++++++++++++------- tests/by-util/test_cp.rs | 26 +++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index e9fb56ef31..e8552a179f 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -43,7 +43,8 @@ use uucore::fs::{ }; use uucore::update_control::{self, UpdateMode}; use uucore::{ - crash, format_usage, help_about, help_section, help_usage, prompt_yes, show_error, show_warning, + crash, format_usage, help_about, help_section, help_usage, prompt_yes, show_error, + show_warning, util_name, }; use crate::copydir::copy_directory; @@ -1251,13 +1252,23 @@ fn copy_source( } impl OverwriteMode { - fn verify(&self, path: &Path) -> CopyResult<()> { + fn verify(&self, path: &Path, verbose: bool) -> CopyResult<()> { match *self { - Self::NoClobber => Err(Error::NotAllFilesCopied), + Self::NoClobber => { + if verbose { + println!("skipped {}", path.quote()); + } else { + eprintln!("{}: not replacing {}", util_name(), path.quote()); + } + Err(Error::NotAllFilesCopied) + } Self::Interactive(_) => { if prompt_yes!("overwrite {}?", path.quote()) { Ok(()) } else { + if verbose { + println!("skipped {}", path.quote()); + } Err(Error::Skipped) } } @@ -1465,7 +1476,7 @@ fn handle_existing_dest( return Err(format!("{} and {} are the same file", source.quote(), dest.quote()).into()); } - options.overwrite.verify(dest)?; + options.overwrite.verify(dest, options.verbose)?; let backup_path = backup_control::get_backup_path(options.backup, dest, &options.backup_suffix); if let Some(backup_path) = backup_path { @@ -1823,7 +1834,7 @@ fn copy_helper( File::create(dest).context(dest.display().to_string())?; } else if source_is_fifo && options.recursive && !options.copy_contents { #[cfg(unix)] - copy_fifo(dest, options.overwrite)?; + copy_fifo(dest, options.overwrite, options.verbose)?; } else if source_is_symlink { copy_link(source, dest, symlinked_files)?; } else { @@ -1848,9 +1859,9 @@ fn copy_helper( // "Copies" a FIFO by creating a new one. This workaround is because Rust's // built-in fs::copy does not handle FIFOs (see rust-lang/rust/issues/79390). #[cfg(unix)] -fn copy_fifo(dest: &Path, overwrite: OverwriteMode) -> CopyResult<()> { +fn copy_fifo(dest: &Path, overwrite: OverwriteMode, verbose: bool) -> CopyResult<()> { if dest.exists() { - overwrite.verify(dest)?; + overwrite.verify(dest, verbose)?; fs::remove_file(dest)?; } diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 690aa8b4eb..7f153343d6 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -456,6 +456,29 @@ fn test_cp_arg_interactive_update() { .no_stdout(); } +#[test] +#[cfg(not(target_os = "android"))] +fn test_cp_arg_interactive_verbose() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("a"); + at.touch("b"); + ucmd.args(&["-vi", "a", "b"]) + .pipe_in("N\n") + .fails() + .stdout_is("skipped 'b'\n"); +} + +#[test] +#[cfg(not(target_os = "android"))] +fn test_cp_arg_interactive_verbose_clobber() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("a"); + at.touch("b"); + ucmd.args(&["-vin", "a", "b"]) + .fails() + .stdout_is("skipped 'b'\n"); +} + #[test] #[cfg(target_os = "linux")] fn test_cp_arg_link() { @@ -487,7 +510,8 @@ fn test_cp_arg_no_clobber() { ucmd.arg(TEST_HELLO_WORLD_SOURCE) .arg(TEST_HOW_ARE_YOU_SOURCE) .arg("--no-clobber") - .fails(); + .fails() + .stderr_contains("not replacing"); assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n"); } From bbfa77dcad9057756fdc28846320d9a6e6b1e983 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 2 Jun 2023 09:46:24 +0200 Subject: [PATCH 423/477] cp: replace assert!(false) with panic!() --- tests/by-util/test_cp.rs | 42 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 7f153343d6..9ccf6777ed 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -2946,21 +2946,18 @@ fn test_cp_debug_default() { if !stdout_str .contains("copy offload: unknown, reflink: unsupported, sparse detection: unsupported") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } #[cfg(target_os = "linux")] if !stdout_str.contains("copy offload: unknown, reflink: unsupported, sparse detection: no") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } #[cfg(windows)] if !stdout_str .contains("copy offload: unsupported, reflink: unsupported, sparse detection: unsupported") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } } @@ -2987,8 +2984,7 @@ fn test_cp_debug_multiple_default() { if !stdout_str .contains("copy offload: unknown, reflink: unsupported, sparse detection: unsupported") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } // two files, two occurrences @@ -3007,8 +3003,7 @@ fn test_cp_debug_multiple_default() { { if !stdout_str.contains("copy offload: unknown, reflink: unsupported, sparse detection: no") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } // two files, two occurrences @@ -3026,8 +3021,7 @@ fn test_cp_debug_multiple_default() { if !stdout_str.contains( "copy offload: unsupported, reflink: unsupported, sparse detection: unsupported", ) { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } // two files, two occurrences @@ -3058,8 +3052,7 @@ fn test_cp_debug_sparse_reflink() { let stdout_str = result.stdout_str(); if !stdout_str.contains("copy offload: avoided, reflink: no, sparse detection: zeros") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } } @@ -3079,8 +3072,7 @@ fn test_cp_debug_sparse_always() { let stdout_str = result.stdout_str(); if !stdout_str.contains("copy offload: avoided, reflink: unsupported, sparse detection: zeros") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } } @@ -3099,8 +3091,7 @@ fn test_cp_debug_sparse_never() { .succeeds(); let stdout_str = result.stdout_str(); if !stdout_str.contains("copy offload: unknown, reflink: unsupported, sparse detection: no") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } } @@ -3122,14 +3113,12 @@ fn test_cp_debug_sparse_auto() { if !stdout_str .contains("copy offload: unknown, reflink: unsupported, sparse detection: unsupported") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } #[cfg(target_os = "linux")] if !stdout_str.contains("copy offload: unknown, reflink: unsupported, sparse detection: no") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } } @@ -3152,8 +3141,7 @@ fn test_cp_debug_reflink_auto() { let stdout_str = result.stdout_str(); if !stdout_str.contains("copy offload: unknown, reflink: unsupported, sparse detection: no") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } } @@ -3163,8 +3151,7 @@ fn test_cp_debug_reflink_auto() { if !stdout_str .contains("copy offload: unknown, reflink: unsupported, sparse detection: unsupported") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } } } @@ -3186,7 +3173,6 @@ fn test_cp_debug_sparse_always_reflink_auto() { let stdout_str = result.stdout_str(); if !stdout_str.contains("copy offload: avoided, reflink: unsupported, sparse detection: zeros") { - println!("Failure: stdout was \n{stdout_str}"); - assert!(false); + panic!("Failure: stdout was \n{stdout_str}"); } } From ca9cf3757b4e26e913c9e4d3b3384840308e10d5 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 4 Jun 2023 09:15:37 +0200 Subject: [PATCH 424/477] specify the sccache version because of https://github.com/mozilla/sccache/issues/1789 --- .github/workflows/CICD.yml | 22 ++++++++++++++++++++++ .github/workflows/freebsd.yml | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index fb2300ba9c..8c595537fd 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -183,6 +183,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Initialize workflow variables id: vars shell: bash @@ -293,6 +295,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Initialize workflow variables id: vars shell: bash @@ -347,6 +351,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Initialize workflow variables id: vars shell: bash @@ -435,6 +441,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: "`make build`" shell: bash run: | @@ -477,6 +485,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Test run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: @@ -504,6 +514,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Test run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: @@ -527,6 +539,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Install dependencies shell: bash run: | @@ -652,6 +666,8 @@ jobs: key: "${{ matrix.job.os }}_${{ matrix.job.target }}" - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Initialize workflow variables id: vars shell: bash @@ -905,6 +921,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Install/setup prerequisites shell: bash run: | @@ -989,6 +1007,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Build coreutils as multiple binaries shell: bash run: | @@ -1073,6 +1093,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" # - name: Reattach HEAD ## may be needed for accurate code coverage info # run: git checkout ${{ github.head_ref }} - name: Initialize workflow variables diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml index 9507b3a564..50746154b8 100644 --- a/.github/workflows/freebsd.yml +++ b/.github/workflows/freebsd.yml @@ -34,6 +34,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Prepare, build and test uses: vmactions/freebsd-vm@v0.3.0 with: @@ -124,6 +126,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 + with: + version: "v0.5.0" - name: Prepare, build and test uses: vmactions/freebsd-vm@v0.3.0 with: From ee4691f4a2f9b5942d87646d204fcec6da9f4cd1 Mon Sep 17 00:00:00 2001 From: Guillaume Ranquet Date: Thu, 1 Jun 2023 17:16:46 +0200 Subject: [PATCH 425/477] cp: makes --preserve requires = prevents --preserve to eat the next argument when no value is passed. default value for --preserve is set to mode,ownership(unix only),timestamps before the patch: cp --preserve foo bar error: invalid value 'foo' for '--preserve [...]' [possible values: mode, ownership, timestamps, context, link, links, xattr, all] Signed-off-by: Guillaume Ranquet --- src/uu/cp/src/cp.rs | 1 + tests/by-util/test_cp.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index e8552a179f..60ef540954 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -515,6 +515,7 @@ pub fn uu_app() -> Command { PRESERVABLE_ATTRIBUTES, )) .num_args(0..) + .require_equals(true) .value_name("ATTR_LIST") .overrides_with_all([ options::ARCHIVE, diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 9ccf6777ed..fa5845eac3 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1223,6 +1223,33 @@ fn test_cp_preserve_no_args() { } } +#[test] +fn test_cp_preserve_no_args_before_opts() { + let (at, mut ucmd) = at_and_ucmd!(); + let src_file = "a"; + let dst_file = "b"; + + // Prepare the source file + at.touch(src_file); + #[cfg(unix)] + at.set_mode(src_file, 0o0500); + + // Copy + ucmd.arg("--preserve") + .arg(src_file) + .arg(dst_file) + .succeeds(); + + #[cfg(all(unix, not(target_os = "freebsd")))] + { + // Assert that the mode, ownership, and timestamps are preserved + // NOTICE: the ownership is not modified on the src file, because that requires root permissions + let metadata_src = at.metadata(src_file); + let metadata_dst = at.metadata(dst_file); + assert_metadata_eq!(metadata_src, metadata_dst); + } +} + #[test] fn test_cp_preserve_all() { let (at, mut ucmd) = at_and_ucmd!(); From a0f4576f8a98b18c76d803d18bf56eb341d632d0 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Jun 2023 08:25:03 +0200 Subject: [PATCH 426/477] update of the release doc --- util/update-version.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/util/update-version.sh b/util/update-version.sh index 2e2dca9030..e248d13cd1 100755 --- a/util/update-version.sh +++ b/util/update-version.sh @@ -7,9 +7,10 @@ # 2) run it: sh util/update-version.sh # 3) Do a spot check with "git diff" # 4) cargo test --release --features unix -# 5) Run util/publish.sh in dry mode (it will fail as packages needs more recent version of uucore) -# 6) Run util/publish.sh --do-it -# 7) In some cases, you might have to fix dependencies and run import +# 5) git commit -m "New release" +# 6) Run util/publish.sh in dry mode (it will fail as packages needs more recent version of uucore) +# 7) Run util/publish.sh --do-it +# 8) In some cases, you might have to fix dependencies and run import FROM="0.0.17" TO="0.0.18" From 830b7d5ce1621f5e40838e91d3a066d68ddc40c2 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Jun 2023 08:25:23 +0200 Subject: [PATCH 427/477] New release --- Cargo.lock | 214 ++++++++++++------------- Cargo.toml | 212 ++++++++++++------------ src/uu/arch/Cargo.toml | 2 +- src/uu/base32/Cargo.toml | 2 +- src/uu/base64/Cargo.toml | 2 +- src/uu/basename/Cargo.toml | 2 +- src/uu/basenc/Cargo.toml | 2 +- src/uu/cat/Cargo.toml | 2 +- src/uu/chcon/Cargo.toml | 2 +- src/uu/chgrp/Cargo.toml | 2 +- src/uu/chmod/Cargo.toml | 2 +- src/uu/chown/Cargo.toml | 2 +- src/uu/chroot/Cargo.toml | 2 +- src/uu/cksum/Cargo.toml | 2 +- src/uu/comm/Cargo.toml | 2 +- src/uu/cp/Cargo.toml | 2 +- src/uu/csplit/Cargo.toml | 2 +- src/uu/cut/Cargo.toml | 2 +- src/uu/date/Cargo.toml | 2 +- src/uu/dd/Cargo.toml | 2 +- src/uu/df/Cargo.toml | 2 +- src/uu/dir/Cargo.toml | 2 +- src/uu/dircolors/Cargo.toml | 2 +- src/uu/dirname/Cargo.toml | 2 +- src/uu/du/Cargo.toml | 2 +- src/uu/echo/Cargo.toml | 2 +- src/uu/env/Cargo.toml | 2 +- src/uu/expand/Cargo.toml | 2 +- src/uu/expr/Cargo.toml | 2 +- src/uu/factor/Cargo.toml | 2 +- src/uu/false/Cargo.toml | 2 +- src/uu/fmt/Cargo.toml | 2 +- src/uu/fold/Cargo.toml | 2 +- src/uu/groups/Cargo.toml | 2 +- src/uu/hashsum/Cargo.toml | 2 +- src/uu/head/Cargo.toml | 2 +- src/uu/hostid/Cargo.toml | 2 +- src/uu/hostname/Cargo.toml | 2 +- src/uu/id/Cargo.toml | 2 +- src/uu/install/Cargo.toml | 2 +- src/uu/join/Cargo.toml | 2 +- src/uu/kill/Cargo.toml | 2 +- src/uu/link/Cargo.toml | 2 +- src/uu/ln/Cargo.toml | 2 +- src/uu/logname/Cargo.toml | 2 +- src/uu/ls/Cargo.toml | 2 +- src/uu/mkdir/Cargo.toml | 2 +- src/uu/mkfifo/Cargo.toml | 2 +- src/uu/mknod/Cargo.toml | 2 +- src/uu/mktemp/Cargo.toml | 2 +- src/uu/more/Cargo.toml | 2 +- src/uu/mv/Cargo.toml | 2 +- src/uu/nice/Cargo.toml | 2 +- src/uu/nl/Cargo.toml | 2 +- src/uu/nohup/Cargo.toml | 2 +- src/uu/nproc/Cargo.toml | 2 +- src/uu/numfmt/Cargo.toml | 2 +- src/uu/od/Cargo.toml | 2 +- src/uu/paste/Cargo.toml | 2 +- src/uu/pathchk/Cargo.toml | 2 +- src/uu/pinky/Cargo.toml | 2 +- src/uu/pr/Cargo.toml | 2 +- src/uu/printenv/Cargo.toml | 2 +- src/uu/printf/Cargo.toml | 2 +- src/uu/ptx/Cargo.toml | 2 +- src/uu/pwd/Cargo.toml | 2 +- src/uu/readlink/Cargo.toml | 2 +- src/uu/realpath/Cargo.toml | 2 +- src/uu/relpath/Cargo.toml | 2 +- src/uu/rm/Cargo.toml | 2 +- src/uu/rmdir/Cargo.toml | 2 +- src/uu/runcon/Cargo.toml | 2 +- src/uu/seq/Cargo.toml | 2 +- src/uu/shred/Cargo.toml | 2 +- src/uu/shuf/Cargo.toml | 2 +- src/uu/sleep/Cargo.toml | 2 +- src/uu/sort/Cargo.toml | 2 +- src/uu/split/Cargo.toml | 2 +- src/uu/stat/Cargo.toml | 2 +- src/uu/stdbuf/Cargo.toml | 4 +- src/uu/stdbuf/src/libstdbuf/Cargo.toml | 4 +- src/uu/stty/Cargo.toml | 2 +- src/uu/sum/Cargo.toml | 2 +- src/uu/sync/Cargo.toml | 2 +- src/uu/tac/Cargo.toml | 2 +- src/uu/tail/Cargo.toml | 2 +- src/uu/tee/Cargo.toml | 2 +- src/uu/test/Cargo.toml | 2 +- src/uu/timeout/Cargo.toml | 2 +- src/uu/touch/Cargo.toml | 2 +- src/uu/tr/Cargo.toml | 2 +- src/uu/true/Cargo.toml | 2 +- src/uu/truncate/Cargo.toml | 2 +- src/uu/tsort/Cargo.toml | 2 +- src/uu/tty/Cargo.toml | 2 +- src/uu/uname/Cargo.toml | 2 +- src/uu/unexpand/Cargo.toml | 2 +- src/uu/uniq/Cargo.toml | 2 +- src/uu/unlink/Cargo.toml | 2 +- src/uu/uptime/Cargo.toml | 2 +- src/uu/users/Cargo.toml | 2 +- src/uu/vdir/Cargo.toml | 2 +- src/uu/wc/Cargo.toml | 2 +- src/uu/who/Cargo.toml | 2 +- src/uu/whoami/Cargo.toml | 2 +- src/uu/yes/Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- src/uucore_procs/Cargo.toml | 2 +- util/update-version.sh | 4 +- 109 files changed, 323 insertions(+), 323 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c38199dca5..f45951917e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -394,7 +394,7 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "coreutils" -version = "0.0.18" +version = "0.0.19" dependencies = [ "chrono", "clap", @@ -2387,7 +2387,7 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uu_arch" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "platform-info", @@ -2396,7 +2396,7 @@ dependencies = [ [[package]] name = "uu_base32" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2404,7 +2404,7 @@ dependencies = [ [[package]] name = "uu_base64" -version = "0.0.18" +version = "0.0.19" dependencies = [ "uu_base32", "uucore", @@ -2412,7 +2412,7 @@ dependencies = [ [[package]] name = "uu_basename" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2420,7 +2420,7 @@ dependencies = [ [[package]] name = "uu_basenc" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uu_base32", @@ -2429,7 +2429,7 @@ dependencies = [ [[package]] name = "uu_cat" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "is-terminal", @@ -2440,7 +2440,7 @@ dependencies = [ [[package]] name = "uu_chcon" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "fts-sys", @@ -2452,7 +2452,7 @@ dependencies = [ [[package]] name = "uu_chgrp" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2460,7 +2460,7 @@ dependencies = [ [[package]] name = "uu_chmod" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -2469,7 +2469,7 @@ dependencies = [ [[package]] name = "uu_chown" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2477,7 +2477,7 @@ dependencies = [ [[package]] name = "uu_chroot" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2485,7 +2485,7 @@ dependencies = [ [[package]] name = "uu_cksum" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "hex", @@ -2494,7 +2494,7 @@ dependencies = [ [[package]] name = "uu_comm" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2502,7 +2502,7 @@ dependencies = [ [[package]] name = "uu_cp" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "exacl", @@ -2518,7 +2518,7 @@ dependencies = [ [[package]] name = "uu_csplit" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "regex", @@ -2528,7 +2528,7 @@ dependencies = [ [[package]] name = "uu_cut" -version = "0.0.18" +version = "0.0.19" dependencies = [ "bstr", "clap", @@ -2539,7 +2539,7 @@ dependencies = [ [[package]] name = "uu_date" -version = "0.0.18" +version = "0.0.19" dependencies = [ "chrono", "clap", @@ -2552,7 +2552,7 @@ dependencies = [ [[package]] name = "uu_dd" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "gcd", @@ -2564,7 +2564,7 @@ dependencies = [ [[package]] name = "uu_df" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "unicode-width", @@ -2573,7 +2573,7 @@ dependencies = [ [[package]] name = "uu_dir" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uu_ls", @@ -2582,7 +2582,7 @@ dependencies = [ [[package]] name = "uu_dircolors" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2590,7 +2590,7 @@ dependencies = [ [[package]] name = "uu_dirname" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2598,7 +2598,7 @@ dependencies = [ [[package]] name = "uu_du" -version = "0.0.18" +version = "0.0.19" dependencies = [ "chrono", "clap", @@ -2609,7 +2609,7 @@ dependencies = [ [[package]] name = "uu_echo" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2617,7 +2617,7 @@ dependencies = [ [[package]] name = "uu_env" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "nix", @@ -2627,7 +2627,7 @@ dependencies = [ [[package]] name = "uu_expand" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "unicode-width", @@ -2636,7 +2636,7 @@ dependencies = [ [[package]] name = "uu_expr" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "num-bigint", @@ -2647,7 +2647,7 @@ dependencies = [ [[package]] name = "uu_factor" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "coz", @@ -2660,7 +2660,7 @@ dependencies = [ [[package]] name = "uu_false" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2668,7 +2668,7 @@ dependencies = [ [[package]] name = "uu_fmt" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "unicode-width", @@ -2677,7 +2677,7 @@ dependencies = [ [[package]] name = "uu_fold" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2685,7 +2685,7 @@ dependencies = [ [[package]] name = "uu_groups" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2693,7 +2693,7 @@ dependencies = [ [[package]] name = "uu_hashsum" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "hex", @@ -2704,7 +2704,7 @@ dependencies = [ [[package]] name = "uu_head" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "memchr", @@ -2713,7 +2713,7 @@ dependencies = [ [[package]] name = "uu_hostid" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -2722,7 +2722,7 @@ dependencies = [ [[package]] name = "uu_hostname" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "hostname", @@ -2732,7 +2732,7 @@ dependencies = [ [[package]] name = "uu_id" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "selinux", @@ -2741,7 +2741,7 @@ dependencies = [ [[package]] name = "uu_install" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "file_diff", @@ -2753,7 +2753,7 @@ dependencies = [ [[package]] name = "uu_join" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "memchr", @@ -2762,7 +2762,7 @@ dependencies = [ [[package]] name = "uu_kill" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "nix", @@ -2771,7 +2771,7 @@ dependencies = [ [[package]] name = "uu_link" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2779,7 +2779,7 @@ dependencies = [ [[package]] name = "uu_ln" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2787,7 +2787,7 @@ dependencies = [ [[package]] name = "uu_logname" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -2796,7 +2796,7 @@ dependencies = [ [[package]] name = "uu_ls" -version = "0.0.18" +version = "0.0.19" dependencies = [ "chrono", "clap", @@ -2814,7 +2814,7 @@ dependencies = [ [[package]] name = "uu_mkdir" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2822,7 +2822,7 @@ dependencies = [ [[package]] name = "uu_mkfifo" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -2831,7 +2831,7 @@ dependencies = [ [[package]] name = "uu_mknod" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -2840,7 +2840,7 @@ dependencies = [ [[package]] name = "uu_mktemp" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "rand", @@ -2850,7 +2850,7 @@ dependencies = [ [[package]] name = "uu_more" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "crossterm", @@ -2863,7 +2863,7 @@ dependencies = [ [[package]] name = "uu_mv" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "fs_extra", @@ -2873,7 +2873,7 @@ dependencies = [ [[package]] name = "uu_nice" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -2883,7 +2883,7 @@ dependencies = [ [[package]] name = "uu_nl" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "regex", @@ -2892,7 +2892,7 @@ dependencies = [ [[package]] name = "uu_nohup" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "is-terminal", @@ -2902,7 +2902,7 @@ dependencies = [ [[package]] name = "uu_nproc" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -2911,7 +2911,7 @@ dependencies = [ [[package]] name = "uu_numfmt" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2919,7 +2919,7 @@ dependencies = [ [[package]] name = "uu_od" -version = "0.0.18" +version = "0.0.19" dependencies = [ "byteorder", "clap", @@ -2929,7 +2929,7 @@ dependencies = [ [[package]] name = "uu_paste" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2937,7 +2937,7 @@ dependencies = [ [[package]] name = "uu_pathchk" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -2946,7 +2946,7 @@ dependencies = [ [[package]] name = "uu_pinky" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2954,7 +2954,7 @@ dependencies = [ [[package]] name = "uu_pr" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "itertools", @@ -2966,7 +2966,7 @@ dependencies = [ [[package]] name = "uu_printenv" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2974,7 +2974,7 @@ dependencies = [ [[package]] name = "uu_printf" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2982,7 +2982,7 @@ dependencies = [ [[package]] name = "uu_ptx" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "regex", @@ -2991,7 +2991,7 @@ dependencies = [ [[package]] name = "uu_pwd" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -2999,7 +2999,7 @@ dependencies = [ [[package]] name = "uu_readlink" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3007,7 +3007,7 @@ dependencies = [ [[package]] name = "uu_realpath" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3015,7 +3015,7 @@ dependencies = [ [[package]] name = "uu_relpath" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3023,7 +3023,7 @@ dependencies = [ [[package]] name = "uu_rm" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -3034,7 +3034,7 @@ dependencies = [ [[package]] name = "uu_rmdir" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -3043,7 +3043,7 @@ dependencies = [ [[package]] name = "uu_runcon" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -3054,7 +3054,7 @@ dependencies = [ [[package]] name = "uu_seq" -version = "0.0.18" +version = "0.0.19" dependencies = [ "bigdecimal", "clap", @@ -3065,7 +3065,7 @@ dependencies = [ [[package]] name = "uu_shred" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -3075,7 +3075,7 @@ dependencies = [ [[package]] name = "uu_shuf" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "memchr", @@ -3086,7 +3086,7 @@ dependencies = [ [[package]] name = "uu_sleep" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "fundu", @@ -3095,7 +3095,7 @@ dependencies = [ [[package]] name = "uu_sort" -version = "0.0.18" +version = "0.0.19" dependencies = [ "binary-heap-plus", "clap", @@ -3114,7 +3114,7 @@ dependencies = [ [[package]] name = "uu_split" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "memchr", @@ -3123,7 +3123,7 @@ dependencies = [ [[package]] name = "uu_stat" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3131,7 +3131,7 @@ dependencies = [ [[package]] name = "uu_stdbuf" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "tempfile", @@ -3141,7 +3141,7 @@ dependencies = [ [[package]] name = "uu_stdbuf_libstdbuf" -version = "0.0.18" +version = "0.0.19" dependencies = [ "cpp", "cpp_build", @@ -3151,7 +3151,7 @@ dependencies = [ [[package]] name = "uu_stty" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "nix", @@ -3160,7 +3160,7 @@ dependencies = [ [[package]] name = "uu_sum" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3168,7 +3168,7 @@ dependencies = [ [[package]] name = "uu_sync" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -3179,7 +3179,7 @@ dependencies = [ [[package]] name = "uu_tac" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "memchr", @@ -3190,7 +3190,7 @@ dependencies = [ [[package]] name = "uu_tail" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "fundu", @@ -3207,7 +3207,7 @@ dependencies = [ [[package]] name = "uu_tee" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -3216,7 +3216,7 @@ dependencies = [ [[package]] name = "uu_test" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -3226,7 +3226,7 @@ dependencies = [ [[package]] name = "uu_timeout" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -3236,7 +3236,7 @@ dependencies = [ [[package]] name = "uu_touch" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "filetime", @@ -3248,7 +3248,7 @@ dependencies = [ [[package]] name = "uu_tr" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "nom", @@ -3257,7 +3257,7 @@ dependencies = [ [[package]] name = "uu_true" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3265,7 +3265,7 @@ dependencies = [ [[package]] name = "uu_truncate" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3273,7 +3273,7 @@ dependencies = [ [[package]] name = "uu_tsort" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3281,7 +3281,7 @@ dependencies = [ [[package]] name = "uu_tty" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "is-terminal", @@ -3291,7 +3291,7 @@ dependencies = [ [[package]] name = "uu_uname" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "platform-info", @@ -3300,7 +3300,7 @@ dependencies = [ [[package]] name = "uu_unexpand" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "unicode-width", @@ -3309,7 +3309,7 @@ dependencies = [ [[package]] name = "uu_uniq" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3317,7 +3317,7 @@ dependencies = [ [[package]] name = "uu_unlink" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3325,7 +3325,7 @@ dependencies = [ [[package]] name = "uu_uptime" -version = "0.0.18" +version = "0.0.19" dependencies = [ "chrono", "clap", @@ -3334,7 +3334,7 @@ dependencies = [ [[package]] name = "uu_users" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3342,7 +3342,7 @@ dependencies = [ [[package]] name = "uu_vdir" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uu_ls", @@ -3351,7 +3351,7 @@ dependencies = [ [[package]] name = "uu_wc" -version = "0.0.18" +version = "0.0.19" dependencies = [ "bytecount", "clap", @@ -3364,7 +3364,7 @@ dependencies = [ [[package]] name = "uu_who" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "uucore", @@ -3372,7 +3372,7 @@ dependencies = [ [[package]] name = "uu_whoami" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "libc", @@ -3382,7 +3382,7 @@ dependencies = [ [[package]] name = "uu_yes" -version = "0.0.18" +version = "0.0.19" dependencies = [ "clap", "itertools", @@ -3392,7 +3392,7 @@ dependencies = [ [[package]] name = "uucore" -version = "0.0.18" +version = "0.0.19" dependencies = [ "blake2b_simd", "blake3", @@ -3428,7 +3428,7 @@ dependencies = [ [[package]] name = "uucore_procs" -version = "0.0.18" +version = "0.0.19" dependencies = [ "help_parser", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index ebd9a4bf40..c1b1c3dae5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ [package] name = "coreutils" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "coreutils ~ GNU coreutils (updated); implemented as universal (cross-platform) utils, written in Rust" @@ -342,8 +342,8 @@ blake3 = "1.3.3" sm3 = "0.4.2" digest = "0.10.7" -uucore = { version=">=0.0.18", package="uucore", path="src/uucore" } -uucore_procs = { version=">=0.0.18", package="uucore_procs", path="src/uucore_procs" } +uucore = { version=">=0.0.19", package="uucore", path="src/uucore" } +uucore_procs = { version=">=0.0.19", package="uucore_procs", path="src/uucore_procs" } uu_ls = { version=">=0.0.18", path="src/uu/ls" } uu_base32 = { version=">=0.0.18", path="src/uu/base32"} @@ -361,110 +361,110 @@ zip = { workspace=true, optional = true } help_parser = { path="src/help_parser", optional = true } # * uutils -uu_test = { optional=true, version="0.0.18", package="uu_test", path="src/uu/test" } +uu_test = { optional=true, version="0.0.19", package="uu_test", path="src/uu/test" } # -arch = { optional=true, version="0.0.18", package="uu_arch", path="src/uu/arch" } -base32 = { optional=true, version="0.0.18", package="uu_base32", path="src/uu/base32" } -base64 = { optional=true, version="0.0.18", package="uu_base64", path="src/uu/base64" } -basename = { optional=true, version="0.0.18", package="uu_basename", path="src/uu/basename" } -basenc = { optional=true, version="0.0.18", package="uu_basenc", path="src/uu/basenc" } -cat = { optional=true, version="0.0.18", package="uu_cat", path="src/uu/cat" } -chcon = { optional=true, version="0.0.18", package="uu_chcon", path="src/uu/chcon" } -chgrp = { optional=true, version="0.0.18", package="uu_chgrp", path="src/uu/chgrp" } -chmod = { optional=true, version="0.0.18", package="uu_chmod", path="src/uu/chmod" } -chown = { optional=true, version="0.0.18", package="uu_chown", path="src/uu/chown" } -chroot = { optional=true, version="0.0.18", package="uu_chroot", path="src/uu/chroot" } -cksum = { optional=true, version="0.0.18", package="uu_cksum", path="src/uu/cksum" } -comm = { optional=true, version="0.0.18", package="uu_comm", path="src/uu/comm" } -cp = { optional=true, version="0.0.18", package="uu_cp", path="src/uu/cp" } -csplit = { optional=true, version="0.0.18", package="uu_csplit", path="src/uu/csplit" } -cut = { optional=true, version="0.0.18", package="uu_cut", path="src/uu/cut" } -date = { optional=true, version="0.0.18", package="uu_date", path="src/uu/date" } -dd = { optional=true, version="0.0.18", package="uu_dd", path="src/uu/dd" } -df = { optional=true, version="0.0.18", package="uu_df", path="src/uu/df" } -dir = { optional=true, version="0.0.18", package="uu_dir", path="src/uu/dir" } -dircolors= { optional=true, version="0.0.18", package="uu_dircolors", path="src/uu/dircolors" } -dirname = { optional=true, version="0.0.18", package="uu_dirname", path="src/uu/dirname" } -du = { optional=true, version="0.0.18", package="uu_du", path="src/uu/du" } -echo = { optional=true, version="0.0.18", package="uu_echo", path="src/uu/echo" } -env = { optional=true, version="0.0.18", package="uu_env", path="src/uu/env" } -expand = { optional=true, version="0.0.18", package="uu_expand", path="src/uu/expand" } -expr = { optional=true, version="0.0.18", package="uu_expr", path="src/uu/expr" } -factor = { optional=true, version="0.0.18", package="uu_factor", path="src/uu/factor" } -false = { optional=true, version="0.0.18", package="uu_false", path="src/uu/false" } -fmt = { optional=true, version="0.0.18", package="uu_fmt", path="src/uu/fmt" } -fold = { optional=true, version="0.0.18", package="uu_fold", path="src/uu/fold" } -groups = { optional=true, version="0.0.18", package="uu_groups", path="src/uu/groups" } -hashsum = { optional=true, version="0.0.18", package="uu_hashsum", path="src/uu/hashsum" } -head = { optional=true, version="0.0.18", package="uu_head", path="src/uu/head" } -hostid = { optional=true, version="0.0.18", package="uu_hostid", path="src/uu/hostid" } -hostname = { optional=true, version="0.0.18", package="uu_hostname", path="src/uu/hostname" } -id = { optional=true, version="0.0.18", package="uu_id", path="src/uu/id" } -install = { optional=true, version="0.0.18", package="uu_install", path="src/uu/install" } -join = { optional=true, version="0.0.18", package="uu_join", path="src/uu/join" } -kill = { optional=true, version="0.0.18", package="uu_kill", path="src/uu/kill" } -link = { optional=true, version="0.0.18", package="uu_link", path="src/uu/link" } -ln = { optional=true, version="0.0.18", package="uu_ln", path="src/uu/ln" } -ls = { optional=true, version="0.0.18", package="uu_ls", path="src/uu/ls" } -logname = { optional=true, version="0.0.18", package="uu_logname", path="src/uu/logname" } -mkdir = { optional=true, version="0.0.18", package="uu_mkdir", path="src/uu/mkdir" } -mkfifo = { optional=true, version="0.0.18", package="uu_mkfifo", path="src/uu/mkfifo" } -mknod = { optional=true, version="0.0.18", package="uu_mknod", path="src/uu/mknod" } -mktemp = { optional=true, version="0.0.18", package="uu_mktemp", path="src/uu/mktemp" } -more = { optional=true, version="0.0.18", package="uu_more", path="src/uu/more" } -mv = { optional=true, version="0.0.18", package="uu_mv", path="src/uu/mv" } -nice = { optional=true, version="0.0.18", package="uu_nice", path="src/uu/nice" } -nl = { optional=true, version="0.0.18", package="uu_nl", path="src/uu/nl" } -nohup = { optional=true, version="0.0.18", package="uu_nohup", path="src/uu/nohup" } -nproc = { optional=true, version="0.0.18", package="uu_nproc", path="src/uu/nproc" } -numfmt = { optional=true, version="0.0.18", package="uu_numfmt", path="src/uu/numfmt" } -od = { optional=true, version="0.0.18", package="uu_od", path="src/uu/od" } -paste = { optional=true, version="0.0.18", package="uu_paste", path="src/uu/paste" } -pathchk = { optional=true, version="0.0.18", package="uu_pathchk", path="src/uu/pathchk" } -pinky = { optional=true, version="0.0.18", package="uu_pinky", path="src/uu/pinky" } -pr = { optional=true, version="0.0.18", package="uu_pr", path="src/uu/pr" } -printenv = { optional=true, version="0.0.18", package="uu_printenv", path="src/uu/printenv" } -printf = { optional=true, version="0.0.18", package="uu_printf", path="src/uu/printf" } -ptx = { optional=true, version="0.0.18", package="uu_ptx", path="src/uu/ptx" } -pwd = { optional=true, version="0.0.18", package="uu_pwd", path="src/uu/pwd" } -readlink = { optional=true, version="0.0.18", package="uu_readlink", path="src/uu/readlink" } -realpath = { optional=true, version="0.0.18", package="uu_realpath", path="src/uu/realpath" } -relpath = { optional=true, version="0.0.18", package="uu_relpath", path="src/uu/relpath" } -rm = { optional=true, version="0.0.18", package="uu_rm", path="src/uu/rm" } -rmdir = { optional=true, version="0.0.18", package="uu_rmdir", path="src/uu/rmdir" } -runcon = { optional=true, version="0.0.18", package="uu_runcon", path="src/uu/runcon" } -seq = { optional=true, version="0.0.18", package="uu_seq", path="src/uu/seq" } -shred = { optional=true, version="0.0.18", package="uu_shred", path="src/uu/shred" } -shuf = { optional=true, version="0.0.18", package="uu_shuf", path="src/uu/shuf" } -sleep = { optional=true, version="0.0.18", package="uu_sleep", path="src/uu/sleep" } -sort = { optional=true, version="0.0.18", package="uu_sort", path="src/uu/sort" } -split = { optional=true, version="0.0.18", package="uu_split", path="src/uu/split" } -stat = { optional=true, version="0.0.18", package="uu_stat", path="src/uu/stat" } -stdbuf = { optional=true, version="0.0.18", package="uu_stdbuf", path="src/uu/stdbuf" } -stty = { optional=true, version="0.0.18", package="uu_stty", path="src/uu/stty" } -sum = { optional=true, version="0.0.18", package="uu_sum", path="src/uu/sum" } -sync = { optional=true, version="0.0.18", package="uu_sync", path="src/uu/sync" } -tac = { optional=true, version="0.0.18", package="uu_tac", path="src/uu/tac" } -tail = { optional=true, version="0.0.18", package="uu_tail", path="src/uu/tail" } -tee = { optional=true, version="0.0.18", package="uu_tee", path="src/uu/tee" } -timeout = { optional=true, version="0.0.18", package="uu_timeout", path="src/uu/timeout" } -touch = { optional=true, version="0.0.18", package="uu_touch", path="src/uu/touch" } -tr = { optional=true, version="0.0.18", package="uu_tr", path="src/uu/tr" } -true = { optional=true, version="0.0.18", package="uu_true", path="src/uu/true" } -truncate = { optional=true, version="0.0.18", package="uu_truncate", path="src/uu/truncate" } -tsort = { optional=true, version="0.0.18", package="uu_tsort", path="src/uu/tsort" } -tty = { optional=true, version="0.0.18", package="uu_tty", path="src/uu/tty" } -uname = { optional=true, version="0.0.18", package="uu_uname", path="src/uu/uname" } -unexpand = { optional=true, version="0.0.18", package="uu_unexpand", path="src/uu/unexpand" } -uniq = { optional=true, version="0.0.18", package="uu_uniq", path="src/uu/uniq" } -unlink = { optional=true, version="0.0.18", package="uu_unlink", path="src/uu/unlink" } -uptime = { optional=true, version="0.0.18", package="uu_uptime", path="src/uu/uptime" } -users = { optional=true, version="0.0.18", package="uu_users", path="src/uu/users" } -vdir = { optional=true, version="0.0.18", package="uu_vdir", path="src/uu/vdir" } -wc = { optional=true, version="0.0.18", package="uu_wc", path="src/uu/wc" } -who = { optional=true, version="0.0.18", package="uu_who", path="src/uu/who" } -whoami = { optional=true, version="0.0.18", package="uu_whoami", path="src/uu/whoami" } -yes = { optional=true, version="0.0.18", package="uu_yes", path="src/uu/yes" } +arch = { optional=true, version="0.0.19", package="uu_arch", path="src/uu/arch" } +base32 = { optional=true, version="0.0.19", package="uu_base32", path="src/uu/base32" } +base64 = { optional=true, version="0.0.19", package="uu_base64", path="src/uu/base64" } +basename = { optional=true, version="0.0.19", package="uu_basename", path="src/uu/basename" } +basenc = { optional=true, version="0.0.19", package="uu_basenc", path="src/uu/basenc" } +cat = { optional=true, version="0.0.19", package="uu_cat", path="src/uu/cat" } +chcon = { optional=true, version="0.0.19", package="uu_chcon", path="src/uu/chcon" } +chgrp = { optional=true, version="0.0.19", package="uu_chgrp", path="src/uu/chgrp" } +chmod = { optional=true, version="0.0.19", package="uu_chmod", path="src/uu/chmod" } +chown = { optional=true, version="0.0.19", package="uu_chown", path="src/uu/chown" } +chroot = { optional=true, version="0.0.19", package="uu_chroot", path="src/uu/chroot" } +cksum = { optional=true, version="0.0.19", package="uu_cksum", path="src/uu/cksum" } +comm = { optional=true, version="0.0.19", package="uu_comm", path="src/uu/comm" } +cp = { optional=true, version="0.0.19", package="uu_cp", path="src/uu/cp" } +csplit = { optional=true, version="0.0.19", package="uu_csplit", path="src/uu/csplit" } +cut = { optional=true, version="0.0.19", package="uu_cut", path="src/uu/cut" } +date = { optional=true, version="0.0.19", package="uu_date", path="src/uu/date" } +dd = { optional=true, version="0.0.19", package="uu_dd", path="src/uu/dd" } +df = { optional=true, version="0.0.19", package="uu_df", path="src/uu/df" } +dir = { optional=true, version="0.0.19", package="uu_dir", path="src/uu/dir" } +dircolors= { optional=true, version="0.0.19", package="uu_dircolors", path="src/uu/dircolors" } +dirname = { optional=true, version="0.0.19", package="uu_dirname", path="src/uu/dirname" } +du = { optional=true, version="0.0.19", package="uu_du", path="src/uu/du" } +echo = { optional=true, version="0.0.19", package="uu_echo", path="src/uu/echo" } +env = { optional=true, version="0.0.19", package="uu_env", path="src/uu/env" } +expand = { optional=true, version="0.0.19", package="uu_expand", path="src/uu/expand" } +expr = { optional=true, version="0.0.19", package="uu_expr", path="src/uu/expr" } +factor = { optional=true, version="0.0.19", package="uu_factor", path="src/uu/factor" } +false = { optional=true, version="0.0.19", package="uu_false", path="src/uu/false" } +fmt = { optional=true, version="0.0.19", package="uu_fmt", path="src/uu/fmt" } +fold = { optional=true, version="0.0.19", package="uu_fold", path="src/uu/fold" } +groups = { optional=true, version="0.0.19", package="uu_groups", path="src/uu/groups" } +hashsum = { optional=true, version="0.0.19", package="uu_hashsum", path="src/uu/hashsum" } +head = { optional=true, version="0.0.19", package="uu_head", path="src/uu/head" } +hostid = { optional=true, version="0.0.19", package="uu_hostid", path="src/uu/hostid" } +hostname = { optional=true, version="0.0.19", package="uu_hostname", path="src/uu/hostname" } +id = { optional=true, version="0.0.19", package="uu_id", path="src/uu/id" } +install = { optional=true, version="0.0.19", package="uu_install", path="src/uu/install" } +join = { optional=true, version="0.0.19", package="uu_join", path="src/uu/join" } +kill = { optional=true, version="0.0.19", package="uu_kill", path="src/uu/kill" } +link = { optional=true, version="0.0.19", package="uu_link", path="src/uu/link" } +ln = { optional=true, version="0.0.19", package="uu_ln", path="src/uu/ln" } +ls = { optional=true, version="0.0.19", package="uu_ls", path="src/uu/ls" } +logname = { optional=true, version="0.0.19", package="uu_logname", path="src/uu/logname" } +mkdir = { optional=true, version="0.0.19", package="uu_mkdir", path="src/uu/mkdir" } +mkfifo = { optional=true, version="0.0.19", package="uu_mkfifo", path="src/uu/mkfifo" } +mknod = { optional=true, version="0.0.19", package="uu_mknod", path="src/uu/mknod" } +mktemp = { optional=true, version="0.0.19", package="uu_mktemp", path="src/uu/mktemp" } +more = { optional=true, version="0.0.19", package="uu_more", path="src/uu/more" } +mv = { optional=true, version="0.0.19", package="uu_mv", path="src/uu/mv" } +nice = { optional=true, version="0.0.19", package="uu_nice", path="src/uu/nice" } +nl = { optional=true, version="0.0.19", package="uu_nl", path="src/uu/nl" } +nohup = { optional=true, version="0.0.19", package="uu_nohup", path="src/uu/nohup" } +nproc = { optional=true, version="0.0.19", package="uu_nproc", path="src/uu/nproc" } +numfmt = { optional=true, version="0.0.19", package="uu_numfmt", path="src/uu/numfmt" } +od = { optional=true, version="0.0.19", package="uu_od", path="src/uu/od" } +paste = { optional=true, version="0.0.19", package="uu_paste", path="src/uu/paste" } +pathchk = { optional=true, version="0.0.19", package="uu_pathchk", path="src/uu/pathchk" } +pinky = { optional=true, version="0.0.19", package="uu_pinky", path="src/uu/pinky" } +pr = { optional=true, version="0.0.19", package="uu_pr", path="src/uu/pr" } +printenv = { optional=true, version="0.0.19", package="uu_printenv", path="src/uu/printenv" } +printf = { optional=true, version="0.0.19", package="uu_printf", path="src/uu/printf" } +ptx = { optional=true, version="0.0.19", package="uu_ptx", path="src/uu/ptx" } +pwd = { optional=true, version="0.0.19", package="uu_pwd", path="src/uu/pwd" } +readlink = { optional=true, version="0.0.19", package="uu_readlink", path="src/uu/readlink" } +realpath = { optional=true, version="0.0.19", package="uu_realpath", path="src/uu/realpath" } +relpath = { optional=true, version="0.0.19", package="uu_relpath", path="src/uu/relpath" } +rm = { optional=true, version="0.0.19", package="uu_rm", path="src/uu/rm" } +rmdir = { optional=true, version="0.0.19", package="uu_rmdir", path="src/uu/rmdir" } +runcon = { optional=true, version="0.0.19", package="uu_runcon", path="src/uu/runcon" } +seq = { optional=true, version="0.0.19", package="uu_seq", path="src/uu/seq" } +shred = { optional=true, version="0.0.19", package="uu_shred", path="src/uu/shred" } +shuf = { optional=true, version="0.0.19", package="uu_shuf", path="src/uu/shuf" } +sleep = { optional=true, version="0.0.19", package="uu_sleep", path="src/uu/sleep" } +sort = { optional=true, version="0.0.19", package="uu_sort", path="src/uu/sort" } +split = { optional=true, version="0.0.19", package="uu_split", path="src/uu/split" } +stat = { optional=true, version="0.0.19", package="uu_stat", path="src/uu/stat" } +stdbuf = { optional=true, version="0.0.19", package="uu_stdbuf", path="src/uu/stdbuf" } +stty = { optional=true, version="0.0.19", package="uu_stty", path="src/uu/stty" } +sum = { optional=true, version="0.0.19", package="uu_sum", path="src/uu/sum" } +sync = { optional=true, version="0.0.19", package="uu_sync", path="src/uu/sync" } +tac = { optional=true, version="0.0.19", package="uu_tac", path="src/uu/tac" } +tail = { optional=true, version="0.0.19", package="uu_tail", path="src/uu/tail" } +tee = { optional=true, version="0.0.19", package="uu_tee", path="src/uu/tee" } +timeout = { optional=true, version="0.0.19", package="uu_timeout", path="src/uu/timeout" } +touch = { optional=true, version="0.0.19", package="uu_touch", path="src/uu/touch" } +tr = { optional=true, version="0.0.19", package="uu_tr", path="src/uu/tr" } +true = { optional=true, version="0.0.19", package="uu_true", path="src/uu/true" } +truncate = { optional=true, version="0.0.19", package="uu_truncate", path="src/uu/truncate" } +tsort = { optional=true, version="0.0.19", package="uu_tsort", path="src/uu/tsort" } +tty = { optional=true, version="0.0.19", package="uu_tty", path="src/uu/tty" } +uname = { optional=true, version="0.0.19", package="uu_uname", path="src/uu/uname" } +unexpand = { optional=true, version="0.0.19", package="uu_unexpand", path="src/uu/unexpand" } +uniq = { optional=true, version="0.0.19", package="uu_uniq", path="src/uu/uniq" } +unlink = { optional=true, version="0.0.19", package="uu_unlink", path="src/uu/unlink" } +uptime = { optional=true, version="0.0.19", package="uu_uptime", path="src/uu/uptime" } +users = { optional=true, version="0.0.19", package="uu_users", path="src/uu/users" } +vdir = { optional=true, version="0.0.19", package="uu_vdir", path="src/uu/vdir" } +wc = { optional=true, version="0.0.19", package="uu_wc", path="src/uu/wc" } +who = { optional=true, version="0.0.19", package="uu_who", path="src/uu/who" } +whoami = { optional=true, version="0.0.19", package="uu_whoami", path="src/uu/whoami" } +yes = { optional=true, version="0.0.19", package="uu_yes", path="src/uu/yes" } # this breaks clippy linting with: "tests/by-util/test_factor_benches.rs: No such file or directory (os error 2)" # factor_benches = { optional = true, version = "0.0.0", package = "uu_factor_benches", path = "tests/benches/factor" } diff --git a/src/uu/arch/Cargo.toml b/src/uu/arch/Cargo.toml index b2cdfdc17a..10df726e1b 100644 --- a/src/uu/arch/Cargo.toml +++ b/src/uu/arch/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_arch" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "arch ~ (uutils) display machine architecture" diff --git a/src/uu/base32/Cargo.toml b/src/uu/base32/Cargo.toml index e4a8464d95..077204e1fd 100644 --- a/src/uu/base32/Cargo.toml +++ b/src/uu/base32/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_base32" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "base32 ~ (uutils) decode/encode input (base32-encoding)" diff --git a/src/uu/base64/Cargo.toml b/src/uu/base64/Cargo.toml index e5ea4cf149..e21b34161c 100644 --- a/src/uu/base64/Cargo.toml +++ b/src/uu/base64/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_base64" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "base64 ~ (uutils) decode/encode input (base64-encoding)" diff --git a/src/uu/basename/Cargo.toml b/src/uu/basename/Cargo.toml index f234d1021f..c17651506e 100644 --- a/src/uu/basename/Cargo.toml +++ b/src/uu/basename/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_basename" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "basename ~ (uutils) display PATHNAME with leading directory components removed" diff --git a/src/uu/basenc/Cargo.toml b/src/uu/basenc/Cargo.toml index cc4264b519..3e8c3ed8ad 100644 --- a/src/uu/basenc/Cargo.toml +++ b/src/uu/basenc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_basenc" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "basenc ~ (uutils) decode/encode input" diff --git a/src/uu/cat/Cargo.toml b/src/uu/cat/Cargo.toml index 941637514f..2b78e9da75 100644 --- a/src/uu/cat/Cargo.toml +++ b/src/uu/cat/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cat" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "cat ~ (uutils) concatenate and display input" diff --git a/src/uu/chcon/Cargo.toml b/src/uu/chcon/Cargo.toml index e5dc6b93cd..53165dfe0f 100644 --- a/src/uu/chcon/Cargo.toml +++ b/src/uu/chcon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chcon" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "chcon ~ (uutils) change file security context" diff --git a/src/uu/chgrp/Cargo.toml b/src/uu/chgrp/Cargo.toml index 13b8c7e4d5..cceb32658d 100644 --- a/src/uu/chgrp/Cargo.toml +++ b/src/uu/chgrp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chgrp" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "chgrp ~ (uutils) change the group ownership of FILE" diff --git a/src/uu/chmod/Cargo.toml b/src/uu/chmod/Cargo.toml index 8b7d09e920..af133128da 100644 --- a/src/uu/chmod/Cargo.toml +++ b/src/uu/chmod/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chmod" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "chmod ~ (uutils) change mode of FILE" diff --git a/src/uu/chown/Cargo.toml b/src/uu/chown/Cargo.toml index bc28d86403..0b4db615d9 100644 --- a/src/uu/chown/Cargo.toml +++ b/src/uu/chown/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chown" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "chown ~ (uutils) change the ownership of FILE" diff --git a/src/uu/chroot/Cargo.toml b/src/uu/chroot/Cargo.toml index ca083753d6..1c3527eda9 100644 --- a/src/uu/chroot/Cargo.toml +++ b/src/uu/chroot/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_chroot" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "chroot ~ (uutils) run COMMAND under a new root directory" diff --git a/src/uu/cksum/Cargo.toml b/src/uu/cksum/Cargo.toml index 61c66e7048..707a7ee5cd 100644 --- a/src/uu/cksum/Cargo.toml +++ b/src/uu/cksum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cksum" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "cksum ~ (uutils) display CRC and size of input" diff --git a/src/uu/comm/Cargo.toml b/src/uu/comm/Cargo.toml index 0371d46c17..31fda282f4 100644 --- a/src/uu/comm/Cargo.toml +++ b/src/uu/comm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_comm" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "comm ~ (uutils) compare sorted inputs" diff --git a/src/uu/cp/Cargo.toml b/src/uu/cp/Cargo.toml index 32d34112ba..b14add4638 100644 --- a/src/uu/cp/Cargo.toml +++ b/src/uu/cp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cp" -version = "0.0.18" +version = "0.0.19" authors = [ "Jordy Dickinson ", "Joshua S. Miller ", diff --git a/src/uu/csplit/Cargo.toml b/src/uu/csplit/Cargo.toml index 560ddf6e83..3d0bafb484 100644 --- a/src/uu/csplit/Cargo.toml +++ b/src/uu/csplit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_csplit" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "csplit ~ (uutils) Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output" diff --git a/src/uu/cut/Cargo.toml b/src/uu/cut/Cargo.toml index 6e49ce4d41..d6b9d932f6 100644 --- a/src/uu/cut/Cargo.toml +++ b/src/uu/cut/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_cut" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "cut ~ (uutils) display byte/field columns of input lines" diff --git a/src/uu/date/Cargo.toml b/src/uu/date/Cargo.toml index 923ca4aa74..852e8cc9d1 100644 --- a/src/uu/date/Cargo.toml +++ b/src/uu/date/Cargo.toml @@ -1,7 +1,7 @@ # spell-checker:ignore humantime [package] name = "uu_date" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "date ~ (uutils) display or set the current time" diff --git a/src/uu/dd/Cargo.toml b/src/uu/dd/Cargo.toml index 04b60dc311..1b0b015beb 100644 --- a/src/uu/dd/Cargo.toml +++ b/src/uu/dd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dd" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "dd ~ (uutils) copy and convert files" diff --git a/src/uu/df/Cargo.toml b/src/uu/df/Cargo.toml index 9cca407bb4..159c876850 100644 --- a/src/uu/df/Cargo.toml +++ b/src/uu/df/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_df" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "df ~ (uutils) display file system information" diff --git a/src/uu/dir/Cargo.toml b/src/uu/dir/Cargo.toml index c8cb861f96..2a3adda963 100644 --- a/src/uu/dir/Cargo.toml +++ b/src/uu/dir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dir" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "shortcut to ls -C -b" diff --git a/src/uu/dircolors/Cargo.toml b/src/uu/dircolors/Cargo.toml index 7d729f3965..d922c1cf3e 100644 --- a/src/uu/dircolors/Cargo.toml +++ b/src/uu/dircolors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dircolors" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "dircolors ~ (uutils) display commands to set LS_COLORS" diff --git a/src/uu/dirname/Cargo.toml b/src/uu/dirname/Cargo.toml index f002bf15af..cd211661d7 100644 --- a/src/uu/dirname/Cargo.toml +++ b/src/uu/dirname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_dirname" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "dirname ~ (uutils) display parent directory of PATHNAME" diff --git a/src/uu/du/Cargo.toml b/src/uu/du/Cargo.toml index 22659bc0ee..6e883f769d 100644 --- a/src/uu/du/Cargo.toml +++ b/src/uu/du/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_du" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "du ~ (uutils) display disk usage" diff --git a/src/uu/echo/Cargo.toml b/src/uu/echo/Cargo.toml index 276fdaf850..90ea225984 100644 --- a/src/uu/echo/Cargo.toml +++ b/src/uu/echo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_echo" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "echo ~ (uutils) display TEXT" diff --git a/src/uu/env/Cargo.toml b/src/uu/env/Cargo.toml index 689bb12a40..8a19ce1213 100644 --- a/src/uu/env/Cargo.toml +++ b/src/uu/env/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_env" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "env ~ (uutils) set each NAME to VALUE in the environment and run COMMAND" diff --git a/src/uu/expand/Cargo.toml b/src/uu/expand/Cargo.toml index f30fcbce51..1f923f9bcc 100644 --- a/src/uu/expand/Cargo.toml +++ b/src/uu/expand/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_expand" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "expand ~ (uutils) convert input tabs to spaces" diff --git a/src/uu/expr/Cargo.toml b/src/uu/expr/Cargo.toml index 26c9d67245..f28215e0f5 100644 --- a/src/uu/expr/Cargo.toml +++ b/src/uu/expr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_expr" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "expr ~ (uutils) display the value of EXPRESSION" diff --git a/src/uu/factor/Cargo.toml b/src/uu/factor/Cargo.toml index 8de973503c..b70976b768 100644 --- a/src/uu/factor/Cargo.toml +++ b/src/uu/factor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_factor" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "factor ~ (uutils) display the prime factors of each NUMBER" diff --git a/src/uu/false/Cargo.toml b/src/uu/false/Cargo.toml index 44d9837881..84ac4e553a 100644 --- a/src/uu/false/Cargo.toml +++ b/src/uu/false/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_false" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "false ~ (uutils) do nothing and fail" diff --git a/src/uu/fmt/Cargo.toml b/src/uu/fmt/Cargo.toml index 1446e8ba55..df51f659cc 100644 --- a/src/uu/fmt/Cargo.toml +++ b/src/uu/fmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_fmt" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "fmt ~ (uutils) reformat each paragraph of input" diff --git a/src/uu/fold/Cargo.toml b/src/uu/fold/Cargo.toml index 3358fb7cc7..bb7e3fa07d 100644 --- a/src/uu/fold/Cargo.toml +++ b/src/uu/fold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_fold" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "fold ~ (uutils) wrap each line of input" diff --git a/src/uu/groups/Cargo.toml b/src/uu/groups/Cargo.toml index 940661bc40..3feb634b6f 100644 --- a/src/uu/groups/Cargo.toml +++ b/src/uu/groups/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_groups" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "groups ~ (uutils) display group memberships for USERNAME" diff --git a/src/uu/hashsum/Cargo.toml b/src/uu/hashsum/Cargo.toml index 638b3b60f5..84b19d6e5d 100644 --- a/src/uu/hashsum/Cargo.toml +++ b/src/uu/hashsum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hashsum" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "hashsum ~ (uutils) display or check input digests" diff --git a/src/uu/head/Cargo.toml b/src/uu/head/Cargo.toml index a826782859..d680a6eb76 100644 --- a/src/uu/head/Cargo.toml +++ b/src/uu/head/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_head" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "head ~ (uutils) display the first lines of input" diff --git a/src/uu/hostid/Cargo.toml b/src/uu/hostid/Cargo.toml index a31286bbdc..67045e8f69 100644 --- a/src/uu/hostid/Cargo.toml +++ b/src/uu/hostid/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hostid" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "hostid ~ (uutils) display the numeric identifier of the current host" diff --git a/src/uu/hostname/Cargo.toml b/src/uu/hostname/Cargo.toml index c39f8fdaec..718bf43db9 100644 --- a/src/uu/hostname/Cargo.toml +++ b/src/uu/hostname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_hostname" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "hostname ~ (uutils) display or set the host name of the current host" diff --git a/src/uu/id/Cargo.toml b/src/uu/id/Cargo.toml index dd363340b2..9e0a35f7f2 100644 --- a/src/uu/id/Cargo.toml +++ b/src/uu/id/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_id" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "id ~ (uutils) display user and group information for USER" diff --git a/src/uu/install/Cargo.toml b/src/uu/install/Cargo.toml index 789f84de33..89849059dd 100644 --- a/src/uu/install/Cargo.toml +++ b/src/uu/install/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_install" -version = "0.0.18" +version = "0.0.19" authors = [ "Ben Eills ", "uutils developers", diff --git a/src/uu/join/Cargo.toml b/src/uu/join/Cargo.toml index d92c032aad..a2c6d19bc4 100644 --- a/src/uu/join/Cargo.toml +++ b/src/uu/join/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_join" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "join ~ (uutils) merge lines from inputs with matching join fields" diff --git a/src/uu/kill/Cargo.toml b/src/uu/kill/Cargo.toml index 21010160cf..e373bfe782 100644 --- a/src/uu/kill/Cargo.toml +++ b/src/uu/kill/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_kill" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "kill ~ (uutils) send a signal to a process" diff --git a/src/uu/link/Cargo.toml b/src/uu/link/Cargo.toml index 2d81883a62..6f034dcae8 100644 --- a/src/uu/link/Cargo.toml +++ b/src/uu/link/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_link" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "link ~ (uutils) create a hard (file system) link to FILE" diff --git a/src/uu/ln/Cargo.toml b/src/uu/ln/Cargo.toml index c06218fb74..b31f64f301 100644 --- a/src/uu/ln/Cargo.toml +++ b/src/uu/ln/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ln" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "ln ~ (uutils) create a (file system) link to TARGET" diff --git a/src/uu/logname/Cargo.toml b/src/uu/logname/Cargo.toml index e75571e0fc..19a4ab0351 100644 --- a/src/uu/logname/Cargo.toml +++ b/src/uu/logname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_logname" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "logname ~ (uutils) display the login name of the current user" diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index 251268c2b4..e162aeab13 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ls" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "ls ~ (uutils) display directory contents" diff --git a/src/uu/mkdir/Cargo.toml b/src/uu/mkdir/Cargo.toml index e2b65c0309..24ce412d32 100644 --- a/src/uu/mkdir/Cargo.toml +++ b/src/uu/mkdir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mkdir" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "mkdir ~ (uutils) create DIRECTORY" diff --git a/src/uu/mkfifo/Cargo.toml b/src/uu/mkfifo/Cargo.toml index 8fd154a3f6..2e24bb53dc 100644 --- a/src/uu/mkfifo/Cargo.toml +++ b/src/uu/mkfifo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mkfifo" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "mkfifo ~ (uutils) create FIFOs (named pipes)" diff --git a/src/uu/mknod/Cargo.toml b/src/uu/mknod/Cargo.toml index ee272dbf7b..8a50a61fc7 100644 --- a/src/uu/mknod/Cargo.toml +++ b/src/uu/mknod/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mknod" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "mknod ~ (uutils) create special file NAME of TYPE" diff --git a/src/uu/mktemp/Cargo.toml b/src/uu/mktemp/Cargo.toml index 7f1ac62eef..31bd53a00b 100644 --- a/src/uu/mktemp/Cargo.toml +++ b/src/uu/mktemp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mktemp" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "mktemp ~ (uutils) create and display a temporary file or directory from TEMPLATE" diff --git a/src/uu/more/Cargo.toml b/src/uu/more/Cargo.toml index 573eafc437..a19fc577da 100644 --- a/src/uu/more/Cargo.toml +++ b/src/uu/more/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_more" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "more ~ (uutils) input perusal filter" diff --git a/src/uu/mv/Cargo.toml b/src/uu/mv/Cargo.toml index 5bc660d087..8747c950ca 100644 --- a/src/uu/mv/Cargo.toml +++ b/src/uu/mv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_mv" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "mv ~ (uutils) move (rename) SOURCE to DESTINATION" diff --git a/src/uu/nice/Cargo.toml b/src/uu/nice/Cargo.toml index 3c5d763dad..d63f253126 100644 --- a/src/uu/nice/Cargo.toml +++ b/src/uu/nice/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nice" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "nice ~ (uutils) run PROGRAM with modified scheduling priority" diff --git a/src/uu/nl/Cargo.toml b/src/uu/nl/Cargo.toml index efa3f3e0ba..ead669d3d7 100644 --- a/src/uu/nl/Cargo.toml +++ b/src/uu/nl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nl" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "nl ~ (uutils) display input with added line numbers" diff --git a/src/uu/nohup/Cargo.toml b/src/uu/nohup/Cargo.toml index 7067e51e82..40f332c5fe 100644 --- a/src/uu/nohup/Cargo.toml +++ b/src/uu/nohup/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nohup" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "nohup ~ (uutils) run COMMAND, ignoring hangup signals" diff --git a/src/uu/nproc/Cargo.toml b/src/uu/nproc/Cargo.toml index 13202b739a..ae2e74f068 100644 --- a/src/uu/nproc/Cargo.toml +++ b/src/uu/nproc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_nproc" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "nproc ~ (uutils) display the number of processing units available" diff --git a/src/uu/numfmt/Cargo.toml b/src/uu/numfmt/Cargo.toml index 2f3a2e69a2..9ba3c00753 100644 --- a/src/uu/numfmt/Cargo.toml +++ b/src/uu/numfmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_numfmt" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "numfmt ~ (uutils) reformat NUMBER" diff --git a/src/uu/od/Cargo.toml b/src/uu/od/Cargo.toml index 28abbfce22..e7cc7d34e3 100644 --- a/src/uu/od/Cargo.toml +++ b/src/uu/od/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_od" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "od ~ (uutils) display formatted representation of input" diff --git a/src/uu/paste/Cargo.toml b/src/uu/paste/Cargo.toml index 36765594e3..836aa05bd2 100644 --- a/src/uu/paste/Cargo.toml +++ b/src/uu/paste/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_paste" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "paste ~ (uutils) merge lines from inputs" diff --git a/src/uu/pathchk/Cargo.toml b/src/uu/pathchk/Cargo.toml index 01a626042c..c37b0b4810 100644 --- a/src/uu/pathchk/Cargo.toml +++ b/src/uu/pathchk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pathchk" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "pathchk ~ (uutils) diagnose invalid or non-portable PATHNAME" diff --git a/src/uu/pinky/Cargo.toml b/src/uu/pinky/Cargo.toml index f2c930831e..efee7c06a5 100644 --- a/src/uu/pinky/Cargo.toml +++ b/src/uu/pinky/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pinky" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "pinky ~ (uutils) display user information" diff --git a/src/uu/pr/Cargo.toml b/src/uu/pr/Cargo.toml index 414168c64d..037db2ee70 100644 --- a/src/uu/pr/Cargo.toml +++ b/src/uu/pr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pr" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "pr ~ (uutils) convert text files for printing" diff --git a/src/uu/printenv/Cargo.toml b/src/uu/printenv/Cargo.toml index 007348a95a..f3a7f2b403 100644 --- a/src/uu/printenv/Cargo.toml +++ b/src/uu/printenv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_printenv" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "printenv ~ (uutils) display value of environment VAR" diff --git a/src/uu/printf/Cargo.toml b/src/uu/printf/Cargo.toml index aa64a24ef6..c534ba544c 100644 --- a/src/uu/printf/Cargo.toml +++ b/src/uu/printf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_printf" -version = "0.0.18" +version = "0.0.19" authors = [ "Nathan Ross", "uutils developers", diff --git a/src/uu/ptx/Cargo.toml b/src/uu/ptx/Cargo.toml index 8f2cda9389..c3498c25b7 100644 --- a/src/uu/ptx/Cargo.toml +++ b/src/uu/ptx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_ptx" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "ptx ~ (uutils) display a permuted index of input" diff --git a/src/uu/pwd/Cargo.toml b/src/uu/pwd/Cargo.toml index af1451564c..fd76eec5bd 100644 --- a/src/uu/pwd/Cargo.toml +++ b/src/uu/pwd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_pwd" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "pwd ~ (uutils) display current working directory" diff --git a/src/uu/readlink/Cargo.toml b/src/uu/readlink/Cargo.toml index aed0652070..718a381205 100644 --- a/src/uu/readlink/Cargo.toml +++ b/src/uu/readlink/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_readlink" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "readlink ~ (uutils) display resolved path of PATHNAME" diff --git a/src/uu/realpath/Cargo.toml b/src/uu/realpath/Cargo.toml index 17af009c6a..0ecd971c1c 100644 --- a/src/uu/realpath/Cargo.toml +++ b/src/uu/realpath/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_realpath" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "realpath ~ (uutils) display resolved absolute path of PATHNAME" diff --git a/src/uu/relpath/Cargo.toml b/src/uu/relpath/Cargo.toml index 7046aafee2..96fdca9468 100644 --- a/src/uu/relpath/Cargo.toml +++ b/src/uu/relpath/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_relpath" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "relpath ~ (uutils) display relative path of PATHNAME_TO from PATHNAME_FROM" diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index 5151beb93b..c69bd59642 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_rm" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "rm ~ (uutils) remove PATHNAME" diff --git a/src/uu/rmdir/Cargo.toml b/src/uu/rmdir/Cargo.toml index f35817c6cf..2a40ad0581 100644 --- a/src/uu/rmdir/Cargo.toml +++ b/src/uu/rmdir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_rmdir" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "rmdir ~ (uutils) remove empty DIRECTORY" diff --git a/src/uu/runcon/Cargo.toml b/src/uu/runcon/Cargo.toml index 5373658e4c..0060e497b2 100644 --- a/src/uu/runcon/Cargo.toml +++ b/src/uu/runcon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_runcon" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "runcon ~ (uutils) run command with specified security context" diff --git a/src/uu/seq/Cargo.toml b/src/uu/seq/Cargo.toml index c217d067fa..e996c2b5c5 100644 --- a/src/uu/seq/Cargo.toml +++ b/src/uu/seq/Cargo.toml @@ -1,7 +1,7 @@ # spell-checker:ignore bigdecimal [package] name = "uu_seq" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "seq ~ (uutils) display a sequence of numbers" diff --git a/src/uu/shred/Cargo.toml b/src/uu/shred/Cargo.toml index e085041c33..5d52ee58ac 100644 --- a/src/uu/shred/Cargo.toml +++ b/src/uu/shred/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_shred" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "shred ~ (uutils) hide former FILE contents with repeated overwrites" diff --git a/src/uu/shuf/Cargo.toml b/src/uu/shuf/Cargo.toml index 8c7dd72784..f86a1eac5c 100644 --- a/src/uu/shuf/Cargo.toml +++ b/src/uu/shuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_shuf" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "shuf ~ (uutils) display random permutations of input lines" diff --git a/src/uu/sleep/Cargo.toml b/src/uu/sleep/Cargo.toml index 6091ac1da7..ae05bdf0e2 100644 --- a/src/uu/sleep/Cargo.toml +++ b/src/uu/sleep/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sleep" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "sleep ~ (uutils) pause for DURATION" diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index 41d6bd66f8..7889ab009a 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sort" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "sort ~ (uutils) sort input lines" diff --git a/src/uu/split/Cargo.toml b/src/uu/split/Cargo.toml index cae21b1635..b9649ad5f0 100644 --- a/src/uu/split/Cargo.toml +++ b/src/uu/split/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_split" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "split ~ (uutils) split input into output files" diff --git a/src/uu/stat/Cargo.toml b/src/uu/stat/Cargo.toml index bd873404e8..3176347041 100644 --- a/src/uu/stat/Cargo.toml +++ b/src/uu/stat/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stat" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "stat ~ (uutils) display FILE status" diff --git a/src/uu/stdbuf/Cargo.toml b/src/uu/stdbuf/Cargo.toml index 224af033ee..06bd0fa51b 100644 --- a/src/uu/stdbuf/Cargo.toml +++ b/src/uu/stdbuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stdbuf" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "stdbuf ~ (uutils) run COMMAND with modified standard stream buffering" @@ -20,7 +20,7 @@ tempfile = { workspace=true } uucore = { workspace=true } [build-dependencies] -libstdbuf = { version="0.0.18", package="uu_stdbuf_libstdbuf", path="src/libstdbuf" } +libstdbuf = { version="0.0.19", package="uu_stdbuf_libstdbuf", path="src/libstdbuf" } [[bin]] name = "stdbuf" diff --git a/src/uu/stdbuf/src/libstdbuf/Cargo.toml b/src/uu/stdbuf/src/libstdbuf/Cargo.toml index d9d94cd578..abd2aaa4e1 100644 --- a/src/uu/stdbuf/src/libstdbuf/Cargo.toml +++ b/src/uu/stdbuf/src/libstdbuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stdbuf_libstdbuf" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "stdbuf/libstdbuf ~ (uutils); dynamic library required for stdbuf" @@ -19,7 +19,7 @@ crate-type = ["cdylib", "rlib"] # XXX: note: the rlib is just to prevent Cargo f [dependencies] cpp = "0.5" libc = { workspace=true } -uucore = { version=">=0.0.18", package="uucore", path="../../../../uucore" } +uucore = { version=">=0.0.19", package="uucore", path="../../../../uucore" } [build-dependencies] cpp_build = "0.5" diff --git a/src/uu/stty/Cargo.toml b/src/uu/stty/Cargo.toml index f6ea290d9e..ec715314d3 100644 --- a/src/uu/stty/Cargo.toml +++ b/src/uu/stty/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_stty" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "stty ~ (uutils) print or change terminal characteristics" diff --git a/src/uu/sum/Cargo.toml b/src/uu/sum/Cargo.toml index 37a997224c..806c2171d3 100644 --- a/src/uu/sum/Cargo.toml +++ b/src/uu/sum/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sum" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "sum ~ (uutils) display checksum and block counts for input" diff --git a/src/uu/sync/Cargo.toml b/src/uu/sync/Cargo.toml index 49cfbf1b54..c6062b7c1f 100644 --- a/src/uu/sync/Cargo.toml +++ b/src/uu/sync/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_sync" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "sync ~ (uutils) synchronize cache writes to storage" diff --git a/src/uu/tac/Cargo.toml b/src/uu/tac/Cargo.toml index 0d90569156..ca68be99dc 100644 --- a/src/uu/tac/Cargo.toml +++ b/src/uu/tac/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "uu_tac" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "tac ~ (uutils) concatenate and display input lines in reverse order" diff --git a/src/uu/tail/Cargo.toml b/src/uu/tail/Cargo.toml index a82670f9e8..e71c988aa7 100644 --- a/src/uu/tail/Cargo.toml +++ b/src/uu/tail/Cargo.toml @@ -1,7 +1,7 @@ # spell-checker:ignore (libs) kqueue fundu [package] name = "uu_tail" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "tail ~ (uutils) display the last lines of input" diff --git a/src/uu/tee/Cargo.toml b/src/uu/tee/Cargo.toml index b0cf0e916a..ee4bedec80 100644 --- a/src/uu/tee/Cargo.toml +++ b/src/uu/tee/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tee" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "tee ~ (uutils) display input and copy to FILE" diff --git a/src/uu/test/Cargo.toml b/src/uu/test/Cargo.toml index b3229f5063..794aa53770 100644 --- a/src/uu/test/Cargo.toml +++ b/src/uu/test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_test" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "test ~ (uutils) evaluate comparison and file type expressions" diff --git a/src/uu/timeout/Cargo.toml b/src/uu/timeout/Cargo.toml index 8b92f9d8b1..b4b24db126 100644 --- a/src/uu/timeout/Cargo.toml +++ b/src/uu/timeout/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_timeout" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "timeout ~ (uutils) run COMMAND with a DURATION time limit" diff --git a/src/uu/touch/Cargo.toml b/src/uu/touch/Cargo.toml index 0bb89ec849..3aac9abc47 100644 --- a/src/uu/touch/Cargo.toml +++ b/src/uu/touch/Cargo.toml @@ -1,7 +1,7 @@ # spell-checker:ignore humantime [package] name = "uu_touch" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "touch ~ (uutils) change FILE timestamps" diff --git a/src/uu/tr/Cargo.toml b/src/uu/tr/Cargo.toml index 559546efd6..4869941e99 100644 --- a/src/uu/tr/Cargo.toml +++ b/src/uu/tr/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tr" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "tr ~ (uutils) translate characters within input and display" diff --git a/src/uu/true/Cargo.toml b/src/uu/true/Cargo.toml index bab8161d87..3171845de1 100644 --- a/src/uu/true/Cargo.toml +++ b/src/uu/true/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_true" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "true ~ (uutils) do nothing and succeed" diff --git a/src/uu/truncate/Cargo.toml b/src/uu/truncate/Cargo.toml index 0d5615eead..54578d038c 100644 --- a/src/uu/truncate/Cargo.toml +++ b/src/uu/truncate/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_truncate" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "truncate ~ (uutils) truncate (or extend) FILE to SIZE" diff --git a/src/uu/tsort/Cargo.toml b/src/uu/tsort/Cargo.toml index 08a035eacb..46ee8a47e7 100644 --- a/src/uu/tsort/Cargo.toml +++ b/src/uu/tsort/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tsort" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "tsort ~ (uutils) topologically sort input (partially ordered) pairs" diff --git a/src/uu/tty/Cargo.toml b/src/uu/tty/Cargo.toml index ed4f2ba53b..4e32f38730 100644 --- a/src/uu/tty/Cargo.toml +++ b/src/uu/tty/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_tty" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "tty ~ (uutils) display the name of the terminal connected to standard input" diff --git a/src/uu/uname/Cargo.toml b/src/uu/uname/Cargo.toml index a24113cb7b..5c02c5e2ef 100644 --- a/src/uu/uname/Cargo.toml +++ b/src/uu/uname/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uname" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "uname ~ (uutils) display system information" diff --git a/src/uu/unexpand/Cargo.toml b/src/uu/unexpand/Cargo.toml index 5e4d486cb5..537750d3d4 100644 --- a/src/uu/unexpand/Cargo.toml +++ b/src/uu/unexpand/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_unexpand" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "unexpand ~ (uutils) convert input spaces to tabs" diff --git a/src/uu/uniq/Cargo.toml b/src/uu/uniq/Cargo.toml index 1491f81f2b..c1343ab011 100644 --- a/src/uu/uniq/Cargo.toml +++ b/src/uu/uniq/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uniq" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "uniq ~ (uutils) filter identical adjacent lines from input" diff --git a/src/uu/unlink/Cargo.toml b/src/uu/unlink/Cargo.toml index 99efdbaeea..cc30f7dbd5 100644 --- a/src/uu/unlink/Cargo.toml +++ b/src/uu/unlink/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_unlink" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "unlink ~ (uutils) remove a (file system) link to FILE" diff --git a/src/uu/uptime/Cargo.toml b/src/uu/uptime/Cargo.toml index fdd49cb841..ab38951c5e 100644 --- a/src/uu/uptime/Cargo.toml +++ b/src/uu/uptime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_uptime" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "uptime ~ (uutils) display dynamic system information" diff --git a/src/uu/users/Cargo.toml b/src/uu/users/Cargo.toml index 023b34a3e2..ec32f3e8aa 100644 --- a/src/uu/users/Cargo.toml +++ b/src/uu/users/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_users" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "users ~ (uutils) display names of currently logged-in users" diff --git a/src/uu/vdir/Cargo.toml b/src/uu/vdir/Cargo.toml index 281e7158e0..4d62489799 100644 --- a/src/uu/vdir/Cargo.toml +++ b/src/uu/vdir/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_vdir" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "shortcut to ls -l -b" diff --git a/src/uu/wc/Cargo.toml b/src/uu/wc/Cargo.toml index 2b42affb58..b781eaed61 100644 --- a/src/uu/wc/Cargo.toml +++ b/src/uu/wc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_wc" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "wc ~ (uutils) display newline, word, and byte counts for input" diff --git a/src/uu/who/Cargo.toml b/src/uu/who/Cargo.toml index 5b5b57bf10..cae50b9a6e 100644 --- a/src/uu/who/Cargo.toml +++ b/src/uu/who/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_who" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "who ~ (uutils) display information about currently logged-in users" diff --git a/src/uu/whoami/Cargo.toml b/src/uu/whoami/Cargo.toml index 7e13c14f3d..3114f721a5 100644 --- a/src/uu/whoami/Cargo.toml +++ b/src/uu/whoami/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_whoami" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "whoami ~ (uutils) display user name of current effective user ID" diff --git a/src/uu/yes/Cargo.toml b/src/uu/yes/Cargo.toml index 9d661fb0d9..40674f05a2 100644 --- a/src/uu/yes/Cargo.toml +++ b/src/uu/yes/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uu_yes" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "yes ~ (uutils) repeatedly display a line with STRING (or 'y')" diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index ea6bb2424b..0745ca03f0 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "uucore" -version = "0.0.18" +version = "0.0.19" authors = ["uutils developers"] license = "MIT" description = "uutils ~ 'core' uutils code library (cross-platform)" diff --git a/src/uucore_procs/Cargo.toml b/src/uucore_procs/Cargo.toml index bb41a82a67..d2d3102e3a 100644 --- a/src/uucore_procs/Cargo.toml +++ b/src/uucore_procs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uucore_procs" -version = "0.0.18" +version = "0.0.19" authors = ["Roy Ivy III "] license = "MIT" description = "uutils ~ 'uucore' proc-macros" diff --git a/util/update-version.sh b/util/update-version.sh index e248d13cd1..b6340bf593 100755 --- a/util/update-version.sh +++ b/util/update-version.sh @@ -12,8 +12,8 @@ # 7) Run util/publish.sh --do-it # 8) In some cases, you might have to fix dependencies and run import -FROM="0.0.17" -TO="0.0.18" +FROM="0.0.18" +TO="0.0.19" PROGS=$(ls -1d src/uu/*/Cargo.toml src/uu/stdbuf/src/libstdbuf/Cargo.toml src/uucore/Cargo.toml Cargo.toml) From a13d7f4060d3e200bbe375077b6c89ea389cea42 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Jun 2023 20:36:03 +0200 Subject: [PATCH 428/477] uuhelp_parser: add the desc --- src/help_parser/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/help_parser/Cargo.toml b/src/help_parser/Cargo.toml index d3a8a0f543..2c4080c811 100644 --- a/src/help_parser/Cargo.toml +++ b/src/help_parser/Cargo.toml @@ -3,3 +3,4 @@ name = "help_parser" version = "0.0.18" edition = "2021" license = "MIT" +description = "A collection of functions to parse the markdown code of help files" From c8b4e06828c7869eb7b2c2bc735e230366da208c Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Jun 2023 20:37:38 +0200 Subject: [PATCH 429/477] add uuhelp_parser to the publish script --- util/publish.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/publish.sh b/util/publish.sh index d9039fa606..b656f62292 100755 --- a/util/publish.sh +++ b/util/publish.sh @@ -35,7 +35,7 @@ TOTAL_ORDER=$(echo -e $PARTIAL_ORDER | tsort | tac) TOTAL_ORDER=${TOTAL_ORDER#ROOT} set -e -for dir in src/uucore_procs/ src/uucore/ src/uu/stdbuf/src/libstdbuf/; do +for dir in src/uuhelp_parser/ src/uucore_procs/ src/uucore/ src/uu/stdbuf/src/libstdbuf/; do ( cd "$dir" #shellcheck disable=SC2086 From e3cb5a111de1a1ba1d64a74044921beb9d8e4385 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Jun 2023 20:38:55 +0200 Subject: [PATCH 430/477] Rename help_parser => uuhelp_parser --- Cargo.lock | 12 ++++++------ Cargo.toml | 4 ++-- src/bin/uudoc.rs | 6 +++--- src/uucore_procs/Cargo.toml | 2 +- src/uucore_procs/src/lib.rs | 6 +++--- src/{help_parser => uuhelp_parser}/Cargo.toml | 2 +- src/{help_parser => uuhelp_parser}/src/lib.rs | 0 7 files changed, 16 insertions(+), 16 deletions(-) rename src/{help_parser => uuhelp_parser}/Cargo.toml (86%) rename src/{help_parser => uuhelp_parser}/src/lib.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index f45951917e..5048b4aa07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -403,7 +403,6 @@ dependencies = [ "conv", "filetime", "glob", - "help_parser", "hex-literal", "is-terminal", "libc", @@ -529,6 +528,7 @@ dependencies = [ "uu_whoami", "uu_yes", "uucore", + "uuhelp_parser", "walkdir", "zip", ] @@ -1107,10 +1107,6 @@ dependencies = [ "ahash", ] -[[package]] -name = "help_parser" -version = "0.0.18" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -3430,11 +3426,15 @@ dependencies = [ name = "uucore_procs" version = "0.0.19" dependencies = [ - "help_parser", "proc-macro2", "quote", + "uuhelp_parser", ] +[[package]] +name = "uuhelp_parser" +version = "0.0.18" + [[package]] name = "uuid" version = "1.2.2" diff --git a/Cargo.toml b/Cargo.toml index c1b1c3dae5..7e851363f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ windows = [ "feat_os_windows" ] nightly = [] test_unimplemented = [] # * only build `uudoc` when `--feature uudoc` is activated -uudoc = ["zip", "dep:help_parser"] +uudoc = ["zip", "dep:uuhelp_parser"] ## features # "feat_acl" == enable support for ACLs (access control lists; by using`--features feat_acl`) # NOTE: @@ -358,7 +358,7 @@ selinux = { workspace=true, optional = true } textwrap = { workspace=true } zip = { workspace=true, optional = true } -help_parser = { path="src/help_parser", optional = true } +uuhelp_parser = { path="src/uuhelp_parser", optional = true } # * uutils uu_test = { optional=true, version="0.0.19", package="uu_test", path="src/uu/test" } diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index b7a2ce5816..e379258254 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -178,7 +178,7 @@ impl<'a, 'b> MDWriter<'a, 'b> { fn usage(&mut self) -> io::Result<()> { if let Some(markdown) = &self.markdown { - let usage = help_parser::parse_usage(markdown); + let usage = uuhelp_parser::parse_usage(markdown); let usage = usage.replace("{}", self.name); writeln!(self.w, "\n```")?; @@ -191,7 +191,7 @@ impl<'a, 'b> MDWriter<'a, 'b> { fn about(&mut self) -> io::Result<()> { if let Some(markdown) = &self.markdown { - writeln!(self.w, "{}", help_parser::parse_about(markdown)) + writeln!(self.w, "{}", uuhelp_parser::parse_about(markdown)) } else { Ok(()) } @@ -199,7 +199,7 @@ impl<'a, 'b> MDWriter<'a, 'b> { fn after_help(&mut self) -> io::Result<()> { if let Some(markdown) = &self.markdown { - if let Some(after_help) = help_parser::parse_section("after help", markdown) { + if let Some(after_help) = uuhelp_parser::parse_section("after help", markdown) { return writeln!(self.w, "\n\n{after_help}"); } } diff --git a/src/uucore_procs/Cargo.toml b/src/uucore_procs/Cargo.toml index d2d3102e3a..0ef44fbaeb 100644 --- a/src/uucore_procs/Cargo.toml +++ b/src/uucore_procs/Cargo.toml @@ -18,4 +18,4 @@ proc-macro = true [dependencies] proc-macro2 = "1.0" quote = "1.0" -help_parser = { path="../help_parser", version="0.0.18" } +uuhelp_parser = { path="../uuhelp_parser", version="0.0.18" } diff --git a/src/uucore_procs/src/lib.rs b/src/uucore_procs/src/lib.rs index 4bc2521b87..ba32f649be 100644 --- a/src/uucore_procs/src/lib.rs +++ b/src/uucore_procs/src/lib.rs @@ -58,7 +58,7 @@ fn render_markdown(s: &str) -> String { pub fn help_about(input: TokenStream) -> TokenStream { let input: Vec = input.into_iter().collect(); let filename = get_argument(&input, 0, "filename"); - let text: String = help_parser::parse_about(&read_help(&filename)); + let text: String = uuhelp_parser::parse_about(&read_help(&filename)); TokenTree::Literal(Literal::string(&text)).into() } @@ -72,7 +72,7 @@ pub fn help_about(input: TokenStream) -> TokenStream { pub fn help_usage(input: TokenStream) -> TokenStream { let input: Vec = input.into_iter().collect(); let filename = get_argument(&input, 0, "filename"); - let text: String = help_parser::parse_usage(&read_help(&filename)); + let text: String = uuhelp_parser::parse_usage(&read_help(&filename)); TokenTree::Literal(Literal::string(&text)).into() } @@ -106,7 +106,7 @@ pub fn help_section(input: TokenStream) -> TokenStream { let section = get_argument(&input, 0, "section"); let filename = get_argument(&input, 1, "filename"); - if let Some(text) = help_parser::parse_section(§ion, &read_help(&filename)) { + if let Some(text) = uuhelp_parser::parse_section(§ion, &read_help(&filename)) { let rendered = render_markdown(&text); TokenTree::Literal(Literal::string(&rendered)).into() } else { diff --git a/src/help_parser/Cargo.toml b/src/uuhelp_parser/Cargo.toml similarity index 86% rename from src/help_parser/Cargo.toml rename to src/uuhelp_parser/Cargo.toml index 2c4080c811..9f4c0d68d9 100644 --- a/src/help_parser/Cargo.toml +++ b/src/uuhelp_parser/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "help_parser" +name = "uuhelp_parser" version = "0.0.18" edition = "2021" license = "MIT" diff --git a/src/help_parser/src/lib.rs b/src/uuhelp_parser/src/lib.rs similarity index 100% rename from src/help_parser/src/lib.rs rename to src/uuhelp_parser/src/lib.rs From 204d9b64f98ea81001c3da745356d98e9a185c1b Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Jun 2023 21:06:34 +0200 Subject: [PATCH 431/477] uuhelp_parser: update of the version --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/uucore_procs/Cargo.toml | 2 +- src/uuhelp_parser/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5048b4aa07..33b7b498a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3433,7 +3433,7 @@ dependencies = [ [[package]] name = "uuhelp_parser" -version = "0.0.18" +version = "0.0.19" [[package]] name = "uuid" diff --git a/Cargo.toml b/Cargo.toml index 7e851363f2..a5c7684685 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -358,7 +358,7 @@ selinux = { workspace=true, optional = true } textwrap = { workspace=true } zip = { workspace=true, optional = true } -uuhelp_parser = { path="src/uuhelp_parser", optional = true } +uuhelp_parser = { optional=true, version=">=0.0.19", path="src/uuhelp_parser"} # * uutils uu_test = { optional=true, version="0.0.19", package="uu_test", path="src/uu/test" } diff --git a/src/uucore_procs/Cargo.toml b/src/uucore_procs/Cargo.toml index 0ef44fbaeb..9da5e5ab2a 100644 --- a/src/uucore_procs/Cargo.toml +++ b/src/uucore_procs/Cargo.toml @@ -18,4 +18,4 @@ proc-macro = true [dependencies] proc-macro2 = "1.0" quote = "1.0" -uuhelp_parser = { path="../uuhelp_parser", version="0.0.18" } +uuhelp_parser = { path="../uuhelp_parser", version="0.0.19" } diff --git a/src/uuhelp_parser/Cargo.toml b/src/uuhelp_parser/Cargo.toml index 9f4c0d68d9..ced3a0893b 100644 --- a/src/uuhelp_parser/Cargo.toml +++ b/src/uuhelp_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uuhelp_parser" -version = "0.0.18" +version = "0.0.19" edition = "2021" license = "MIT" description = "A collection of functions to parse the markdown code of help files" From c6ad9846f9c3d68e37dee50e3bee7277244455f5 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 1 Jun 2023 21:12:29 +0200 Subject: [PATCH 432/477] update of the version script --- util/update-version.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/update-version.sh b/util/update-version.sh index b6340bf593..106f296fc1 100755 --- a/util/update-version.sh +++ b/util/update-version.sh @@ -24,6 +24,9 @@ sed -i -e "s|version = \"$FROM\"|version = \"$TO\"|" $PROGS # Update uucore_procs sed -i -e "s|version = \"$FROM\"|version = \"$TO\"|" src/uucore_procs/Cargo.toml +# Update uuhelp_parser +sed -i -e "s|version = \"$FROM\"|version = \"$TO\"|" src/uuhelp_parser/Cargo.toml + # Update the stdbuf stuff sed -i -e "s|libstdbuf = { version=\"$FROM\"|libstdbuf = { version=\"$TO\"|" src/uu/stdbuf/Cargo.toml sed -i -e "s|= { optional=true, version=\"$FROM\", package=\"uu_|= { optional=true, version=\"$TO\", package=\"uu_|g" Cargo.toml From 9f38142522b92d7b2648ebadebe372869b8a63b7 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 4 Jun 2023 11:27:50 +0200 Subject: [PATCH 433/477] add uuhelp to the ignore spell --- Cargo.toml | 2 +- src/bin/uudoc.rs | 2 +- src/uucore_procs/Cargo.toml | 1 + src/uucore_procs/src/lib.rs | 2 +- src/uuhelp_parser/Cargo.toml | 1 + util/publish.sh | 1 + util/update-version.sh | 2 ++ 7 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a5c7684685..c2d858d927 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ # coreutils (uutils) # * see the repository LICENSE, README, and CONTRIBUTING files for more information -# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen humantime +# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen humantime uuhelp [package] name = "coreutils" diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index e379258254..5ac8582262 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -2,7 +2,7 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore tldr +// spell-checker:ignore tldr uuhelp use clap::Command; use std::collections::HashMap; diff --git a/src/uucore_procs/Cargo.toml b/src/uucore_procs/Cargo.toml index 9da5e5ab2a..eedc9001c0 100644 --- a/src/uucore_procs/Cargo.toml +++ b/src/uucore_procs/Cargo.toml @@ -1,3 +1,4 @@ +# spell-checker:ignore uuhelp [package] name = "uucore_procs" version = "0.0.19" diff --git a/src/uucore_procs/src/lib.rs b/src/uucore_procs/src/lib.rs index ba32f649be..b78da78221 100644 --- a/src/uucore_procs/src/lib.rs +++ b/src/uucore_procs/src/lib.rs @@ -1,5 +1,5 @@ // Copyright (C) ~ Roy Ivy III ; MIT license -// spell-checker:ignore backticks +// spell-checker:ignore backticks uuhelp use std::{fs::File, io::Read, path::PathBuf}; diff --git a/src/uuhelp_parser/Cargo.toml b/src/uuhelp_parser/Cargo.toml index ced3a0893b..888d075344 100644 --- a/src/uuhelp_parser/Cargo.toml +++ b/src/uuhelp_parser/Cargo.toml @@ -1,3 +1,4 @@ +# spell-checker:ignore uuhelp [package] name = "uuhelp_parser" version = "0.0.19" diff --git a/util/publish.sh b/util/publish.sh index b656f62292..71830f1f91 100755 --- a/util/publish.sh +++ b/util/publish.sh @@ -1,4 +1,5 @@ #!/bin/sh +# spell-checker:ignore uuhelp ARG="" if test "$1" != "--do-it"; then ARG="--dry-run --allow-dirty" diff --git a/util/update-version.sh b/util/update-version.sh index 106f296fc1..0fd15422ad 100755 --- a/util/update-version.sh +++ b/util/update-version.sh @@ -1,4 +1,6 @@ #!/bin/sh +# spell-checker:ignore uuhelp + # This is a stupid helper. I will mass replace all versions (including other crates) # So, it should be triple-checked From 29027405d722a1eb895c1cf167456a514d559cc3 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 4 Jun 2023 13:03:31 +0200 Subject: [PATCH 434/477] Revert "specify the sccache version " --- .github/workflows/CICD.yml | 22 ---------------------- .github/workflows/freebsd.yml | 4 ---- 2 files changed, 26 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 8c595537fd..fb2300ba9c 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -183,8 +183,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Initialize workflow variables id: vars shell: bash @@ -295,8 +293,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Initialize workflow variables id: vars shell: bash @@ -351,8 +347,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Initialize workflow variables id: vars shell: bash @@ -441,8 +435,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: "`make build`" shell: bash run: | @@ -485,8 +477,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Test run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: @@ -514,8 +504,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Test run: cargo nextest run --hide-progress-bar --profile ci ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: @@ -539,8 +527,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Install dependencies shell: bash run: | @@ -666,8 +652,6 @@ jobs: key: "${{ matrix.job.os }}_${{ matrix.job.target }}" - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Initialize workflow variables id: vars shell: bash @@ -921,8 +905,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Install/setup prerequisites shell: bash run: | @@ -1007,8 +989,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Build coreutils as multiple binaries shell: bash run: | @@ -1093,8 +1073,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" # - name: Reattach HEAD ## may be needed for accurate code coverage info # run: git checkout ${{ github.head_ref }} - name: Initialize workflow variables diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml index 50746154b8..9507b3a564 100644 --- a/.github/workflows/freebsd.yml +++ b/.github/workflows/freebsd.yml @@ -34,8 +34,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Prepare, build and test uses: vmactions/freebsd-vm@v0.3.0 with: @@ -126,8 +124,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Run sccache-cache uses: mozilla-actions/sccache-action@v0.0.3 - with: - version: "v0.5.0" - name: Prepare, build and test uses: vmactions/freebsd-vm@v0.3.0 with: From 7958c5d061c2a493ce8001e92ab0168eab0a8de7 Mon Sep 17 00:00:00 2001 From: x-dune <39018755+x-dune@users.noreply.github.com> Date: Sun, 4 Jun 2023 20:17:52 +0800 Subject: [PATCH 435/477] pr: use chrono instead of time --- Cargo.lock | 2 +- src/uu/pr/Cargo.toml | 2 +- src/uu/pr/src/pr.rs | 20 ++++++-------------- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c38199dca5..58750f1ac6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2956,11 +2956,11 @@ dependencies = [ name = "uu_pr" version = "0.0.18" dependencies = [ + "chrono", "clap", "itertools", "quick-error", "regex", - "time", "uucore", ] diff --git a/src/uu/pr/Cargo.toml b/src/uu/pr/Cargo.toml index 414168c64d..0a506e6135 100644 --- a/src/uu/pr/Cargo.toml +++ b/src/uu/pr/Cargo.toml @@ -16,11 +16,11 @@ path = "src/pr.rs" [dependencies] clap = { workspace=true } -time = { workspace=true, features = ["local-offset", "macros", "formatting"] } uucore = { workspace=true, features=["entries"] } quick-error = { workspace=true } itertools = { workspace=true } regex = { workspace=true } +chrono = { workspace=true } [[bin]] name = "pr" diff --git a/src/uu/pr/src/pr.rs b/src/uu/pr/src/pr.rs index b3be8a755a..37674bad7a 100644 --- a/src/uu/pr/src/pr.rs +++ b/src/uu/pr/src/pr.rs @@ -6,6 +6,7 @@ // spell-checker:ignore (ToDO) adFfmprt, kmerge +use chrono::{DateTime, Local}; use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; use itertools::Itertools; use quick_error::ResultExt; @@ -15,8 +16,6 @@ use std::fs::{metadata, File}; use std::io::{stdin, stdout, BufRead, BufReader, Lines, Read, Write}; #[cfg(unix)] use std::os::unix::fs::FileTypeExt; -use time::macros::format_description; -use time::OffsetDateTime; use quick_error::quick_error; use uucore::display::Quotable; @@ -37,8 +36,7 @@ const DEFAULT_COLUMN_WIDTH: usize = 72; const DEFAULT_COLUMN_WIDTH_WITH_S_OPTION: usize = 512; const DEFAULT_COLUMN_SEPARATOR: &char = &TAB; const FF: u8 = 0x0C_u8; -const DATE_TIME_FORMAT: &[time::format_description::FormatItem] = - format_description!("[month repr:short] [day] [hour]:[minute] [year]"); +const DATE_TIME_FORMAT: &str = "%b %d %H:%M %Y"; mod options { pub const HEADER: &str = "header"; @@ -571,10 +569,8 @@ fn build_options( let line_separator = "\n".to_string(); let last_modified_time = if is_merge_mode || paths[0].eq(FILE_STDIN) { - // let date_time = Local::now(); - // date_time.format("%b %d %H:%M %Y").to_string() - let date_time = OffsetDateTime::now_local().unwrap(); - date_time.format(&DATE_TIME_FORMAT).unwrap() + let date_time = Local::now(); + date_time.format(DATE_TIME_FORMAT).to_string() } else { file_last_modified_time(paths.first().unwrap()) }; @@ -1215,12 +1211,8 @@ fn file_last_modified_time(path: &str) -> String { .map(|i| { i.modified() .map(|x| { - let date_time: OffsetDateTime = x.into(); - let offset = OffsetDateTime::now_local().unwrap().offset(); - date_time - .to_offset(offset) - .format(&DATE_TIME_FORMAT) - .unwrap() + let date_time: DateTime = x.into(); + date_time.format(DATE_TIME_FORMAT).to_string() }) .unwrap_or_default() }) From 29f011e28c4621aac7802260164b4d5edd3fc767 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 4 Jun 2023 14:55:16 +0200 Subject: [PATCH 436/477] Remove users crate --- Cargo.lock | 11 ----------- Cargo.toml | 1 - tests/by-util/test_chgrp.rs | 12 ++++++------ tests/by-util/test_chown.rs | 4 ++-- tests/by-util/test_date.rs | 12 ++++++------ tests/by-util/test_install.rs | 6 +++--- 6 files changed, 17 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c38199dca5..b7ca5c517a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -424,7 +424,6 @@ dependencies = [ "textwrap", "time", "unindent", - "users", "uu_arch", "uu_base32", "uu_base64", @@ -2369,16 +2368,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa30f5ea51ff7edfc797c6d3f9ec8cbd8cfedef5371766b7181d33977f4814f" -[[package]] -name = "users" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032" -dependencies = [ - "libc", - "log", -] - [[package]] name = "utf8parse" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index ebd9a4bf40..e2c7988300 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -499,7 +499,6 @@ rlimit = "0.9.1" [target.'cfg(unix)'.dev-dependencies] nix = { workspace=true, features=["process", "signal", "user"] } -rust-users = { version="0.11", package="users" } rand_pcg = "0.3" [build-dependencies] diff --git a/tests/by-util/test_chgrp.rs b/tests/by-util/test_chgrp.rs index 69224b0bdc..cf6c62ff7f 100644 --- a/tests/by-util/test_chgrp.rs +++ b/tests/by-util/test_chgrp.rs @@ -1,7 +1,7 @@ // spell-checker:ignore (words) nosuchgroup groupname use crate::common::util::TestScenario; -use rust_users::get_effective_gid; +use uucore::process::getegid; #[test] fn test_invalid_option() { @@ -53,7 +53,7 @@ fn test_invalid_group() { #[test] fn test_1() { - if get_effective_gid() != 0 { + if getegid() != 0 { new_ucmd!().arg("bin").arg(DIR).fails().stderr_contains( // linux fails with "Operation not permitted (os error 1)" // because of insufficient permissions, @@ -66,7 +66,7 @@ fn test_1() { #[test] fn test_fail_silently() { - if get_effective_gid() != 0 { + if getegid() != 0 { for opt in ["-f", "--silent", "--quiet", "--sil", "--qui"] { new_ucmd!() .arg(opt) @@ -137,7 +137,7 @@ fn test_reference() { // skip for root or MS-WSL // * MS-WSL is bugged (as of 2019-12-25), allowing non-root accounts su-level privileges for `chgrp` // * for MS-WSL, succeeds and stdout == 'group of /etc retained as root' - if !(get_effective_gid() == 0 || uucore::os::is_wsl_1()) { + if !(getegid() == 0 || uucore::os::is_wsl_1()) { new_ucmd!() .arg("-v") .arg("--reference=/etc/passwd") @@ -203,7 +203,7 @@ fn test_missing_files() { #[test] #[cfg(target_os = "linux")] fn test_big_p() { - if get_effective_gid() != 0 { + if getegid() != 0 { new_ucmd!() .arg("-RP") .arg("bin") @@ -218,7 +218,7 @@ fn test_big_p() { #[test] #[cfg(any(target_os = "linux", target_os = "android"))] fn test_big_h() { - if get_effective_gid() != 0 { + if getegid() != 0 { assert!( new_ucmd!() .arg("-RH") diff --git a/tests/by-util/test_chown.rs b/tests/by-util/test_chown.rs index 191e4a86b3..7a1a4a6bd7 100644 --- a/tests/by-util/test_chown.rs +++ b/tests/by-util/test_chown.rs @@ -2,7 +2,7 @@ use crate::common::util::{is_ci, run_ucmd_as_root, CmdResult, TestScenario}; #[cfg(any(target_os = "linux", target_os = "android"))] -use rust_users::get_effective_uid; +use uucore::process::geteuid; // Apparently some CI environments have configuration issues, e.g. with 'whoami' and 'id'. // If we are running inside the CI and "needle" is in "stderr" skipping this test is @@ -701,7 +701,7 @@ fn test_root_preserve() { #[cfg(any(target_os = "linux", target_os = "android"))] #[test] fn test_big_p() { - if get_effective_uid() != 0 { + if geteuid() != 0 { new_ucmd!() .arg("-RP") .arg("bin") diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index c8c33aa890..669f02e331 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -1,7 +1,7 @@ use crate::common::util::TestScenario; use regex::Regex; #[cfg(all(unix, not(target_os = "macos")))] -use rust_users::get_effective_uid; +use uucore::process::geteuid; #[test] fn test_invalid_arg() { @@ -213,7 +213,7 @@ fn test_date_format_literal() { #[test] #[cfg(all(unix, not(target_os = "macos")))] fn test_date_set_valid() { - if get_effective_uid() == 0 { + if geteuid() == 0 { new_ucmd!() .arg("--set") .arg("2020-03-12 13:30:00+08:00") @@ -234,7 +234,7 @@ fn test_date_set_invalid() { #[test] #[cfg(all(unix, not(any(target_os = "android", target_os = "macos"))))] fn test_date_set_permissions_error() { - if !(get_effective_uid() == 0 || uucore::os::is_wsl_1()) { + if !(geteuid() == 0 || uucore::os::is_wsl_1()) { let result = new_ucmd!() .arg("--set") .arg("2020-03-11 21:45:00+08:00") @@ -261,7 +261,7 @@ fn test_date_set_mac_unavailable() { #[cfg(all(unix, not(target_os = "macos")))] /// TODO: expected to fail currently; change to succeeds() when required. fn test_date_set_valid_2() { - if get_effective_uid() == 0 { + if geteuid() == 0 { let result = new_ucmd!() .arg("--set") .arg("Sat 20 Mar 2021 14:53:01 AWST") // spell-checker:disable-line @@ -325,7 +325,7 @@ fn test_date_for_file() { #[cfg(all(unix, not(target_os = "macos")))] /// TODO: expected to fail currently; change to succeeds() when required. fn test_date_set_valid_3() { - if get_effective_uid() == 0 { + if geteuid() == 0 { let result = new_ucmd!() .arg("--set") .arg("Sat 20 Mar 2021 14:53:01") // Local timezone @@ -339,7 +339,7 @@ fn test_date_set_valid_3() { #[cfg(all(unix, not(target_os = "macos")))] /// TODO: expected to fail currently; change to succeeds() when required. fn test_date_set_valid_4() { - if get_effective_uid() == 0 { + if geteuid() == 0 { let result = new_ucmd!() .arg("--set") .arg("2020-03-11 21:45:00") // Local timezone diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index a30737f059..d76ce1e014 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -2,12 +2,12 @@ use crate::common::util::{is_ci, TestScenario}; use filetime::FileTime; -use rust_users::{get_effective_gid, get_effective_uid}; use std::os::unix::fs::PermissionsExt; #[cfg(not(any(windows, target_os = "freebsd")))] use std::process::Command; #[cfg(any(target_os = "linux", target_os = "android"))] use std::thread::sleep; +use uucore::process::{getegid, geteuid}; #[test] fn test_invalid_arg() { @@ -322,7 +322,7 @@ fn test_install_target_new_file_with_group() { let (at, mut ucmd) = at_and_ucmd!(); let file = "file"; let dir = "target_dir"; - let gid = get_effective_gid(); + let gid = getegid(); at.touch(file); at.mkdir(dir); @@ -349,7 +349,7 @@ fn test_install_target_new_file_with_owner() { let (at, mut ucmd) = at_and_ucmd!(); let file = "file"; let dir = "target_dir"; - let uid = get_effective_uid(); + let uid = geteuid(); at.touch(file); at.mkdir(dir); From 126bbba17aa2a7937bbbfd902752884df3f683a1 Mon Sep 17 00:00:00 2001 From: Tracy Date: Sun, 4 Jun 2023 10:03:01 -0400 Subject: [PATCH 437/477] pwd: Fixes #4855 (#4937) Based on testing with GNU's pwd, it seems like the -P flag should take precedence over the use of the POSIXLY_CORRECT flag. Co-authored-by: Terts Diepraam --- src/uu/pwd/src/pwd.rs | 4 +++- tests/by-util/test_pwd.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/uu/pwd/src/pwd.rs b/src/uu/pwd/src/pwd.rs index 7af1948726..9e04dd38be 100644 --- a/src/uu/pwd/src/pwd.rs +++ b/src/uu/pwd/src/pwd.rs @@ -115,7 +115,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { // if POSIXLY_CORRECT is set, we want to a logical resolution. // This produces a different output when doing mkdir -p a/b && ln -s a/b c && cd c && pwd // We should get c in this case instead of a/b at the end of the path - let cwd = if matches.get_flag(OPT_LOGICAL) || env::var("POSIXLY_CORRECT").is_ok() { + let cwd = if matches.get_flag(OPT_PHYSICAL) { + physical_path() + } else if matches.get_flag(OPT_LOGICAL) || env::var("POSIXLY_CORRECT").is_ok() { logical_path() } else { physical_path() diff --git a/tests/by-util/test_pwd.rs b/tests/by-util/test_pwd.rs index 076e72089a..1e43f5be6b 100644 --- a/tests/by-util/test_pwd.rs +++ b/tests/by-util/test_pwd.rs @@ -116,7 +116,7 @@ fn test_symlinked_default_posix_p() { .env("POSIXLY_CORRECT", "1") .arg("-P") .succeeds() - .stdout_is(env.symdir + "\n"); + .stdout_is(env.subdir + "\n"); } #[cfg(not(windows))] From ee2aa85cd8fd7c061218be010239fa5efb91792c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 4 Jun 2023 14:03:47 +0000 Subject: [PATCH 438/477] chore(deps): update rust crate once_cell to 1.18.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c38199dca5..d137adc58c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1549,9 +1549,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "once_cell" -version = "1.17.2" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "onig" diff --git a/Cargo.toml b/Cargo.toml index ebd9a4bf40..238070fe03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -299,7 +299,7 @@ notify = { version = "=6.0.0", features=["macos_kqueue"]} num-bigint = "0.4.3" num-traits = "0.2.15" number_prefix = "0.4" -once_cell = "1.17.2" +once_cell = "1.18.0" onig = { version = "~6.4", default-features = false } ouroboros = "0.15.6" phf = "0.11.1" From 65a8e1540cb6cda640ca0125d420e83748c5ebcb Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 5 Jun 2023 10:09:03 +0200 Subject: [PATCH 439/477] Bump getrandom from 0.2.8 to 0.2.9 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c2af231be..7b9b230c2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1073,9 +1073,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "libc", From 1c4d7b2f879ac38c64e2a707eb8f9e39b1c6d117 Mon Sep 17 00:00:00 2001 From: Miles Liu Date: Mon, 5 Jun 2023 16:34:50 +0800 Subject: [PATCH 440/477] install: remove time crate --- Cargo.lock | 1 - src/uu/install/Cargo.toml | 3 --- 2 files changed, 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c2af231be..7c826fac54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2732,7 +2732,6 @@ dependencies = [ "file_diff", "filetime", "libc", - "time", "uucore", ] diff --git a/src/uu/install/Cargo.toml b/src/uu/install/Cargo.toml index 89849059dd..b833babad4 100644 --- a/src/uu/install/Cargo.toml +++ b/src/uu/install/Cargo.toml @@ -24,9 +24,6 @@ file_diff = { workspace=true } libc = { workspace=true } uucore = { workspace=true, features=["fs", "mode", "perms", "entries"] } -[dev-dependencies] -time = { workspace=true } - [[bin]] name = "install" path = "src/main.rs" From b0705062557ec5d497cf02d4ece27b0b37da8ce5 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Fri, 2 Jun 2023 14:42:47 -0400 Subject: [PATCH 441/477] tsort: Switch to BTreeHash and BTreeSet Using HashMap and HashSet give a valid topological sort, but the output will change randomly at each run. BTree based structures will guarantee that the output is always ordered in the same way. This also makes the ouptut similar to the output of the C version of the tools, on which some applications rely. --- src/uu/tsort/src/tsort.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uu/tsort/src/tsort.rs b/src/uu/tsort/src/tsort.rs index a70f32dfdd..6e11a7f580 100644 --- a/src/uu/tsort/src/tsort.rs +++ b/src/uu/tsort/src/tsort.rs @@ -6,7 +6,7 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. use clap::{crate_version, Arg, Command}; -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, BTreeSet}; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; use std::path::Path; @@ -103,8 +103,8 @@ pub fn uu_app() -> Command { // but using integer may improve performance. #[derive(Default)] struct Graph { - in_edges: HashMap>, - out_edges: HashMap>, + in_edges: BTreeMap>, + out_edges: BTreeMap>, result: Vec, } @@ -122,7 +122,7 @@ impl Graph { } fn init_node(&mut self, n: &str) { - self.in_edges.insert(n.to_string(), HashSet::new()); + self.in_edges.insert(n.to_string(), BTreeSet::new()); self.out_edges.insert(n.to_string(), vec![]); } From 43a8d62b903d254af282cc70a4f52be55e302f63 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Mon, 5 Jun 2023 11:00:47 -0400 Subject: [PATCH 442/477] tsort: Add test for ordered floating nodes Signed-off-by: Detlev Casanova --- tests/by-util/test_tsort.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/by-util/test_tsort.rs b/tests/by-util/test_tsort.rs index 8b01e2a2d6..62a74c31d0 100644 --- a/tests/by-util/test_tsort.rs +++ b/tests/by-util/test_tsort.rs @@ -20,6 +20,14 @@ fn test_sort_self_loop() { .stdout_only("first\nsecond\n"); } +#[test] +fn test_sort_floating_nodes() { + new_ucmd!() + .pipe_in("d d\nc c\na a\nb b") + .succeeds() + .stdout_only("a\nb\nc\nd\n"); +} + #[test] fn test_no_such_file() { new_ucmd!() From c9f4c5dfb5fdb8d53156edd255680b16f650992c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 17:46:52 +0000 Subject: [PATCH 443/477] chore(deps): update rust crate regex to 1.8.4 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c826fac54..75dd10da1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1899,9 +1899,9 @@ checksum = "f1bfbf25d7eb88ddcbb1ec3d755d0634da8f7657b2cb8b74089121409ab8228f" [[package]] name = "regex" -version = "1.8.3" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "aho-corasick 1.0.1", "memchr", diff --git a/Cargo.toml b/Cargo.toml index d939d43f71..bc4ca752d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -310,7 +310,7 @@ rand = { version = "0.8", features = ["small_rng"] } rand_core = "0.6" rayon = "1.7" redox_syscall = "0.3" -regex = "1.8.3" +regex = "1.8.4" rstest = "0.17.0" rust-ini = "0.18.0" same-file = "1.0.6" From 42a22c12f1ad54e85f11c4fc4f17af786589e39a Mon Sep 17 00:00:00 2001 From: Wandering Lethe Date: Mon, 5 Jun 2023 21:41:32 +0200 Subject: [PATCH 444/477] Remove time dependency from date Also upgrades humantime_to_duration to the latest version, it switched from time to chrono. Because touch still depends on time, its humantime_to_duration package version deviates from the workspace version. --- Cargo.lock | 47 +++++++++++++++++++++++++++++++++-------- Cargo.toml | 2 +- src/uu/date/Cargo.toml | 2 -- src/uu/date/src/date.rs | 12 ++++------- src/uu/touch/Cargo.toml | 3 ++- 5 files changed, 45 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c826fac54..63d748f9d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -272,7 +272,10 @@ checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", + "time 0.1.45", + "wasm-bindgen", "winapi", ] @@ -421,7 +424,7 @@ dependencies = [ "sha1", "tempfile", "textwrap", - "time", + "time 0.3.20", "unindent", "uu_arch", "uu_base32", @@ -1079,7 +1082,7 @@ checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -1151,7 +1154,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "714764645f21cc70c4c151d7798dd158409641f37ad820bed65224aae403cbed" dependencies = [ "regex", - "time", + "time 0.3.20", +] + +[[package]] +name = "humantime_to_duration" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a674b970a2bbad01671718ca07604ca89258dd5e25d9af835c14ac6e0bc792" +dependencies = [ + "chrono", + "regex", ] [[package]] @@ -1434,7 +1447,7 @@ checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.45.0", ] @@ -2289,6 +2302,17 @@ dependencies = [ "syn", ] +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + [[package]] name = "time" version = "0.3.20" @@ -2528,9 +2552,8 @@ version = "0.0.19" dependencies = [ "chrono", "clap", - "humantime_to_duration", + "humantime_to_duration 0.3.0", "libc", - "time", "uucore", "windows-sys 0.48.0", ] @@ -3224,8 +3247,8 @@ version = "0.0.19" dependencies = [ "clap", "filetime", - "humantime_to_duration", - "time", + "humantime_to_duration 0.2.1", + "time 0.3.20", "uucore", "windows-sys 0.48.0", ] @@ -3401,7 +3424,7 @@ dependencies = [ "sm3", "tempfile", "thiserror", - "time", + "time 0.3.20", "uucore_procs", "walkdir", "wild", @@ -3446,6 +3469,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index d939d43f71..3df9aa1ac0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -286,7 +286,7 @@ fundu = "0.5.1" gcd = "2.3" glob = "0.3.1" half = "2.2" -humantime_to_duration = "0.2.1" +humantime_to_duration = "0.3.0" indicatif = "0.17" is-terminal = "0.4.7" itertools = "0.10.5" diff --git a/src/uu/date/Cargo.toml b/src/uu/date/Cargo.toml index 852e8cc9d1..1ffcbed666 100644 --- a/src/uu/date/Cargo.toml +++ b/src/uu/date/Cargo.toml @@ -17,8 +17,6 @@ path = "src/date.rs" [dependencies] chrono = { workspace=true } -#/ TODO: check if we can avoid chrono+time -time = { workspace=true } clap = { workspace=true } uucore = { workspace=true } humantime_to_duration = { workspace=true } diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index 381619f06f..44b54be5e8 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -9,7 +9,7 @@ // spell-checker:ignore (chrono) Datelike Timelike ; (format) DATEFILE MMDDhhmm ; (vars) datetime datetimes humantime use chrono::format::{Item, StrftimeItems}; -use chrono::{DateTime, Duration as ChronoDuration, FixedOffset, Local, Offset, Utc}; +use chrono::{DateTime, Duration, FixedOffset, Local, Offset, Utc}; #[cfg(windows)] use chrono::{Datelike, Timelike}; use clap::{crate_version, Arg, ArgAction, Command}; @@ -18,7 +18,6 @@ use libc::{clock_settime, timespec, CLOCK_REALTIME}; use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::PathBuf; -use time::Duration; use uucore::display::Quotable; #[cfg(not(any(target_os = "redox")))] use uucore::error::FromIo; @@ -226,13 +225,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let iter = std::iter::once(date); Box::new(iter) } - DateSource::Human(ref input) => { - // Get the current DateTime and convert the input time::Duration to chrono::Duration - // for things like "1 year ago" + DateSource::Human(relative_time) => { + // Get the current DateTime for things like "1 year ago" let current_time = DateTime::::from(Local::now()); - let input_chrono = ChronoDuration::seconds(input.as_seconds_f32() as i64) - + ChronoDuration::nanoseconds(input.subsec_nanoseconds() as i64); - let iter = std::iter::once(Ok(current_time + input_chrono)); + let iter = std::iter::once(Ok(current_time + relative_time)); Box::new(iter) } DateSource::File(ref path) => { diff --git a/src/uu/touch/Cargo.toml b/src/uu/touch/Cargo.toml index 3aac9abc47..80840525c0 100644 --- a/src/uu/touch/Cargo.toml +++ b/src/uu/touch/Cargo.toml @@ -18,7 +18,8 @@ path = "src/touch.rs" [dependencies] filetime = { workspace=true } clap = { workspace=true } -humantime_to_duration = { workspace=true } +# TODO: use workspace dependency (0.3) when switching from time to chrono +humantime_to_duration = "0.2.1" time = { workspace=true, features = ["parsing", "formatting", "local-offset", "macros"] } uucore = { workspace=true, features=["libc"] } From 2842d1fa0f2d0004d84805b73a413e31686bceb3 Mon Sep 17 00:00:00 2001 From: Wandering Lethe Date: Mon, 5 Jun 2023 22:54:26 +0200 Subject: [PATCH 445/477] Add duplicate packages to deny ban skips Duplicates of humantime_to_duration and time can be removed when touch switches from time to chrono --- deny.toml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/deny.toml b/deny.toml index 14470b9b0d..aa0203b9ba 100644 --- a/deny.toml +++ b/deny.toml @@ -76,8 +76,11 @@ skip = [ { name = "windows_x86_64_msvc", version = "0.42.2" }, # tempfile { name = "redox_syscall", version = "0.3.5" }, - # cpp_macros - { name = "aho-corasick", version = "0.7.19" }, + # chrono -> time + { name = "wasi", version = "0.10.0+wasi-snapshot-preview1" }, + # touch can be remove when touch switches from time to chrono + { name = "humantime_to_duration", version = "0.2.1" }, + { name = "time", version = "0.3.20" }, ] # spell-checker: enable From 1ff4684f8a757ea570642d7a97f9486d8303f174 Mon Sep 17 00:00:00 2001 From: Wandering Lethe Date: Mon, 5 Jun 2023 23:01:26 +0200 Subject: [PATCH 446/477] Revert accidental removal of skipped deny --- deny.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deny.toml b/deny.toml index aa0203b9ba..ba516de842 100644 --- a/deny.toml +++ b/deny.toml @@ -76,6 +76,8 @@ skip = [ { name = "windows_x86_64_msvc", version = "0.42.2" }, # tempfile { name = "redox_syscall", version = "0.3.5" }, + # cpp_macros + { name = "aho-corasick", version = "0.7.19" }, # chrono -> time { name = "wasi", version = "0.10.0+wasi-snapshot-preview1" }, # touch can be remove when touch switches from time to chrono From c68b665bf920bbf9d2757191f3b09cdf3b748574 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 14:39:50 +0000 Subject: [PATCH 447/477] fix(deps): update rust crate libc to 0.2.146 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/uucore/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75dd10da1d..cce3816cfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1309,9 +1309,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.144" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "libloading" diff --git a/Cargo.toml b/Cargo.toml index bc4ca752d8..c67aaa9a90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -290,7 +290,7 @@ humantime_to_duration = "0.2.1" indicatif = "0.17" is-terminal = "0.4.7" itertools = "0.10.5" -libc = "0.2.144" +libc = "0.2.146" lscolors = { version = "0.14.0", default-features=false, features = ["nu-ansi-term"] } memchr = "2" nix = { version="0.26", default-features=false } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 0745ca03f0..d16c3c79e3 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -32,7 +32,7 @@ time = { workspace=true, optional=true, features = ["formatting", "local-offset" data-encoding = { version="2.4", optional=true } data-encoding-macro = { version="0.1.13", optional=true } z85 = { version="3.0.5", optional=true } -libc = { version="0.2.144", optional=true } +libc = { version="0.2.146", optional=true } once_cell = { workspace=true } os_display = "0.1.3" From 3f33c5b816d5949271a31fee3d9a1e7370fd1baa Mon Sep 17 00:00:00 2001 From: Rayhan Faizel Date: Tue, 6 Jun 2023 20:55:42 +0530 Subject: [PATCH 448/477] ls: Implement --sort=width --- src/uu/ls/src/ls.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index e5ad4bcd45..7db591cf3b 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -294,6 +294,7 @@ enum Sort { Time, Version, Extension, + Width, } #[derive(PartialEq)] @@ -496,6 +497,7 @@ fn extract_sort(options: &clap::ArgMatches) -> Sort { "size" => Sort::Size, "version" => Sort::Version, "extension" => Sort::Extension, + "width" => Sort::Width, // below should never happen as clap already restricts the values. _ => unreachable!("Invalid field for --sort"), } @@ -1322,9 +1324,9 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::SORT) .long(options::SORT) - .help("Sort by : name, none (-U), time (-t), size (-S) or extension (-X)") + .help("Sort by : name, none (-U), time (-t), size (-S), extension (-X) or width") .value_name("field") - .value_parser(["name", "none", "time", "size", "version", "extension"]) + .value_parser(["name", "none", "time", "size", "version", "extension", "width"]) .require_equals(true) .overrides_with_all([ options::SORT, @@ -1937,6 +1939,12 @@ fn sort_entries(entries: &mut [PathData], config: &Config, out: &mut BufWriter entries.sort_by(|a, b| { + a.display_name + .len() + .cmp(&b.display_name.len()) + .then(a.display_name.cmp(&b.display_name)) + }), Sort::None => {} } From 21f1a119c3378e9cc17603352c1903a72845d4b2 Mon Sep 17 00:00:00 2001 From: Rayhan Faizel Date: Tue, 6 Jun 2023 20:56:42 +0530 Subject: [PATCH 449/477] tests/ls: Implement tests for sort by width option --- tests/by-util/test_ls.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 45ced867a4..49c2272c09 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1564,6 +1564,28 @@ fn test_ls_sort_name() { .stdout_is(".a\n.b\na\nb\n"); } +#[test] +fn test_ls_sort_width() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + at.touch("aaaaa"); + at.touch("bbb"); + at.touch("cccc"); + at.touch("eee"); + at.touch("d"); + at.touch("fffff"); + at.touch("abc"); + at.touch("zz"); + at.touch("bcdef"); + + scene + .ucmd() + .arg("--sort=width") + .succeeds() + .stdout_is("d\nzz\nabc\nbbb\neee\ncccc\naaaaa\nbcdef\nfffff\n"); +} + #[test] fn test_ls_order_size() { let scene = TestScenario::new(util_name!()); From c26396087f9b802306e21d14fa02ce4200caa031 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 6 Jun 2023 17:44:04 +0200 Subject: [PATCH 450/477] ls: add words to spell-checker:ignore --- tests/by-util/test_ls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 49c2272c09..1266a7cab9 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -1,4 +1,4 @@ -// spell-checker:ignore (words) READMECAREFULLY birthtime doesntexist oneline somebackup lrwx somefile somegroup somehiddenbackup somehiddenfile tabsize aaaaaaaa bbbb cccc dddddddd ncccc +// spell-checker:ignore (words) READMECAREFULLY birthtime doesntexist oneline somebackup lrwx somefile somegroup somehiddenbackup somehiddenfile tabsize aaaaaaaa bbbb cccc dddddddd ncccc neee naaaaa nbcdef nfffff #[cfg(any(unix, feature = "feat_selinux"))] use crate::common::util::expected_result; From 81313e63eab50a38ffa7c8d5bdcd769aac31ee3f Mon Sep 17 00:00:00 2001 From: Wandering Lethe Date: Tue, 6 Jun 2023 18:07:21 +0200 Subject: [PATCH 451/477] Upgrade humantime_to_duration to version 0.3.1. Latest patch fixes the transitive dependency on time. Which can now also be removed from the deny skipped bans. --- Cargo.lock | 38 +++++++++----------------------------- Cargo.toml | 2 +- deny.toml | 5 +---- 3 files changed, 11 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 63d748f9d8..1603bdc560 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -272,10 +272,7 @@ checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ "android-tzdata", "iana-time-zone", - "js-sys", "num-traits", - "time 0.1.45", - "wasm-bindgen", "winapi", ] @@ -424,7 +421,7 @@ dependencies = [ "sha1", "tempfile", "textwrap", - "time 0.3.20", + "time", "unindent", "uu_arch", "uu_base32", @@ -1082,7 +1079,7 @@ checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -1154,14 +1151,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "714764645f21cc70c4c151d7798dd158409641f37ad820bed65224aae403cbed" dependencies = [ "regex", - "time 0.3.20", + "time", ] [[package]] name = "humantime_to_duration" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a674b970a2bbad01671718ca07604ca89258dd5e25d9af835c14ac6e0bc792" +checksum = "1a80a233096ddccb74e62145f3a49cacea6a2669ee90f6e144e15fe28f4037c4" dependencies = [ "chrono", "regex", @@ -1447,7 +1444,7 @@ checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.45.0", ] @@ -2302,17 +2299,6 @@ dependencies = [ "syn", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.20" @@ -2552,7 +2538,7 @@ version = "0.0.19" dependencies = [ "chrono", "clap", - "humantime_to_duration 0.3.0", + "humantime_to_duration 0.3.1", "libc", "uucore", "windows-sys 0.48.0", @@ -3248,7 +3234,7 @@ dependencies = [ "clap", "filetime", "humantime_to_duration 0.2.1", - "time 0.3.20", + "time", "uucore", "windows-sys 0.48.0", ] @@ -3424,7 +3410,7 @@ dependencies = [ "sm3", "tempfile", "thiserror", - "time 0.3.20", + "time", "uucore_procs", "walkdir", "wild", @@ -3469,12 +3455,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 3df9aa1ac0..9c8d769a45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -286,7 +286,7 @@ fundu = "0.5.1" gcd = "2.3" glob = "0.3.1" half = "2.2" -humantime_to_duration = "0.3.0" +humantime_to_duration = "0.3.1" indicatif = "0.17" is-terminal = "0.4.7" itertools = "0.10.5" diff --git a/deny.toml b/deny.toml index ba516de842..c849842304 100644 --- a/deny.toml +++ b/deny.toml @@ -78,11 +78,8 @@ skip = [ { name = "redox_syscall", version = "0.3.5" }, # cpp_macros { name = "aho-corasick", version = "0.7.19" }, - # chrono -> time - { name = "wasi", version = "0.10.0+wasi-snapshot-preview1" }, - # touch can be remove when touch switches from time to chrono + # touch, can be remove when touch switches from time to chrono { name = "humantime_to_duration", version = "0.2.1" }, - { name = "time", version = "0.3.20" }, ] # spell-checker: enable From 1965ba268e9ffddbe70d61f8a870ebfb5257c8b6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 20:22:27 +0000 Subject: [PATCH 452/477] chore(deps): update rust crate tempfile to 3.6.0 --- Cargo.lock | 31 ++++++++++++++++--------------- Cargo.toml | 2 +- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61d8fcf05e..87b64c4ef1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -855,13 +855,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1248,7 +1248,7 @@ checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", - "rustix 0.37.7", + "rustix 0.37.19", "windows-sys 0.48.0", ] @@ -1350,9 +1350,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.3.0" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd550e73688e6d578f0ac2119e32b797a327631a42f9433e59d02e139c8df60d" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "lock_api" @@ -2012,16 +2012,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.7" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", - "linux-raw-sys 0.3.0", - "windows-sys 0.45.0", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", ] [[package]] @@ -2228,15 +2228,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.7", - "windows-sys 0.45.0", + "rustix 0.37.19", + "windows-sys 0.48.0", ] [[package]] @@ -2263,7 +2264,7 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" dependencies = [ - "rustix 0.37.7", + "rustix 0.37.19", "windows-sys 0.48.0", ] diff --git a/Cargo.toml b/Cargo.toml index 1e6e220889..aac51b8c6e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -317,7 +317,7 @@ same-file = "1.0.6" selinux = "0.4" signal-hook = "0.3.15" smallvec = { version = "1.10", features = ["union"] } -tempfile = "3.5.0" +tempfile = "3.6.0" term_grid = "0.1.5" terminal_size = "0.2.6" textwrap = { version="0.16.0", features=["terminal_size"] } From 750eacc10c8cd11365696964f087590915186609 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 7 Jun 2023 10:42:01 +0200 Subject: [PATCH 453/477] mkdir: remove TEST_DIR consts in tests --- tests/by-util/test_mkdir.rs | 120 ++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 59 deletions(-) diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index 425be8c35c..c8dd7e243c 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -12,20 +12,6 @@ use std::sync::Mutex; // when writing a test case, acquire this mutex before proceeding with the main logic of the test static TEST_MUTEX: Lazy> = Lazy::new(|| Mutex::new(())); -static TEST_DIR1: &str = "mkdir_test1"; -static TEST_DIR2: &str = "mkdir_test2"; -static TEST_DIR3: &str = "mkdir_test3"; -static TEST_DIR4: &str = "mkdir_test4/mkdir_test4_1"; -static TEST_DIR5: &str = "mkdir_test5/mkdir_test5_1"; -static TEST_DIR6: &str = "mkdir_test6"; -static TEST_FILE7: &str = "mkdir_test7"; -static TEST_DIR8: &str = "mkdir_test8/mkdir_test8_1/mkdir_test8_2"; -static TEST_DIR9: &str = "mkdir_test9/../mkdir_test9_1/../mkdir_test9_2"; -static TEST_DIR10: &str = "mkdir_test10/."; -static TEST_DIR11: &str = "mkdir_test11/.."; -#[cfg(not(windows))] -static TEST_DIR12: &str = "mkdir_test12"; - #[test] fn test_invalid_arg() { let _guard = TEST_MUTEX.lock(); @@ -35,15 +21,15 @@ fn test_invalid_arg() { #[test] fn test_mkdir_mkdir() { let _guard = TEST_MUTEX.lock(); - new_ucmd!().arg(TEST_DIR1).succeeds(); + new_ucmd!().arg("test_dir").succeeds(); } #[test] fn test_mkdir_verbose() { let _guard = TEST_MUTEX.lock(); - let expected = "mkdir: created directory 'mkdir_test1'\n"; + let expected = "mkdir: created directory 'test_dir'\n"; new_ucmd!() - .arg(TEST_DIR1) + .arg("test_dir") .arg("-v") .run() .stdout_is(expected); @@ -52,39 +38,47 @@ fn test_mkdir_verbose() { #[test] fn test_mkdir_dup_dir() { let _guard = TEST_MUTEX.lock(); + let scene = TestScenario::new(util_name!()); - scene.ucmd().arg(TEST_DIR2).succeeds(); - scene.ucmd().arg(TEST_DIR2).fails(); + let test_dir = "test_dir"; + + scene.ucmd().arg(test_dir).succeeds(); + scene.ucmd().arg(test_dir).fails(); } #[test] fn test_mkdir_mode() { let _guard = TEST_MUTEX.lock(); - new_ucmd!().arg("-m").arg("755").arg(TEST_DIR3).succeeds(); + new_ucmd!().arg("-m").arg("755").arg("test_dir").succeeds(); } #[test] fn test_mkdir_parent() { let _guard = TEST_MUTEX.lock(); let scene = TestScenario::new(util_name!()); - scene.ucmd().arg("-p").arg(TEST_DIR4).succeeds(); - scene.ucmd().arg("-p").arg(TEST_DIR4).succeeds(); - scene.ucmd().arg("--parent").arg(TEST_DIR4).succeeds(); - scene.ucmd().arg("--parents").arg(TEST_DIR4).succeeds(); + let test_dir = "parent_dir/child_dir"; + + scene.ucmd().arg("-p").arg(test_dir).succeeds(); + scene.ucmd().arg("-p").arg(test_dir).succeeds(); + scene.ucmd().arg("--parent").arg(test_dir).succeeds(); + scene.ucmd().arg("--parents").arg(test_dir).succeeds(); } #[test] fn test_mkdir_no_parent() { let _guard = TEST_MUTEX.lock(); - new_ucmd!().arg(TEST_DIR5).fails(); + new_ucmd!().arg("parent_dir/child_dir").fails(); } #[test] fn test_mkdir_dup_dir_parent() { let _guard = TEST_MUTEX.lock(); + let scene = TestScenario::new(util_name!()); - scene.ucmd().arg(TEST_DIR6).succeeds(); - scene.ucmd().arg("-p").arg(TEST_DIR6).succeeds(); + let test_dir = "test_dir"; + + scene.ucmd().arg(test_dir).succeeds(); + scene.ucmd().arg("-p").arg(test_dir).succeeds(); } #[cfg(not(windows))] @@ -158,12 +152,16 @@ fn test_mkdir_parent_mode_check_existing_parent() { #[test] fn test_mkdir_dup_file() { let _guard = TEST_MUTEX.lock(); + let scene = TestScenario::new(util_name!()); - scene.fixtures.touch(TEST_FILE7); - scene.ucmd().arg(TEST_FILE7).fails(); + let test_file = "test_file.txt"; + + scene.fixtures.touch(test_file); + + scene.ucmd().arg(test_file).fails(); // mkdir should fail for a file even if -p is specified. - scene.ucmd().arg("-p").arg(TEST_FILE7).fails(); + scene.ucmd().arg("-p").arg(test_file).fails(); } #[test] @@ -171,9 +169,10 @@ fn test_mkdir_dup_file() { fn test_symbolic_mode() { let _guard = TEST_MUTEX.lock(); let (at, mut ucmd) = at_and_ucmd!(); + let test_dir = "test_dir"; - ucmd.arg("-m").arg("a=rwx").arg(TEST_DIR1).succeeds(); - let perms = at.metadata(TEST_DIR1).permissions().mode(); + ucmd.arg("-m").arg("a=rwx").arg(test_dir).succeeds(); + let perms = at.metadata(test_dir).permissions().mode(); assert_eq!(perms, 0o40777); } @@ -182,12 +181,13 @@ fn test_symbolic_mode() { fn test_symbolic_alteration() { let _guard = TEST_MUTEX.lock(); let (at, mut ucmd) = at_and_ucmd!(); + let test_dir = "test_dir"; let default_umask = 0o022; let original_umask = unsafe { umask(default_umask) }; - ucmd.arg("-m").arg("-w").arg(TEST_DIR1).succeeds(); - let perms = at.metadata(TEST_DIR1).permissions().mode(); + ucmd.arg("-m").arg("-w").arg(test_dir).succeeds(); + let perms = at.metadata(test_dir).permissions().mode(); assert_eq!(perms, 0o40577); unsafe { umask(original_umask) }; @@ -198,60 +198,60 @@ fn test_symbolic_alteration() { fn test_multi_symbolic() { let _guard = TEST_MUTEX.lock(); let (at, mut ucmd) = at_and_ucmd!(); + let test_dir = "test_dir"; - ucmd.arg("-m") - .arg("u=rwx,g=rx,o=") - .arg(TEST_DIR1) - .succeeds(); - let perms = at.metadata(TEST_DIR1).permissions().mode(); + ucmd.arg("-m").arg("u=rwx,g=rx,o=").arg(test_dir).succeeds(); + let perms = at.metadata(test_dir).permissions().mode(); assert_eq!(perms, 0o40750); } #[test] fn test_recursive_reporting() { let _guard = TEST_MUTEX.lock(); + let test_dir = "test_dir/test_dir_a/test_dir_b"; + new_ucmd!() .arg("-p") .arg("-v") - .arg(TEST_DIR8) + .arg(test_dir) .succeeds() - .stdout_contains("created directory 'mkdir_test8'") - .stdout_contains("created directory 'mkdir_test8/mkdir_test8_1'") - .stdout_contains("created directory 'mkdir_test8/mkdir_test8_1/mkdir_test8_2'"); - new_ucmd!().arg("-v").arg(TEST_DIR8).fails().no_stdout(); + .stdout_contains("created directory 'test_dir'") + .stdout_contains("created directory 'test_dir/test_dir_a'") + .stdout_contains("created directory 'test_dir/test_dir_a/test_dir_b'"); + new_ucmd!().arg("-v").arg(test_dir).fails().no_stdout(); + + let test_dir = "test_dir/../test_dir_a/../test_dir_b"; + new_ucmd!() .arg("-p") .arg("-v") - .arg(TEST_DIR9) + .arg(test_dir) .succeeds() - .stdout_contains("created directory 'mkdir_test9'") - .stdout_contains("created directory 'mkdir_test9/../mkdir_test9_1'") - .stdout_contains("created directory 'mkdir_test9/../mkdir_test9_1/../mkdir_test9_2'"); + .stdout_contains("created directory 'test_dir'") + .stdout_contains("created directory 'test_dir/../test_dir_a'") + .stdout_contains("created directory 'test_dir/../test_dir_a/../test_dir_b'"); } #[test] fn test_mkdir_trailing_dot() { let _guard = TEST_MUTEX.lock(); let scene2 = TestScenario::new("ls"); - new_ucmd!() - .arg("-p") - .arg("-v") - .arg("mkdir_test10-2") - .succeeds(); + + new_ucmd!().arg("-p").arg("-v").arg("test_dir").succeeds(); new_ucmd!() .arg("-p") .arg("-v") - .arg(TEST_DIR10) + .arg("test_dir_a/.") .succeeds() - .stdout_contains("created directory 'mkdir_test10'"); + .stdout_contains("created directory 'test_dir_a'"); new_ucmd!() .arg("-p") .arg("-v") - .arg(TEST_DIR11) + .arg("test_dir_b/..") .succeeds() - .stdout_contains("created directory 'mkdir_test11'"); + .stdout_contains("created directory 'test_dir_b'"); let result = scene2.ucmd().arg("-al").run(); println!("ls dest {}", result.stdout_str()); } @@ -261,12 +261,14 @@ fn test_mkdir_trailing_dot() { fn test_umask_compliance() { fn test_single_case(umask_set: mode_t) { let _guard = TEST_MUTEX.lock(); + + let test_dir = "test_dir"; let (at, mut ucmd) = at_and_ucmd!(); let original_umask = unsafe { umask(umask_set) }; - ucmd.arg(TEST_DIR12).succeeds(); - let perms = at.metadata(TEST_DIR12).permissions().mode() as mode_t; + ucmd.arg(test_dir).succeeds(); + let perms = at.metadata(test_dir).permissions().mode() as mode_t; assert_eq!(perms, (!umask_set & 0o0777) + 0o40000); // before compare, add the set GUID, UID bits unsafe { From 3caa2c0d8fa4e214910ceaed6faf88a02c743a92 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 7 Jun 2023 10:44:11 +0200 Subject: [PATCH 454/477] mkdir: rename var "scene2" -> "scene" in test --- tests/by-util/test_mkdir.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index c8dd7e243c..11a860d5a0 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -235,7 +235,6 @@ fn test_recursive_reporting() { #[test] fn test_mkdir_trailing_dot() { let _guard = TEST_MUTEX.lock(); - let scene2 = TestScenario::new("ls"); new_ucmd!().arg("-p").arg("-v").arg("test_dir").succeeds(); @@ -252,7 +251,9 @@ fn test_mkdir_trailing_dot() { .arg("test_dir_b/..") .succeeds() .stdout_contains("created directory 'test_dir_b'"); - let result = scene2.ucmd().arg("-al").run(); + + let scene = TestScenario::new("ls"); + let result = scene.ucmd().arg("-al").run(); println!("ls dest {}", result.stdout_str()); } From e115ee54462bd0cbc1065e29728a5cce85e504dd Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 6 Jun 2023 18:21:10 +0200 Subject: [PATCH 455/477] Run format toml in the CI --- .github/workflows/CICD.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index fb2300ba9c..b52ea50980 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -1048,6 +1048,15 @@ jobs: name: toybox-result.json path: ${{ steps.vars.outputs.TEST_SUMMARY_FILE }} + toml_format: + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v3 + + - name: Check + run: npx --yes @taplo/cli fmt --check + coverage: name: Code Coverage runs-on: ${{ matrix.job.os }} From 6ecef3a0e3ada3d98b9d82d24ecea8c80a12d9e4 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 8 Jun 2023 09:07:12 +0200 Subject: [PATCH 456/477] Reformat TOML files with taplo npx --yes @taplo/cli fmt --- Cargo.toml | 620 ++++++++++++------------- Makefile.toml | 162 +++---- deny.toml | 62 +-- docs/book.toml | 2 +- src/uu/arch/Cargo.toml | 6 +- src/uu/base32/Cargo.toml | 4 +- src/uu/base64/Cargo.toml | 4 +- src/uu/basename/Cargo.toml | 4 +- src/uu/basenc/Cargo.toml | 6 +- src/uu/cat/Cargo.toml | 6 +- src/uu/chcon/Cargo.toml | 10 +- src/uu/chgrp/Cargo.toml | 4 +- src/uu/chmod/Cargo.toml | 6 +- src/uu/chown/Cargo.toml | 4 +- src/uu/chroot/Cargo.toml | 4 +- src/uu/cksum/Cargo.toml | 6 +- src/uu/comm/Cargo.toml | 4 +- src/uu/cp/Cargo.toml | 26 +- src/uu/csplit/Cargo.toml | 6 +- src/uu/cut/Cargo.toml | 10 +- src/uu/date/Cargo.toml | 15 +- src/uu/dd/Cargo.toml | 12 +- src/uu/df/Cargo.toml | 6 +- src/uu/dir/Cargo.toml | 6 +- src/uu/dircolors/Cargo.toml | 4 +- src/uu/dirname/Cargo.toml | 4 +- src/uu/du/Cargo.toml | 13 +- src/uu/echo/Cargo.toml | 4 +- src/uu/env/Cargo.toml | 8 +- src/uu/expand/Cargo.toml | 6 +- src/uu/expr/Cargo.toml | 10 +- src/uu/factor/Cargo.toml | 14 +- src/uu/false/Cargo.toml | 4 +- src/uu/fmt/Cargo.toml | 6 +- src/uu/fold/Cargo.toml | 4 +- src/uu/groups/Cargo.toml | 4 +- src/uu/hashsum/Cargo.toml | 10 +- src/uu/head/Cargo.toml | 6 +- src/uu/hostid/Cargo.toml | 6 +- src/uu/hostname/Cargo.toml | 9 +- src/uu/id/Cargo.toml | 6 +- src/uu/install/Cargo.toml | 15 +- src/uu/join/Cargo.toml | 6 +- src/uu/kill/Cargo.toml | 6 +- src/uu/link/Cargo.toml | 4 +- src/uu/ln/Cargo.toml | 4 +- src/uu/logname/Cargo.toml | 6 +- src/uu/ls/Cargo.toml | 24 +- src/uu/mkdir/Cargo.toml | 4 +- src/uu/mkfifo/Cargo.toml | 6 +- src/uu/mknod/Cargo.toml | 6 +- src/uu/mktemp/Cargo.toml | 8 +- src/uu/more/Cargo.toml | 14 +- src/uu/mv/Cargo.toml | 8 +- src/uu/nice/Cargo.toml | 8 +- src/uu/nl/Cargo.toml | 6 +- src/uu/nohup/Cargo.toml | 8 +- src/uu/nproc/Cargo.toml | 6 +- src/uu/numfmt/Cargo.toml | 4 +- src/uu/od/Cargo.toml | 8 +- src/uu/paste/Cargo.toml | 4 +- src/uu/pathchk/Cargo.toml | 6 +- src/uu/pinky/Cargo.toml | 4 +- src/uu/pr/Cargo.toml | 12 +- src/uu/printenv/Cargo.toml | 4 +- src/uu/printf/Cargo.toml | 9 +- src/uu/ptx/Cargo.toml | 6 +- src/uu/pwd/Cargo.toml | 4 +- src/uu/readlink/Cargo.toml | 4 +- src/uu/realpath/Cargo.toml | 4 +- src/uu/relpath/Cargo.toml | 4 +- src/uu/rm/Cargo.toml | 10 +- src/uu/rmdir/Cargo.toml | 6 +- src/uu/runcon/Cargo.toml | 10 +- src/uu/seq/Cargo.toml | 10 +- src/uu/shred/Cargo.toml | 8 +- src/uu/shuf/Cargo.toml | 10 +- src/uu/sleep/Cargo.toml | 6 +- src/uu/sort/Cargo.toml | 26 +- src/uu/split/Cargo.toml | 6 +- src/uu/stat/Cargo.toml | 4 +- src/uu/stdbuf/Cargo.toml | 8 +- src/uu/stdbuf/src/libstdbuf/Cargo.toml | 9 +- src/uu/stty/Cargo.toml | 6 +- src/uu/sum/Cargo.toml | 4 +- src/uu/sync/Cargo.toml | 14 +- src/uu/tac/Cargo.toml | 8 +- src/uu/tail/Cargo.toml | 25 +- src/uu/tee/Cargo.toml | 6 +- src/uu/test/Cargo.toml | 8 +- src/uu/timeout/Cargo.toml | 8 +- src/uu/touch/Cargo.toml | 18 +- src/uu/tr/Cargo.toml | 6 +- src/uu/true/Cargo.toml | 4 +- src/uu/truncate/Cargo.toml | 4 +- src/uu/tsort/Cargo.toml | 4 +- src/uu/tty/Cargo.toml | 8 +- src/uu/uname/Cargo.toml | 6 +- src/uu/unexpand/Cargo.toml | 6 +- src/uu/uniq/Cargo.toml | 4 +- src/uu/unlink/Cargo.toml | 4 +- src/uu/uptime/Cargo.toml | 6 +- src/uu/users/Cargo.toml | 4 +- src/uu/vdir/Cargo.toml | 6 +- src/uu/wc/Cargo.toml | 14 +- src/uu/who/Cargo.toml | 4 +- src/uu/whoami/Cargo.toml | 12 +- src/uu/yes/Cargo.toml | 10 +- src/uucore/Cargo.toml | 66 +-- src/uucore_procs/Cargo.toml | 2 +- 110 files changed, 844 insertions(+), 861 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index aac51b8c6e..179584604f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,11 +22,11 @@ edition = "2021" build = "build.rs" [features] -default = [ "feat_common_core" ] +default = ["feat_common_core"] ## OS feature shortcodes -macos = [ "feat_os_macos" ] -unix = [ "feat_os_unix" ] -windows = [ "feat_os_windows" ] +macos = ["feat_os_macos"] +unix = ["feat_os_unix"] +windows = ["feat_os_windows"] ## project-specific feature shortcodes nightly = [] test_unimplemented = [] @@ -42,225 +42,219 @@ feat_acl = ["cp/feat_acl"] # NOTE: # * The selinux(-sys) crate requires `libselinux` headers and shared library to be accessible in the C toolchain at compile time. # * Running a uutils compiled with `feat_selinux` requires an SELinux enabled Kernel at run time. -feat_selinux = ["cp/selinux", "id/selinux", "ls/selinux", "selinux", "feat_require_selinux"] +feat_selinux = [ + "cp/selinux", + "id/selinux", + "ls/selinux", + "selinux", + "feat_require_selinux", +] ## ## feature sets ## (common/core and Tier1) feature sets # "feat_common_core" == baseline core set of utilities which can be built/run on most targets feat_common_core = [ - "base32", - "base64", - "basename", - "basenc", - "cat", - "cksum", - "comm", - "cp", - "csplit", - "cut", - "date", - "df", - "dir", - "dircolors", - "dirname", - "dd", - "du", - "echo", - "env", - "expand", - "expr", - "factor", - "false", - "fmt", - "fold", - "hashsum", - "head", - "join", - "link", - "ln", - "ls", - "mkdir", - "mktemp", - "more", - "mv", - "nl", - "numfmt", - "od", - "paste", - "pr", - "printenv", - "printf", - "ptx", - "pwd", - "readlink", - "realpath", - "relpath", - "rm", - "rmdir", - "seq", - "shred", - "shuf", - "sleep", - "sort", - "split", - "sum", - "tac", - "tail", - "tee", - "test", - "tr", - "true", - "truncate", - "tsort", - "touch", - "unexpand", - "uniq", - "unlink", - "vdir", - "wc", - "yes", + "base32", + "base64", + "basename", + "basenc", + "cat", + "cksum", + "comm", + "cp", + "csplit", + "cut", + "date", + "df", + "dir", + "dircolors", + "dirname", + "dd", + "du", + "echo", + "env", + "expand", + "expr", + "factor", + "false", + "fmt", + "fold", + "hashsum", + "head", + "join", + "link", + "ln", + "ls", + "mkdir", + "mktemp", + "more", + "mv", + "nl", + "numfmt", + "od", + "paste", + "pr", + "printenv", + "printf", + "ptx", + "pwd", + "readlink", + "realpath", + "relpath", + "rm", + "rmdir", + "seq", + "shred", + "shuf", + "sleep", + "sort", + "split", + "sum", + "tac", + "tail", + "tee", + "test", + "tr", + "true", + "truncate", + "tsort", + "touch", + "unexpand", + "uniq", + "unlink", + "vdir", + "wc", + "yes", ] # "feat_Tier1" == expanded set of utilities which can be built/run on the usual rust "Tier 1" target platforms (ref: ) feat_Tier1 = [ - "feat_common_core", - # - "arch", - "hostname", - "nproc", - "sync", - "touch", - "uname", - "whoami", + "feat_common_core", + # + "arch", + "hostname", + "nproc", + "sync", + "touch", + "uname", + "whoami", ] ## (primary platforms) feature sets # "feat_os_macos" == set of utilities which can be built/run on the MacOS platform feat_os_macos = [ - "feat_os_unix", ## == a modern/usual *nix platform - # - "feat_require_unix_hostid", + "feat_os_unix", ## == a modern/usual *nix platform + # + "feat_require_unix_hostid", ] # "feat_os_unix" == set of utilities which can be built/run on modern/usual *nix platforms feat_os_unix = [ - "feat_Tier1", - # - "feat_require_crate_cpp", - "feat_require_unix", - "feat_require_unix_utmpx", + "feat_Tier1", + # + "feat_require_crate_cpp", + "feat_require_unix", + "feat_require_unix_utmpx", ] # "feat_os_windows" == set of utilities which can be built/run on modern/usual windows platforms feat_os_windows = [ - "feat_Tier1", ## == "feat_os_windows_legacy" + "hostname" + "feat_Tier1", ## == "feat_os_windows_legacy" + "hostname" ] ## (secondary platforms) feature sets # "feat_os_unix_gnueabihf" == set of utilities which can be built/run on the "arm-unknown-linux-gnueabihf" target (ARMv6 Linux [hardfloat]) feat_os_unix_gnueabihf = [ - "feat_Tier1", - # - "feat_require_unix", - "feat_require_unix_hostid", - "feat_require_unix_utmpx", + "feat_Tier1", + # + "feat_require_unix", + "feat_require_unix_hostid", + "feat_require_unix_utmpx", ] # "feat_os_unix_musl" == set of utilities which can be built/run on targets binding to the "musl" library (ref: ) feat_os_unix_musl = [ - "feat_Tier1", - # - "feat_require_unix", - "feat_require_unix_hostid", + "feat_Tier1", + # + "feat_require_unix", + "feat_require_unix_hostid", ] feat_os_unix_android = [ - "feat_Tier1", - # - "feat_require_unix", + "feat_Tier1", + # + "feat_require_unix", ] ## feature sets with requirements (restricting cross-platform availability) # # ** NOTE: these `feat_require_...` sets should be minimized as much as possible to encourage cross-platform availability of utilities # # "feat_require_crate_cpp" == set of utilities requiring the `cpp` crate (which fail to compile on several platforms; as of 2020-04-23) -feat_require_crate_cpp = [ - "stdbuf", -] +feat_require_crate_cpp = ["stdbuf"] # "feat_require_unix" == set of utilities requiring support which is only available on unix platforms (as of 2020-04-23) feat_require_unix = [ - "chgrp", - "chmod", - "chown", - "chroot", - "groups", - "id", - "install", - "kill", - "logname", - "mkfifo", - "mknod", - "nice", - "nohup", - "pathchk", - "stat", - "stty", - "timeout", - "tty", + "chgrp", + "chmod", + "chown", + "chroot", + "groups", + "id", + "install", + "kill", + "logname", + "mkfifo", + "mknod", + "nice", + "nohup", + "pathchk", + "stat", + "stty", + "timeout", + "tty", ] # "feat_require_unix_utmpx" == set of utilities requiring unix utmp/utmpx support # * ref: -feat_require_unix_utmpx = [ - "pinky", - "uptime", - "users", - "who", -] +feat_require_unix_utmpx = ["pinky", "uptime", "users", "who"] # "feat_require_unix_hostid" == set of utilities requiring gethostid in libc (only some unixes provide) -feat_require_unix_hostid = [ - "hostid", -] +feat_require_unix_hostid = ["hostid"] # "feat_require_selinux" == set of utilities depending on SELinux. -feat_require_selinux = [ - "chcon", - "runcon", -] +feat_require_selinux = ["chcon", "runcon"] ## (alternate/newer/smaller platforms) feature sets # "feat_os_unix_fuchsia" == set of utilities which can be built/run on the "Fuchsia" OS (refs: ; ) feat_os_unix_fuchsia = [ - "feat_common_core", - # - "feat_require_crate_cpp", - # - "chgrp", - "chmod", - "chown", - "du", - "groups", - "hostid", - "install", - "logname", - "mkfifo", - "mknod", - "nice", - "pathchk", - "tty", - "uname", - "unlink", + "feat_common_core", + # + "feat_require_crate_cpp", + # + "chgrp", + "chmod", + "chown", + "du", + "groups", + "hostid", + "install", + "logname", + "mkfifo", + "mknod", + "nice", + "pathchk", + "tty", + "uname", + "unlink", ] # "feat_os_unix_redox" == set of utilities which can be built/run on "Redox OS" (refs: ; ) feat_os_unix_redox = [ - "feat_common_core", - # - "chmod", - "uname", + "feat_common_core", + # + "chmod", + "uname", ] # "feat_os_windows_legacy" == slightly restricted set of utilities which can be built/run on early windows platforms (eg, "WinXP") feat_os_windows_legacy = [ - "feat_common_core", - # - "arch", - "nproc", - "sync", - "touch", - "whoami", + "feat_common_core", + # + "arch", + "nproc", + "sync", + "touch", + "whoami", ] ## # * bypass/override ~ translate 'test' feature name to avoid dependency collision with rust core 'test' crate (o/w surfaces as compiler errors during testing) -test = [ "uu_test" ] +test = ["uu_test"] [workspace.dependencies] bigdecimal = "0.3" @@ -268,7 +262,11 @@ binary-heap-plus = "0.5.0" bstr = "1.5" bytecount = "0.6.3" byteorder = "1.4.3" -chrono = { version="^0.4.26", default-features=false, features=["std", "alloc", "clock"]} +chrono = { version = "^0.4.26", default-features = false, features = [ + "std", + "alloc", + "clock", +] } clap = { version = "4.3", features = ["wrap_help", "cargo"] } clap_complete = "4.3" clap_mangen = "0.2" @@ -291,11 +289,13 @@ indicatif = "0.17" is-terminal = "0.4.7" itertools = "0.10.5" libc = "0.2.146" -lscolors = { version = "0.14.0", default-features=false, features = ["nu-ansi-term"] } +lscolors = { version = "0.14.0", default-features = false, features = [ + "nu-ansi-term", +] } memchr = "2" -nix = { version="0.26", default-features=false } +nix = { version = "0.26", default-features = false } nom = "7.1.3" -notify = { version = "=6.0.0", features=["macos_kqueue"]} +notify = { version = "=6.0.0", features = ["macos_kqueue"] } num-bigint = "0.4.3" num-traits = "0.2.15" number_prefix = "0.4" @@ -320,17 +320,17 @@ smallvec = { version = "1.10", features = ["union"] } tempfile = "3.6.0" term_grid = "0.1.5" terminal_size = "0.2.6" -textwrap = { version="0.16.0", features=["terminal_size"] } +textwrap = { version = "0.16.0", features = ["terminal_size"] } thiserror = "1.0" -time = { version="0.3" } +time = { version = "0.3" } unicode-segmentation = "1.10.1" unicode-width = "0.1.10" utf-8 = "0.7.6" walkdir = "2.3" winapi-util = "0.1.5" -windows-sys = { version="0.48.0", default-features=false } +windows-sys = { version = "0.48.0", default-features = false } xattr = "1.0.0" -zip = { version = "0.6.6", default_features=false, features=["deflate"] } +zip = { version = "0.6.6", default_features = false, features = ["deflate"] } hex = "0.4.3" md-5 = "0.10.5" @@ -342,129 +342,129 @@ blake3 = "1.3.3" sm3 = "0.4.2" digest = "0.10.7" -uucore = { version=">=0.0.19", package="uucore", path="src/uucore" } -uucore_procs = { version=">=0.0.19", package="uucore_procs", path="src/uucore_procs" } -uu_ls = { version=">=0.0.18", path="src/uu/ls" } -uu_base32 = { version=">=0.0.18", path="src/uu/base32"} +uucore = { version = ">=0.0.19", package = "uucore", path = "src/uucore" } +uucore_procs = { version = ">=0.0.19", package = "uucore_procs", path = "src/uucore_procs" } +uu_ls = { version = ">=0.0.18", path = "src/uu/ls" } +uu_base32 = { version = ">=0.0.18", path = "src/uu/base32" } [dependencies] -clap = { workspace=true } -once_cell = { workspace=true } -uucore = { workspace=true } -clap_complete = { workspace=true } -clap_mangen = { workspace=true } -phf = { workspace=true } -selinux = { workspace=true, optional = true } -textwrap = { workspace=true } -zip = { workspace=true, optional = true } +clap = { workspace = true } +once_cell = { workspace = true } +uucore = { workspace = true } +clap_complete = { workspace = true } +clap_mangen = { workspace = true } +phf = { workspace = true } +selinux = { workspace = true, optional = true } +textwrap = { workspace = true } +zip = { workspace = true, optional = true } -uuhelp_parser = { optional=true, version=">=0.0.19", path="src/uuhelp_parser"} +uuhelp_parser = { optional = true, version = ">=0.0.19", path = "src/uuhelp_parser" } # * uutils -uu_test = { optional=true, version="0.0.19", package="uu_test", path="src/uu/test" } +uu_test = { optional = true, version = "0.0.19", package = "uu_test", path = "src/uu/test" } # -arch = { optional=true, version="0.0.19", package="uu_arch", path="src/uu/arch" } -base32 = { optional=true, version="0.0.19", package="uu_base32", path="src/uu/base32" } -base64 = { optional=true, version="0.0.19", package="uu_base64", path="src/uu/base64" } -basename = { optional=true, version="0.0.19", package="uu_basename", path="src/uu/basename" } -basenc = { optional=true, version="0.0.19", package="uu_basenc", path="src/uu/basenc" } -cat = { optional=true, version="0.0.19", package="uu_cat", path="src/uu/cat" } -chcon = { optional=true, version="0.0.19", package="uu_chcon", path="src/uu/chcon" } -chgrp = { optional=true, version="0.0.19", package="uu_chgrp", path="src/uu/chgrp" } -chmod = { optional=true, version="0.0.19", package="uu_chmod", path="src/uu/chmod" } -chown = { optional=true, version="0.0.19", package="uu_chown", path="src/uu/chown" } -chroot = { optional=true, version="0.0.19", package="uu_chroot", path="src/uu/chroot" } -cksum = { optional=true, version="0.0.19", package="uu_cksum", path="src/uu/cksum" } -comm = { optional=true, version="0.0.19", package="uu_comm", path="src/uu/comm" } -cp = { optional=true, version="0.0.19", package="uu_cp", path="src/uu/cp" } -csplit = { optional=true, version="0.0.19", package="uu_csplit", path="src/uu/csplit" } -cut = { optional=true, version="0.0.19", package="uu_cut", path="src/uu/cut" } -date = { optional=true, version="0.0.19", package="uu_date", path="src/uu/date" } -dd = { optional=true, version="0.0.19", package="uu_dd", path="src/uu/dd" } -df = { optional=true, version="0.0.19", package="uu_df", path="src/uu/df" } -dir = { optional=true, version="0.0.19", package="uu_dir", path="src/uu/dir" } -dircolors= { optional=true, version="0.0.19", package="uu_dircolors", path="src/uu/dircolors" } -dirname = { optional=true, version="0.0.19", package="uu_dirname", path="src/uu/dirname" } -du = { optional=true, version="0.0.19", package="uu_du", path="src/uu/du" } -echo = { optional=true, version="0.0.19", package="uu_echo", path="src/uu/echo" } -env = { optional=true, version="0.0.19", package="uu_env", path="src/uu/env" } -expand = { optional=true, version="0.0.19", package="uu_expand", path="src/uu/expand" } -expr = { optional=true, version="0.0.19", package="uu_expr", path="src/uu/expr" } -factor = { optional=true, version="0.0.19", package="uu_factor", path="src/uu/factor" } -false = { optional=true, version="0.0.19", package="uu_false", path="src/uu/false" } -fmt = { optional=true, version="0.0.19", package="uu_fmt", path="src/uu/fmt" } -fold = { optional=true, version="0.0.19", package="uu_fold", path="src/uu/fold" } -groups = { optional=true, version="0.0.19", package="uu_groups", path="src/uu/groups" } -hashsum = { optional=true, version="0.0.19", package="uu_hashsum", path="src/uu/hashsum" } -head = { optional=true, version="0.0.19", package="uu_head", path="src/uu/head" } -hostid = { optional=true, version="0.0.19", package="uu_hostid", path="src/uu/hostid" } -hostname = { optional=true, version="0.0.19", package="uu_hostname", path="src/uu/hostname" } -id = { optional=true, version="0.0.19", package="uu_id", path="src/uu/id" } -install = { optional=true, version="0.0.19", package="uu_install", path="src/uu/install" } -join = { optional=true, version="0.0.19", package="uu_join", path="src/uu/join" } -kill = { optional=true, version="0.0.19", package="uu_kill", path="src/uu/kill" } -link = { optional=true, version="0.0.19", package="uu_link", path="src/uu/link" } -ln = { optional=true, version="0.0.19", package="uu_ln", path="src/uu/ln" } -ls = { optional=true, version="0.0.19", package="uu_ls", path="src/uu/ls" } -logname = { optional=true, version="0.0.19", package="uu_logname", path="src/uu/logname" } -mkdir = { optional=true, version="0.0.19", package="uu_mkdir", path="src/uu/mkdir" } -mkfifo = { optional=true, version="0.0.19", package="uu_mkfifo", path="src/uu/mkfifo" } -mknod = { optional=true, version="0.0.19", package="uu_mknod", path="src/uu/mknod" } -mktemp = { optional=true, version="0.0.19", package="uu_mktemp", path="src/uu/mktemp" } -more = { optional=true, version="0.0.19", package="uu_more", path="src/uu/more" } -mv = { optional=true, version="0.0.19", package="uu_mv", path="src/uu/mv" } -nice = { optional=true, version="0.0.19", package="uu_nice", path="src/uu/nice" } -nl = { optional=true, version="0.0.19", package="uu_nl", path="src/uu/nl" } -nohup = { optional=true, version="0.0.19", package="uu_nohup", path="src/uu/nohup" } -nproc = { optional=true, version="0.0.19", package="uu_nproc", path="src/uu/nproc" } -numfmt = { optional=true, version="0.0.19", package="uu_numfmt", path="src/uu/numfmt" } -od = { optional=true, version="0.0.19", package="uu_od", path="src/uu/od" } -paste = { optional=true, version="0.0.19", package="uu_paste", path="src/uu/paste" } -pathchk = { optional=true, version="0.0.19", package="uu_pathchk", path="src/uu/pathchk" } -pinky = { optional=true, version="0.0.19", package="uu_pinky", path="src/uu/pinky" } -pr = { optional=true, version="0.0.19", package="uu_pr", path="src/uu/pr" } -printenv = { optional=true, version="0.0.19", package="uu_printenv", path="src/uu/printenv" } -printf = { optional=true, version="0.0.19", package="uu_printf", path="src/uu/printf" } -ptx = { optional=true, version="0.0.19", package="uu_ptx", path="src/uu/ptx" } -pwd = { optional=true, version="0.0.19", package="uu_pwd", path="src/uu/pwd" } -readlink = { optional=true, version="0.0.19", package="uu_readlink", path="src/uu/readlink" } -realpath = { optional=true, version="0.0.19", package="uu_realpath", path="src/uu/realpath" } -relpath = { optional=true, version="0.0.19", package="uu_relpath", path="src/uu/relpath" } -rm = { optional=true, version="0.0.19", package="uu_rm", path="src/uu/rm" } -rmdir = { optional=true, version="0.0.19", package="uu_rmdir", path="src/uu/rmdir" } -runcon = { optional=true, version="0.0.19", package="uu_runcon", path="src/uu/runcon" } -seq = { optional=true, version="0.0.19", package="uu_seq", path="src/uu/seq" } -shred = { optional=true, version="0.0.19", package="uu_shred", path="src/uu/shred" } -shuf = { optional=true, version="0.0.19", package="uu_shuf", path="src/uu/shuf" } -sleep = { optional=true, version="0.0.19", package="uu_sleep", path="src/uu/sleep" } -sort = { optional=true, version="0.0.19", package="uu_sort", path="src/uu/sort" } -split = { optional=true, version="0.0.19", package="uu_split", path="src/uu/split" } -stat = { optional=true, version="0.0.19", package="uu_stat", path="src/uu/stat" } -stdbuf = { optional=true, version="0.0.19", package="uu_stdbuf", path="src/uu/stdbuf" } -stty = { optional=true, version="0.0.19", package="uu_stty", path="src/uu/stty" } -sum = { optional=true, version="0.0.19", package="uu_sum", path="src/uu/sum" } -sync = { optional=true, version="0.0.19", package="uu_sync", path="src/uu/sync" } -tac = { optional=true, version="0.0.19", package="uu_tac", path="src/uu/tac" } -tail = { optional=true, version="0.0.19", package="uu_tail", path="src/uu/tail" } -tee = { optional=true, version="0.0.19", package="uu_tee", path="src/uu/tee" } -timeout = { optional=true, version="0.0.19", package="uu_timeout", path="src/uu/timeout" } -touch = { optional=true, version="0.0.19", package="uu_touch", path="src/uu/touch" } -tr = { optional=true, version="0.0.19", package="uu_tr", path="src/uu/tr" } -true = { optional=true, version="0.0.19", package="uu_true", path="src/uu/true" } -truncate = { optional=true, version="0.0.19", package="uu_truncate", path="src/uu/truncate" } -tsort = { optional=true, version="0.0.19", package="uu_tsort", path="src/uu/tsort" } -tty = { optional=true, version="0.0.19", package="uu_tty", path="src/uu/tty" } -uname = { optional=true, version="0.0.19", package="uu_uname", path="src/uu/uname" } -unexpand = { optional=true, version="0.0.19", package="uu_unexpand", path="src/uu/unexpand" } -uniq = { optional=true, version="0.0.19", package="uu_uniq", path="src/uu/uniq" } -unlink = { optional=true, version="0.0.19", package="uu_unlink", path="src/uu/unlink" } -uptime = { optional=true, version="0.0.19", package="uu_uptime", path="src/uu/uptime" } -users = { optional=true, version="0.0.19", package="uu_users", path="src/uu/users" } -vdir = { optional=true, version="0.0.19", package="uu_vdir", path="src/uu/vdir" } -wc = { optional=true, version="0.0.19", package="uu_wc", path="src/uu/wc" } -who = { optional=true, version="0.0.19", package="uu_who", path="src/uu/who" } -whoami = { optional=true, version="0.0.19", package="uu_whoami", path="src/uu/whoami" } -yes = { optional=true, version="0.0.19", package="uu_yes", path="src/uu/yes" } +arch = { optional = true, version = "0.0.19", package = "uu_arch", path = "src/uu/arch" } +base32 = { optional = true, version = "0.0.19", package = "uu_base32", path = "src/uu/base32" } +base64 = { optional = true, version = "0.0.19", package = "uu_base64", path = "src/uu/base64" } +basename = { optional = true, version = "0.0.19", package = "uu_basename", path = "src/uu/basename" } +basenc = { optional = true, version = "0.0.19", package = "uu_basenc", path = "src/uu/basenc" } +cat = { optional = true, version = "0.0.19", package = "uu_cat", path = "src/uu/cat" } +chcon = { optional = true, version = "0.0.19", package = "uu_chcon", path = "src/uu/chcon" } +chgrp = { optional = true, version = "0.0.19", package = "uu_chgrp", path = "src/uu/chgrp" } +chmod = { optional = true, version = "0.0.19", package = "uu_chmod", path = "src/uu/chmod" } +chown = { optional = true, version = "0.0.19", package = "uu_chown", path = "src/uu/chown" } +chroot = { optional = true, version = "0.0.19", package = "uu_chroot", path = "src/uu/chroot" } +cksum = { optional = true, version = "0.0.19", package = "uu_cksum", path = "src/uu/cksum" } +comm = { optional = true, version = "0.0.19", package = "uu_comm", path = "src/uu/comm" } +cp = { optional = true, version = "0.0.19", package = "uu_cp", path = "src/uu/cp" } +csplit = { optional = true, version = "0.0.19", package = "uu_csplit", path = "src/uu/csplit" } +cut = { optional = true, version = "0.0.19", package = "uu_cut", path = "src/uu/cut" } +date = { optional = true, version = "0.0.19", package = "uu_date", path = "src/uu/date" } +dd = { optional = true, version = "0.0.19", package = "uu_dd", path = "src/uu/dd" } +df = { optional = true, version = "0.0.19", package = "uu_df", path = "src/uu/df" } +dir = { optional = true, version = "0.0.19", package = "uu_dir", path = "src/uu/dir" } +dircolors = { optional = true, version = "0.0.19", package = "uu_dircolors", path = "src/uu/dircolors" } +dirname = { optional = true, version = "0.0.19", package = "uu_dirname", path = "src/uu/dirname" } +du = { optional = true, version = "0.0.19", package = "uu_du", path = "src/uu/du" } +echo = { optional = true, version = "0.0.19", package = "uu_echo", path = "src/uu/echo" } +env = { optional = true, version = "0.0.19", package = "uu_env", path = "src/uu/env" } +expand = { optional = true, version = "0.0.19", package = "uu_expand", path = "src/uu/expand" } +expr = { optional = true, version = "0.0.19", package = "uu_expr", path = "src/uu/expr" } +factor = { optional = true, version = "0.0.19", package = "uu_factor", path = "src/uu/factor" } +false = { optional = true, version = "0.0.19", package = "uu_false", path = "src/uu/false" } +fmt = { optional = true, version = "0.0.19", package = "uu_fmt", path = "src/uu/fmt" } +fold = { optional = true, version = "0.0.19", package = "uu_fold", path = "src/uu/fold" } +groups = { optional = true, version = "0.0.19", package = "uu_groups", path = "src/uu/groups" } +hashsum = { optional = true, version = "0.0.19", package = "uu_hashsum", path = "src/uu/hashsum" } +head = { optional = true, version = "0.0.19", package = "uu_head", path = "src/uu/head" } +hostid = { optional = true, version = "0.0.19", package = "uu_hostid", path = "src/uu/hostid" } +hostname = { optional = true, version = "0.0.19", package = "uu_hostname", path = "src/uu/hostname" } +id = { optional = true, version = "0.0.19", package = "uu_id", path = "src/uu/id" } +install = { optional = true, version = "0.0.19", package = "uu_install", path = "src/uu/install" } +join = { optional = true, version = "0.0.19", package = "uu_join", path = "src/uu/join" } +kill = { optional = true, version = "0.0.19", package = "uu_kill", path = "src/uu/kill" } +link = { optional = true, version = "0.0.19", package = "uu_link", path = "src/uu/link" } +ln = { optional = true, version = "0.0.19", package = "uu_ln", path = "src/uu/ln" } +ls = { optional = true, version = "0.0.19", package = "uu_ls", path = "src/uu/ls" } +logname = { optional = true, version = "0.0.19", package = "uu_logname", path = "src/uu/logname" } +mkdir = { optional = true, version = "0.0.19", package = "uu_mkdir", path = "src/uu/mkdir" } +mkfifo = { optional = true, version = "0.0.19", package = "uu_mkfifo", path = "src/uu/mkfifo" } +mknod = { optional = true, version = "0.0.19", package = "uu_mknod", path = "src/uu/mknod" } +mktemp = { optional = true, version = "0.0.19", package = "uu_mktemp", path = "src/uu/mktemp" } +more = { optional = true, version = "0.0.19", package = "uu_more", path = "src/uu/more" } +mv = { optional = true, version = "0.0.19", package = "uu_mv", path = "src/uu/mv" } +nice = { optional = true, version = "0.0.19", package = "uu_nice", path = "src/uu/nice" } +nl = { optional = true, version = "0.0.19", package = "uu_nl", path = "src/uu/nl" } +nohup = { optional = true, version = "0.0.19", package = "uu_nohup", path = "src/uu/nohup" } +nproc = { optional = true, version = "0.0.19", package = "uu_nproc", path = "src/uu/nproc" } +numfmt = { optional = true, version = "0.0.19", package = "uu_numfmt", path = "src/uu/numfmt" } +od = { optional = true, version = "0.0.19", package = "uu_od", path = "src/uu/od" } +paste = { optional = true, version = "0.0.19", package = "uu_paste", path = "src/uu/paste" } +pathchk = { optional = true, version = "0.0.19", package = "uu_pathchk", path = "src/uu/pathchk" } +pinky = { optional = true, version = "0.0.19", package = "uu_pinky", path = "src/uu/pinky" } +pr = { optional = true, version = "0.0.19", package = "uu_pr", path = "src/uu/pr" } +printenv = { optional = true, version = "0.0.19", package = "uu_printenv", path = "src/uu/printenv" } +printf = { optional = true, version = "0.0.19", package = "uu_printf", path = "src/uu/printf" } +ptx = { optional = true, version = "0.0.19", package = "uu_ptx", path = "src/uu/ptx" } +pwd = { optional = true, version = "0.0.19", package = "uu_pwd", path = "src/uu/pwd" } +readlink = { optional = true, version = "0.0.19", package = "uu_readlink", path = "src/uu/readlink" } +realpath = { optional = true, version = "0.0.19", package = "uu_realpath", path = "src/uu/realpath" } +relpath = { optional = true, version = "0.0.19", package = "uu_relpath", path = "src/uu/relpath" } +rm = { optional = true, version = "0.0.19", package = "uu_rm", path = "src/uu/rm" } +rmdir = { optional = true, version = "0.0.19", package = "uu_rmdir", path = "src/uu/rmdir" } +runcon = { optional = true, version = "0.0.19", package = "uu_runcon", path = "src/uu/runcon" } +seq = { optional = true, version = "0.0.19", package = "uu_seq", path = "src/uu/seq" } +shred = { optional = true, version = "0.0.19", package = "uu_shred", path = "src/uu/shred" } +shuf = { optional = true, version = "0.0.19", package = "uu_shuf", path = "src/uu/shuf" } +sleep = { optional = true, version = "0.0.19", package = "uu_sleep", path = "src/uu/sleep" } +sort = { optional = true, version = "0.0.19", package = "uu_sort", path = "src/uu/sort" } +split = { optional = true, version = "0.0.19", package = "uu_split", path = "src/uu/split" } +stat = { optional = true, version = "0.0.19", package = "uu_stat", path = "src/uu/stat" } +stdbuf = { optional = true, version = "0.0.19", package = "uu_stdbuf", path = "src/uu/stdbuf" } +stty = { optional = true, version = "0.0.19", package = "uu_stty", path = "src/uu/stty" } +sum = { optional = true, version = "0.0.19", package = "uu_sum", path = "src/uu/sum" } +sync = { optional = true, version = "0.0.19", package = "uu_sync", path = "src/uu/sync" } +tac = { optional = true, version = "0.0.19", package = "uu_tac", path = "src/uu/tac" } +tail = { optional = true, version = "0.0.19", package = "uu_tail", path = "src/uu/tail" } +tee = { optional = true, version = "0.0.19", package = "uu_tee", path = "src/uu/tee" } +timeout = { optional = true, version = "0.0.19", package = "uu_timeout", path = "src/uu/timeout" } +touch = { optional = true, version = "0.0.19", package = "uu_touch", path = "src/uu/touch" } +tr = { optional = true, version = "0.0.19", package = "uu_tr", path = "src/uu/tr" } +true = { optional = true, version = "0.0.19", package = "uu_true", path = "src/uu/true" } +truncate = { optional = true, version = "0.0.19", package = "uu_truncate", path = "src/uu/truncate" } +tsort = { optional = true, version = "0.0.19", package = "uu_tsort", path = "src/uu/tsort" } +tty = { optional = true, version = "0.0.19", package = "uu_tty", path = "src/uu/tty" } +uname = { optional = true, version = "0.0.19", package = "uu_uname", path = "src/uu/uname" } +unexpand = { optional = true, version = "0.0.19", package = "uu_unexpand", path = "src/uu/unexpand" } +uniq = { optional = true, version = "0.0.19", package = "uu_uniq", path = "src/uu/uniq" } +unlink = { optional = true, version = "0.0.19", package = "uu_unlink", path = "src/uu/unlink" } +uptime = { optional = true, version = "0.0.19", package = "uu_uptime", path = "src/uu/uptime" } +users = { optional = true, version = "0.0.19", package = "uu_users", path = "src/uu/users" } +vdir = { optional = true, version = "0.0.19", package = "uu_vdir", path = "src/uu/vdir" } +wc = { optional = true, version = "0.0.19", package = "uu_wc", path = "src/uu/wc" } +who = { optional = true, version = "0.0.19", package = "uu_who", path = "src/uu/who" } +whoami = { optional = true, version = "0.0.19", package = "uu_whoami", path = "src/uu/whoami" } +yes = { optional = true, version = "0.0.19", package = "uu_yes", path = "src/uu/yes" } # this breaks clippy linting with: "tests/by-util/test_factor_benches.rs: No such file or directory (os error 2)" # factor_benches = { optional = true, version = "0.0.0", package = "uu_factor_benches", path = "tests/benches/factor" } @@ -475,21 +475,21 @@ yes = { optional=true, version="0.0.19", package="uu_yes", path="src/uu/yes #pin_cc = { version="1.0.61, < 1.0.62", package="cc" } ## cc v1.0.62 has compiler errors for MinRustV v1.32.0, requires 1.34 (for `std::str::split_ascii_whitespace()`) [dev-dependencies] -chrono = { workspace=true } +chrono = { workspace = true } conv = "0.3" -filetime = { workspace=true } -glob = { workspace=true } -libc = { workspace=true } +filetime = { workspace = true } +glob = { workspace = true } +libc = { workspace = true } pretty_assertions = "1" -rand = { workspace=true } -regex = { workspace=true } -sha1 = { version="0.10", features=["std"] } -tempfile = { workspace=true } -time = { workspace=true, features=["local-offset"] } +rand = { workspace = true } +regex = { workspace = true } +sha1 = { version = "0.10", features = ["std"] } +tempfile = { workspace = true } +time = { workspace = true, features = ["local-offset"] } unindent = "0.2" -uucore = { workspace=true, features=["entries", "process", "signals"] } -walkdir = { workspace=true } -is-terminal = { workspace=true } +uucore = { workspace = true, features = ["entries", "process", "signals"] } +walkdir = { workspace = true } +is-terminal = { workspace = true } hex-literal = "0.4.1" rstest = "0.17.0" @@ -498,11 +498,11 @@ procfs = { version = "0.15", default-features = false } rlimit = "0.9.1" [target.'cfg(unix)'.dev-dependencies] -nix = { workspace=true, features=["process", "signal", "user"] } +nix = { workspace = true, features = ["process", "signal", "user"] } rand_pcg = "0.3" [build-dependencies] -phf_codegen = { workspace=true } +phf_codegen = { workspace = true } [[bin]] name = "coreutils" diff --git a/Makefile.toml b/Makefile.toml index ded2cd55b8..84698df5f9 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -20,15 +20,12 @@ run_task = "_init" [tasks._init] private = true -dependencies = [ - "_init-vars", -] +dependencies = ["_init-vars"] [tasks._init-vars] private = true script_runner = "@duckscript" -script = [ -''' +script = [''' # reset build/test flags set_env CARGO_MAKE_CARGO_BUILD_TEST_FLAGS "" # determine features @@ -90,54 +87,36 @@ for arg in "${args_utils_list}" end args_utils = trim "${args_utils}" set_env CARGO_MAKE_TASK_BUILD_UTILS_ARGS "${args_utils}" -''' -] +'''] ### tasks [tasks.default] description = "## *DEFAULT* Build (debug-mode) and test project" category = "[project]" -dependencies = [ - "action-build-debug", - "test-terse", -] +dependencies = ["action-build-debug", "test-terse"] ## [tasks.build] description = "## Build (release-mode) project" category = "[project]" -dependencies = [ - "core::pre-build", - "action-build-release", - "core::post-build", -] +dependencies = ["core::pre-build", "action-build-release", "core::post-build"] [tasks.build-debug] description = "## Build (debug-mode) project" category = "[project]" -dependencies = [ - "action-build-debug", -] +dependencies = ["action-build-debug"] [tasks.build-examples] description = "## Build (release-mode) project example(s); usage: `cargo make (build-examples | examples) [EXAMPLE]...`" category = "[project]" -dependencies = [ - "core::pre-build", - "action-build-examples", - "core::post-build", -] +dependencies = ["core::pre-build", "action-build-examples", "core::post-build"] [tasks.build-features] description = "## Build (with features; release-mode) project; usage: `cargo make (build-features | features) FEATURE...`" category = "[project]" -dependencies = [ - "core::pre-build", - "action-build-features", - "core::post-build", -] +dependencies = ["core::pre-build", "action-build-features", "core::post-build"] [tasks.build-release] alias = "build" @@ -148,9 +127,7 @@ alias = "build-debug" [tasks.example] description = "hidden singular-form alias for 'examples'" category = "[project]" -dependencies = [ - "examples", -] +dependencies = ["examples"] [tasks.examples] alias = "build-examples" @@ -161,17 +138,12 @@ alias = "build-features" [tasks.format] description = "## Format code files (with `cargo fmt`; includes tests)" category = "[project]" -dependencies = [ - "action-format", - "action-format-tests", -] +dependencies = ["action-format", "action-format-tests"] [tasks.help] description = "## Display help" category = "[project]" -dependencies = [ - "action-display-help", -] +dependencies = ["action-display-help"] [tasks.install] description = "## Install project binary (to $HOME/.cargo/bin)" @@ -182,10 +154,7 @@ args = ["install", "--path", "."] [tasks.lint] description = "## Display lint report" category = "[project]" -dependencies = [ - "action-clippy", - "action-fmt_report", -] +dependencies = ["action-clippy", "action-fmt_report"] [tasks.release] alias = "build" @@ -193,48 +162,32 @@ alias = "build" [tasks.test] description = "## Run project tests" category = "[project]" -dependencies = [ - "core::pre-test", - "core::test", - "core::post-test", -] +dependencies = ["core::pre-test", "core::test", "core::post-test"] [tasks.test-terse] description = "## Run project tests (with terse/summary output)" category = "[project]" -dependencies = [ - "core::pre-test", - "action-test_quiet", - "core::post-test", -] +dependencies = ["core::pre-test", "action-test_quiet", "core::post-test"] [tasks.test-util] description = "## Test (individual) utilities; usage: `cargo make (test-util | test-uutil) [UTIL_NAME...]`" category = "[project]" -dependencies = [ - "action-test-utils", -] +dependencies = ["action-test-utils"] [tasks.test-utils] description = "hidden plural-form alias for 'test-util'" category = "[project]" -dependencies = [ - "test-util", -] +dependencies = ["test-util"] [tasks.test-uutil] description = "hidden alias for 'test-util'" category = "[project]" -dependencies = [ - "test-util", -] +dependencies = ["test-util"] [tasks.test-uutils] description = "hidden alias for 'test-util'" category = "[project]" -dependencies = [ - "test-util", -] +dependencies = ["test-util"] [tasks.uninstall] description = "## Remove project binary (from $HOME/.cargo/bin)" @@ -246,63 +199,66 @@ args = ["uninstall"] description = "## Build (individual; release-mode) utilities; usage: `cargo make (util | uutil) [UTIL_NAME...]`" category = "[project]" dependencies = [ - "core::pre-build", - "action-determine-utils", - "action-build-utils", - "core::post-build", + "core::pre-build", + "action-determine-utils", + "action-build-utils", + "core::post-build", ] [tasks.utils] description = "hidden plural-form alias for 'util'" category = "[project]" -dependencies = [ - "util", -] +dependencies = ["util"] [tasks.uutil] description = "hidden alias for 'util'" category = "[project]" -dependencies = [ - "util", -] +dependencies = ["util"] [tasks.uutils] description = "hidden plural-form alias for 'util'" category = "[project]" -dependencies = [ - "util", -] +dependencies = ["util"] ### actions [tasks.action-build-release] description = "`cargo build --release`" command = "cargo" -args = ["build", "--release", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )" ] +args = ["build", "--release", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )"] [tasks.action-build-debug] description = "`cargo build`" command = "cargo" -args = ["build", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )" ] +args = ["build", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )"] [tasks.action-build-examples] description = "`cargo build (--examples|(--example EXAMPLE)...)`" command = "cargo" -args = ["build", "--release", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )", "${CARGO_MAKE_TASK_BUILD_EXAMPLES_ARGS}" ] +args = [ + "build", + "--release", + "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )", + "${CARGO_MAKE_TASK_BUILD_EXAMPLES_ARGS}", +] [tasks.action-build-features] description = "`cargo build --release --features FEATURES`" command = "cargo" -args = ["build", "--release", "--no-default-features", "--features", "${CARGO_MAKE_TASK_BUILD_FEATURES_ARGS}" ] +args = [ + "build", + "--release", + "--no-default-features", + "--features", + "${CARGO_MAKE_TASK_BUILD_FEATURES_ARGS}", +] [tasks.action-build-utils] description = "Build individual utilities" -dependencies = [ - "action-determine-utils", -] +dependencies = ["action-determine-utils"] command = "cargo" # args = ["build", "@@remove-empty(CARGO_MAKE_TASK_BUILD_UTILS_ARGS)" ] -args = ["build", "--release", "@@split(CARGO_MAKE_TASK_BUILD_UTILS_ARGS, )" ] +args = ["build", "--release", "@@split(CARGO_MAKE_TASK_BUILD_UTILS_ARGS, )"] [tasks.action-clippy] description = "`cargo clippy` lint report" @@ -311,8 +267,7 @@ args = ["clippy", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )"] [tasks.action-determine-utils] script_runner = "@duckscript" -script = [ -''' +script = [''' package_options = get_env CARGO_MAKE_TASK_BUILD_UTILS_ARGS if is_empty "${package_options}" show_utils = get_env CARGO_MAKE_VAR_SHOW_UTILS @@ -335,13 +290,11 @@ if is_empty "${package_options}" package_options = trim "${package_options}" end_if set_env CARGO_MAKE_TASK_BUILD_UTILS_ARGS "${package_options}" -''' -] +'''] [tasks.action-determine-tests] script_runner = "@duckscript" -script = [ -''' +script = [''' test_files = glob_array tests/**/*.rs for file in ${test_files} file = replace "${file}" "\\" "/" @@ -354,8 +307,7 @@ for file in ${test_files} end_if end set_env CARGO_MAKE_VAR_TESTS "${tests}" -''' -] +'''] [tasks.action-format] description = "`cargo fmt`" @@ -364,9 +316,7 @@ args = ["fmt"] [tasks.action-format-tests] description = "`cargo fmt` tests" -dependencies = [ - "action-determine-tests", -] +dependencies = ["action-determine-tests"] command = "cargo" args = ["fmt", "--", "@@split(CARGO_MAKE_VAR_TESTS, )"] @@ -381,16 +331,18 @@ args = ["fmt", "--", "--check"] [tasks.action-spellcheck-codespell] description = "`codespell` spellcheck repository" command = "codespell" # (from `pip install codespell`) -args = [".", "--skip=*/.git,./target,./tests/fixtures", "--ignore-words-list=mut,od"] +args = [ + ".", + "--skip=*/.git,./target,./tests/fixtures", + "--ignore-words-list=mut,od", +] [tasks.action-test-utils] description = "Build individual utilities" -dependencies = [ - "action-determine-utils", -] +dependencies = ["action-determine-utils"] command = "cargo" # args = ["build", "@@remove-empty(CARGO_MAKE_TASK_BUILD_UTILS_ARGS)" ] -args = ["test", "@@split(CARGO_MAKE_TASK_BUILD_UTILS_ARGS, )" ] +args = ["test", "@@split(CARGO_MAKE_TASK_BUILD_UTILS_ARGS, )"] [tasks.action-test_quiet] description = "Test (in `--quiet` mode)" @@ -399,8 +351,7 @@ args = ["test", "--quiet", "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )"] [tasks.action-display-help] script_runner = "@duckscript" -script = [ -''' +script = [''' echo "" echo "usage: `cargo make TARGET [ARGS...]`" echo "" @@ -432,5 +383,4 @@ script = [ end_if end echo "" -''' -] +'''] diff --git a/deny.toml b/deny.toml index c849842304..3aaee354a9 100644 --- a/deny.toml +++ b/deny.toml @@ -11,7 +11,7 @@ unmaintained = "warn" yanked = "warn" notice = "warn" ignore = [ - #"RUSTSEC-0000-0000", + #"RUSTSEC-0000-0000", ] # This section is considered when running `cargo deny check licenses` @@ -20,15 +20,15 @@ ignore = [ [licenses] unlicensed = "deny" allow = [ - "MIT", - "Apache-2.0", - "ISC", - "BSD-2-Clause", - "BSD-2-Clause-FreeBSD", - "BSD-3-Clause", - "CC0-1.0", - "MPL-2.0", # XXX considered copyleft? - "Unicode-DFS-2016", + "MIT", + "Apache-2.0", + "ISC", + "BSD-2-Clause", + "BSD-2-Clause-FreeBSD", + "BSD-3-Clause", + "CC0-1.0", + "MPL-2.0", # XXX considered copyleft? + "Unicode-DFS-2016", ] copyleft = "deny" allow-osi-fsf-free = "neither" @@ -59,27 +59,27 @@ highlight = "all" # introduces it. # spell-checker: disable skip = [ - # is-terminal - { name = "hermit-abi", version = "0.3.1" }, - # procfs - { name = "rustix", version = "0.36.14" }, - { name = "linux-raw-sys", version = "0.1.4" }, - # various crates - { name = "windows-sys", version = "0.45.0" }, - { name = "windows-targets", version = "0.42.2" }, - { name = "windows_aarch64_gnullvm", version = "0.42.2" }, - { name = "windows_aarch64_msvc", version = "0.42.2" }, - { name = "windows_i686_gnu", version = "0.42.2" }, - { name = "windows_i686_msvc", version = "0.42.2" }, - { name = "windows_x86_64_gnu", version = "0.42.2" }, - { name = "windows_x86_64_gnullvm", version = "0.42.2" }, - { name = "windows_x86_64_msvc", version = "0.42.2" }, - # tempfile - { name = "redox_syscall", version = "0.3.5" }, - # cpp_macros - { name = "aho-corasick", version = "0.7.19" }, - # touch, can be remove when touch switches from time to chrono - { name = "humantime_to_duration", version = "0.2.1" }, + # is-terminal + { name = "hermit-abi", version = "0.3.1" }, + # procfs + { name = "rustix", version = "0.36.14" }, + { name = "linux-raw-sys", version = "0.1.4" }, + # various crates + { name = "windows-sys", version = "0.45.0" }, + { name = "windows-targets", version = "0.42.2" }, + { name = "windows_aarch64_gnullvm", version = "0.42.2" }, + { name = "windows_aarch64_msvc", version = "0.42.2" }, + { name = "windows_i686_gnu", version = "0.42.2" }, + { name = "windows_i686_msvc", version = "0.42.2" }, + { name = "windows_x86_64_gnu", version = "0.42.2" }, + { name = "windows_x86_64_gnullvm", version = "0.42.2" }, + { name = "windows_x86_64_msvc", version = "0.42.2" }, + # tempfile + { name = "redox_syscall", version = "0.3.5" }, + # cpp_macros + { name = "aho-corasick", version = "0.7.19" }, + # touch, can be remove when touch switches from time to chrono + { name = "humantime_to_duration", version = "0.2.1" }, ] # spell-checker: enable diff --git a/docs/book.toml b/docs/book.toml index b9b31cfaf6..f2da19338c 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -10,4 +10,4 @@ git-repository-url = "https://github.com/rust-lang/cargo/tree/master/src/doc/src [preprocessor.toc] command = "mdbook-toc" -renderer = ["html"] \ No newline at end of file +renderer = ["html"] diff --git a/src/uu/arch/Cargo.toml b/src/uu/arch/Cargo.toml index 10df726e1b..42ac16b891 100644 --- a/src/uu/arch/Cargo.toml +++ b/src/uu/arch/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/arch.rs" [dependencies] -platform-info = { workspace=true } -clap = { workspace=true } -uucore = { workspace=true } +platform-info = { workspace = true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "arch" diff --git a/src/uu/base32/Cargo.toml b/src/uu/base32/Cargo.toml index 077204e1fd..ea718e8dc2 100644 --- a/src/uu/base32/Cargo.toml +++ b/src/uu/base32/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/base32.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features = ["encoding"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["encoding"] } [[bin]] name = "base32" diff --git a/src/uu/base64/Cargo.toml b/src/uu/base64/Cargo.toml index e21b34161c..ba82290738 100644 --- a/src/uu/base64/Cargo.toml +++ b/src/uu/base64/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/base64.rs" [dependencies] -uucore = { workspace=true, features = ["encoding"] } -uu_base32 = { workspace=true } +uucore = { workspace = true, features = ["encoding"] } +uu_base32 = { workspace = true } [[bin]] name = "base64" diff --git a/src/uu/basename/Cargo.toml b/src/uu/basename/Cargo.toml index c17651506e..a1ea12c5ee 100644 --- a/src/uu/basename/Cargo.toml +++ b/src/uu/basename/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/basename.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "basename" diff --git a/src/uu/basenc/Cargo.toml b/src/uu/basenc/Cargo.toml index 3e8c3ed8ad..20665402a9 100644 --- a/src/uu/basenc/Cargo.toml +++ b/src/uu/basenc/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/basenc.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features = ["encoding"] } -uu_base32 = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true, features = ["encoding"] } +uu_base32 = { workspace = true } [[bin]] name = "basenc" diff --git a/src/uu/cat/Cargo.toml b/src/uu/cat/Cargo.toml index 2b78e9da75..e341fb5353 100644 --- a/src/uu/cat/Cargo.toml +++ b/src/uu/cat/Cargo.toml @@ -15,13 +15,13 @@ edition = "2021" path = "src/cat.rs" [dependencies] -clap = { workspace=true } +clap = { workspace = true } thiserror = { workspace = true } is-terminal = { workspace = true } -uucore = { workspace=true, features=["fs", "pipes"] } +uucore = { workspace = true, features = ["fs", "pipes"] } [target.'cfg(unix)'.dependencies] -nix = { workspace=true } +nix = { workspace = true } [[bin]] name = "cat" diff --git a/src/uu/chcon/Cargo.toml b/src/uu/chcon/Cargo.toml index 53165dfe0f..58d6b9b469 100644 --- a/src/uu/chcon/Cargo.toml +++ b/src/uu/chcon/Cargo.toml @@ -14,12 +14,12 @@ edition = "2021" path = "src/chcon.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["entries", "fs", "perms"] } -selinux = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true, features = ["entries", "fs", "perms"] } +selinux = { workspace = true } thiserror = { workspace = true } -libc = { workspace=true } -fts-sys = { workspace=true } +libc = { workspace = true } +fts-sys = { workspace = true } [[bin]] name = "chcon" diff --git a/src/uu/chgrp/Cargo.toml b/src/uu/chgrp/Cargo.toml index cceb32658d..97ffc09b72 100644 --- a/src/uu/chgrp/Cargo.toml +++ b/src/uu/chgrp/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/chgrp.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["entries", "fs", "perms"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["entries", "fs", "perms"] } [[bin]] name = "chgrp" diff --git a/src/uu/chmod/Cargo.toml b/src/uu/chmod/Cargo.toml index af133128da..a4b4b799d7 100644 --- a/src/uu/chmod/Cargo.toml +++ b/src/uu/chmod/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/chmod.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -uucore = { workspace=true, features=["fs", "mode"] } +clap = { workspace = true } +libc = { workspace = true } +uucore = { workspace = true, features = ["fs", "mode"] } [[bin]] name = "chmod" diff --git a/src/uu/chown/Cargo.toml b/src/uu/chown/Cargo.toml index 0b4db615d9..cd1f881eed 100644 --- a/src/uu/chown/Cargo.toml +++ b/src/uu/chown/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/chown.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["entries", "fs", "perms"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["entries", "fs", "perms"] } [[bin]] name = "chown" diff --git a/src/uu/chroot/Cargo.toml b/src/uu/chroot/Cargo.toml index 1c3527eda9..1256a96c81 100644 --- a/src/uu/chroot/Cargo.toml +++ b/src/uu/chroot/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/chroot.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["entries", "fs"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["entries", "fs"] } [[bin]] name = "chroot" diff --git a/src/uu/cksum/Cargo.toml b/src/uu/cksum/Cargo.toml index 707a7ee5cd..345dfb2384 100644 --- a/src/uu/cksum/Cargo.toml +++ b/src/uu/cksum/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/cksum.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["sum"] } -hex = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true, features = ["sum"] } +hex = { workspace = true } [[bin]] name = "cksum" diff --git a/src/uu/comm/Cargo.toml b/src/uu/comm/Cargo.toml index 31fda282f4..e5947bb84e 100644 --- a/src/uu/comm/Cargo.toml +++ b/src/uu/comm/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/comm.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "comm" diff --git a/src/uu/cp/Cargo.toml b/src/uu/cp/Cargo.toml index b14add4638..ff8f21160b 100644 --- a/src/uu/cp/Cargo.toml +++ b/src/uu/cp/Cargo.toml @@ -2,9 +2,9 @@ name = "uu_cp" version = "0.0.19" authors = [ - "Jordy Dickinson ", - "Joshua S. Miller ", - "uutils developers", + "Jordy Dickinson ", + "Joshua S. Miller ", + "uutils developers", ] license = "MIT" description = "cp ~ (uutils) copy SOURCE to DESTINATION" @@ -19,18 +19,18 @@ edition = "2021" path = "src/cp.rs" [dependencies] -clap = { workspace=true } -filetime = { workspace=true } -libc = { workspace=true } -quick-error = { workspace=true } -selinux = { workspace=true, optional=true } -uucore = { workspace=true, features=["entries", "fs", "perms", "mode"] } -walkdir = { workspace=true } -indicatif = { workspace=true } +clap = { workspace = true } +filetime = { workspace = true } +libc = { workspace = true } +quick-error = { workspace = true } +selinux = { workspace = true, optional = true } +uucore = { workspace = true, features = ["entries", "fs", "perms", "mode"] } +walkdir = { workspace = true } +indicatif = { workspace = true } [target.'cfg(unix)'.dependencies] -xattr = { workspace=true } -exacl = { workspace=true, optional=true } +xattr = { workspace = true } +exacl = { workspace = true, optional = true } [[bin]] name = "cp" diff --git a/src/uu/csplit/Cargo.toml b/src/uu/csplit/Cargo.toml index 3d0bafb484..023d972434 100644 --- a/src/uu/csplit/Cargo.toml +++ b/src/uu/csplit/Cargo.toml @@ -15,10 +15,10 @@ edition = "2021" path = "src/csplit.rs" [dependencies] -clap = { workspace=true } +clap = { workspace = true } thiserror = { workspace = true } -regex = { workspace=true } -uucore = { workspace=true, features=["entries", "fs"] } +regex = { workspace = true } +uucore = { workspace = true, features = ["entries", "fs"] } [[bin]] name = "csplit" diff --git a/src/uu/cut/Cargo.toml b/src/uu/cut/Cargo.toml index d6b9d932f6..6e8c28d74a 100644 --- a/src/uu/cut/Cargo.toml +++ b/src/uu/cut/Cargo.toml @@ -15,11 +15,11 @@ edition = "2021" path = "src/cut.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } -memchr = { workspace=true } -bstr = { workspace=true } -is-terminal = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } +memchr = { workspace = true } +bstr = { workspace = true } +is-terminal = { workspace = true } [[bin]] name = "cut" diff --git a/src/uu/date/Cargo.toml b/src/uu/date/Cargo.toml index 1ffcbed666..62308bf53a 100644 --- a/src/uu/date/Cargo.toml +++ b/src/uu/date/Cargo.toml @@ -16,16 +16,19 @@ edition = "2021" path = "src/date.rs" [dependencies] -chrono = { workspace=true } -clap = { workspace=true } -uucore = { workspace=true } -humantime_to_duration = { workspace=true } +chrono = { workspace = true } +clap = { workspace = true } +uucore = { workspace = true } +humantime_to_duration = { workspace = true } [target.'cfg(unix)'.dependencies] -libc = { workspace=true } +libc = { workspace = true } [target.'cfg(windows)'.dependencies] -windows-sys = { workspace=true, features = ["Win32_Foundation", "Win32_System_SystemInformation"] } +windows-sys = { workspace = true, features = [ + "Win32_Foundation", + "Win32_System_SystemInformation", +] } [[bin]] name = "date" diff --git a/src/uu/dd/Cargo.toml b/src/uu/dd/Cargo.toml index 1b0b015beb..0ac25657ef 100644 --- a/src/uu/dd/Cargo.toml +++ b/src/uu/dd/Cargo.toml @@ -15,16 +15,16 @@ edition = "2021" path = "src/dd.rs" [dependencies] -clap = { workspace=true } -gcd = { workspace=true } -libc = { workspace=true } -uucore = { workspace=true, features=["memo"] } +clap = { workspace = true } +gcd = { workspace = true } +libc = { workspace = true } +uucore = { workspace = true, features = ["memo"] } [target.'cfg(any(target_os = "linux"))'.dependencies] -nix = { workspace=true, features = ["fs"] } +nix = { workspace = true, features = ["fs"] } [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] -signal-hook = { workspace=true } +signal-hook = { workspace = true } [[bin]] name = "dd" diff --git a/src/uu/df/Cargo.toml b/src/uu/df/Cargo.toml index 159c876850..0974a443c5 100644 --- a/src/uu/df/Cargo.toml +++ b/src/uu/df/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/df.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["libc", "fsext"] } -unicode-width = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true, features = ["libc", "fsext"] } +unicode-width = { workspace = true } [[bin]] name = "df" diff --git a/src/uu/dir/Cargo.toml b/src/uu/dir/Cargo.toml index 2a3adda963..d61b041dcf 100644 --- a/src/uu/dir/Cargo.toml +++ b/src/uu/dir/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/dir.rs" [dependencies] -clap = { workspace=true, features = ["env"] } -uucore = { workspace=true, features=["entries", "fs"] } -uu_ls = { workspace=true } +clap = { workspace = true, features = ["env"] } +uucore = { workspace = true, features = ["entries", "fs"] } +uu_ls = { workspace = true } [[bin]] name = "dir" diff --git a/src/uu/dircolors/Cargo.toml b/src/uu/dircolors/Cargo.toml index d922c1cf3e..952e7ad3f7 100644 --- a/src/uu/dircolors/Cargo.toml +++ b/src/uu/dircolors/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/dircolors.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "dircolors" diff --git a/src/uu/dirname/Cargo.toml b/src/uu/dirname/Cargo.toml index cd211661d7..46dec707df 100644 --- a/src/uu/dirname/Cargo.toml +++ b/src/uu/dirname/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/dirname.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "dirname" diff --git a/src/uu/du/Cargo.toml b/src/uu/du/Cargo.toml index 6e883f769d..693e7c81cd 100644 --- a/src/uu/du/Cargo.toml +++ b/src/uu/du/Cargo.toml @@ -15,14 +15,17 @@ edition = "2021" path = "src/du.rs" [dependencies] -chrono = { workspace=true } +chrono = { workspace = true } # For the --exclude & --exclude-from options -glob = { workspace=true } -clap = { workspace=true } -uucore = { workspace=true } +glob = { workspace = true } +clap = { workspace = true } +uucore = { workspace = true } [target.'cfg(target_os = "windows")'.dependencies] -windows-sys = { workspace=true, features = ["Win32_Storage_FileSystem", "Win32_Foundation"] } +windows-sys = { workspace = true, features = [ + "Win32_Storage_FileSystem", + "Win32_Foundation", +] } [[bin]] name = "du" diff --git a/src/uu/echo/Cargo.toml b/src/uu/echo/Cargo.toml index 90ea225984..e12460a51b 100644 --- a/src/uu/echo/Cargo.toml +++ b/src/uu/echo/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/echo.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "echo" diff --git a/src/uu/env/Cargo.toml b/src/uu/env/Cargo.toml index 8a19ce1213..2b05cd3e7b 100644 --- a/src/uu/env/Cargo.toml +++ b/src/uu/env/Cargo.toml @@ -15,12 +15,12 @@ edition = "2021" path = "src/env.rs" [dependencies] -clap = { workspace=true } -rust-ini = { workspace=true } -uucore = { workspace=true, features=["signals"]} +clap = { workspace = true } +rust-ini = { workspace = true } +uucore = { workspace = true, features = ["signals"] } [target.'cfg(unix)'.dependencies] -nix = { workspace=true, features = ["signal"] } +nix = { workspace = true, features = ["signal"] } [[bin]] diff --git a/src/uu/expand/Cargo.toml b/src/uu/expand/Cargo.toml index 1f923f9bcc..dd0b769827 100644 --- a/src/uu/expand/Cargo.toml +++ b/src/uu/expand/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/expand.rs" [dependencies] -clap = { workspace=true } -unicode-width = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +unicode-width = { workspace = true } +uucore = { workspace = true } [[bin]] name = "expand" diff --git a/src/uu/expr/Cargo.toml b/src/uu/expr/Cargo.toml index f28215e0f5..68224ee45c 100644 --- a/src/uu/expr/Cargo.toml +++ b/src/uu/expr/Cargo.toml @@ -15,11 +15,11 @@ edition = "2021" path = "src/expr.rs" [dependencies] -clap = { workspace=true } -num-bigint = { workspace=true } -num-traits = { workspace=true } -onig = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +num-bigint = { workspace = true } +num-traits = { workspace = true } +onig = { workspace = true } +uucore = { workspace = true } [[bin]] name = "expr" diff --git a/src/uu/factor/Cargo.toml b/src/uu/factor/Cargo.toml index b70976b768..a0fc539e16 100644 --- a/src/uu/factor/Cargo.toml +++ b/src/uu/factor/Cargo.toml @@ -12,15 +12,15 @@ categories = ["command-line-utilities"] edition = "2021" [build-dependencies] -num-traits = { workspace=true } # used in src/numerics.rs, which is included by build.rs +num-traits = { workspace = true } # used in src/numerics.rs, which is included by build.rs [dependencies] -clap = { workspace=true } -coz = { workspace=true, optional = true } -num-traits = { workspace=true } -rand = { workspace=true } -smallvec = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +coz = { workspace = true, optional = true } +num-traits = { workspace = true } +rand = { workspace = true } +smallvec = { workspace = true } +uucore = { workspace = true } [dev-dependencies] quickcheck = "1.0.3" diff --git a/src/uu/false/Cargo.toml b/src/uu/false/Cargo.toml index 84ac4e553a..88b5751cb2 100644 --- a/src/uu/false/Cargo.toml +++ b/src/uu/false/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/false.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "false" diff --git a/src/uu/fmt/Cargo.toml b/src/uu/fmt/Cargo.toml index df51f659cc..0de6218b86 100644 --- a/src/uu/fmt/Cargo.toml +++ b/src/uu/fmt/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/fmt.rs" [dependencies] -clap = { workspace=true } -unicode-width = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +unicode-width = { workspace = true } +uucore = { workspace = true } [[bin]] name = "fmt" diff --git a/src/uu/fold/Cargo.toml b/src/uu/fold/Cargo.toml index bb7e3fa07d..f0377c5ab8 100644 --- a/src/uu/fold/Cargo.toml +++ b/src/uu/fold/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/fold.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "fold" diff --git a/src/uu/groups/Cargo.toml b/src/uu/groups/Cargo.toml index 3feb634b6f..a33b34f761 100644 --- a/src/uu/groups/Cargo.toml +++ b/src/uu/groups/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/groups.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["entries", "process"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["entries", "process"] } [[bin]] name = "groups" diff --git a/src/uu/hashsum/Cargo.toml b/src/uu/hashsum/Cargo.toml index 84b19d6e5d..0a12254d04 100644 --- a/src/uu/hashsum/Cargo.toml +++ b/src/uu/hashsum/Cargo.toml @@ -15,11 +15,11 @@ edition = "2021" path = "src/hashsum.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["sum"] } -memchr = { workspace=true } -regex = { workspace=true } -hex = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true, features = ["sum"] } +memchr = { workspace = true } +regex = { workspace = true } +hex = { workspace = true } [[bin]] name = "hashsum" diff --git a/src/uu/head/Cargo.toml b/src/uu/head/Cargo.toml index d680a6eb76..6b53b1526b 100644 --- a/src/uu/head/Cargo.toml +++ b/src/uu/head/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/head.rs" [dependencies] -clap = { workspace=true } -memchr = { workspace=true } -uucore = { workspace=true, features=["ringbuffer", "lines"] } +clap = { workspace = true } +memchr = { workspace = true } +uucore = { workspace = true, features = ["ringbuffer", "lines"] } [[bin]] name = "head" diff --git a/src/uu/hostid/Cargo.toml b/src/uu/hostid/Cargo.toml index 67045e8f69..175c319305 100644 --- a/src/uu/hostid/Cargo.toml +++ b/src/uu/hostid/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/hostid.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +libc = { workspace = true } +uucore = { workspace = true } [[bin]] name = "hostid" diff --git a/src/uu/hostname/Cargo.toml b/src/uu/hostname/Cargo.toml index 718bf43db9..d94a703ebf 100644 --- a/src/uu/hostname/Cargo.toml +++ b/src/uu/hostname/Cargo.toml @@ -15,12 +15,15 @@ edition = "2021" path = "src/hostname.rs" [dependencies] -clap = { workspace=true } +clap = { workspace = true } hostname = { version = "0.3", features = ["set"] } -uucore = { workspace=true, features=["wide"] } +uucore = { workspace = true, features = ["wide"] } [target.'cfg(target_os = "windows")'.dependencies] -windows-sys = { workspace=true, features = ["Win32_Networking_WinSock", "Win32_Foundation"] } +windows-sys = { workspace = true, features = [ + "Win32_Networking_WinSock", + "Win32_Foundation", +] } [[bin]] name = "hostname" diff --git a/src/uu/id/Cargo.toml b/src/uu/id/Cargo.toml index 9e0a35f7f2..4d32f6e59d 100644 --- a/src/uu/id/Cargo.toml +++ b/src/uu/id/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/id.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["entries", "process"] } -selinux = { workspace=true, optional=true } +clap = { workspace = true } +uucore = { workspace = true, features = ["entries", "process"] } +selinux = { workspace = true, optional = true } [[bin]] name = "id" diff --git a/src/uu/install/Cargo.toml b/src/uu/install/Cargo.toml index b833babad4..14be22a977 100644 --- a/src/uu/install/Cargo.toml +++ b/src/uu/install/Cargo.toml @@ -1,10 +1,7 @@ [package] name = "uu_install" version = "0.0.19" -authors = [ - "Ben Eills ", - "uutils developers", -] +authors = ["Ben Eills ", "uutils developers"] license = "MIT" description = "install ~ (uutils) copy files from SOURCE to DESTINATION (with specified attributes)" @@ -18,11 +15,11 @@ edition = "2021" path = "src/install.rs" [dependencies] -clap = { workspace=true } -filetime = { workspace=true } -file_diff = { workspace=true } -libc = { workspace=true } -uucore = { workspace=true, features=["fs", "mode", "perms", "entries"] } +clap = { workspace = true } +filetime = { workspace = true } +file_diff = { workspace = true } +libc = { workspace = true } +uucore = { workspace = true, features = ["fs", "mode", "perms", "entries"] } [[bin]] name = "install" diff --git a/src/uu/join/Cargo.toml b/src/uu/join/Cargo.toml index a2c6d19bc4..946056cc18 100644 --- a/src/uu/join/Cargo.toml +++ b/src/uu/join/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/join.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } -memchr = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } +memchr = { workspace = true } [[bin]] name = "join" diff --git a/src/uu/kill/Cargo.toml b/src/uu/kill/Cargo.toml index e373bfe782..1f5515d03b 100644 --- a/src/uu/kill/Cargo.toml +++ b/src/uu/kill/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/kill.rs" [dependencies] -clap = { workspace=true } -nix = { workspace=true, features = ["signal"] } -uucore = { workspace=true, features=["signals"] } +clap = { workspace = true } +nix = { workspace = true, features = ["signal"] } +uucore = { workspace = true, features = ["signals"] } [[bin]] name = "kill" diff --git a/src/uu/link/Cargo.toml b/src/uu/link/Cargo.toml index 6f034dcae8..fae9d59d94 100644 --- a/src/uu/link/Cargo.toml +++ b/src/uu/link/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/link.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "link" diff --git a/src/uu/ln/Cargo.toml b/src/uu/ln/Cargo.toml index b31f64f301..c4260cb8f4 100644 --- a/src/uu/ln/Cargo.toml +++ b/src/uu/ln/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/ln.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["fs"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [[bin]] name = "ln" diff --git a/src/uu/logname/Cargo.toml b/src/uu/logname/Cargo.toml index 19a4ab0351..a6bb6b0b7d 100644 --- a/src/uu/logname/Cargo.toml +++ b/src/uu/logname/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/logname.rs" [dependencies] -libc = { workspace=true } -clap = { workspace=true } -uucore = { workspace=true } +libc = { workspace = true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "logname" diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index e162aeab13..196e29795f 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -15,18 +15,18 @@ edition = "2021" path = "src/ls.rs" [dependencies] -clap = { workspace=true, features = ["env"] } -chrono = { workspace=true } -unicode-width = { workspace=true } -number_prefix = { workspace=true } -term_grid = { workspace=true } -terminal_size = { workspace=true } -glob = { workspace=true } -lscolors = { workspace=true } -uucore = { workspace=true, features = ["entries", "fs"] } -once_cell = { workspace=true } -is-terminal = { workspace=true } -selinux = { workspace=true, optional = true } +clap = { workspace = true, features = ["env"] } +chrono = { workspace = true } +unicode-width = { workspace = true } +number_prefix = { workspace = true } +term_grid = { workspace = true } +terminal_size = { workspace = true } +glob = { workspace = true } +lscolors = { workspace = true } +uucore = { workspace = true, features = ["entries", "fs"] } +once_cell = { workspace = true } +is-terminal = { workspace = true } +selinux = { workspace = true, optional = true } [[bin]] name = "ls" diff --git a/src/uu/mkdir/Cargo.toml b/src/uu/mkdir/Cargo.toml index 24ce412d32..9d1edc5c66 100644 --- a/src/uu/mkdir/Cargo.toml +++ b/src/uu/mkdir/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/mkdir.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["fs", "mode"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["fs", "mode"] } [[bin]] name = "mkdir" diff --git a/src/uu/mkfifo/Cargo.toml b/src/uu/mkfifo/Cargo.toml index 2e24bb53dc..54a4a51b56 100644 --- a/src/uu/mkfifo/Cargo.toml +++ b/src/uu/mkfifo/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/mkfifo.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +libc = { workspace = true } +uucore = { workspace = true } [[bin]] name = "mkfifo" diff --git a/src/uu/mknod/Cargo.toml b/src/uu/mknod/Cargo.toml index 8a50a61fc7..d73ea59b7a 100644 --- a/src/uu/mknod/Cargo.toml +++ b/src/uu/mknod/Cargo.toml @@ -16,9 +16,9 @@ name = "uu_mknod" path = "src/mknod.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -uucore = { workspace=true, features=["mode"] } +clap = { workspace = true } +libc = { workspace = true } +uucore = { workspace = true, features = ["mode"] } [[bin]] name = "mknod" diff --git a/src/uu/mktemp/Cargo.toml b/src/uu/mktemp/Cargo.toml index 31bd53a00b..001bf54111 100644 --- a/src/uu/mktemp/Cargo.toml +++ b/src/uu/mktemp/Cargo.toml @@ -15,10 +15,10 @@ edition = "2021" path = "src/mktemp.rs" [dependencies] -clap = { workspace=true } -rand = { workspace=true } -tempfile = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +rand = { workspace = true } +tempfile = { workspace = true } +uucore = { workspace = true } [[bin]] name = "mktemp" diff --git a/src/uu/more/Cargo.toml b/src/uu/more/Cargo.toml index a19fc577da..ff677ad875 100644 --- a/src/uu/more/Cargo.toml +++ b/src/uu/more/Cargo.toml @@ -15,15 +15,15 @@ edition = "2021" path = "src/more.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } -crossterm = { workspace=true } -is-terminal = { workspace=true } -unicode-width = { workspace=true } -unicode-segmentation = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } +crossterm = { workspace = true } +is-terminal = { workspace = true } +unicode-width = { workspace = true } +unicode-segmentation = { workspace = true } [target.'cfg(all(unix, not(target_os = "fuchsia")))'.dependencies] -nix = { workspace=true } +nix = { workspace = true } [[bin]] name = "more" diff --git a/src/uu/mv/Cargo.toml b/src/uu/mv/Cargo.toml index 8747c950ca..2e67ec151a 100644 --- a/src/uu/mv/Cargo.toml +++ b/src/uu/mv/Cargo.toml @@ -15,10 +15,10 @@ edition = "2021" path = "src/mv.rs" [dependencies] -clap = { workspace=true } -fs_extra = { workspace=true } -indicatif = { workspace=true } -uucore = { workspace=true, features=["fs"] } +clap = { workspace = true } +fs_extra = { workspace = true } +indicatif = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [[bin]] name = "mv" diff --git a/src/uu/nice/Cargo.toml b/src/uu/nice/Cargo.toml index d63f253126..70d6f0f87c 100644 --- a/src/uu/nice/Cargo.toml +++ b/src/uu/nice/Cargo.toml @@ -15,10 +15,10 @@ edition = "2021" path = "src/nice.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -nix = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +libc = { workspace = true } +nix = { workspace = true } +uucore = { workspace = true } [[bin]] name = "nice" diff --git a/src/uu/nl/Cargo.toml b/src/uu/nl/Cargo.toml index ead669d3d7..020eba8295 100644 --- a/src/uu/nl/Cargo.toml +++ b/src/uu/nl/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/nl.rs" [dependencies] -clap = { workspace=true } -regex = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +regex = { workspace = true } +uucore = { workspace = true } [[bin]] name = "nl" diff --git a/src/uu/nohup/Cargo.toml b/src/uu/nohup/Cargo.toml index 40f332c5fe..74bdd89ae7 100644 --- a/src/uu/nohup/Cargo.toml +++ b/src/uu/nohup/Cargo.toml @@ -15,10 +15,10 @@ edition = "2021" path = "src/nohup.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -is-terminal = { workspace=true } -uucore = { workspace=true, features=["fs"] } +clap = { workspace = true } +libc = { workspace = true } +is-terminal = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [[bin]] name = "nohup" diff --git a/src/uu/nproc/Cargo.toml b/src/uu/nproc/Cargo.toml index ae2e74f068..239afef5e7 100644 --- a/src/uu/nproc/Cargo.toml +++ b/src/uu/nproc/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/nproc.rs" [dependencies] -libc = { workspace=true } -clap = { workspace=true } -uucore = { workspace=true, features=["fs"] } +libc = { workspace = true } +clap = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [[bin]] name = "nproc" diff --git a/src/uu/numfmt/Cargo.toml b/src/uu/numfmt/Cargo.toml index 9ba3c00753..e17b4e56eb 100644 --- a/src/uu/numfmt/Cargo.toml +++ b/src/uu/numfmt/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/numfmt.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "numfmt" diff --git a/src/uu/od/Cargo.toml b/src/uu/od/Cargo.toml index e7cc7d34e3..f26006d7e5 100644 --- a/src/uu/od/Cargo.toml +++ b/src/uu/od/Cargo.toml @@ -15,10 +15,10 @@ edition = "2021" path = "src/od.rs" [dependencies] -byteorder = { workspace=true } -clap = { workspace=true } -half = { workspace=true } -uucore = { workspace=true } +byteorder = { workspace = true } +clap = { workspace = true } +half = { workspace = true } +uucore = { workspace = true } [[bin]] name = "od" diff --git a/src/uu/paste/Cargo.toml b/src/uu/paste/Cargo.toml index 836aa05bd2..e9a78d828b 100644 --- a/src/uu/paste/Cargo.toml +++ b/src/uu/paste/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/paste.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "paste" diff --git a/src/uu/pathchk/Cargo.toml b/src/uu/pathchk/Cargo.toml index c37b0b4810..f11d85b5cc 100644 --- a/src/uu/pathchk/Cargo.toml +++ b/src/uu/pathchk/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/pathchk.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +libc = { workspace = true } +uucore = { workspace = true } [[bin]] name = "pathchk" diff --git a/src/uu/pinky/Cargo.toml b/src/uu/pinky/Cargo.toml index efee7c06a5..ee17a46c5b 100644 --- a/src/uu/pinky/Cargo.toml +++ b/src/uu/pinky/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/pinky.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["utmpx", "entries"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["utmpx", "entries"] } [[bin]] name = "pinky" diff --git a/src/uu/pr/Cargo.toml b/src/uu/pr/Cargo.toml index 888daee907..bae1b251da 100644 --- a/src/uu/pr/Cargo.toml +++ b/src/uu/pr/Cargo.toml @@ -15,12 +15,12 @@ edition = "2021" path = "src/pr.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["entries"] } -quick-error = { workspace=true } -itertools = { workspace=true } -regex = { workspace=true } -chrono = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true, features = ["entries"] } +quick-error = { workspace = true } +itertools = { workspace = true } +regex = { workspace = true } +chrono = { workspace = true } [[bin]] name = "pr" diff --git a/src/uu/printenv/Cargo.toml b/src/uu/printenv/Cargo.toml index f3a7f2b403..59dcee7782 100644 --- a/src/uu/printenv/Cargo.toml +++ b/src/uu/printenv/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/printenv.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "printenv" diff --git a/src/uu/printf/Cargo.toml b/src/uu/printf/Cargo.toml index c534ba544c..51812945f4 100644 --- a/src/uu/printf/Cargo.toml +++ b/src/uu/printf/Cargo.toml @@ -1,10 +1,7 @@ [package] name = "uu_printf" version = "0.0.19" -authors = [ - "Nathan Ross", - "uutils developers", -] +authors = ["Nathan Ross", "uutils developers"] license = "MIT" description = "printf ~ (uutils) FORMAT and display ARGUMENTS" @@ -18,8 +15,8 @@ edition = "2021" path = "src/printf.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["memo"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["memo"] } [[bin]] name = "printf" diff --git a/src/uu/ptx/Cargo.toml b/src/uu/ptx/Cargo.toml index c3498c25b7..358c640db1 100644 --- a/src/uu/ptx/Cargo.toml +++ b/src/uu/ptx/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/ptx.rs" [dependencies] -clap = { workspace=true } -regex = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +regex = { workspace = true } +uucore = { workspace = true } [[bin]] name = "ptx" diff --git a/src/uu/pwd/Cargo.toml b/src/uu/pwd/Cargo.toml index fd76eec5bd..60cb9aae00 100644 --- a/src/uu/pwd/Cargo.toml +++ b/src/uu/pwd/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/pwd.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "pwd" diff --git a/src/uu/readlink/Cargo.toml b/src/uu/readlink/Cargo.toml index 718a381205..4a0ad66e57 100644 --- a/src/uu/readlink/Cargo.toml +++ b/src/uu/readlink/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/readlink.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["fs"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [[bin]] name = "readlink" diff --git a/src/uu/realpath/Cargo.toml b/src/uu/realpath/Cargo.toml index 0ecd971c1c..9b2b5352c4 100644 --- a/src/uu/realpath/Cargo.toml +++ b/src/uu/realpath/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/realpath.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["fs"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [[bin]] name = "realpath" diff --git a/src/uu/relpath/Cargo.toml b/src/uu/relpath/Cargo.toml index 96fdca9468..4108d612c0 100644 --- a/src/uu/relpath/Cargo.toml +++ b/src/uu/relpath/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/relpath.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["fs"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [[bin]] name = "relpath" diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index c69bd59642..ec46031d06 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -15,15 +15,15 @@ edition = "2021" path = "src/rm.rs" [dependencies] -clap = { workspace=true } -walkdir = { workspace=true } -uucore = { workspace=true, features=["fs"] } +clap = { workspace = true } +walkdir = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [target.'cfg(unix)'.dependencies] -libc = { workspace=true } +libc = { workspace = true } [target.'cfg(windows)'.dependencies] -windows-sys = { workspace=true, features = ["Win32_Storage_FileSystem"] } +windows-sys = { workspace = true, features = ["Win32_Storage_FileSystem"] } [[bin]] name = "rm" diff --git a/src/uu/rmdir/Cargo.toml b/src/uu/rmdir/Cargo.toml index 2a40ad0581..6c152a82a1 100644 --- a/src/uu/rmdir/Cargo.toml +++ b/src/uu/rmdir/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/rmdir.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["fs"] } -libc = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true, features = ["fs"] } +libc = { workspace = true } [[bin]] name = "rmdir" diff --git a/src/uu/runcon/Cargo.toml b/src/uu/runcon/Cargo.toml index 0060e497b2..191d9f0137 100644 --- a/src/uu/runcon/Cargo.toml +++ b/src/uu/runcon/Cargo.toml @@ -14,11 +14,11 @@ edition = "2021" path = "src/runcon.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["entries", "fs", "perms"] } -selinux = { workspace=true } -thiserror = { workspace=true } -libc = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true, features = ["entries", "fs", "perms"] } +selinux = { workspace = true } +thiserror = { workspace = true } +libc = { workspace = true } [[bin]] name = "runcon" diff --git a/src/uu/seq/Cargo.toml b/src/uu/seq/Cargo.toml index e996c2b5c5..e327b3eba0 100644 --- a/src/uu/seq/Cargo.toml +++ b/src/uu/seq/Cargo.toml @@ -16,11 +16,11 @@ edition = "2021" path = "src/seq.rs" [dependencies] -bigdecimal = { workspace=true } -clap = { workspace=true } -num-bigint = { workspace=true } -num-traits = { workspace=true } -uucore = { workspace=true, features=["memo"] } +bigdecimal = { workspace = true } +clap = { workspace = true } +num-bigint = { workspace = true } +num-traits = { workspace = true } +uucore = { workspace = true, features = ["memo"] } [[bin]] name = "seq" diff --git a/src/uu/shred/Cargo.toml b/src/uu/shred/Cargo.toml index 5d52ee58ac..3da23ff2b8 100644 --- a/src/uu/shred/Cargo.toml +++ b/src/uu/shred/Cargo.toml @@ -15,10 +15,10 @@ edition = "2021" path = "src/shred.rs" [dependencies] -clap = { workspace=true } -rand = { workspace=true } -uucore = { workspace=true } -libc = { workspace=true } +clap = { workspace = true } +rand = { workspace = true } +uucore = { workspace = true } +libc = { workspace = true } [[bin]] name = "shred" diff --git a/src/uu/shuf/Cargo.toml b/src/uu/shuf/Cargo.toml index f86a1eac5c..974791ee1e 100644 --- a/src/uu/shuf/Cargo.toml +++ b/src/uu/shuf/Cargo.toml @@ -15,11 +15,11 @@ edition = "2021" path = "src/shuf.rs" [dependencies] -clap = { workspace=true } -memchr = { workspace=true } -rand = { workspace=true } -rand_core = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +memchr = { workspace = true } +rand = { workspace = true } +rand_core = { workspace = true } +uucore = { workspace = true } [[bin]] name = "shuf" diff --git a/src/uu/sleep/Cargo.toml b/src/uu/sleep/Cargo.toml index ae05bdf0e2..2cd38988e1 100644 --- a/src/uu/sleep/Cargo.toml +++ b/src/uu/sleep/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/sleep.rs" [dependencies] -clap = { workspace=true } -fundu = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +fundu = { workspace = true } +uucore = { workspace = true } [[bin]] name = "sleep" diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index 7889ab009a..7540522ed2 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -15,19 +15,19 @@ edition = "2021" path = "src/sort.rs" [dependencies] -binary-heap-plus = { workspace=true } -clap = { workspace=true } -compare = { workspace=true } -ctrlc = { workspace=true } -fnv = { workspace=true } -itertools = { workspace=true } -memchr = { workspace=true } -ouroboros = { workspace=true } -rand = { workspace=true } -rayon = { workspace=true } -tempfile = { workspace=true } -unicode-width = { workspace=true } -uucore = { workspace=true, features=["fs"] } +binary-heap-plus = { workspace = true } +clap = { workspace = true } +compare = { workspace = true } +ctrlc = { workspace = true } +fnv = { workspace = true } +itertools = { workspace = true } +memchr = { workspace = true } +ouroboros = { workspace = true } +rand = { workspace = true } +rayon = { workspace = true } +tempfile = { workspace = true } +unicode-width = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [[bin]] name = "sort" diff --git a/src/uu/split/Cargo.toml b/src/uu/split/Cargo.toml index b9649ad5f0..32cfd6fda2 100644 --- a/src/uu/split/Cargo.toml +++ b/src/uu/split/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/split.rs" [dependencies] -clap = { workspace=true } -memchr = { workspace=true } -uucore = { workspace=true, features=["fs"] } +clap = { workspace = true } +memchr = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [[bin]] name = "split" diff --git a/src/uu/stat/Cargo.toml b/src/uu/stat/Cargo.toml index 3176347041..3f165c3573 100644 --- a/src/uu/stat/Cargo.toml +++ b/src/uu/stat/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/stat.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["entries", "libc", "fs", "fsext"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["entries", "libc", "fs", "fsext"] } [[bin]] name = "stat" diff --git a/src/uu/stdbuf/Cargo.toml b/src/uu/stdbuf/Cargo.toml index 06bd0fa51b..bce2f8dba4 100644 --- a/src/uu/stdbuf/Cargo.toml +++ b/src/uu/stdbuf/Cargo.toml @@ -15,12 +15,12 @@ edition = "2021" path = "src/stdbuf.rs" [dependencies] -clap = { workspace=true } -tempfile = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +tempfile = { workspace = true } +uucore = { workspace = true } [build-dependencies] -libstdbuf = { version="0.0.19", package="uu_stdbuf_libstdbuf", path="src/libstdbuf" } +libstdbuf = { version = "0.0.19", package = "uu_stdbuf_libstdbuf", path = "src/libstdbuf" } [[bin]] name = "stdbuf" diff --git a/src/uu/stdbuf/src/libstdbuf/Cargo.toml b/src/uu/stdbuf/src/libstdbuf/Cargo.toml index abd2aaa4e1..b3f1861189 100644 --- a/src/uu/stdbuf/src/libstdbuf/Cargo.toml +++ b/src/uu/stdbuf/src/libstdbuf/Cargo.toml @@ -14,12 +14,15 @@ edition = "2021" [lib] name = "libstdbuf" path = "src/libstdbuf.rs" -crate-type = ["cdylib", "rlib"] # XXX: note: the rlib is just to prevent Cargo from spitting out a warning +crate-type = [ + "cdylib", + "rlib", +] # XXX: note: the rlib is just to prevent Cargo from spitting out a warning [dependencies] cpp = "0.5" -libc = { workspace=true } -uucore = { version=">=0.0.19", package="uucore", path="../../../../uucore" } +libc = { workspace = true } +uucore = { version = ">=0.0.19", package = "uucore", path = "../../../../uucore" } [build-dependencies] cpp_build = "0.5" diff --git a/src/uu/stty/Cargo.toml b/src/uu/stty/Cargo.toml index ec715314d3..220651003a 100644 --- a/src/uu/stty/Cargo.toml +++ b/src/uu/stty/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/stty.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } -nix = { workspace=true, features = ["term", "ioctl"] } +clap = { workspace = true } +uucore = { workspace = true } +nix = { workspace = true, features = ["term", "ioctl"] } [[bin]] name = "stty" diff --git a/src/uu/sum/Cargo.toml b/src/uu/sum/Cargo.toml index 806c2171d3..37b4d21e0a 100644 --- a/src/uu/sum/Cargo.toml +++ b/src/uu/sum/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/sum.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "sum" diff --git a/src/uu/sync/Cargo.toml b/src/uu/sync/Cargo.toml index c6062b7c1f..36d110046a 100644 --- a/src/uu/sync/Cargo.toml +++ b/src/uu/sync/Cargo.toml @@ -15,15 +15,19 @@ edition = "2021" path = "src/sync.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -uucore = { workspace=true, features=["wide"] } +clap = { workspace = true } +libc = { workspace = true } +uucore = { workspace = true, features = ["wide"] } [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] -nix = { workspace=true } +nix = { workspace = true } [target.'cfg(target_os = "windows")'.dependencies] -windows-sys = { workspace=true, features = ["Win32_Storage_FileSystem", "Win32_System_WindowsProgramming", "Win32_Foundation"] } +windows-sys = { workspace = true, features = [ + "Win32_Storage_FileSystem", + "Win32_System_WindowsProgramming", + "Win32_Foundation", +] } [[bin]] name = "sync" diff --git a/src/uu/tac/Cargo.toml b/src/uu/tac/Cargo.toml index ca68be99dc..a1c2e076a9 100644 --- a/src/uu/tac/Cargo.toml +++ b/src/uu/tac/Cargo.toml @@ -17,11 +17,11 @@ edition = "2021" path = "src/tac.rs" [dependencies] -memchr = { workspace=true } +memchr = { workspace = true } memmap2 = "0.6" -regex = { workspace=true } -clap = { workspace=true } -uucore = { workspace=true } +regex = { workspace = true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "tac" diff --git a/src/uu/tail/Cargo.toml b/src/uu/tail/Cargo.toml index e71c988aa7..81213b5885 100644 --- a/src/uu/tail/Cargo.toml +++ b/src/uu/tail/Cargo.toml @@ -16,21 +16,24 @@ edition = "2021" path = "src/tail.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -memchr = { workspace=true } -notify = { workspace=true } -uucore = { workspace=true } -same-file = { workspace=true } -is-terminal = { workspace=true } -fundu = { workspace=true } +clap = { workspace = true } +libc = { workspace = true } +memchr = { workspace = true } +notify = { workspace = true } +uucore = { workspace = true } +same-file = { workspace = true } +is-terminal = { workspace = true } +fundu = { workspace = true } [target.'cfg(windows)'.dependencies] -windows-sys = { workspace=true, features = ["Win32_System_Threading", "Win32_Foundation"] } -winapi-util = { workspace=true } +windows-sys = { workspace = true, features = [ + "Win32_System_Threading", + "Win32_Foundation", +] } +winapi-util = { workspace = true } [dev-dependencies] -rstest = { workspace=true } +rstest = { workspace = true } [[bin]] name = "tail" diff --git a/src/uu/tee/Cargo.toml b/src/uu/tee/Cargo.toml index ee4bedec80..21d64c0c2e 100644 --- a/src/uu/tee/Cargo.toml +++ b/src/uu/tee/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/tee.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -uucore = { workspace=true, features=["libc", "signals"] } +clap = { workspace = true } +libc = { workspace = true } +uucore = { workspace = true, features = ["libc", "signals"] } [[bin]] name = "tee" diff --git a/src/uu/test/Cargo.toml b/src/uu/test/Cargo.toml index 794aa53770..3c2f274019 100644 --- a/src/uu/test/Cargo.toml +++ b/src/uu/test/Cargo.toml @@ -15,12 +15,12 @@ edition = "2021" path = "src/test.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +libc = { workspace = true } +uucore = { workspace = true } [target.'cfg(target_os = "redox")'.dependencies] -redox_syscall = { workspace=true } +redox_syscall = { workspace = true } [[bin]] name = "test" diff --git a/src/uu/timeout/Cargo.toml b/src/uu/timeout/Cargo.toml index b4b24db126..43cadf3e5d 100644 --- a/src/uu/timeout/Cargo.toml +++ b/src/uu/timeout/Cargo.toml @@ -15,10 +15,10 @@ edition = "2021" path = "src/timeout.rs" [dependencies] -clap = { workspace=true } -libc = { workspace=true } -nix = { workspace=true, features = ["signal"] } -uucore = { workspace=true, features=["process", "signals"] } +clap = { workspace = true } +libc = { workspace = true } +nix = { workspace = true, features = ["signal"] } +uucore = { workspace = true, features = ["process", "signals"] } [[bin]] name = "timeout" diff --git a/src/uu/touch/Cargo.toml b/src/uu/touch/Cargo.toml index 80840525c0..f90725197b 100644 --- a/src/uu/touch/Cargo.toml +++ b/src/uu/touch/Cargo.toml @@ -16,15 +16,23 @@ edition = "2021" path = "src/touch.rs" [dependencies] -filetime = { workspace=true } -clap = { workspace=true } +filetime = { workspace = true } +clap = { workspace = true } # TODO: use workspace dependency (0.3) when switching from time to chrono humantime_to_duration = "0.2.1" -time = { workspace=true, features = ["parsing", "formatting", "local-offset", "macros"] } -uucore = { workspace=true, features=["libc"] } +time = { workspace = true, features = [ + "parsing", + "formatting", + "local-offset", + "macros", +] } +uucore = { workspace = true, features = ["libc"] } [target.'cfg(target_os = "windows")'.dependencies] -windows-sys = { workspace=true, features = ["Win32_Storage_FileSystem", "Win32_Foundation"] } +windows-sys = { workspace = true, features = [ + "Win32_Storage_FileSystem", + "Win32_Foundation", +] } [[bin]] name = "touch" diff --git a/src/uu/tr/Cargo.toml b/src/uu/tr/Cargo.toml index 4869941e99..e3eba0a102 100644 --- a/src/uu/tr/Cargo.toml +++ b/src/uu/tr/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/tr.rs" [dependencies] -nom = { workspace=true } -clap = { workspace=true } -uucore = { workspace=true } +nom = { workspace = true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "tr" diff --git a/src/uu/true/Cargo.toml b/src/uu/true/Cargo.toml index 3171845de1..f7f7e1a6ae 100644 --- a/src/uu/true/Cargo.toml +++ b/src/uu/true/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/true.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "true" diff --git a/src/uu/truncate/Cargo.toml b/src/uu/truncate/Cargo.toml index 54578d038c..bf36e8257c 100644 --- a/src/uu/truncate/Cargo.toml +++ b/src/uu/truncate/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/truncate.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "truncate" diff --git a/src/uu/tsort/Cargo.toml b/src/uu/tsort/Cargo.toml index 46ee8a47e7..b7df32a1dd 100644 --- a/src/uu/tsort/Cargo.toml +++ b/src/uu/tsort/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/tsort.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "tsort" diff --git a/src/uu/tty/Cargo.toml b/src/uu/tty/Cargo.toml index 4e32f38730..d3d16d22a0 100644 --- a/src/uu/tty/Cargo.toml +++ b/src/uu/tty/Cargo.toml @@ -15,10 +15,10 @@ edition = "2021" path = "src/tty.rs" [dependencies] -clap = { workspace=true } -nix = { workspace=true, features=["term"] } -is-terminal = { workspace=true } -uucore = { workspace=true, features=["fs"] } +clap = { workspace = true } +nix = { workspace = true, features = ["term"] } +is-terminal = { workspace = true } +uucore = { workspace = true, features = ["fs"] } [[bin]] name = "tty" diff --git a/src/uu/uname/Cargo.toml b/src/uu/uname/Cargo.toml index 5c02c5e2ef..7b5f455a36 100644 --- a/src/uu/uname/Cargo.toml +++ b/src/uu/uname/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/uname.rs" [dependencies] -platform-info = { workspace=true } -clap = { workspace=true } -uucore = { workspace=true } +platform-info = { workspace = true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "uname" diff --git a/src/uu/unexpand/Cargo.toml b/src/uu/unexpand/Cargo.toml index 537750d3d4..b3d5e1b40b 100644 --- a/src/uu/unexpand/Cargo.toml +++ b/src/uu/unexpand/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/unexpand.rs" [dependencies] -clap = { workspace=true } -unicode-width = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +unicode-width = { workspace = true } +uucore = { workspace = true } [[bin]] name = "unexpand" diff --git a/src/uu/uniq/Cargo.toml b/src/uu/uniq/Cargo.toml index c1343ab011..dec4bf2a49 100644 --- a/src/uu/uniq/Cargo.toml +++ b/src/uu/uniq/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/uniq.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "uniq" diff --git a/src/uu/unlink/Cargo.toml b/src/uu/unlink/Cargo.toml index cc30f7dbd5..10ec571d19 100644 --- a/src/uu/unlink/Cargo.toml +++ b/src/uu/unlink/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/unlink.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true } [[bin]] name = "unlink" diff --git a/src/uu/uptime/Cargo.toml b/src/uu/uptime/Cargo.toml index ab38951c5e..b92254cda2 100644 --- a/src/uu/uptime/Cargo.toml +++ b/src/uu/uptime/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/uptime.rs" [dependencies] -chrono = { workspace=true } -clap = { workspace=true } -uucore = { workspace=true, features=["libc", "utmpx"] } +chrono = { workspace = true } +clap = { workspace = true } +uucore = { workspace = true, features = ["libc", "utmpx"] } [[bin]] name = "uptime" diff --git a/src/uu/users/Cargo.toml b/src/uu/users/Cargo.toml index ec32f3e8aa..81af586291 100644 --- a/src/uu/users/Cargo.toml +++ b/src/uu/users/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/users.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["utmpx"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["utmpx"] } [[bin]] name = "users" diff --git a/src/uu/vdir/Cargo.toml b/src/uu/vdir/Cargo.toml index 4d62489799..68d0c34aeb 100644 --- a/src/uu/vdir/Cargo.toml +++ b/src/uu/vdir/Cargo.toml @@ -15,9 +15,9 @@ edition = "2021" path = "src/vdir.rs" [dependencies] -clap = { workspace=true, features = ["env"] } -uucore = { workspace=true, features=["entries", "fs"] } -uu_ls = { workspace=true } +clap = { workspace = true, features = ["env"] } +uucore = { workspace = true, features = ["entries", "fs"] } +uu_ls = { workspace = true } [[bin]] name = "vdir" diff --git a/src/uu/wc/Cargo.toml b/src/uu/wc/Cargo.toml index b781eaed61..363483bf8a 100644 --- a/src/uu/wc/Cargo.toml +++ b/src/uu/wc/Cargo.toml @@ -15,15 +15,15 @@ edition = "2021" path = "src/wc.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["pipes"] } -bytecount = { workspace=true } -thiserror = { workspace=true } -unicode-width = { workspace=true } +clap = { workspace = true } +uucore = { workspace = true, features = ["pipes"] } +bytecount = { workspace = true } +thiserror = { workspace = true } +unicode-width = { workspace = true } [target.'cfg(unix)'.dependencies] -nix = { workspace=true } -libc = { workspace=true } +nix = { workspace = true } +libc = { workspace = true } [[bin]] name = "wc" diff --git a/src/uu/who/Cargo.toml b/src/uu/who/Cargo.toml index cae50b9a6e..bfbd7909d8 100644 --- a/src/uu/who/Cargo.toml +++ b/src/uu/who/Cargo.toml @@ -15,8 +15,8 @@ edition = "2021" path = "src/who.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["utmpx"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["utmpx"] } [[bin]] name = "who" diff --git a/src/uu/whoami/Cargo.toml b/src/uu/whoami/Cargo.toml index 3114f721a5..fe06a0a7e6 100644 --- a/src/uu/whoami/Cargo.toml +++ b/src/uu/whoami/Cargo.toml @@ -15,14 +15,18 @@ edition = "2021" path = "src/whoami.rs" [dependencies] -clap = { workspace=true } -uucore = { workspace=true, features=["entries"] } +clap = { workspace = true } +uucore = { workspace = true, features = ["entries"] } [target.'cfg(target_os = "windows")'.dependencies] -windows-sys = { workspace=true, features = ["Win32_NetworkManagement_NetManagement", "Win32_System_WindowsProgramming", "Win32_Foundation"] } +windows-sys = { workspace = true, features = [ + "Win32_NetworkManagement_NetManagement", + "Win32_System_WindowsProgramming", + "Win32_Foundation", +] } [target.'cfg(unix)'.dependencies] -libc = { workspace=true } +libc = { workspace = true } [[bin]] name = "whoami" diff --git a/src/uu/yes/Cargo.toml b/src/uu/yes/Cargo.toml index 40674f05a2..0e2b934f3a 100644 --- a/src/uu/yes/Cargo.toml +++ b/src/uu/yes/Cargo.toml @@ -15,15 +15,15 @@ edition = "2021" path = "src/yes.rs" [dependencies] -clap = { workspace=true } -itertools = { workspace=true } +clap = { workspace = true } +itertools = { workspace = true } [target.'cfg(unix)'.dependencies] -uucore = { workspace=true, features=["pipes", "signals"] } -nix = { workspace=true } +uucore = { workspace = true, features = ["pipes", "signals"] } +nix = { workspace = true } [target.'cfg(not(unix))'.dependencies] -uucore = { workspace=true, features=["pipes"] } +uucore = { workspace = true, features = ["pipes"] } [[bin]] name = "yes" diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index d16c3c79e3..7fa4aa3445 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -15,50 +15,58 @@ categories = ["command-line-utilities"] edition = "2021" [lib] -path="src/lib/lib.rs" +path = "src/lib/lib.rs" [dependencies] -clap = { workspace=true } -uucore_procs = { workspace=true } -dns-lookup = { version="2.0.2", optional=true } +clap = { workspace = true } +uucore_procs = { workspace = true } +dns-lookup = { version = "2.0.2", optional = true } dunce = "1.0.4" wild = "2.1" glob = "0.3.1" # * optional -itertools = { version="0.10.5", optional=true } -thiserror = { workspace=true, optional=true } -time = { workspace=true, optional=true, features = ["formatting", "local-offset", "macros"] } +itertools = { version = "0.10.5", optional = true } +thiserror = { workspace = true, optional = true } +time = { workspace = true, optional = true, features = [ + "formatting", + "local-offset", + "macros", +] } # * "problem" dependencies (pinned) -data-encoding = { version="2.4", optional=true } -data-encoding-macro = { version="0.1.13", optional=true } -z85 = { version="3.0.5", optional=true } -libc = { version="0.2.146", optional=true } -once_cell = { workspace=true } +data-encoding = { version = "2.4", optional = true } +data-encoding-macro = { version = "0.1.13", optional = true } +z85 = { version = "3.0.5", optional = true } +libc = { version = "0.2.146", optional = true } +once_cell = { workspace = true } os_display = "0.1.3" -digest = { workspace=true } -hex = { workspace=true } -memchr = { workspace=true } -md-5 = { workspace=true } -sha1 = { workspace=true } -sha2 = { workspace=true } -sha3 = { workspace=true } -blake2b_simd = { workspace=true } -blake3 = { workspace=true } -sm3 = { workspace=true } +digest = { workspace = true } +hex = { workspace = true } +memchr = { workspace = true } +md-5 = { workspace = true } +sha1 = { workspace = true } +sha2 = { workspace = true } +sha3 = { workspace = true } +blake2b_simd = { workspace = true } +blake3 = { workspace = true } +sm3 = { workspace = true } [target.'cfg(unix)'.dependencies] -walkdir = { workspace=true, optional=true } -nix = { workspace=true, features = ["fs", "uio", "zerocopy", "signal"] } +walkdir = { workspace = true, optional = true } +nix = { workspace = true, features = ["fs", "uio", "zerocopy", "signal"] } [dev-dependencies] -clap = { workspace=true } -once_cell = { workspace=true } -tempfile = { workspace=true } +clap = { workspace = true } +once_cell = { workspace = true } +tempfile = { workspace = true } [target.'cfg(target_os = "windows")'.dependencies] -winapi-util = { version= "0.1.5", optional=true } -windows-sys = { version = "0.48.0", optional = true, default-features = false, features = ["Win32_Storage_FileSystem", "Win32_Foundation", "Win32_System_WindowsProgramming"] } +winapi-util = { version = "0.1.5", optional = true } +windows-sys = { version = "0.48.0", optional = true, default-features = false, features = [ + "Win32_Storage_FileSystem", + "Win32_Foundation", + "Win32_System_WindowsProgramming", +] } [features] default = [] diff --git a/src/uucore_procs/Cargo.toml b/src/uucore_procs/Cargo.toml index eedc9001c0..a83baf1d42 100644 --- a/src/uucore_procs/Cargo.toml +++ b/src/uucore_procs/Cargo.toml @@ -19,4 +19,4 @@ proc-macro = true [dependencies] proc-macro2 = "1.0" quote = "1.0" -uuhelp_parser = { path="../uuhelp_parser", version="0.0.19" } +uuhelp_parser = { path = "../uuhelp_parser", version = "0.0.19" } From e817e6fc27cc61cc754de3ab418522c6ef74b3a1 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Thu, 8 Jun 2023 10:52:15 +0200 Subject: [PATCH 457/477] deny.toml: add comments --- deny.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/deny.toml b/deny.toml index 3aaee354a9..57e432767e 100644 --- a/deny.toml +++ b/deny.toml @@ -63,16 +63,25 @@ skip = [ { name = "hermit-abi", version = "0.3.1" }, # procfs { name = "rustix", version = "0.36.14" }, + # rustix { name = "linux-raw-sys", version = "0.1.4" }, # various crates { name = "windows-sys", version = "0.45.0" }, + # windows-sys { name = "windows-targets", version = "0.42.2" }, + # windows-targets { name = "windows_aarch64_gnullvm", version = "0.42.2" }, + # windows-targets { name = "windows_aarch64_msvc", version = "0.42.2" }, + # windows-targets { name = "windows_i686_gnu", version = "0.42.2" }, + # windows-targets { name = "windows_i686_msvc", version = "0.42.2" }, + # windows-targets { name = "windows_x86_64_gnu", version = "0.42.2" }, + # windows-targets { name = "windows_x86_64_gnullvm", version = "0.42.2" }, + # windows-targets { name = "windows_x86_64_msvc", version = "0.42.2" }, # tempfile { name = "redox_syscall", version = "0.3.5" }, From d26c596a4ceb609d306732afcf95215324ef135e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Jun 2023 11:02:36 +0000 Subject: [PATCH 458/477] fix(deps): update rust crate memmap2 to 0.7 --- Cargo.lock | 4 ++-- src/uu/tac/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87b64c4ef1..10f1bf0409 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1405,9 +1405,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9ff02d2efdc645fca1ee55f45545b996e7da776b5b60c4e170334457551693" +checksum = "180d4b35be83d33392d1d1bfbd2ae1eca7ff5de1a94d3fc87faaa99a069e7cbd" dependencies = [ "libc", ] diff --git a/src/uu/tac/Cargo.toml b/src/uu/tac/Cargo.toml index a1c2e076a9..4455ebe139 100644 --- a/src/uu/tac/Cargo.toml +++ b/src/uu/tac/Cargo.toml @@ -18,7 +18,7 @@ path = "src/tac.rs" [dependencies] memchr = { workspace = true } -memmap2 = "0.6" +memmap2 = "0.7" regex = { workspace = true } clap = { workspace = true } uucore = { workspace = true } From e1fd9e5342484c6a1943a26977a69c502da9fd30 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Jun 2023 22:55:22 +0000 Subject: [PATCH 459/477] chore(deps): update rust crate blake3 to 1.4.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10f1bf0409..0357f7fe09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,9 +192,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.3.3" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +checksum = "729b71f35bd3fa1a4c86b85d32c8b9069ea7fe14f7a53cfabb65f62d4265b888" dependencies = [ "arrayref", "arrayvec", diff --git a/Cargo.toml b/Cargo.toml index 179584604f..3d20bb97d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -338,7 +338,7 @@ sha1 = "0.10.5" sha2 = "0.10.6" sha3 = "0.10.8" blake2b_simd = "1.0.1" -blake3 = "1.3.3" +blake3 = "1.4.0" sm3 = "0.4.2" digest = "0.10.7" From ad96a1b8a065fa42903079d9c2b296700954908b Mon Sep 17 00:00:00 2001 From: Frantisek Kropac Date: Sat, 10 Jun 2023 09:22:01 +0200 Subject: [PATCH 460/477] Find MountInfo properly when symlink is used (#4929) * Find MountInfo properly when symlink is entered According to GNU implementation the entered path is being compared with the canonicalized device name in MountInfo. Co-authored-by: Frantisek Kropac Co-authored-by: Sylvestre Ledru --- Cargo.lock | 1 + src/uu/df/Cargo.toml | 3 +++ src/uu/df/src/filesystem.rs | 24 ++++++++++++++++++++---- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0357f7fe09..b7f071c5e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2562,6 +2562,7 @@ name = "uu_df" version = "0.0.19" dependencies = [ "clap", + "tempfile", "unicode-width", "uucore", ] diff --git a/src/uu/df/Cargo.toml b/src/uu/df/Cargo.toml index 0974a443c5..2be3967afb 100644 --- a/src/uu/df/Cargo.toml +++ b/src/uu/df/Cargo.toml @@ -19,6 +19,9 @@ clap = { workspace = true } uucore = { workspace = true, features = ["libc", "fsext"] } unicode-width = { workspace = true } +[dev-dependencies] +tempfile = "3" + [[bin]] name = "df" path = "src/main.rs" diff --git a/src/uu/df/src/filesystem.rs b/src/uu/df/src/filesystem.rs index 461815e671..813846a6c7 100644 --- a/src/uu/df/src/filesystem.rs +++ b/src/uu/df/src/filesystem.rs @@ -42,7 +42,7 @@ pub(crate) struct Filesystem { /// This function returns the element of `mounts` on which `path` is /// mounted. If there are no matches, this function returns /// [`None`]. If there are two or more matches, then the single -/// [`MountInfo`] with the longest mount directory is returned. +/// [`MountInfo`] with the device name corresponding to the entered path. /// /// If `canonicalize` is `true`, then the `path` is canonicalized /// before checking whether it matches any mount directories. @@ -68,9 +68,19 @@ where path.as_ref().to_path_buf() }; + // Find the potential mount point that matches entered path let maybe_mount_point = mounts .iter() - .find(|mi| mi.dev_name.eq(&path.to_string_lossy())); + // Create pair MountInfo, canonicalized device name + // TODO Abstract from accessing real filesystem to + // make code more testable + .map(|m| (m, std::fs::canonicalize(&m.dev_name))) + // Ignore non existing paths + .filter(|m| m.1.is_ok()) + .map(|m| (m.0, m.1.ok().unwrap())) + // Try to find canonicalized device name corresponding to entered path + .find(|m| m.1.eq(&path)) + .map(|m| m.0); maybe_mount_point.or_else(|| { mounts @@ -211,10 +221,16 @@ mod tests { #[test] fn test_dev_name_match() { + let tmp = tempfile::TempDir::new().expect("Failed to create temp dir"); + let dev_name = std::fs::canonicalize(tmp.path()) + .expect("Failed to canonicalize tmp path") + .to_string_lossy() + .to_string(); + let mut mount_info = mount_info("/foo"); - mount_info.dev_name = "/dev/sda2".to_string(); + mount_info.dev_name = dev_name.clone(); let mounts = [mount_info]; - let actual = mount_info_from_path(&mounts, "/dev/sda2", false).unwrap(); + let actual = mount_info_from_path(&mounts, dev_name, false).unwrap(); assert!(mount_info_eq(actual, &mounts[0])); } } From ab42b1e5995dec8dfbf145c0229afc9a0c71d920 Mon Sep 17 00:00:00 2001 From: Rayhan Faizel Date: Sat, 10 Jun 2023 18:31:30 +0530 Subject: [PATCH 461/477] uucore: add function which checks hardlink as well as directed symlink --- src/uucore/src/lib/features/fs.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/uucore/src/lib/features/fs.rs b/src/uucore/src/lib/features/fs.rs index 797be9c2cd..a97e8ac9c2 100644 --- a/src/uucore/src/lib/features/fs.rs +++ b/src/uucore/src/lib/features/fs.rs @@ -648,6 +648,36 @@ pub fn are_hardlinks_to_same_file(source: &Path, target: &Path) -> bool { source_metadata.ino() == target_metadata.ino() && source_metadata.dev() == target_metadata.dev() } +#[cfg(not(unix))] +pub fn are_hardlinks_or_one_way_symlink_to_same_file(_source: &Path, _target: &Path) -> bool { + false +} + +/// Checks if either two paths are hard links to the same file or if the source path is a symbolic link which when fully resolved points to target path +/// +/// # Arguments +/// +/// * `source` - A reference to a `Path` representing the source path. +/// * `target` - A reference to a `Path` representing the target path. +/// +/// # Returns +/// +/// * `bool` - Returns `true` if either of above conditions are true, and `false` otherwise. +#[cfg(unix)] +pub fn are_hardlinks_or_one_way_symlink_to_same_file(source: &Path, target: &Path) -> bool { + let source_metadata = match fs::metadata(source) { + Ok(metadata) => metadata, + Err(_) => return false, + }; + + let target_metadata = match fs::symlink_metadata(target) { + Ok(metadata) => metadata, + Err(_) => return false, + }; + + source_metadata.ino() == target_metadata.ino() && source_metadata.dev() == target_metadata.dev() +} + #[cfg(test)] mod tests { // Note this useful idiom: importing names from outer (for mod tests) scope. From 28ad5cab9f25f15e6584ac6eb97dec301670dc31 Mon Sep 17 00:00:00 2001 From: Rayhan Faizel Date: Sat, 10 Jun 2023 18:32:09 +0530 Subject: [PATCH 462/477] mv: fix GNU test tests/mv/into-self-2.sh --- src/uu/mv/src/mv.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 5ca677c696..523183b0b7 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -25,7 +25,7 @@ use std::path::{Path, PathBuf}; use uucore::backup_control::{self, BackupMode}; use uucore::display::Quotable; use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError}; -use uucore::fs::are_hardlinks_to_same_file; +use uucore::fs::are_hardlinks_or_one_way_symlink_to_same_file; use uucore::update_control::{self, UpdateMode}; use uucore::{format_usage, help_about, help_section, help_usage, prompt_yes, show}; @@ -255,7 +255,7 @@ fn handle_two_paths(source: &Path, target: &Path, b: &Behavior) -> UResult<()> { return Err(MvError::NoSuchFile(source.quote().to_string()).into()); } - if (source.eq(target) || are_hardlinks_to_same_file(source, target)) + if (source.eq(target) || are_hardlinks_or_one_way_symlink_to_same_file(source, target)) && b.backup != BackupMode::SimpleBackup { if source.eq(Path::new(".")) || source.ends_with("/.") || source.is_file() { From 6bc15aac99d6fd77d09fa8cc88b109f6a18c39d5 Mon Sep 17 00:00:00 2001 From: Rayhan Faizel Date: Sat, 10 Jun 2023 18:32:41 +0530 Subject: [PATCH 463/477] tests/mv: Test for particular edge cases when handling symlink files --- tests/by-util/test_mv.rs | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index f73d3249d4..cef95d195d 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -417,6 +417,54 @@ fn test_mv_same_hardlink() { .stderr_is(format!("mv: '{file_a}' and '{file_b}' are the same file\n",)); } +#[test] +#[cfg(all(unix, not(target_os = "android")))] +fn test_mv_same_symlink() { + let (at, mut ucmd) = at_and_ucmd!(); + let file_a = "test_mv_same_file_a"; + let file_b = "test_mv_same_file_b"; + let file_c = "test_mv_same_file_c"; + + at.touch(file_a); + + at.symlink_file(file_a, file_b); + + ucmd.arg(file_b) + .arg(file_a) + .fails() + .stderr_is(format!("mv: '{file_b}' and '{file_a}' are the same file\n",)); + + let (at2, mut ucmd2) = at_and_ucmd!(); + at2.touch(file_a); + + at2.symlink_file(file_a, file_b); + ucmd2.arg(file_a).arg(file_b).succeeds(); + assert!(at2.file_exists(file_b)); + assert!(!at2.file_exists(file_a)); + + let (at3, mut ucmd3) = at_and_ucmd!(); + at3.touch(file_a); + + at3.symlink_file(file_a, file_b); + at3.symlink_file(file_b, file_c); + + ucmd3.arg(file_c).arg(file_b).succeeds(); + assert!(!at3.symlink_exists(file_c)); + assert!(at3.symlink_exists(file_b)); + + let (at4, mut ucmd4) = at_and_ucmd!(); + at4.touch(file_a); + + at4.symlink_file(file_a, file_b); + at4.symlink_file(file_b, file_c); + + ucmd4 + .arg(file_c) + .arg(file_a) + .fails() + .stderr_is(format!("mv: '{file_c}' and '{file_a}' are the same file\n",)); +} + #[test] #[cfg(all(unix, not(target_os = "android")))] fn test_mv_same_hardlink_backup_simple() { From 67114ac63c580a7a7ff9e75ef7605b3d20385c91 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 11 Jun 2023 14:05:26 +0200 Subject: [PATCH 464/477] date: switch to parse_datetime --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 4 ++-- deny.toml | 2 -- src/uu/date/Cargo.toml | 4 ++-- src/uu/date/src/date.rs | 4 ++-- 5 files changed, 18 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bba47cff64..a92d014169 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1154,16 +1154,6 @@ dependencies = [ "time", ] -[[package]] -name = "humantime_to_duration" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a80a233096ddccb74e62145f3a49cacea6a2669ee90f6e144e15fe28f4037c4" -dependencies = [ - "chrono", - "regex", -] - [[package]] name = "iana-time-zone" version = "0.1.53" @@ -1654,6 +1644,16 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "parse_datetime" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fecceaede7767a9a98058687a321bc91742eff7670167a34104afb30fc8757df" +dependencies = [ + "chrono", + "regex", +] + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -2539,8 +2539,8 @@ version = "0.0.19" dependencies = [ "chrono", "clap", - "humantime_to_duration 0.3.1", "libc", + "parse_datetime", "uucore", "windows-sys 0.48.0", ] @@ -3235,7 +3235,7 @@ version = "0.0.19" dependencies = [ "clap", "filetime", - "humantime_to_duration 0.2.1", + "humantime_to_duration", "time", "uucore", "windows-sys 0.48.0", diff --git a/Cargo.toml b/Cargo.toml index 6f7cec3c98..09e1209577 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ # coreutils (uutils) # * see the repository LICENSE, README, and CONTRIBUTING files for more information -# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen humantime uuhelp +# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen datetime uuhelp [package] name = "coreutils" @@ -284,7 +284,6 @@ fundu = "1.0.0" gcd = "2.3" glob = "0.3.1" half = "2.2" -humantime_to_duration = "0.3.1" indicatif = "0.17" is-terminal = "0.4.7" itertools = "0.10.5" @@ -302,6 +301,7 @@ number_prefix = "0.4" once_cell = "1.18.0" onig = { version = "~6.4", default-features = false } ouroboros = "0.15.6" +parse_datetime = "0.4.0" phf = "0.11.1" phf_codegen = "0.11.1" platform-info = "2.0.1" diff --git a/deny.toml b/deny.toml index 57e432767e..8687fbfae6 100644 --- a/deny.toml +++ b/deny.toml @@ -87,8 +87,6 @@ skip = [ { name = "redox_syscall", version = "0.3.5" }, # cpp_macros { name = "aho-corasick", version = "0.7.19" }, - # touch, can be remove when touch switches from time to chrono - { name = "humantime_to_duration", version = "0.2.1" }, ] # spell-checker: enable diff --git a/src/uu/date/Cargo.toml b/src/uu/date/Cargo.toml index 62308bf53a..e28762493e 100644 --- a/src/uu/date/Cargo.toml +++ b/src/uu/date/Cargo.toml @@ -1,4 +1,4 @@ -# spell-checker:ignore humantime +# spell-checker:ignore datetime [package] name = "uu_date" version = "0.0.19" @@ -19,7 +19,7 @@ path = "src/date.rs" chrono = { workspace = true } clap = { workspace = true } uucore = { workspace = true } -humantime_to_duration = { workspace = true } +parse_datetime = { workspace = true } [target.'cfg(unix)'.dependencies] libc = { workspace = true } diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index 44b54be5e8..7bd64839c6 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -6,7 +6,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (chrono) Datelike Timelike ; (format) DATEFILE MMDDhhmm ; (vars) datetime datetimes humantime +// spell-checker:ignore (chrono) Datelike Timelike ; (format) DATEFILE MMDDhhmm ; (vars) datetime datetimes use chrono::format::{Item, StrftimeItems}; use chrono::{DateTime, Duration, FixedOffset, Local, Offset, Utc}; @@ -170,7 +170,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { }; let date_source = if let Some(date) = matches.get_one::(OPT_DATE) { - if let Ok(duration) = humantime_to_duration::from_str(date.as_str()) { + if let Ok(duration) = parse_datetime::from_str(date.as_str()) { DateSource::Human(duration) } else { DateSource::Custom(date.into()) From 18cbb862e21380d7714b2a0729fe2aea323c83d0 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 11 Jun 2023 18:53:42 +0200 Subject: [PATCH 465/477] Create a FUNDING.yml file The sponsor will be used for improving the CI machines on github --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..ccae1f8313 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: uutils From c113284a4bf6441e59d621bc1022f23d48405f85 Mon Sep 17 00:00:00 2001 From: Rayhan Faizel Date: Mon, 12 Jun 2023 23:46:33 +0530 Subject: [PATCH 466/477] uucore: modify are_hardlinks_to_same_file to check only immediate metadata --- src/uucore/src/lib/features/fs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uucore/src/lib/features/fs.rs b/src/uucore/src/lib/features/fs.rs index a97e8ac9c2..e92d0977f5 100644 --- a/src/uucore/src/lib/features/fs.rs +++ b/src/uucore/src/lib/features/fs.rs @@ -635,12 +635,12 @@ pub fn are_hardlinks_to_same_file(_source: &Path, _target: &Path) -> bool { /// * `bool` - Returns `true` if the paths are hard links to the same file, and `false` otherwise. #[cfg(unix)] pub fn are_hardlinks_to_same_file(source: &Path, target: &Path) -> bool { - let source_metadata = match fs::metadata(source) { + let source_metadata = match fs::symlink_metadata(source) { Ok(metadata) => metadata, Err(_) => return false, }; - let target_metadata = match fs::metadata(target) { + let target_metadata = match fs::symlink_metadata(target) { Ok(metadata) => metadata, Err(_) => return false, }; From fa11315ce7f2b47c098cb5b3741a0b0b1e11eb9e Mon Sep 17 00:00:00 2001 From: Rayhan Faizel Date: Mon, 12 Jun 2023 23:48:49 +0530 Subject: [PATCH 467/477] mv: check strictly for hard links first before checking for symlinks to catch a very special case, plus ensure only nobackupmode is considered --- src/uu/mv/src/mv.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 523183b0b7..6289e79f90 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -25,7 +25,7 @@ use std::path::{Path, PathBuf}; use uucore::backup_control::{self, BackupMode}; use uucore::display::Quotable; use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError}; -use uucore::fs::are_hardlinks_or_one_way_symlink_to_same_file; +use uucore::fs::{are_hardlinks_or_one_way_symlink_to_same_file, are_hardlinks_to_same_file}; use uucore::update_control::{self, UpdateMode}; use uucore::{format_usage, help_about, help_section, help_usage, prompt_yes, show}; @@ -255,8 +255,10 @@ fn handle_two_paths(source: &Path, target: &Path, b: &Behavior) -> UResult<()> { return Err(MvError::NoSuchFile(source.quote().to_string()).into()); } - if (source.eq(target) || are_hardlinks_or_one_way_symlink_to_same_file(source, target)) - && b.backup != BackupMode::SimpleBackup + if (source.eq(target) + || are_hardlinks_to_same_file(source, target) + || are_hardlinks_or_one_way_symlink_to_same_file(source, target)) + && b.backup == BackupMode::NoBackup { if source.eq(Path::new(".")) || source.ends_with("/.") || source.is_file() { return Err( From 269ffc12b47243fcd16dcda561eee558f4eb12dd Mon Sep 17 00:00:00 2001 From: Rayhan Faizel Date: Mon, 12 Jun 2023 23:49:28 +0530 Subject: [PATCH 468/477] tests/mv: add tests to check for copying symlinks onto hardlinks to symlink --- tests/by-util/test_mv.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index cef95d195d..0c292c50d8 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -465,6 +465,35 @@ fn test_mv_same_symlink() { .stderr_is(format!("mv: '{file_c}' and '{file_a}' are the same file\n",)); } +#[test] +#[cfg(all(unix, not(target_os = "android")))] +fn test_mv_hardlink_to_symlink() { + let (at, mut ucmd) = at_and_ucmd!(); + let file = "file"; + let symlink_file = "symlink"; + let hardlink_to_symlink_file = "hardlink_to_symlink"; + + at.touch(file); + at.symlink_file(file, symlink_file); + at.hard_link(symlink_file, hardlink_to_symlink_file); + + ucmd.arg(symlink_file).arg(hardlink_to_symlink_file).fails(); + + let (at2, mut ucmd2) = at_and_ucmd!(); + + at2.touch(file); + at2.symlink_file(file, symlink_file); + at2.hard_link(symlink_file, hardlink_to_symlink_file); + + ucmd2 + .arg("--backup") + .arg(symlink_file) + .arg(hardlink_to_symlink_file) + .succeeds(); + assert!(!at2.symlink_exists(symlink_file)); + assert!(at2.symlink_exists(&format!("{hardlink_to_symlink_file}~"))); +} + #[test] #[cfg(all(unix, not(target_os = "android")))] fn test_mv_same_hardlink_backup_simple() { From fe5bf911e54cd0a7631061d62a08372c1ff333c8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 06:09:54 +0000 Subject: [PATCH 469/477] chore(deps): update davidanson/markdownlint-cli2-action action to v11 --- .github/workflows/CICD.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index b52ea50980..47da567b28 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -319,7 +319,7 @@ jobs: shell: bash run: | RUSTDOCFLAGS="-Dwarnings" cargo doc ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-deps --workspace --document-private-items - - uses: DavidAnson/markdownlint-cli2-action@v10 + - uses: DavidAnson/markdownlint-cli2-action@v11 with: command: fix globs: | From 3506dd11b8562e08c9cb3f0a7abc69ac514de5d0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Jun 2023 19:18:09 +0000 Subject: [PATCH 470/477] chore(deps): update rust crate sha2 to 0.10.7 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a92d014169..84d6a9c34a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2096,9 +2096,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", diff --git a/Cargo.toml b/Cargo.toml index 09e1209577..a7df5d46a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -335,7 +335,7 @@ zip = { version = "0.6.6", default_features = false, features = ["deflate"] } hex = "0.4.3" md-5 = "0.10.5" sha1 = "0.10.5" -sha2 = "0.10.6" +sha2 = "0.10.7" sha3 = "0.10.8" blake2b_simd = "1.0.1" blake3 = "1.4.0" From 6865f91fd3b92ea9338ef4c7a2c96780a195c926 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Jun 2023 00:01:15 +0000 Subject: [PATCH 471/477] chore(deps): update rust crate notify to v6.0.1 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a92d014169..1c9553fe60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1462,9 +1462,9 @@ dependencies = [ [[package]] name = "notify" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d9ba6c734de18ca27c8cef5cd7058aa4ac9f63596131e4c7e41e579319032a2" +checksum = "5738a2795d57ea20abec2d6d76c6081186709c0024187cd5977265eda6598b51" dependencies = [ "bitflags", "crossbeam-channel", diff --git a/Cargo.toml b/Cargo.toml index 09e1209577..d35f38ddb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -294,7 +294,7 @@ lscolors = { version = "0.14.0", default-features = false, features = [ memchr = "2" nix = { version = "0.26", default-features = false } nom = "7.1.3" -notify = { version = "=6.0.0", features = ["macos_kqueue"] } +notify = { version = "=6.0.1", features = ["macos_kqueue"] } num-bigint = "0.4.3" num-traits = "0.2.15" number_prefix = "0.4" From 47d0ac4a421b370e4655051d59b05830aa8138da Mon Sep 17 00:00:00 2001 From: John Shin Date: Sat, 17 Jun 2023 19:31:27 -0700 Subject: [PATCH 472/477] sync: fix error msg --- src/uu/sync/src/sync.rs | 4 ++-- tests/by-util/test_sync.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/uu/sync/src/sync.rs b/src/uu/sync/src/sync.rs index e12703bcab..821ad639b5 100644 --- a/src/uu/sync/src/sync.rs +++ b/src/uu/sync/src/sync.rs @@ -173,7 +173,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let path = Path::new(&f); if let Err(e) = open(path, OFlag::O_NONBLOCK, Mode::empty()) { if e != Errno::EACCES || (e == Errno::EACCES && path.is_dir()) { - return e.map_err_context(|| format!("cannot stat {}", f.quote()))?; + return e.map_err_context(|| format!("error opening {}", f.quote()))?; } } } @@ -183,7 +183,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if !Path::new(&f).exists() { return Err(USimpleError::new( 1, - format!("cannot stat {}: No such file or directory", f.quote()), + format!("error opening {}: No such file or directory", f.quote()), )); } } diff --git a/tests/by-util/test_sync.rs b/tests/by-util/test_sync.rs index d55a874ba8..9cae3b8a0c 100644 --- a/tests/by-util/test_sync.rs +++ b/tests/by-util/test_sync.rs @@ -41,7 +41,7 @@ fn test_sync_no_existing_files() { .arg("--data") .arg("do-no-exist") .fails() - .stderr_contains("cannot stat"); + .stderr_contains("error opening"); } #[test] @@ -63,9 +63,9 @@ fn test_sync_no_permission_dir() { ts.ccmd("chmod").arg("0").arg(dir).succeeds(); let result = ts.ucmd().arg("--data").arg(dir).fails(); - result.stderr_contains("sync: cannot stat 'foo': Permission denied"); + result.stderr_contains("sync: error opening 'foo': Permission denied"); let result = ts.ucmd().arg(dir).fails(); - result.stderr_contains("sync: cannot stat 'foo': Permission denied"); + result.stderr_contains("sync: error opening 'foo': Permission denied"); } #[cfg(not(target_os = "windows"))] From 5882151eb10878e177df2f483c7ca0b234a52b54 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 18 Jun 2023 15:13:15 +0200 Subject: [PATCH 473/477] deny.toml: add hashbrown to skip list --- deny.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deny.toml b/deny.toml index 8687fbfae6..780de3c8cf 100644 --- a/deny.toml +++ b/deny.toml @@ -87,6 +87,8 @@ skip = [ { name = "redox_syscall", version = "0.3.5" }, # cpp_macros { name = "aho-corasick", version = "0.7.19" }, + # ordered-multimap (via rust-ini) + { name = "hashbrown", version = "0.13.2" }, ] # spell-checker: enable From 9fbc98fc4edb505d830fa696dad8fd1e8d684e7b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 18 Jun 2023 14:05:34 +0000 Subject: [PATCH 474/477] chore(deps): update rust crate rust-ini to 0.19.0 --- Cargo.lock | 62 +++++++++++++++++++++++++++++++++++++++++++++++------- Cargo.toml | 2 +- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7394c98a1b..2e39978ca6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -371,6 +371,28 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "const-random" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e" +dependencies = [ + "const-random-macro", + "proc-macro-hack", +] + +[[package]] +name = "const-random-macro" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb" +dependencies = [ + "getrandom", + "once_cell", + "proc-macro-hack", + "tiny-keccak", +] + [[package]] name = "constant_time_eq" version = "0.2.4" @@ -809,9 +831,12 @@ dependencies = [ [[package]] name = "dlv-list" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" +checksum = "d529fd73d344663edfd598ccb3f344e46034db51ebd103518eae34338248ad73" +dependencies = [ + "const-random", +] [[package]] name = "dns-lookup" @@ -1106,6 +1131,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1572,12 +1603,12 @@ dependencies = [ [[package]] name = "ordered-multimap" -version = "0.4.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +checksum = "4ed8acf08e98e744e5384c8bc63ceb0364e68a6854187221c18df61c4797690e" dependencies = [ "dlv-list", - "hashbrown", + "hashbrown 0.13.2", ] [[package]] @@ -1774,6 +1805,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "proc-macro2" version = "1.0.47" @@ -1973,9 +2010,9 @@ dependencies = [ [[package]] name = "rust-ini" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" +checksum = "7e2a3bcec1f113553ef1c88aae6c020a369d03d55b58de9869a0908930385091" dependencies = [ "cfg-if", "ordered-multimap", @@ -2329,6 +2366,15 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "typenum" version = "1.15.0" @@ -2347,7 +2393,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137" dependencies = [ - "hashbrown", + "hashbrown 0.12.3", "regex", ] diff --git a/Cargo.toml b/Cargo.toml index c0f6ab7795..e92f6719e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -312,7 +312,7 @@ rayon = "1.7" redox_syscall = "0.3" regex = "1.8.4" rstest = "0.17.0" -rust-ini = "0.18.0" +rust-ini = "0.19.0" same-file = "1.0.6" selinux = "0.4" signal-hook = "0.3.15" From 7306be6e5862fd7081ea735effe6c17290523d19 Mon Sep 17 00:00:00 2001 From: Kostiantyn Hryshchuk Date: Sun, 18 Jun 2023 15:26:23 +0200 Subject: [PATCH 475/477] fixed shred -u for windows fixed shred panic on windows --- src/uu/shred/src/shred.rs | 4 +++- tests/by-util/test_shred.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 5ec1d12135..fd14a32459 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -532,7 +532,9 @@ fn wipe_name(orig_path: &Path, verbose: bool) -> Option { } // Sync every file rename - let new_file = File::open(new_path.clone()) + let new_file = OpenOptions::new() + .write(true) + .open(new_path.clone()) .expect("Failed to open renamed file for syncing"); new_file.sync_all().expect("Failed to sync renamed file"); diff --git a/tests/by-util/test_shred.rs b/tests/by-util/test_shred.rs index a34345aeee..d98b840c47 100644 --- a/tests/by-util/test_shred.rs +++ b/tests/by-util/test_shred.rs @@ -18,7 +18,7 @@ fn test_shred_remove() { at.touch(file_b); // Shred file_a. - scene.ucmd().arg("-u").arg(file_a).run(); + scene.ucmd().arg("-u").arg(file_a).succeeds(); // file_a was deleted, file_b exists. assert!(!at.file_exists(file_a)); From b7154a80e121e75429769c6c04ac16bc9dc1325d Mon Sep 17 00:00:00 2001 From: Damon Harris Date: Sun, 18 Jun 2023 07:41:11 +0530 Subject: [PATCH 476/477] od: fix parsing of hex input ending with `E` --- src/uu/od/src/parse_nrofbytes.rs | 3 ++- tests/by-util/test_od.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/uu/od/src/parse_nrofbytes.rs b/src/uu/od/src/parse_nrofbytes.rs index 4c310755b3..7d3bca03db 100644 --- a/src/uu/od/src/parse_nrofbytes.rs +++ b/src/uu/od/src/parse_nrofbytes.rs @@ -43,7 +43,7 @@ pub fn parse_number_of_bytes(s: &str) -> Result { len -= 1; } #[cfg(target_pointer_width = "64")] - Some('E') => { + Some('E') if radix != 16 => { multiply = 1024 * 1024 * 1024 * 1024 * 1024 * 1024; len -= 1; } @@ -84,6 +84,7 @@ fn test_parse_number_of_bytes() { // hex input assert_eq!(15, parse_number_of_bytes("0xf").unwrap()); + assert_eq!(14, parse_number_of_bytes("0XE").unwrap()); assert_eq!(15, parse_number_of_bytes("0XF").unwrap()); assert_eq!(27, parse_number_of_bytes("0x1b").unwrap()); assert_eq!(16 * 1024, parse_number_of_bytes("0x10k").unwrap()); diff --git a/tests/by-util/test_od.rs b/tests/by-util/test_od.rs index 24626cd767..54ac06384a 100644 --- a/tests/by-util/test_od.rs +++ b/tests/by-util/test_od.rs @@ -627,6 +627,35 @@ fn test_skip_bytes() { )); } +#[test] +fn test_skip_bytes_hex() { + let input = "abcdefghijklmnopq"; // spell-checker:disable-line + new_ucmd!() + .arg("-c") + .arg("--skip-bytes=0xB") + .run_piped_stdin(input.as_bytes()) + .no_stderr() + .success() + .stdout_is(unindent( + " + 0000013 l m n o p q + 0000021 + ", + )); + new_ucmd!() + .arg("-c") + .arg("--skip-bytes=0xE") + .run_piped_stdin(input.as_bytes()) + .no_stderr() + .success() + .stdout_is(unindent( + " + 0000016 o p q + 0000021 + ", + )); +} + #[test] fn test_skip_bytes_error() { let input = "12345"; From c3f2ac6f044e1d00cb440214c7ddb5d5bdeea505 Mon Sep 17 00:00:00 2001 From: yt2b Date: Tue, 20 Jun 2023 23:20:22 +0900 Subject: [PATCH 477/477] yes: add --version option --- src/uu/yes/src/yes.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uu/yes/src/yes.rs b/src/uu/yes/src/yes.rs index fd51240646..72c19b8728 100644 --- a/src/uu/yes/src/yes.rs +++ b/src/uu/yes/src/yes.rs @@ -9,7 +9,7 @@ // cSpell:ignore strs -use clap::{builder::ValueParser, Arg, ArgAction, Command}; +use clap::{builder::ValueParser, crate_version, Arg, ArgAction, Command}; use std::error::Error; use std::ffi::OsString; use std::io::{self, Write}; @@ -44,6 +44,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pub fn uu_app() -> Command { Command::new(uucore::util_name()) + .version(crate_version!()) .about(ABOUT) .override_usage(format_usage(USAGE)) .arg(