mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
l10n: port chmod for translation + add french
This commit is contained in:
parent
05eb7ee374
commit
d8ba6c01e4
5 changed files with 112 additions and 50 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2797,6 +2797,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
"thiserror 2.0.12",
|
||||
"uucore",
|
||||
]
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ path = "src/chmod.rs"
|
|||
[dependencies]
|
||||
clap = { workspace = true }
|
||||
libc = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
uucore = { workspace = true, features = ["entries", "fs", "mode", "perms"] }
|
||||
|
||||
[[bin]]
|
||||
|
|
|
@ -4,3 +4,28 @@ chmod-usage = chmod [OPTION]... MODE[,MODE]... FILE...
|
|||
chmod [OPTION]... OCTAL-MODE FILE...
|
||||
chmod [OPTION]... --reference=RFILE FILE...
|
||||
chmod-after-help = Each MODE is of the form [ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+.
|
||||
chmod-error-cannot-stat = cannot stat attributes of {$file}
|
||||
chmod-error-dangling-symlink = cannot operate on dangling symlink {$file}
|
||||
chmod-error-no-such-file = cannot access {$file}: No such file or directory
|
||||
chmod-error-preserve-root = it is dangerous to operate recursively on {$file}
|
||||
chmod: use --no-preserve-root to override this failsafe
|
||||
chmod-error-permission-denied = {$file}: Permission denied
|
||||
chmod-error-new-permissions = {$file}: new permissions are {$actual}, not {$expected}
|
||||
chmod-error-missing-operand = missing operand
|
||||
|
||||
# Help messages
|
||||
chmod-help-print-help = Print help information.
|
||||
chmod-help-changes = like verbose but report only when a change is made
|
||||
chmod-help-quiet = suppress most error messages
|
||||
chmod-help-verbose = output a diagnostic for every file processed
|
||||
chmod-help-no-preserve-root = do not treat '/' specially (the default)
|
||||
chmod-help-preserve-root = fail to operate recursively on '/'
|
||||
chmod-help-recursive = change files and directories recursively
|
||||
chmod-help-reference = use RFILE's mode instead of MODE values
|
||||
|
||||
# Verbose messages
|
||||
chmod-verbose-failed-dangling = failed to change mode of {$file} from 0000 (---------) to 1500 (r-x-----T)
|
||||
chmod-verbose-neither-changed = neither symbolic link {$file} nor referent has been changed
|
||||
chmod-verbose-mode-retained = mode of {$file} retained as {$mode_octal} ({$mode_display})
|
||||
chmod-verbose-failed-change = failed to change mode of file {$file} from {$old_mode} ({$old_mode_display}) to {$new_mode} ({$new_mode_display})
|
||||
chmod-verbose-mode-changed = mode of {$file} changed from {$old_mode} ({$old_mode_display}) to {$new_mode} ({$new_mode_display})
|
||||
|
|
33
src/uu/chmod/locales/fr-FR.ftl
Normal file
33
src/uu/chmod/locales/fr-FR.ftl
Normal file
|
@ -0,0 +1,33 @@
|
|||
chmod-about = Changer le mode de chaque FICHIER vers MODE.
|
||||
Avec --reference, changer le mode de chaque FICHIER vers celui de RFICHIER.
|
||||
chmod-usage = chmod [OPTION]... MODE[,MODE]... FICHIER...
|
||||
chmod [OPTION]... MODE-OCTAL FICHIER...
|
||||
chmod [OPTION]... --reference=RFICHIER FICHIER...
|
||||
chmod-after-help = Chaque MODE est de la forme [ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+.
|
||||
|
||||
# Messages d'aide
|
||||
chmod-help-print-help = Afficher les informations d'aide.
|
||||
chmod-help-changes = comme verbeux mais rapporter seulement lors d'un changement
|
||||
chmod-help-quiet = supprimer la plupart des messages d'erreur
|
||||
chmod-help-verbose = afficher un diagnostic pour chaque fichier traité
|
||||
chmod-help-no-preserve-root = ne pas traiter '/' spécialement (par défaut)
|
||||
chmod-help-preserve-root = échouer à opérer récursivement sur '/'
|
||||
chmod-help-recursive = changer les fichiers et répertoires récursivement
|
||||
chmod-help-reference = utiliser le mode de RFICHIER au lieu des valeurs de MODE
|
||||
|
||||
# Messages d'erreur
|
||||
chmod-error-cannot-stat = impossible d'obtenir les attributs de {$file}
|
||||
chmod-error-dangling-symlink = impossible d'opérer sur le lien symbolique pendouillant {$file}
|
||||
chmod-error-no-such-file = impossible d'accéder à {$file} : Aucun fichier ou dossier de ce type
|
||||
chmod-error-preserve-root = il est dangereux d'opérer récursivement sur {$file}
|
||||
chmod: utiliser --no-preserve-root pour outrepasser cette protection
|
||||
chmod-error-permission-denied = {$file} : Permission refusée
|
||||
chmod-error-new-permissions = {$file} : les nouvelles permissions sont {$actual}, pas {$expected}
|
||||
chmod-error-missing-operand = opérande manquant
|
||||
|
||||
# Messages verbeux/de statut
|
||||
chmod-verbose-failed-dangling = échec du changement de mode de {$file} de 0000 (---------) vers 1500 (r-x-----T)
|
||||
chmod-verbose-neither-changed = ni le lien symbolique {$file} ni la référence n'ont été changés
|
||||
chmod-verbose-mode-retained = mode de {$file} conservé comme {$mode_octal} ({$mode_display})
|
||||
chmod-verbose-failed-change = échec du changement de mode du fichier {$file} de {$old_mode} ({$old_mode_display}) vers {$new_mode} ({$new_mode_display})
|
||||
chmod-verbose-mode-changed = mode de {$file} changé de {$old_mode} ({$old_mode_display}) vers {$new_mode} ({$new_mode_display})
|
|
@ -6,12 +6,14 @@
|
|||
// spell-checker:ignore (ToDO) Chmoder cmode fmode fperm fref ugoa RFILE RFILE's
|
||||
|
||||
use clap::{Arg, ArgAction, Command};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
||||
use std::path::Path;
|
||||
use thiserror::Error;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{ExitCode, UResult, USimpleError, UUsageError, set_exit_code};
|
||||
use uucore::error::{ExitCode, UError, UResult, USimpleError, UUsageError, set_exit_code};
|
||||
use uucore::fs::display_permissions_unix;
|
||||
use uucore::libc::mode_t;
|
||||
#[cfg(not(windows))]
|
||||
|
@ -19,7 +21,25 @@ use uucore::mode;
|
|||
use uucore::perms::{TraverseSymlinks, configure_symlink_and_recursion};
|
||||
use uucore::{format_usage, show, show_error};
|
||||
|
||||
use uucore::locale::get_message;
|
||||
use uucore::locale::{get_message, get_message_with_args};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum ChmodError {
|
||||
#[error("{}", get_message_with_args("chmod-error-cannot-stat", HashMap::from([("file".to_string(), _0.quote().to_string())])))]
|
||||
CannotStat(String),
|
||||
#[error("{}", get_message_with_args("chmod-error-dangling-symlink", HashMap::from([("file".to_string(), _0.quote().to_string())])))]
|
||||
DanglingSymlink(String),
|
||||
#[error("{}", get_message_with_args("chmod-error-no-such-file", HashMap::from([("file".to_string(), _0.quote().to_string())])))]
|
||||
NoSuchFile(String),
|
||||
#[error("{}", get_message_with_args("chmod-error-preserve-root", HashMap::from([("file".to_string(), _0.quote().to_string())])))]
|
||||
PreserveRoot(String),
|
||||
#[error("{}", get_message_with_args("chmod-error-permission-denied", HashMap::from([("file".to_string(), _0.quote().to_string())])))]
|
||||
PermissionDenied(String),
|
||||
#[error("{}", get_message_with_args("chmod-error-new-permissions", HashMap::from([("file".to_string(), _0.clone()), ("actual".to_string(), _1.clone()), ("expected".to_string(), _2.clone())])))]
|
||||
NewPermissions(String, String, String),
|
||||
}
|
||||
|
||||
impl UError for ChmodError {}
|
||||
|
||||
mod options {
|
||||
pub const HELP: &str = "help";
|
||||
|
@ -103,11 +123,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
let fmode = match matches.get_one::<String>(options::REFERENCE) {
|
||||
Some(fref) => match fs::metadata(fref) {
|
||||
Ok(meta) => Some(meta.mode() & 0o7777),
|
||||
Err(err) => {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("cannot stat attributes of {}: {err}", fref.quote()),
|
||||
));
|
||||
Err(_) => {
|
||||
return Err(ChmodError::CannotStat(fref.to_string()).into());
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
|
@ -135,7 +152,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
};
|
||||
|
||||
if files.is_empty() {
|
||||
return Err(UUsageError::new(1, "missing operand".to_string()));
|
||||
return Err(UUsageError::new(
|
||||
1,
|
||||
get_message("chmod-error-missing-operand"),
|
||||
));
|
||||
}
|
||||
|
||||
let (recursive, dereference, traverse_symlinks) =
|
||||
|
@ -168,14 +188,14 @@ pub fn uu_app() -> Command {
|
|||
.arg(
|
||||
Arg::new(options::HELP)
|
||||
.long(options::HELP)
|
||||
.help("Print help information.")
|
||||
.help(get_message("chmod-help-print-help"))
|
||||
.action(ArgAction::Help),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::CHANGES)
|
||||
.long(options::CHANGES)
|
||||
.short('c')
|
||||
.help("like verbose but report only when a change is made")
|
||||
.help(get_message("chmod-help-changes"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
|
@ -183,40 +203,40 @@ pub fn uu_app() -> Command {
|
|||
.long(options::QUIET)
|
||||
.visible_alias("silent")
|
||||
.short('f')
|
||||
.help("suppress most error messages")
|
||||
.help(get_message("chmod-help-quiet"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::VERBOSE)
|
||||
.long(options::VERBOSE)
|
||||
.short('v')
|
||||
.help("output a diagnostic for every file processed")
|
||||
.help(get_message("chmod-help-verbose"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::NO_PRESERVE_ROOT)
|
||||
.long(options::NO_PRESERVE_ROOT)
|
||||
.help("do not treat '/' specially (the default)")
|
||||
.help(get_message("chmod-help-no-preserve-root"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::PRESERVE_ROOT)
|
||||
.long(options::PRESERVE_ROOT)
|
||||
.help("fail to operate recursively on '/'")
|
||||
.help(get_message("chmod-help-preserve-root"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::RECURSIVE)
|
||||
.long(options::RECURSIVE)
|
||||
.short('R')
|
||||
.help("change files and directories recursively")
|
||||
.help(get_message("chmod-help-recursive"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::REFERENCE)
|
||||
.long("reference")
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
.help("use RFILE's mode instead of MODE values"),
|
||||
.help(get_message("chmod-help-reference")),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::MODE).required_unless_present(options::REFERENCE),
|
||||
|
@ -265,27 +285,21 @@ impl Chmoder {
|
|||
}
|
||||
|
||||
if !self.quiet {
|
||||
show!(USimpleError::new(
|
||||
1,
|
||||
format!("cannot operate on dangling symlink {}", filename.quote()),
|
||||
));
|
||||
show!(ChmodError::DanglingSymlink(filename.to_string()));
|
||||
set_exit_code(1);
|
||||
}
|
||||
|
||||
if self.verbose {
|
||||
println!(
|
||||
"failed to change mode of {} from 0000 (---------) to 1500 (r-x-----T)",
|
||||
filename.quote()
|
||||
"{}",
|
||||
get_message_with_args(
|
||||
"chmod-verbose-failed-dangling",
|
||||
HashMap::from([("file".to_string(), filename.quote().to_string())])
|
||||
)
|
||||
);
|
||||
}
|
||||
} else if !self.quiet {
|
||||
show!(USimpleError::new(
|
||||
1,
|
||||
format!(
|
||||
"cannot access {}: No such file or directory",
|
||||
filename.quote()
|
||||
)
|
||||
));
|
||||
show!(ChmodError::NoSuchFile(filename.to_string()));
|
||||
}
|
||||
// GNU exits with exit code 1 even if -q or --quiet are passed
|
||||
// So we set the exit code, because it hasn't been set yet if `self.quiet` is true.
|
||||
|
@ -298,13 +312,7 @@ impl Chmoder {
|
|||
continue;
|
||||
}
|
||||
if self.recursive && self.preserve_root && filename == "/" {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!(
|
||||
"it is dangerous to operate recursively on {}\nchmod: use --no-preserve-root to override this failsafe",
|
||||
filename.quote()
|
||||
),
|
||||
));
|
||||
return Err(ChmodError::PreserveRoot(filename.to_string()).into());
|
||||
}
|
||||
if self.recursive {
|
||||
r = self.walk_dir(file);
|
||||
|
@ -368,12 +376,9 @@ impl Chmoder {
|
|||
} else if err.kind() == std::io::ErrorKind::PermissionDenied {
|
||||
// These two filenames would normally be conditionally
|
||||
// quoted, but GNU's tests expect them to always be quoted
|
||||
Err(USimpleError::new(
|
||||
1,
|
||||
format!("{}: Permission denied", file.quote()),
|
||||
))
|
||||
Err(ChmodError::PermissionDenied(file.to_string_lossy().to_string()).into())
|
||||
} else {
|
||||
Err(USimpleError::new(1, format!("{}: {err}", file.quote())))
|
||||
Err(ChmodError::CannotStat(file.to_string_lossy().to_string()).into())
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -420,15 +425,12 @@ impl Chmoder {
|
|||
self.change_file(fperm, new_mode, file)?;
|
||||
// if a permission would have been removed if umask was 0, but it wasn't because umask was not 0, print an error and fail
|
||||
if (new_mode & !naively_expected_new_mode) != 0 {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!(
|
||||
"{}: new permissions are {}, not {}",
|
||||
file.maybe_quote(),
|
||||
display_permissions_unix(new_mode as mode_t, false),
|
||||
display_permissions_unix(naively_expected_new_mode as mode_t, false)
|
||||
),
|
||||
));
|
||||
return Err(ChmodError::NewPermissions(
|
||||
file.to_string_lossy().to_string(),
|
||||
display_permissions_unix(new_mode as mode_t, false),
|
||||
display_permissions_unix(naively_expected_new_mode as mode_t, false),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue