From 1821e465a38dc6c5bd28a0dd22678036f3fe0bc5 Mon Sep 17 00:00:00 2001 From: wtcpython <1762993226@qq.com> Date: Fri, 10 Jul 2026 21:42:10 +0800 Subject: [PATCH] install: show backup failure causes --- src/uu/install/locales/en-US.ftl | 2 +- src/uu/install/locales/fr-FR.ftl | 2 +- src/uu/install/src/install.rs | 11 +++++------ tests/by-util/test_install.rs | 15 +++++++++++++++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/uu/install/locales/en-US.ftl b/src/uu/install/locales/en-US.ftl index d63174e7468..1b5b92e5320 100644 --- a/src/uu/install/locales/en-US.ftl +++ b/src/uu/install/locales/en-US.ftl @@ -29,7 +29,7 @@ install-error-chmod-failed-detailed = { $path }: chmod failed with error { $erro install-error-chown-failed = failed to chown { $path }: { $error } install-error-invalid-target = invalid target { $path }: No such file or directory install-error-target-not-dir = target { $path } is not a directory -install-error-backup-failed = cannot backup { $from } to { $to } +install-error-backup-failed = cannot backup { $from }: { $error } install-error-install-failed = cannot install { $from } to { $to }: { $error } install-error-strip-failed = strip program failed: { $error } install-error-strip-abnormal = strip process terminated abnormally - exit code: { $code } diff --git a/src/uu/install/locales/fr-FR.ftl b/src/uu/install/locales/fr-FR.ftl index 6c8eb56b171..1503c0c7c7d 100644 --- a/src/uu/install/locales/fr-FR.ftl +++ b/src/uu/install/locales/fr-FR.ftl @@ -29,7 +29,7 @@ install-error-chmod-failed-detailed = { $path } : échec du chmod avec l'erreur install-error-chown-failed = échec du chown { $path } : { $error } install-error-invalid-target = cible invalide { $path } : Aucun fichier ou répertoire de ce type install-error-target-not-dir = la cible { $path } n'est pas un répertoire -install-error-backup-failed = impossible de sauvegarder { $from } vers { $to } +install-error-backup-failed = impossible de sauvegarder { $from } : { $error } install-error-install-failed = impossible d'installer { $from } vers { $to }: { $error } install-error-strip-failed = échec du programme strip : { $error } install-error-strip-abnormal = le processus strip s'est terminé anormalement - code de sortie : { $code } diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 31051705889..d21d4c7c51d 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -24,7 +24,7 @@ use uucore::backup_control::{self, BackupMode}; use uucore::buf_copy::copy_fast; use uucore::display::Quotable; use uucore::entries::{grp2gid, usr2uid}; -use uucore::error::{FromIo, UError, UResult, UUsageError}; +use uucore::error::{FromIo, UError, UResult, UUsageError, strip_errno}; use uucore::fs::dir_strip_dot_for_creation; use uucore::perms::{Verbosity, VerbosityLevel, wrap_chown}; use uucore::process::{getegid, geteuid}; @@ -88,8 +88,8 @@ enum InstallError { #[error("{}", translate!("install-error-target-not-dir", "path" => .0.quote()))] TargetDirIsntDir(PathBuf), - #[error("{}", translate!("install-error-backup-failed", "from" => .0.quote(), "to" => .1.quote()))] - BackupFailed(PathBuf, PathBuf, #[source] std::io::Error), + #[error("{}", translate!("install-error-backup-failed", "from" => .0.quote(), "error" => strip_errno(.1)))] + BackupFailed(PathBuf, #[source] std::io::Error), #[error("{}", translate!("install-error-install-failed", "from" => .0.quote(), "to" => .1.quote(), "error" => .2.clone()))] InstallFailed(PathBuf, PathBuf, String), @@ -916,9 +916,8 @@ fn perform_backup(to: &Path, b: &Behavior) -> UResult> { } let backup_path = backup_control::get_backup_path(b.backup_mode, to, &b.suffix); if let Some(ref backup_path) = backup_path { - fs::rename(to, backup_path).map_err(|err| { - InstallError::BackupFailed(to.to_path_buf(), backup_path.clone(), err) - })?; + fs::rename(to, backup_path) + .map_err(|err| InstallError::BackupFailed(to.to_path_buf(), err))?; } Ok(backup_path) } else { diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index 2454cb5a320..949c67b9896 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -17,6 +17,7 @@ use std::process; use std::sync::OnceLock; #[cfg(any(target_os = "linux", target_os = "android"))] use std::thread::sleep; +use uucore::error::strip_errno; use uucore::process::{getegid, geteuid}; #[cfg(all( feature = "feat_selinux", @@ -1383,6 +1384,20 @@ fn test_install_backup_custom_suffix_via_env() { assert!(at.file_exists(format!("{file_b}{suffix}"))); } +#[test] +fn test_install_backup_error_includes_cause() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("source"); + at.touch("target"); + at.mkdir("target.backup"); + let error = strip_errno(&fs::rename(at.plus("target"), at.plus("target.backup")).unwrap_err()); + + ucmd.env("SIMPLE_BACKUP_SUFFIX", ".backup") + .args(&["--backup", "source", "target"]) + .fails() + .stderr_is(format!("install: cannot backup 'target': {error}\n")); +} + #[test] fn test_install_backup_numbered_with_t() { let scene = TestScenario::new(util_name!());