mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
l10n: port rm for translation + add french
This commit is contained in:
parent
05eb7ee374
commit
e79bc8790b
5 changed files with 181 additions and 41 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3388,6 +3388,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
"thiserror 2.0.12",
|
||||
"uucore",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
|
|
@ -18,6 +18,7 @@ workspace = true
|
|||
path = "src/rm.rs"
|
||||
|
||||
[dependencies]
|
||||
thiserror = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
uucore = { workspace = true, features = ["fs"] }
|
||||
|
||||
|
|
|
@ -12,3 +12,35 @@ rm-after-help = By default, rm does not remove directories. Use the --recursive
|
|||
Note that if you use rm to remove a file, it might be possible to recover
|
||||
some of its contents, given sufficient expertise and/or time. For greater
|
||||
assurance that the contents are truly unrecoverable, consider using shred.
|
||||
|
||||
# Help text for options
|
||||
rm-help-force = ignore nonexistent files and arguments, never prompt
|
||||
rm-help-prompt-always = prompt before every removal
|
||||
rm-help-prompt-once = prompt once before removing more than three files, or when removing recursively.
|
||||
Less intrusive than -i, while still giving some protection against most mistakes
|
||||
rm-help-interactive = prompt according to WHEN: never, once (-I), or always (-i). Without WHEN,
|
||||
prompts always
|
||||
rm-help-one-file-system = when removing a hierarchy recursively, skip any directory that is on a file
|
||||
system different from that of the corresponding command line argument (NOT
|
||||
IMPLEMENTED)
|
||||
rm-help-no-preserve-root = do not treat '/' specially
|
||||
rm-help-preserve-root = do not remove '/' (default)
|
||||
rm-help-recursive = remove directories and their contents recursively
|
||||
rm-help-dir = remove empty directories
|
||||
rm-help-verbose = explain what is being done
|
||||
|
||||
# Error messages
|
||||
rm-error-missing-operand = missing operand
|
||||
Try '{$util_name} --help' for more information.
|
||||
rm-error-invalid-interactive-argument = Invalid argument to interactive ({$arg})
|
||||
rm-error-cannot-remove-no-such-file = cannot remove {$file}: No such file or directory
|
||||
rm-error-cannot-remove-permission-denied = cannot remove {$file}: Permission denied
|
||||
rm-error-cannot-remove-is-directory = cannot remove {$file}: Is a directory
|
||||
rm-error-dangerous-recursive-operation = it is dangerous to operate recursively on '/'
|
||||
rm-error-use-no-preserve-root = use --no-preserve-root to override this failsafe
|
||||
rm-error-refusing-to-remove-directory = refusing to remove '.' or '..' directory: skipping '{$path}'
|
||||
rm-error-cannot-remove = cannot remove {$file}
|
||||
|
||||
# Verbose messages
|
||||
rm-verbose-removed = removed {$file}
|
||||
rm-verbose-removed-directory = removed directory {$file}
|
||||
|
|
46
src/uu/rm/locales/fr-FR.ftl
Normal file
46
src/uu/rm/locales/fr-FR.ftl
Normal file
|
@ -0,0 +1,46 @@
|
|||
rm-about = Supprimer (délier) le(s) FICHIER(s)
|
||||
rm-usage = rm [OPTION]... FICHIER...
|
||||
rm-after-help = Par défaut, rm ne supprime pas les répertoires. Utilisez l'option --recursive (-r ou -R)
|
||||
pour supprimer également chaque répertoire listé, ainsi que tout son contenu
|
||||
|
||||
Pour supprimer un fichier dont le nom commence par un '-', par exemple '-foo',
|
||||
utilisez une de ces commandes :
|
||||
rm -- -foo
|
||||
|
||||
rm ./-foo
|
||||
|
||||
Notez que si vous utilisez rm pour supprimer un fichier, il pourrait être possible de récupérer
|
||||
une partie de son contenu, avec suffisamment d'expertise et/ou de temps. Pour une meilleure
|
||||
assurance que le contenu est vraiment irrécupérable, considérez utiliser shred.
|
||||
|
||||
# Texte d'aide pour les options
|
||||
rm-help-force = ignorer les fichiers inexistants et les arguments, ne jamais demander
|
||||
rm-help-prompt-always = demander avant chaque suppression
|
||||
rm-help-prompt-once = demander une fois avant de supprimer plus de trois fichiers, ou lors d'une suppression récursive.
|
||||
Moins intrusif que -i, tout en offrant une protection contre la plupart des erreurs
|
||||
rm-help-interactive = demander selon QUAND : never, once (-I), ou always (-i). Sans QUAND,
|
||||
demande toujours
|
||||
rm-help-one-file-system = lors de la suppression récursive d'une hiérarchie, ignorer tout répertoire situé sur un
|
||||
système de fichiers différent de celui de l'argument de ligne de commande correspondant (NON
|
||||
IMPLÉMENTÉ)
|
||||
rm-help-no-preserve-root = ne pas traiter '/' spécialement
|
||||
rm-help-preserve-root = ne pas supprimer '/' (par défaut)
|
||||
rm-help-recursive = supprimer les répertoires et leur contenu récursivement
|
||||
rm-help-dir = supprimer les répertoires vides
|
||||
rm-help-verbose = expliquer ce qui est fait
|
||||
|
||||
# Messages d'erreur
|
||||
rm-error-missing-operand = opérande manquant
|
||||
Essayez '{$util_name} --help' pour plus d'informations.
|
||||
rm-error-invalid-interactive-argument = Argument invalide pour interactive ({$arg})
|
||||
rm-error-cannot-remove-no-such-file = impossible de supprimer {$file} : Aucun fichier ou répertoire de ce type
|
||||
rm-error-cannot-remove-permission-denied = impossible de supprimer {$file} : Permission refusée
|
||||
rm-error-cannot-remove-is-directory = impossible de supprimer {$file} : C'est un répertoire
|
||||
rm-error-dangerous-recursive-operation = il est dangereux d'opérer récursivement sur '/'
|
||||
rm-error-use-no-preserve-root = utilisez --no-preserve-root pour outrepasser cette protection
|
||||
rm-error-refusing-to-remove-directory = refus de supprimer le répertoire '.' ou '..' : ignorer '{$path}'
|
||||
rm-error-cannot-remove = impossible de supprimer {$file}
|
||||
|
||||
# Messages verbeux
|
||||
rm-verbose-removed = {$file} supprimé
|
||||
rm-verbose-removed-directory = répertoire {$file} supprimé
|
|
@ -6,6 +6,7 @@
|
|||
// spell-checker:ignore (path) eacces inacc rm-r4
|
||||
|
||||
use clap::{Arg, ArgAction, Command, builder::ValueParser, parser::ValueSource};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs::{self, Metadata};
|
||||
use std::io::{IsTerminal, stdin};
|
||||
|
@ -16,11 +17,38 @@ use std::os::unix::ffi::OsStrExt;
|
|||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::path::MAIN_SEPARATOR;
|
||||
use std::path::{Path, PathBuf};
|
||||
use thiserror::Error;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
|
||||
use uucore::locale::get_message;
|
||||
use uucore::error::{FromIo, UError, UResult};
|
||||
use uucore::locale::{get_message, get_message_with_args};
|
||||
use uucore::{format_usage, os_str_as_bytes, prompt_yes, show_error};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum RmError {
|
||||
#[error("{}", get_message_with_args("rm-error-missing-operand",
|
||||
HashMap::from([
|
||||
("util_name".to_string(),
|
||||
uucore::execution_phrase().to_string())
|
||||
])))]
|
||||
MissingOperand,
|
||||
#[error("{}", get_message_with_args("rm-error-invalid-interactive-argument", HashMap::from([("arg".to_string(), _0.clone())])))]
|
||||
InvalidInteractiveArgument(String),
|
||||
#[error("{}", get_message_with_args("rm-error-cannot-remove-no-such-file", HashMap::from([("file".to_string(), _0.quote().to_string())])))]
|
||||
CannotRemoveNoSuchFile(String),
|
||||
#[error("{}", get_message_with_args("rm-error-cannot-remove-permission-denied", HashMap::from([("file".to_string(), _0.quote().to_string())])))]
|
||||
CannotRemovePermissionDenied(String),
|
||||
#[error("{}", get_message_with_args("rm-error-cannot-remove-is-directory", HashMap::from([("file".to_string(), _0.quote().to_string())])))]
|
||||
CannotRemoveIsDirectory(String),
|
||||
#[error("{}", get_message("rm-error-dangerous-recursive-operation"))]
|
||||
DangerousRecursiveOperation,
|
||||
#[error("{}", get_message("rm-error-use-no-preserve-root"))]
|
||||
UseNoPreserveRoot,
|
||||
#[error("{}", get_message_with_args("rm-error-refusing-to-remove-directory", HashMap::from([("path".to_string(), _0.to_string())])))]
|
||||
RefusingToRemoveDirectory(String),
|
||||
}
|
||||
|
||||
impl UError for RmError {}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Copy)]
|
||||
/// Enum, determining when the `rm` will prompt the user about the file deletion
|
||||
pub enum InteractiveMode {
|
||||
|
@ -117,7 +145,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
if files.is_empty() && !force_flag {
|
||||
// Still check by hand and not use clap
|
||||
// Because "rm -f" is a thing
|
||||
return Err(UUsageError::new(1, "missing operand"));
|
||||
return Err(RmError::MissingOperand.into());
|
||||
}
|
||||
|
||||
// If -f(--force) is before any -i (or variants) we want prompts else no prompts
|
||||
|
@ -146,10 +174,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
"once" => InteractiveMode::Once,
|
||||
"always" => InteractiveMode::Always,
|
||||
val => {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("Invalid argument to interactive ({val})"),
|
||||
));
|
||||
return Err(RmError::InvalidInteractiveArgument(val.to_string()).into());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -206,31 +231,27 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(OPT_FORCE)
|
||||
.short('f')
|
||||
.long(OPT_FORCE)
|
||||
.help("ignore nonexistent files and arguments, never prompt")
|
||||
.help(get_message("rm-help-force"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(OPT_PROMPT_ALWAYS)
|
||||
.short('i')
|
||||
.help("prompt before every removal")
|
||||
.help(get_message("rm-help-prompt-always"))
|
||||
.overrides_with_all([OPT_PROMPT_ONCE, OPT_INTERACTIVE])
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(OPT_PROMPT_ONCE)
|
||||
.short('I')
|
||||
.help("prompt once before removing more than three files, or when removing recursively. \
|
||||
Less intrusive than -i, while still giving some protection against most mistakes")
|
||||
.help(get_message("rm-help-prompt-once"))
|
||||
.overrides_with_all([OPT_PROMPT_ALWAYS, OPT_INTERACTIVE])
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(OPT_INTERACTIVE)
|
||||
.long(OPT_INTERACTIVE)
|
||||
.help(
|
||||
"prompt according to WHEN: never, once (-I), or always (-i). Without WHEN, \
|
||||
prompts always",
|
||||
)
|
||||
.help(get_message("rm-help-interactive"))
|
||||
.value_name("WHEN")
|
||||
.num_args(0..=1)
|
||||
.require_equals(true)
|
||||
|
@ -240,22 +261,19 @@ pub fn uu_app() -> Command {
|
|||
.arg(
|
||||
Arg::new(OPT_ONE_FILE_SYSTEM)
|
||||
.long(OPT_ONE_FILE_SYSTEM)
|
||||
.help(
|
||||
"when removing a hierarchy recursively, skip any directory that is on a file \
|
||||
system different from that of the corresponding command line argument (NOT \
|
||||
IMPLEMENTED)",
|
||||
).action(ArgAction::SetTrue),
|
||||
.help(get_message("rm-help-one-file-system"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(OPT_NO_PRESERVE_ROOT)
|
||||
.long(OPT_NO_PRESERVE_ROOT)
|
||||
.help("do not treat '/' specially")
|
||||
.help(get_message("rm-help-no-preserve-root"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(OPT_PRESERVE_ROOT)
|
||||
.long(OPT_PRESERVE_ROOT)
|
||||
.help("do not remove '/' (default)")
|
||||
.help(get_message("rm-help-preserve-root"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
|
@ -263,21 +281,21 @@ pub fn uu_app() -> Command {
|
|||
.short('r')
|
||||
.visible_short_alias('R')
|
||||
.long(OPT_RECURSIVE)
|
||||
.help("remove directories and their contents recursively")
|
||||
.help(get_message("rm-help-recursive"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(OPT_DIR)
|
||||
.short('d')
|
||||
.long(OPT_DIR)
|
||||
.help("remove empty directories")
|
||||
.help(get_message("rm-help-dir"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(OPT_VERBOSE)
|
||||
.short('v')
|
||||
.long(OPT_VERBOSE)
|
||||
.help("explain what is being done")
|
||||
.help(get_message("rm-help-verbose"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
// From the GNU source code:
|
||||
|
@ -337,8 +355,8 @@ pub fn remove(files: &[&OsStr], options: &Options) -> bool {
|
|||
false
|
||||
} else {
|
||||
show_error!(
|
||||
"cannot remove {}: No such file or directory",
|
||||
filename.quote()
|
||||
"{}",
|
||||
RmError::CannotRemoveNoSuchFile(filename.to_string_lossy().to_string())
|
||||
);
|
||||
true
|
||||
}
|
||||
|
@ -425,7 +443,12 @@ fn remove_dir_recursive(path: &Path, options: &Options) -> bool {
|
|||
match fs::remove_dir_all(path) {
|
||||
Ok(_) => return false,
|
||||
Err(e) => {
|
||||
let e = e.map_err_context(|| format!("cannot remove {}", path.quote()));
|
||||
let e = e.map_err_context(|| {
|
||||
get_message_with_args(
|
||||
"rm-error-cannot-remove",
|
||||
HashMap::from([("file".to_string(), path.quote().to_string())]),
|
||||
)
|
||||
});
|
||||
show_error!("{e}");
|
||||
return true;
|
||||
}
|
||||
|
@ -487,7 +510,12 @@ fn remove_dir_recursive(path: &Path, options: &Options) -> bool {
|
|||
error = true;
|
||||
}
|
||||
Err(e) if !error => {
|
||||
let e = e.map_err_context(|| format!("cannot remove {}", path.quote()));
|
||||
let e = e.map_err_context(|| {
|
||||
get_message_with_args(
|
||||
"rm-error-cannot-remove",
|
||||
HashMap::from([("file".to_string(), path.quote().to_string())]),
|
||||
)
|
||||
});
|
||||
show_error!("{e}");
|
||||
error = true;
|
||||
}
|
||||
|
@ -497,7 +525,13 @@ fn remove_dir_recursive(path: &Path, options: &Options) -> bool {
|
|||
// show another error message as we return from each level
|
||||
// of the recursion.
|
||||
}
|
||||
Ok(_) if options.verbose => println!("removed directory {}", normalize(path).quote()),
|
||||
Ok(_) if options.verbose => println!(
|
||||
"{}",
|
||||
get_message_with_args(
|
||||
"rm-verbose-removed-directory",
|
||||
HashMap::from([("file".to_string(), normalize(path).quote().to_string())])
|
||||
)
|
||||
),
|
||||
Ok(_) => {}
|
||||
}
|
||||
|
||||
|
@ -510,8 +544,8 @@ fn handle_dir(path: &Path, options: &Options) -> bool {
|
|||
let path = clean_trailing_slashes(path);
|
||||
if path_is_current_or_parent_directory(path) {
|
||||
show_error!(
|
||||
"refusing to remove '.' or '..' directory: skipping '{}'",
|
||||
path.display()
|
||||
"{}",
|
||||
RmError::RefusingToRemoveDirectory(path.display().to_string())
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
@ -522,13 +556,13 @@ fn handle_dir(path: &Path, options: &Options) -> bool {
|
|||
} else if options.dir && (!is_root || !options.preserve_root) {
|
||||
had_err = remove_dir(path, options).bitor(had_err);
|
||||
} else if options.recursive {
|
||||
show_error!("it is dangerous to operate recursively on '{MAIN_SEPARATOR}'");
|
||||
show_error!("use --no-preserve-root to override this failsafe");
|
||||
show_error!("{}", RmError::DangerousRecursiveOperation);
|
||||
show_error!("{}", RmError::UseNoPreserveRoot);
|
||||
had_err = true;
|
||||
} else {
|
||||
show_error!(
|
||||
"cannot remove {}: Is a directory", // GNU's rm error message does not include help
|
||||
path.quote()
|
||||
"{}",
|
||||
RmError::CannotRemoveIsDirectory(path.to_string_lossy().to_string())
|
||||
);
|
||||
had_err = true;
|
||||
}
|
||||
|
@ -547,7 +581,10 @@ fn remove_dir(path: &Path, options: &Options) -> bool {
|
|||
|
||||
// Called to remove a symlink_dir (windows) without "-r"/"-R" or "-d".
|
||||
if !options.dir && !options.recursive {
|
||||
show_error!("cannot remove {}: Is a directory", path.quote());
|
||||
show_error!(
|
||||
"{}",
|
||||
RmError::CannotRemoveIsDirectory(path.to_string_lossy().to_string())
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -555,12 +592,23 @@ fn remove_dir(path: &Path, options: &Options) -> bool {
|
|||
match fs::remove_dir(path) {
|
||||
Ok(_) => {
|
||||
if options.verbose {
|
||||
println!("removed directory {}", normalize(path).quote());
|
||||
println!(
|
||||
"{}",
|
||||
get_message_with_args(
|
||||
"rm-verbose-removed-directory",
|
||||
HashMap::from([("file".to_string(), normalize(path).quote().to_string())])
|
||||
)
|
||||
);
|
||||
}
|
||||
false
|
||||
}
|
||||
Err(e) => {
|
||||
let e = e.map_err_context(|| format!("cannot remove {}", path.quote()));
|
||||
let e = e.map_err_context(|| {
|
||||
get_message_with_args(
|
||||
"rm-error-cannot-remove",
|
||||
HashMap::from([("file".to_string(), path.quote().to_string())]),
|
||||
)
|
||||
});
|
||||
show_error!("{e}");
|
||||
true
|
||||
}
|
||||
|
@ -572,13 +620,25 @@ fn remove_file(path: &Path, options: &Options) -> bool {
|
|||
match fs::remove_file(path) {
|
||||
Ok(_) => {
|
||||
if options.verbose {
|
||||
println!("removed {}", normalize(path).quote());
|
||||
println!(
|
||||
"{}",
|
||||
get_message_with_args(
|
||||
"rm-verbose-removed",
|
||||
HashMap::from([(
|
||||
"file".to_string(),
|
||||
normalize(path).quote().to_string()
|
||||
)])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if e.kind() == std::io::ErrorKind::PermissionDenied {
|
||||
// GNU compatibility (rm/fail-eacces.sh)
|
||||
show_error!("cannot remove {}: {}", path.quote(), "Permission denied");
|
||||
show_error!(
|
||||
"{}",
|
||||
RmError::CannotRemovePermissionDenied(path.to_string_lossy().to_string())
|
||||
);
|
||||
} else {
|
||||
show_error!("cannot remove {}: {e}", path.quote());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue