From cd3c921d1eaa7f4a6a7104700f213660866ef1f9 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 4 May 2025 09:31:34 +0200 Subject: [PATCH] cp: copy dir if source path ends with dot (#7874) --- src/uu/cp/src/copydir.rs | 49 +--------------------------------------- tests/by-util/test_cp.rs | 18 +++++++++++++++ 2 files changed, 19 insertions(+), 48 deletions(-) diff --git a/src/uu/cp/src/copydir.rs b/src/uu/cp/src/copydir.rs index 2079affa3..d2e367c5c 100644 --- a/src/uu/cp/src/copydir.rs +++ b/src/uu/cp/src/copydir.rs @@ -201,27 +201,6 @@ impl Entry { } } -/// Decide whether the given path ends with `/.`. -/// -/// # Examples -/// -/// ```rust,ignore -/// assert!(ends_with_slash_dot("/.")); -/// assert!(ends_with_slash_dot("./.")); -/// assert!(ends_with_slash_dot("a/.")); -/// -/// assert!(!ends_with_slash_dot(".")); -/// assert!(!ends_with_slash_dot("./")); -/// assert!(!ends_with_slash_dot("a/..")); -/// ``` -fn ends_with_slash_dot

(path: P) -> bool -where - P: AsRef, -{ - // `path.ends_with(".")` does not seem to work - path.as_ref().display().to_string().ends_with("/.") -} - #[allow(clippy::too_many_arguments)] /// Copy a single entry during a directory traversal. fn copy_direntry( @@ -248,10 +227,7 @@ fn copy_direntry( // If the source is a directory and the destination does not // exist, ... - if source_absolute.is_dir() - && !ends_with_slash_dot(&source_absolute) - && !local_to_target.exists() - { + if source_absolute.is_dir() && !local_to_target.exists() { return if target_is_file { Err("cannot overwrite non-directory with directory".into()) } else { @@ -590,26 +566,3 @@ fn build_dir( builder.create(path)?; Ok(()) } - -#[cfg(test)] -mod tests { - use super::ends_with_slash_dot; - - #[test] - #[allow(clippy::cognitive_complexity)] - fn test_ends_with_slash_dot() { - assert!(ends_with_slash_dot("/.")); - assert!(ends_with_slash_dot("./.")); - assert!(ends_with_slash_dot("../.")); - assert!(ends_with_slash_dot("a/.")); - assert!(ends_with_slash_dot("/a/.")); - - assert!(!ends_with_slash_dot("")); - assert!(!ends_with_slash_dot(".")); - assert!(!ends_with_slash_dot("./")); - assert!(!ends_with_slash_dot("..")); - assert!(!ends_with_slash_dot("/..")); - assert!(!ends_with_slash_dot("a/..")); - assert!(!ends_with_slash_dot("/a/..")); - } -} diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 683691504..a95e1b599 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -291,6 +291,24 @@ fn test_cp_recurse_several() { assert_eq!(at.read(TEST_COPY_TO_FOLDER_NEW_FILE), "Hello, World!\n"); } +#[test] +fn test_cp_recurse_source_path_ends_with_slash_dot() { + let source_dir = "source_dir"; + let target_dir = "target_dir"; + let file = "file"; + let (at, mut ucmd) = at_and_ucmd!(); + + at.mkdir(source_dir); + at.touch(format!("{source_dir}/{file}")); + + ucmd.arg("-r") + .arg(format!("{source_dir}/.")) + .arg(target_dir) + .succeeds() + .no_output(); + assert!(at.file_exists(format!("{target_dir}/{file}"))); +} + #[test] fn test_cp_with_dirs_t() { let (at, mut ucmd) = at_and_ucmd!();