1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

l10n: port ln for translation + add french

This commit is contained in:
Sylvestre Ledru 2025-06-22 18:44:40 +02:00
parent 1675c3e981
commit e822db6bc5
3 changed files with 147 additions and 34 deletions

View file

@ -11,3 +11,28 @@ ln-after-help = In the 1st form, create a link to TARGET with the name LINK_NAME
When creating hard links, each TARGET must exist. Symbolic links
can hold arbitrary text; if later resolved, a relative link is
interpreted in relation to its parent directory.
ln-help-force = remove existing destination files
ln-help-interactive = prompt whether to remove existing destination files
ln-help-no-dereference = treat LINK_NAME as a normal file if it is a
symbolic link to a directory
ln-help-logical = follow TARGETs that are symbolic links
ln-help-physical = make hard links directly to symbolic links
ln-help-symbolic = make symbolic links instead of hard links
ln-help-target-directory = specify the DIRECTORY in which to create the links
ln-help-no-target-directory = treat LINK_NAME as a normal file always
ln-help-relative = create symbolic links relative to link location
ln-help-verbose = print name of each linked file
ln-error-target-is-not-directory = target {$target} is not a directory
ln-error-same-file = {$file1} and {$file2} are the same file
ln-error-missing-destination = missing destination file operand after {$operand}
ln-error-extra-operand = extra operand {$operand}
Try '{$program} --help' for more information.
ln-error-could-not-update = Could not update {$target}: {$error}
ln-error-cannot-stat = cannot stat {$path}: No such file or directory
ln-error-will-not-overwrite = will not overwrite just-created '{$target}' with '{$source}'
ln-prompt-replace = replace {$file}?
ln-cannot-backup = cannot backup {$file}
ln-failed-to-access = failed to access {$file}
ln-failed-to-create-hard-link = failed to create hard link {$source} => {$dest}
ln-backup = backup: {$backup}

View file

@ -0,0 +1,39 @@
ln-about = Créer des liens entre fichiers
ln-usage = ln [OPTION]... [-T] CIBLE NOM_LIEN
ln [OPTION]... CIBLE
ln [OPTION]... CIBLE... RÉPERTOIRE
ln [OPTION]... -t RÉPERTOIRE CIBLE...
ln-after-help = Dans la 1ère forme, créer un lien vers CIBLE avec le nom NOM_LIEN.
Dans la 2ème forme, créer un lien vers CIBLE dans le répertoire courant.
Dans les 3ème et 4ème formes, créer des liens vers chaque CIBLE dans RÉPERTOIRE.
Créer des liens physiques par défaut, des liens symboliques avec --symbolic.
Par défaut, chaque destination (nom du nouveau lien) ne doit pas déjà exister.
Lors de la création de liens physiques, chaque CIBLE doit exister. Les liens symboliques
peuvent contenir du texte arbitraire ; s'ils sont résolus plus tard, un lien relatif est
interprété en relation avec son répertoire parent.
ln-help-force = supprimer les fichiers de destination existants
ln-help-interactive = demander avant de supprimer les fichiers de destination existants
ln-help-no-dereference = traiter NOM_LIEN comme un fichier normal s'il s'agit d'un
lien symbolique vers un répertoire
ln-help-logical = suivre les CIBLEs qui sont des liens symboliques
ln-help-physical = créer des liens physiques directement vers les liens symboliques
ln-help-symbolic = créer des liens symboliques au lieu de liens physiques
ln-help-target-directory = spécifier le RÉPERTOIRE dans lequel créer les liens
ln-help-no-target-directory = toujours traiter NOM_LIEN comme un fichier normal
ln-help-relative = créer des liens symboliques relatifs à l'emplacement du lien
ln-help-verbose = afficher le nom de chaque fichier lié
ln-error-target-is-not-directory = la cible {$target} n'est pas un répertoire
ln-error-same-file = {$file1} et {$file2} sont le même fichier
ln-error-missing-destination = opérande de fichier de destination manquant après {$operand}
ln-error-extra-operand = opérande supplémentaire {$operand}
Essayez « {$program} --help » pour plus d'informations.
ln-error-could-not-update = Impossible de mettre à jour {$target} : {$error}
ln-error-cannot-stat = impossible d'analyser {$path} : Aucun fichier ou répertoire de ce nom
ln-error-will-not-overwrite = ne remplacera pas le fichier « {$target} » qui vient d'être créé par « {$source} »
ln-prompt-replace = remplacer {$file} ?
ln-cannot-backup = impossible de sauvegarder {$file}
ln-failed-to-access = échec d'accès à {$file}
ln-failed-to-create-hard-link = échec de création du lien physique {$source} => {$dest}
ln-backup = sauvegarde : {$backup}

View file

@ -17,6 +17,7 @@ use std::ffi::OsString;
use std::fs;
use thiserror::Error;
use std::collections::HashMap;
#[cfg(any(unix, target_os = "redox"))]
use std::os::unix::fs::symlink;
#[cfg(windows)]
@ -24,7 +25,7 @@ use std::os::windows::fs::{symlink_dir, symlink_file};
use std::path::{Path, PathBuf};
use uucore::backup_control::{self, BackupMode};
use uucore::fs::{MissingHandling, ResolveMode, canonicalize};
use uucore::locale::get_message;
use uucore::locale::{get_message, get_message_with_args};
pub struct Settings {
overwrite: OverwriteMode,
@ -48,20 +49,19 @@ pub enum OverwriteMode {
#[derive(Error, Debug)]
enum LnError {
#[error("target {} is not a directory", _0.quote())]
#[error("{}", get_message_with_args("ln-error-target-is-not-directory", HashMap::from([("target".to_string(), _0.quote().to_string())])))]
TargetIsNotADirectory(PathBuf),
#[error("")]
SomeLinksFailed,
#[error("{} and {} are the same file", _0.quote(), _1.quote())]
#[error("{}", get_message_with_args("ln-error-same-file", HashMap::from([("file1".to_string(), _0.quote().to_string()), ("file2".to_string(), _1.quote().to_string())])))]
SameFile(PathBuf, PathBuf),
#[error("missing destination file operand after {}", _0.quote())]
#[error("{}", get_message_with_args("ln-error-missing-destination", HashMap::from([("operand".to_string(), _0.quote().to_string())])))]
MissingDestination(PathBuf),
#[error("extra operand {}\nTry '{} --help' for more information.",
format!("{_0:?}").trim_matches('"'), _1)]
#[error("{}", get_message_with_args("ln-error-extra-operand", HashMap::from([("operand".to_string(), format!("{_0:?}").trim_matches('"').to_string()), ("program".to_string(), _1.clone())])))]
ExtraOperand(OsString, String),
}
@ -157,31 +157,28 @@ pub fn uu_app() -> Command {
Arg::new(options::FORCE)
.short('f')
.long(options::FORCE)
.help("remove existing destination files")
.help(get_message("ln-help-force"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::INTERACTIVE)
.short('i')
.long(options::INTERACTIVE)
.help("prompt whether to remove existing destination files")
.help(get_message("ln-help-interactive"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::NO_DEREFERENCE)
.short('n')
.long(options::NO_DEREFERENCE)
.help(
"treat LINK_NAME as a normal file if it is a \
symbolic link to a directory",
)
.help(get_message("ln-help-no-dereference"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::LOGICAL)
.short('L')
.long(options::LOGICAL)
.help("follow TARGETs that are symbolic links")
.help(get_message("ln-help-logical"))
.overrides_with(options::PHYSICAL)
.action(ArgAction::SetTrue),
)
@ -190,14 +187,14 @@ pub fn uu_app() -> Command {
Arg::new(options::PHYSICAL)
.short('P')
.long(options::PHYSICAL)
.help("make hard links directly to symbolic links")
.help(get_message("ln-help-physical"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::SYMBOLIC)
.short('s')
.long(options::SYMBOLIC)
.help("make symbolic links instead of hard links")
.help(get_message("ln-help-symbolic"))
// override added for https://github.com/uutils/coreutils/issues/2359
.overrides_with(options::SYMBOLIC)
.action(ArgAction::SetTrue),
@ -207,7 +204,7 @@ pub fn uu_app() -> Command {
Arg::new(options::TARGET_DIRECTORY)
.short('t')
.long(options::TARGET_DIRECTORY)
.help("specify the DIRECTORY in which to create the links")
.help(get_message("ln-help-target-directory"))
.value_name("DIRECTORY")
.value_hint(clap::ValueHint::DirPath)
.conflicts_with(options::NO_TARGET_DIRECTORY),
@ -216,14 +213,14 @@ pub fn uu_app() -> Command {
Arg::new(options::NO_TARGET_DIRECTORY)
.short('T')
.long(options::NO_TARGET_DIRECTORY)
.help("treat LINK_NAME as a normal file always")
.help(get_message("ln-help-no-target-directory"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::RELATIVE)
.short('r')
.long(options::RELATIVE)
.help("create symbolic links relative to link location")
.help(get_message("ln-help-relative"))
.requires(options::SYMBOLIC)
.action(ArgAction::SetTrue),
)
@ -231,7 +228,7 @@ pub fn uu_app() -> Command {
Arg::new(options::VERBOSE)
.short('v')
.long(options::VERBOSE)
.help("print name of each linked file")
.help(get_message("ln-help-verbose"))
.action(ArgAction::SetTrue),
)
.arg(
@ -296,7 +293,16 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings)
// We need to clean the target
if target_dir.is_file() {
if let Err(e) = fs::remove_file(target_dir) {
show_error!("Could not update {}: {e}", target_dir.quote());
show_error!(
"{}",
get_message_with_args(
"ln-error-could-not-update",
HashMap::from([
("target".to_string(), target_dir.quote().to_string()),
("error".to_string(), e.to_string())
])
)
);
};
}
#[cfg(windows)]
@ -305,7 +311,16 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings)
// considered as a dir
// See test_ln::test_symlink_no_deref_dir
if let Err(e) = fs::remove_dir(target_dir) {
show_error!("Could not update {}: {e}", target_dir.quote());
show_error!(
"{}",
get_message_with_args(
"ln-error-could-not-update",
HashMap::from([
("target".to_string(), target_dir.quote().to_string()),
("error".to_string(), e.to_string())
])
)
);
};
}
target_dir.to_path_buf()
@ -322,7 +337,13 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings)
}
}
None => {
show_error!("cannot stat {}: No such file or directory", srcpath.quote());
show_error!(
"{}",
get_message_with_args(
"ln-error-cannot-stat",
HashMap::from([("path".to_string(), srcpath.quote().to_string())])
)
);
all_successful = false;
continue;
}
@ -332,9 +353,14 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings)
if linked_destinations.contains(&targetpath) {
// If the target file was already created in this ln call, do not overwrite
show_error!(
"will not overwrite just-created '{}' with '{}'",
targetpath.display(),
srcpath.display()
"{}",
get_message_with_args(
"ln-error-will-not-overwrite",
HashMap::from([
("target".to_string(), targetpath.display().to_string()),
("source".to_string(), srcpath.display().to_string())
])
)
);
all_successful = false;
} else if let Err(e) = link(srcpath, &targetpath, settings) {
@ -387,12 +413,23 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> UResult<()> {
}
}
if let Some(ref p) = backup_path {
fs::rename(dst, p).map_err_context(|| format!("cannot backup {}", dst.quote()))?;
fs::rename(dst, p).map_err_context(|| {
get_message_with_args(
"ln-cannot-backup",
HashMap::from([("file".to_string(), dst.quote().to_string())]),
)
})?;
}
match settings.overwrite {
OverwriteMode::NoClobber => {}
OverwriteMode::Interactive => {
if !prompt_yes!("replace {}?", dst.quote()) {
if !prompt_yes!(
"{}",
get_message_with_args(
"ln-prompt-replace",
HashMap::from([("file".to_string(), dst.quote().to_string())])
)
) {
return Err(LnError::SomeLinksFailed.into());
}
@ -416,16 +453,22 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> UResult<()> {
// if we want to have an hard link,
// source is a symlink and -L is passed
// we want to resolve the symlink to create the hardlink
fs::canonicalize(&source)
.map_err_context(|| format!("failed to access {}", source.quote()))?
fs::canonicalize(&source).map_err_context(|| {
get_message_with_args(
"ln-failed-to-access",
HashMap::from([("file".to_string(), source.quote().to_string())]),
)
})?
} else {
source.to_path_buf()
};
fs::hard_link(p, dst).map_err_context(|| {
format!(
"failed to create hard link {} => {}",
source.quote(),
dst.quote()
get_message_with_args(
"ln-failed-to-create-hard-link",
HashMap::from([
("source".to_string(), source.quote().to_string()),
("dest".to_string(), dst.quote().to_string()),
]),
)
})?;
}
@ -433,7 +476,13 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> UResult<()> {
if settings.verbose {
print!("{} -> {}", dst.quote(), source.quote());
match backup_path {
Some(path) => println!(" (backup: {})", path.quote()),
Some(path) => println!(
" ({})",
get_message_with_args(
"ln-backup",
HashMap::from([("backup".to_string(), path.quote().to_string())])
)
),
None => println!(),
}
}