From 5a62dcafaa9f065f343f14c178c292f077a5347d Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 16 Dec 2020 23:52:42 +0100 Subject: [PATCH] bug(cp): like gnu/cp, don't show any message when --no-clobber is used Simple example: touch bar rm -rf /tmp/foo mkdir -p /tmp/foo cp -pnL -v bar /tmp/foo echo $? cp -pnL -v bar /tmp/foo echo $? rm -rf /tmp/foo mkdir -p /tmp/foo ./target/debug/coreutils cp -pnL -v bar /tmp/foo echo $? ./target/debug/coreutils cp -pnL bar /tmp/foo echo $? --- src/uu/cp/src/cp.rs | 19 +++++++++++-------- tests/by-util/test_cp.rs | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 73713555a..e933ce338 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -814,10 +814,17 @@ fn copy(sources: &[Source], target: &Target, options: &Options) -> CopyResult<() } if !found_hard_link { if let Err(error) = copy_source(source, target, &target_type, options) { - show_error!("{}", error); match error { - Error::Skipped(_) => (), - _ => non_fatal_errors = true, + // When using --no-clobber, we don't want to show + // an error message + Error::NotAllFilesCopied => (), + Error::Skipped(_) => { + show_error!("{}", error); + } + _ => { + show_error!("{}", error); + non_fatal_errors = true + } } } } @@ -993,11 +1000,7 @@ fn copy_directory(root: &Path, target: &Target, options: &Options) -> CopyResult impl OverwriteMode { fn verify(&self, path: &Path) -> CopyResult<()> { match *self { - OverwriteMode::NoClobber => Err(Error::Skipped(format!( - "Not overwriting {} because of option '{}'", - path.display(), - OPT_NO_CLOBBER - ))), + OverwriteMode::NoClobber => Err(Error::NotAllFilesCopied), OverwriteMode::Interactive(_) => { if prompt_yes!("{}: overwrite {}? ", executable!(), path.display()) { Ok(()) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 47d28f63a..e7ea67d19 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -255,7 +255,40 @@ fn test_cp_arg_no_clobber() { assert!(result.success); assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n"); - assert!(result.stderr.contains("Not overwriting")); +} + +#[test] +fn test_cp_arg_no_clobber_twice() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + at.touch("source.txt"); + let result = scene + .ucmd() + .arg("--no-clobber") + .arg("source.txt") + .arg("dest.txt") + .run(); + + println!("stderr = {:?}", result.stderr); + println!("stdout = {:?}", result.stdout); + assert!(result.success); + assert!(result.stderr.is_empty()); + assert_eq!(at.read("source.txt"), ""); + + at.append("source.txt", "some-content"); + let result = scene + .ucmd() + .arg("--no-clobber") + .arg("source.txt") + .arg("dest.txt") + .run(); + + assert!(result.success); + assert_eq!(at.read("source.txt"), "some-content"); + // Should be empty as the "no-clobber" should keep + // the previous version + assert_eq!(at.read("dest.txt"), ""); + assert!(!result.stderr.contains("Not overwriting")); } #[test]