From aeeb3c90cf803dbf547424fad5154cb1d6345e83 Mon Sep 17 00:00:00 2001 From: John Shin Date: Wed, 26 Apr 2023 09:47:03 -0700 Subject: [PATCH 1/4] 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 103c1116ab5..7810c3a9506 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 d0a1a766f94..53446dd8a18 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 a93bccb5b93d1fb1adb5e032f95d9c4c25c72155 Mon Sep 17 00:00:00 2001 From: John Shin Date: Thu, 27 Apr 2023 15:35:21 -0700 Subject: [PATCH 2/4] 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 03423410716..3b5aa3ee3d4 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 ee3da4284c8ad844498f6b3314054f5f9321925b Mon Sep 17 00:00:00 2001 From: John Shin Date: Fri, 28 Apr 2023 18:39:41 -0700 Subject: [PATCH 3/4] 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 486cf3227b2..9364961dc02 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 5a77608ef94096fd33b8744e550b81aa2632d7cf Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 29 Apr 2023 09:48:05 +0200 Subject: [PATCH 4/4] 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 9364961dc02..cc7dceedcd5 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