From b009cae5a876801ee9897286bdd8bfabe803f428 Mon Sep 17 00:00:00 2001 From: Zhang Wen Date: Mon, 21 Apr 2025 00:45:15 +0800 Subject: [PATCH] install: improve error message (#7794) * friendly message install file to directory containing directory with same name * install: test install file to directory containing directory with same name --- src/uu/install/src/install.rs | 10 ++++++++++ tests/by-util/test_install.rs | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 6fd04bc14..8c4a8d808 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -98,6 +98,9 @@ enum InstallError { #[error("failed to access {}: Not a directory", .0.quote())] NotADirectory(PathBuf), + + #[error("cannot overwrite directory {} with non-directory {}", .0.quote(), .1.quote())] + OverrideDirectoryFailed(PathBuf, PathBuf), } impl UError for InstallError { @@ -748,6 +751,13 @@ fn copy_normal_file(from: &Path, to: &Path) -> UResult<()> { /// Returns an empty Result or an error in case of failure. /// fn copy_file(from: &Path, to: &Path) -> UResult<()> { + if to.is_dir() && !from.is_dir() { + return Err(InstallError::OverrideDirectoryFailed( + to.to_path_buf().clone(), + from.to_path_buf().clone(), + ) + .into()); + } // fs::copy fails if destination is a invalid symlink. // so lets just remove all existing files at destination before copy. if let Err(e) = fs::remove_file(to) { diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index 2b3ad8a8c..1270460d8 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -1764,3 +1764,17 @@ fn test_install_from_stdin() { assert!(at.file_exists(target)); assert_eq!(at.read(target), test_string); } + +#[test] +fn test_install_failing_copy_file_to_target_contain_subdir_with_same_name() { + let (at, mut ucmd) = at_and_ucmd!(); + let file = "file"; + let dir1 = "dir1"; + + at.touch(file); + at.mkdir_all(&format!("{dir1}/{file}")); + ucmd.arg(file) + .arg(dir1) + .fails() + .stderr_contains("cannot overwrite directory"); +}