mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 11:07:44 +00:00
l10n: port install for translation + add french
This commit is contained in:
parent
0a1a36d900
commit
19f1d18d3c
4 changed files with 233 additions and 64 deletions
|
@ -1,3 +1,56 @@
|
||||||
install-about = Copy SOURCE to DEST or multiple SOURCE(s) to the existing
|
install-about = Copy SOURCE to DEST or multiple SOURCE(s) to the existing
|
||||||
DIRECTORY, while setting permission modes and owner/group
|
DIRECTORY, while setting permission modes and owner/group
|
||||||
install-usage = install [OPTION]... [FILE]...
|
install-usage = install [OPTION]... [FILE]...
|
||||||
|
|
||||||
|
# Help messages
|
||||||
|
install-help-ignored = ignored
|
||||||
|
install-help-compare = compare each pair of source and destination files, and in some cases, do not modify the destination at all
|
||||||
|
install-help-directory = treat all arguments as directory names. create all components of the specified directories
|
||||||
|
install-help-create-leading = create all leading components of DEST except the last, then copy SOURCE to DEST
|
||||||
|
install-help-group = set group ownership, instead of process's current group
|
||||||
|
install-help-mode = set permission mode (as in chmod), instead of rwxr-xr-x
|
||||||
|
install-help-owner = set ownership (super-user only)
|
||||||
|
install-help-preserve-timestamps = apply access/modification times of SOURCE files to corresponding destination files
|
||||||
|
install-help-strip = strip symbol tables (no action Windows)
|
||||||
|
install-help-strip-program = program used to strip binaries (no action Windows)
|
||||||
|
install-help-target-directory = move all SOURCE arguments into DIRECTORY
|
||||||
|
install-help-no-target-directory = treat DEST as a normal file
|
||||||
|
install-help-verbose = explain what is being done
|
||||||
|
install-help-preserve-context = preserve security context
|
||||||
|
install-help-context = set security context of files and directories
|
||||||
|
|
||||||
|
# Error messages
|
||||||
|
install-error-dir-needs-arg = { $util_name } with -d requires at least one argument.
|
||||||
|
install-error-create-dir-failed = failed to create { $path }
|
||||||
|
install-error-chmod-failed = failed to chmod { $path }
|
||||||
|
install-error-chmod-failed-detailed = { $path }: chmod failed with error { $error }
|
||||||
|
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-install-failed = cannot install { $from } to { $to }
|
||||||
|
install-error-strip-failed = strip program failed: { $error }
|
||||||
|
install-error-strip-abnormal = strip process terminated abnormally - exit code: { $code }
|
||||||
|
install-error-metadata-failed = metadata error
|
||||||
|
install-error-invalid-user = invalid user: { $user }
|
||||||
|
install-error-invalid-group = invalid group: { $group }
|
||||||
|
install-error-omitting-directory = omitting directory { $path }
|
||||||
|
install-error-not-a-directory = failed to access { $path }: Not a directory
|
||||||
|
install-error-override-directory-failed = cannot overwrite directory { $dir } with non-directory { $file }
|
||||||
|
install-error-same-file = '{ $file1 }' and '{ $file2 }' are the same file
|
||||||
|
install-error-extra-operand = extra operand { $operand }
|
||||||
|
{ $usage }
|
||||||
|
install-error-invalid-mode = Invalid mode string: { $error }
|
||||||
|
install-error-mutually-exclusive-target = Options --target-directory and --no-target-directory are mutually exclusive
|
||||||
|
install-error-mutually-exclusive-compare-preserve = Options --compare and --preserve-timestamps are mutually exclusive
|
||||||
|
install-error-mutually-exclusive-compare-strip = Options --compare and --strip are mutually exclusive
|
||||||
|
install-error-missing-file-operand = missing file operand
|
||||||
|
install-error-missing-destination-operand = missing destination file operand after '{ $path }'
|
||||||
|
install-error-failed-to-remove = Failed to remove existing file { $path }. Error: { $error }
|
||||||
|
|
||||||
|
# Verbose output
|
||||||
|
install-verbose-creating-directory = creating directory { $path }
|
||||||
|
install-verbose-creating-directory-step = install: creating directory { $path }
|
||||||
|
install-verbose-removed = removed { $path }
|
||||||
|
install-verbose-copy = { $from } -> { $to }
|
||||||
|
install-verbose-backup = (backup: { $backup })
|
||||||
|
|
56
src/uu/install/locales/fr-FR.ftl
Normal file
56
src/uu/install/locales/fr-FR.ftl
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
install-about = Copier SOURCE vers DEST ou plusieurs SOURCE(s) vers le
|
||||||
|
RÉPERTOIRE existant, tout en définissant les modes de permission et propriétaire/groupe
|
||||||
|
install-usage = install [OPTION]... [FICHIER]...
|
||||||
|
|
||||||
|
# Messages d'aide
|
||||||
|
install-help-ignored = ignoré
|
||||||
|
install-help-compare = comparer chaque paire de fichiers source et destination, et dans certains cas, ne pas modifier la destination du tout
|
||||||
|
install-help-directory = traiter tous les arguments comme des noms de répertoires. créer tous les composants des répertoires spécifiés
|
||||||
|
install-help-create-leading = créer tous les composants principaux de DEST sauf le dernier, puis copier SOURCE vers DEST
|
||||||
|
install-help-group = définir la propriété du groupe, au lieu du groupe actuel du processus
|
||||||
|
install-help-mode = définir le mode de permission (comme dans chmod), au lieu de rwxr-xr-x
|
||||||
|
install-help-owner = définir la propriété (super-utilisateur uniquement)
|
||||||
|
install-help-preserve-timestamps = appliquer les temps d'accès/modification des fichiers SOURCE aux fichiers de destination correspondants
|
||||||
|
install-help-strip = supprimer les tables de symboles (aucune action Windows)
|
||||||
|
install-help-strip-program = programme utilisé pour supprimer les binaires (aucune action Windows)
|
||||||
|
install-help-target-directory = déplacer tous les arguments SOURCE dans RÉPERTOIRE
|
||||||
|
install-help-no-target-directory = traiter DEST comme un fichier normal
|
||||||
|
install-help-verbose = expliquer ce qui est fait
|
||||||
|
install-help-preserve-context = préserver le contexte de sécurité
|
||||||
|
install-help-context = définir le contexte de sécurité des fichiers et répertoires
|
||||||
|
|
||||||
|
# Messages d'erreur
|
||||||
|
install-error-dir-needs-arg = { $util_name } avec -d nécessite au moins un argument.
|
||||||
|
install-error-create-dir-failed = échec de la création de { $path }
|
||||||
|
install-error-chmod-failed = échec du chmod { $path }
|
||||||
|
install-error-chmod-failed-detailed = { $path } : échec du chmod avec l'erreur { $error }
|
||||||
|
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-install-failed = impossible d'installer { $from } vers { $to }
|
||||||
|
install-error-strip-failed = échec du programme strip : { $error }
|
||||||
|
install-error-strip-abnormal = le processus strip s'est terminé anormalement - code de sortie : { $code }
|
||||||
|
install-error-metadata-failed = erreur de métadonnées
|
||||||
|
install-error-invalid-user = utilisateur invalide : { $user }
|
||||||
|
install-error-invalid-group = groupe invalide : { $group }
|
||||||
|
install-error-omitting-directory = omission du répertoire { $path }
|
||||||
|
install-error-not-a-directory = échec de l'accès à { $path } : N'est pas un répertoire
|
||||||
|
install-error-override-directory-failed = impossible d'écraser le répertoire { $dir } avec un non-répertoire { $file }
|
||||||
|
install-error-same-file = '{ $file1 }' et '{ $file2 }' sont le même fichier
|
||||||
|
install-error-extra-operand = opérande supplémentaire { $operand }
|
||||||
|
{ $usage }
|
||||||
|
install-error-invalid-mode = Chaîne de mode invalide : { $error }
|
||||||
|
install-error-mutually-exclusive-target = Les options --target-directory et --no-target-directory sont mutuellement exclusives
|
||||||
|
install-error-mutually-exclusive-compare-preserve = Les options --compare et --preserve-timestamps sont mutuellement exclusives
|
||||||
|
install-error-mutually-exclusive-compare-strip = Les options --compare et --strip sont mutuellement exclusives
|
||||||
|
install-error-missing-file-operand = opérande de fichier manquant
|
||||||
|
install-error-missing-destination-operand = opérande de fichier de destination manquant après '{ $path }'
|
||||||
|
install-error-failed-to-remove = Échec de la suppression du fichier existant { $path }. Erreur : { $error }
|
||||||
|
|
||||||
|
# Sortie détaillée
|
||||||
|
install-verbose-creating-directory = création du répertoire { $path }
|
||||||
|
install-verbose-creating-directory-step = install : création du répertoire { $path }
|
||||||
|
install-verbose-removed = supprimé { $path }
|
||||||
|
install-verbose-copy = { $from } -> { $to }
|
||||||
|
install-verbose-backup = (sauvegarde : { $backup })
|
|
@ -10,6 +10,7 @@ mod mode;
|
||||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||||
use file_diff::diff;
|
use file_diff::diff;
|
||||||
use filetime::{FileTime, set_file_times};
|
use filetime::{FileTime, set_file_times};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::fs::{self, metadata};
|
use std::fs::{self, metadata};
|
||||||
|
@ -33,7 +34,7 @@ use uucore::{format_usage, show, show_error, show_if_err};
|
||||||
use std::os::unix::fs::{FileTypeExt, MetadataExt};
|
use std::os::unix::fs::{FileTypeExt, MetadataExt};
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::os::unix::prelude::OsStrExt;
|
use std::os::unix::prelude::OsStrExt;
|
||||||
use uucore::locale::get_message;
|
use uucore::locale::{get_message, get_message_with_args};
|
||||||
|
|
||||||
const DEFAULT_MODE: u32 = 0o755;
|
const DEFAULT_MODE: u32 = 0o755;
|
||||||
const DEFAULT_STRIP_PROGRAM: &str = "strip";
|
const DEFAULT_STRIP_PROGRAM: &str = "strip";
|
||||||
|
@ -60,55 +61,55 @@ pub struct Behavior {
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
enum InstallError {
|
enum InstallError {
|
||||||
#[error("{} with -d requires at least one argument.", uucore::util_name())]
|
#[error("{}", get_message_with_args("install-error-dir-needs-arg", HashMap::from([("util_name".to_string(), uucore::util_name().to_string())])))]
|
||||||
DirNeedsArg,
|
DirNeedsArg,
|
||||||
|
|
||||||
#[error("failed to create {0}")]
|
#[error("{}", get_message_with_args("install-error-create-dir-failed", HashMap::from([("path".to_string(), .0.quote().to_string())])))]
|
||||||
CreateDirFailed(PathBuf, #[source] std::io::Error),
|
CreateDirFailed(PathBuf, #[source] std::io::Error),
|
||||||
|
|
||||||
#[error("failed to chmod {}", .0.quote())]
|
#[error("{}", get_message_with_args("install-error-chmod-failed", HashMap::from([("path".to_string(), .0.quote().to_string())])))]
|
||||||
ChmodFailed(PathBuf),
|
ChmodFailed(PathBuf),
|
||||||
|
|
||||||
#[error("failed to chown {}: {}", .0.quote(), .1)]
|
#[error("{}", get_message_with_args("install-error-chown-failed", HashMap::from([("path".to_string(), .0.quote().to_string()), ("error".to_string(), .1.clone())])))]
|
||||||
ChownFailed(PathBuf, String),
|
ChownFailed(PathBuf, String),
|
||||||
|
|
||||||
#[error("invalid target {}: No such file or directory", .0.quote())]
|
#[error("{}", get_message_with_args("install-error-invalid-target", HashMap::from([("path".to_string(), .0.quote().to_string())])))]
|
||||||
InvalidTarget(PathBuf),
|
InvalidTarget(PathBuf),
|
||||||
|
|
||||||
#[error("target {} is not a directory", .0.quote())]
|
#[error("{}", get_message_with_args("install-error-target-not-dir", HashMap::from([("path".to_string(), .0.quote().to_string())])))]
|
||||||
TargetDirIsntDir(PathBuf),
|
TargetDirIsntDir(PathBuf),
|
||||||
|
|
||||||
#[error("cannot backup {0} to {1}")]
|
#[error("{}", get_message_with_args("install-error-backup-failed", HashMap::from([("from".to_string(), .0.to_string_lossy().to_string()), ("to".to_string(), .1.to_string_lossy().to_string())])))]
|
||||||
BackupFailed(PathBuf, PathBuf, #[source] std::io::Error),
|
BackupFailed(PathBuf, PathBuf, #[source] std::io::Error),
|
||||||
|
|
||||||
#[error("cannot install {0} to {1}")]
|
#[error("{}", get_message_with_args("install-error-install-failed", HashMap::from([("from".to_string(), .0.to_string_lossy().to_string()), ("to".to_string(), .1.to_string_lossy().to_string())])))]
|
||||||
InstallFailed(PathBuf, PathBuf, #[source] std::io::Error),
|
InstallFailed(PathBuf, PathBuf, #[source] std::io::Error),
|
||||||
|
|
||||||
#[error("strip program failed: {0}")]
|
#[error("{}", get_message_with_args("install-error-strip-failed", HashMap::from([("error".to_string(), .0.clone())])))]
|
||||||
StripProgramFailed(String),
|
StripProgramFailed(String),
|
||||||
|
|
||||||
#[error("metadata error")]
|
#[error("{}", get_message("install-error-metadata-failed"))]
|
||||||
MetadataFailed(#[source] std::io::Error),
|
MetadataFailed(#[source] std::io::Error),
|
||||||
|
|
||||||
#[error("invalid user: {}", .0.quote())]
|
#[error("{}", get_message_with_args("install-error-invalid-user", HashMap::from([("user".to_string(), .0.quote().to_string())])))]
|
||||||
InvalidUser(String),
|
InvalidUser(String),
|
||||||
|
|
||||||
#[error("invalid group: {}", .0.quote())]
|
#[error("{}", get_message_with_args("install-error-invalid-group", HashMap::from([("group".to_string(), .0.quote().to_string())])))]
|
||||||
InvalidGroup(String),
|
InvalidGroup(String),
|
||||||
|
|
||||||
#[error("omitting directory {}", .0.quote())]
|
#[error("{}", get_message_with_args("install-error-omitting-directory", HashMap::from([("path".to_string(), .0.quote().to_string())])))]
|
||||||
OmittingDirectory(PathBuf),
|
OmittingDirectory(PathBuf),
|
||||||
|
|
||||||
#[error("failed to access {}: Not a directory", .0.quote())]
|
#[error("{}", get_message_with_args("install-error-not-a-directory", HashMap::from([("path".to_string(), .0.quote().to_string())])))]
|
||||||
NotADirectory(PathBuf),
|
NotADirectory(PathBuf),
|
||||||
|
|
||||||
#[error("cannot overwrite directory {} with non-directory {}", .0.quote(), .1.quote())]
|
#[error("{}", get_message_with_args("install-error-override-directory-failed", HashMap::from([("dir".to_string(), .0.quote().to_string()), ("file".to_string(), .1.quote().to_string())])))]
|
||||||
OverrideDirectoryFailed(PathBuf, PathBuf),
|
OverrideDirectoryFailed(PathBuf, PathBuf),
|
||||||
|
|
||||||
#[error("'{0}' and '{1}' are the same file")]
|
#[error("{}", get_message_with_args("install-error-same-file", HashMap::from([("file1".to_string(), .0.to_string_lossy().to_string()), ("file2".to_string(), .1.to_string_lossy().to_string())])))]
|
||||||
SameFile(PathBuf, PathBuf),
|
SameFile(PathBuf, PathBuf),
|
||||||
|
|
||||||
#[error("extra operand {}\n{}", .0.quote(), .1.quote())]
|
#[error("{}", get_message_with_args("install-error-extra-operand", HashMap::from([("operand".to_string(), .0.quote().to_string()), ("usage".to_string(), .1.clone())])))]
|
||||||
ExtraOperand(String, String),
|
ExtraOperand(String, String),
|
||||||
|
|
||||||
#[cfg(feature = "selinux")]
|
#[cfg(feature = "selinux")]
|
||||||
|
@ -191,57 +192,48 @@ pub fn uu_app() -> Command {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_IGNORED)
|
Arg::new(OPT_IGNORED)
|
||||||
.short('c')
|
.short('c')
|
||||||
.help("ignored")
|
.help(get_message("install-help-ignored"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_COMPARE)
|
Arg::new(OPT_COMPARE)
|
||||||
.short('C')
|
.short('C')
|
||||||
.long(OPT_COMPARE)
|
.long(OPT_COMPARE)
|
||||||
.help(
|
.help(get_message("install-help-compare"))
|
||||||
"compare each pair of source and destination files, and in some cases, \
|
|
||||||
do not modify the destination at all",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_DIRECTORY)
|
Arg::new(OPT_DIRECTORY)
|
||||||
.short('d')
|
.short('d')
|
||||||
.long(OPT_DIRECTORY)
|
.long(OPT_DIRECTORY)
|
||||||
.help(
|
.help(get_message("install-help-directory"))
|
||||||
"treat all arguments as directory names. create all components of \
|
|
||||||
the specified directories",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_CREATE_LEADING)
|
Arg::new(OPT_CREATE_LEADING)
|
||||||
.short('D')
|
.short('D')
|
||||||
.help(
|
.help(get_message("install-help-create-leading"))
|
||||||
"create all leading components of DEST except the last, then copy \
|
|
||||||
SOURCE to DEST",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_GROUP)
|
Arg::new(OPT_GROUP)
|
||||||
.short('g')
|
.short('g')
|
||||||
.long(OPT_GROUP)
|
.long(OPT_GROUP)
|
||||||
.help("set group ownership, instead of process's current group")
|
.help(get_message("install-help-group"))
|
||||||
.value_name("GROUP"),
|
.value_name("GROUP"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_MODE)
|
Arg::new(OPT_MODE)
|
||||||
.short('m')
|
.short('m')
|
||||||
.long(OPT_MODE)
|
.long(OPT_MODE)
|
||||||
.help("set permission mode (as in chmod), instead of rwxr-xr-x")
|
.help(get_message("install-help-mode"))
|
||||||
.value_name("MODE"),
|
.value_name("MODE"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_OWNER)
|
Arg::new(OPT_OWNER)
|
||||||
.short('o')
|
.short('o')
|
||||||
.long(OPT_OWNER)
|
.long(OPT_OWNER)
|
||||||
.help("set ownership (super-user only)")
|
.help(get_message("install-help-owner"))
|
||||||
.value_name("OWNER")
|
.value_name("OWNER")
|
||||||
.value_hint(clap::ValueHint::Username),
|
.value_hint(clap::ValueHint::Username),
|
||||||
)
|
)
|
||||||
|
@ -249,23 +241,20 @@ pub fn uu_app() -> Command {
|
||||||
Arg::new(OPT_PRESERVE_TIMESTAMPS)
|
Arg::new(OPT_PRESERVE_TIMESTAMPS)
|
||||||
.short('p')
|
.short('p')
|
||||||
.long(OPT_PRESERVE_TIMESTAMPS)
|
.long(OPT_PRESERVE_TIMESTAMPS)
|
||||||
.help(
|
.help(get_message("install-help-preserve-timestamps"))
|
||||||
"apply access/modification times of SOURCE files to \
|
|
||||||
corresponding destination files",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_STRIP)
|
Arg::new(OPT_STRIP)
|
||||||
.short('s')
|
.short('s')
|
||||||
.long(OPT_STRIP)
|
.long(OPT_STRIP)
|
||||||
.help("strip symbol tables (no action Windows)")
|
.help(get_message("install-help-strip"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_STRIP_PROGRAM)
|
Arg::new(OPT_STRIP_PROGRAM)
|
||||||
.long(OPT_STRIP_PROGRAM)
|
.long(OPT_STRIP_PROGRAM)
|
||||||
.help("program used to strip binaries (no action Windows)")
|
.help(get_message("install-help-strip-program"))
|
||||||
.value_name("PROGRAM")
|
.value_name("PROGRAM")
|
||||||
.value_hint(clap::ValueHint::CommandName),
|
.value_hint(clap::ValueHint::CommandName),
|
||||||
)
|
)
|
||||||
|
@ -274,7 +263,7 @@ pub fn uu_app() -> Command {
|
||||||
Arg::new(OPT_TARGET_DIRECTORY)
|
Arg::new(OPT_TARGET_DIRECTORY)
|
||||||
.short('t')
|
.short('t')
|
||||||
.long(OPT_TARGET_DIRECTORY)
|
.long(OPT_TARGET_DIRECTORY)
|
||||||
.help("move all SOURCE arguments into DIRECTORY")
|
.help(get_message("install-help-target-directory"))
|
||||||
.value_name("DIRECTORY")
|
.value_name("DIRECTORY")
|
||||||
.value_hint(clap::ValueHint::DirPath),
|
.value_hint(clap::ValueHint::DirPath),
|
||||||
)
|
)
|
||||||
|
@ -282,28 +271,28 @@ pub fn uu_app() -> Command {
|
||||||
Arg::new(OPT_NO_TARGET_DIRECTORY)
|
Arg::new(OPT_NO_TARGET_DIRECTORY)
|
||||||
.short('T')
|
.short('T')
|
||||||
.long(OPT_NO_TARGET_DIRECTORY)
|
.long(OPT_NO_TARGET_DIRECTORY)
|
||||||
.help("treat DEST as a normal file")
|
.help(get_message("install-help-no-target-directory"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_VERBOSE)
|
Arg::new(OPT_VERBOSE)
|
||||||
.short('v')
|
.short('v')
|
||||||
.long(OPT_VERBOSE)
|
.long(OPT_VERBOSE)
|
||||||
.help("explain what is being done")
|
.help(get_message("install-help-verbose"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_PRESERVE_CONTEXT)
|
Arg::new(OPT_PRESERVE_CONTEXT)
|
||||||
.short('P')
|
.short('P')
|
||||||
.long(OPT_PRESERVE_CONTEXT)
|
.long(OPT_PRESERVE_CONTEXT)
|
||||||
.help("preserve security context")
|
.help(get_message("install-help-preserve-context"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(OPT_CONTEXT)
|
Arg::new(OPT_CONTEXT)
|
||||||
.short('Z')
|
.short('Z')
|
||||||
.long(OPT_CONTEXT)
|
.long(OPT_CONTEXT)
|
||||||
.help("set security context of files and directories")
|
.help(get_message("install-help-context"))
|
||||||
.value_name("CONTEXT")
|
.value_name("CONTEXT")
|
||||||
.value_parser(clap::value_parser!(String))
|
.value_parser(clap::value_parser!(String))
|
||||||
.num_args(0..=1),
|
.num_args(0..=1),
|
||||||
|
@ -336,7 +325,13 @@ fn behavior(matches: &ArgMatches) -> UResult<Behavior> {
|
||||||
let specified_mode: Option<u32> = if matches.contains_id(OPT_MODE) {
|
let specified_mode: Option<u32> = if matches.contains_id(OPT_MODE) {
|
||||||
let x = matches.get_one::<String>(OPT_MODE).ok_or(1)?;
|
let x = matches.get_one::<String>(OPT_MODE).ok_or(1)?;
|
||||||
Some(mode::parse(x, considering_dir, get_umask()).map_err(|err| {
|
Some(mode::parse(x, considering_dir, get_umask()).map_err(|err| {
|
||||||
show_error!("Invalid mode string: {err}");
|
show_error!(
|
||||||
|
"{}",
|
||||||
|
get_message_with_args(
|
||||||
|
"install-error-invalid-mode",
|
||||||
|
HashMap::from([("error".to_string(), err)])
|
||||||
|
)
|
||||||
|
);
|
||||||
1
|
1
|
||||||
})?)
|
})?)
|
||||||
} else {
|
} else {
|
||||||
|
@ -347,7 +342,7 @@ fn behavior(matches: &ArgMatches) -> UResult<Behavior> {
|
||||||
let target_dir = matches.get_one::<String>(OPT_TARGET_DIRECTORY).cloned();
|
let target_dir = matches.get_one::<String>(OPT_TARGET_DIRECTORY).cloned();
|
||||||
let no_target_dir = matches.get_flag(OPT_NO_TARGET_DIRECTORY);
|
let no_target_dir = matches.get_flag(OPT_NO_TARGET_DIRECTORY);
|
||||||
if target_dir.is_some() && no_target_dir {
|
if target_dir.is_some() && no_target_dir {
|
||||||
show_error!("Options --target-directory and --no-target-directory are mutually exclusive");
|
show_error!("{}", get_message("install-error-mutually-exclusive-target"));
|
||||||
return Err(1.into());
|
return Err(1.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,11 +350,17 @@ fn behavior(matches: &ArgMatches) -> UResult<Behavior> {
|
||||||
let compare = matches.get_flag(OPT_COMPARE);
|
let compare = matches.get_flag(OPT_COMPARE);
|
||||||
let strip = matches.get_flag(OPT_STRIP);
|
let strip = matches.get_flag(OPT_STRIP);
|
||||||
if preserve_timestamps && compare {
|
if preserve_timestamps && compare {
|
||||||
show_error!("Options --compare and --preserve-timestamps are mutually exclusive");
|
show_error!(
|
||||||
|
"{}",
|
||||||
|
get_message("install-error-mutually-exclusive-compare-preserve")
|
||||||
|
);
|
||||||
return Err(1.into());
|
return Err(1.into());
|
||||||
}
|
}
|
||||||
if compare && strip {
|
if compare && strip {
|
||||||
show_error!("Options --compare and --strip are mutually exclusive");
|
show_error!(
|
||||||
|
"{}",
|
||||||
|
get_message("install-error-mutually-exclusive-compare-strip")
|
||||||
|
);
|
||||||
return Err(1.into());
|
return Err(1.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +457,16 @@ fn directory(paths: &[String], b: &Behavior) -> UResult<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.verbose {
|
if b.verbose {
|
||||||
println!("creating directory {}", path_to_create.quote());
|
println!(
|
||||||
|
"{}",
|
||||||
|
get_message_with_args(
|
||||||
|
"install-verbose-creating-directory",
|
||||||
|
HashMap::from([(
|
||||||
|
"path".to_string(),
|
||||||
|
path_to_create.quote().to_string()
|
||||||
|
)])
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +521,10 @@ fn is_potential_directory_path(path: &Path) -> bool {
|
||||||
fn standard(mut paths: Vec<String>, b: &Behavior) -> UResult<()> {
|
fn standard(mut paths: Vec<String>, b: &Behavior) -> UResult<()> {
|
||||||
// first check that paths contains at least one element
|
// first check that paths contains at least one element
|
||||||
if paths.is_empty() {
|
if paths.is_empty() {
|
||||||
return Err(UUsageError::new(1, "missing file operand"));
|
return Err(UUsageError::new(
|
||||||
|
1,
|
||||||
|
get_message("install-error-missing-file-operand"),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
if b.no_target_dir && paths.len() > 2 {
|
if b.no_target_dir && paths.len() > 2 {
|
||||||
return Err(InstallError::ExtraOperand(
|
return Err(InstallError::ExtraOperand(
|
||||||
|
@ -531,9 +544,9 @@ fn standard(mut paths: Vec<String>, b: &Behavior) -> UResult<()> {
|
||||||
if paths.is_empty() {
|
if paths.is_empty() {
|
||||||
return Err(UUsageError::new(
|
return Err(UUsageError::new(
|
||||||
1,
|
1,
|
||||||
format!(
|
get_message_with_args(
|
||||||
"missing destination file operand after '{}'",
|
"install-error-missing-destination-operand",
|
||||||
last_path.to_str().unwrap()
|
HashMap::from([("path".to_string(), last_path.to_str().unwrap().to_string())]),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -570,7 +583,16 @@ fn standard(mut paths: Vec<String>, b: &Behavior) -> UResult<()> {
|
||||||
result.push(part.as_os_str());
|
result.push(part.as_os_str());
|
||||||
if !result.is_dir() {
|
if !result.is_dir() {
|
||||||
// Don't display when the directory already exists
|
// Don't display when the directory already exists
|
||||||
println!("install: creating directory {}", result.quote());
|
println!(
|
||||||
|
"{}",
|
||||||
|
get_message_with_args(
|
||||||
|
"install-verbose-creating-directory-step",
|
||||||
|
HashMap::from([(
|
||||||
|
"path".to_string(),
|
||||||
|
result.quote().to_string()
|
||||||
|
)])
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -716,7 +738,13 @@ fn chown_optional_user_group(path: &Path, b: &Behavior) -> UResult<()> {
|
||||||
fn perform_backup(to: &Path, b: &Behavior) -> UResult<Option<PathBuf>> {
|
fn perform_backup(to: &Path, b: &Behavior) -> UResult<Option<PathBuf>> {
|
||||||
if to.exists() {
|
if to.exists() {
|
||||||
if b.verbose {
|
if b.verbose {
|
||||||
println!("removed {}", to.quote());
|
println!(
|
||||||
|
"{}",
|
||||||
|
get_message_with_args(
|
||||||
|
"install-verbose-removed",
|
||||||
|
HashMap::from([("path".to_string(), to.quote().to_string())])
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let backup_path = backup_control::get_backup_path(b.backup_mode, to, &b.suffix);
|
let backup_path = backup_control::get_backup_path(b.backup_mode, to, &b.suffix);
|
||||||
if let Some(ref backup_path) = backup_path {
|
if let Some(ref backup_path) = backup_path {
|
||||||
|
@ -777,8 +805,14 @@ fn copy_file(from: &Path, to: &Path) -> UResult<()> {
|
||||||
if let Err(e) = fs::remove_file(to) {
|
if let Err(e) = fs::remove_file(to) {
|
||||||
if e.kind() != std::io::ErrorKind::NotFound {
|
if e.kind() != std::io::ErrorKind::NotFound {
|
||||||
show_error!(
|
show_error!(
|
||||||
"Failed to remove existing file {}. Error: {e:?}",
|
"{}",
|
||||||
to.display(),
|
get_message_with_args(
|
||||||
|
"install-error-failed-to-remove",
|
||||||
|
HashMap::from([
|
||||||
|
("path".to_string(), to.display().to_string()),
|
||||||
|
("error".to_string(), format!("{e:?}"))
|
||||||
|
])
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -832,9 +866,9 @@ fn strip_file(to: &Path, b: &Behavior) -> UResult<()> {
|
||||||
if !status.success() {
|
if !status.success() {
|
||||||
// Follow GNU's behavior: if strip fails, removes the target
|
// Follow GNU's behavior: if strip fails, removes the target
|
||||||
let _ = fs::remove_file(to);
|
let _ = fs::remove_file(to);
|
||||||
return Err(InstallError::StripProgramFailed(format!(
|
return Err(InstallError::StripProgramFailed(get_message_with_args(
|
||||||
"strip process terminated abnormally - exit code: {}",
|
"install-error-strip-abnormal",
|
||||||
status.code().unwrap()
|
HashMap::from([("code".to_string(), status.code().unwrap().to_string())]),
|
||||||
))
|
))
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
@ -940,9 +974,24 @@ fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.verbose {
|
if b.verbose {
|
||||||
print!("{} -> {}", from.quote(), to.quote());
|
print!(
|
||||||
|
"{}",
|
||||||
|
get_message_with_args(
|
||||||
|
"install-verbose-copy",
|
||||||
|
HashMap::from([
|
||||||
|
("from".to_string(), from.quote().to_string()),
|
||||||
|
("to".to_string(), to.quote().to_string())
|
||||||
|
])
|
||||||
|
)
|
||||||
|
);
|
||||||
match backup_path {
|
match backup_path {
|
||||||
Some(path) => println!(" (backup: {})", path.quote()),
|
Some(path) => println!(
|
||||||
|
" {}",
|
||||||
|
get_message_with_args(
|
||||||
|
"install-verbose-backup",
|
||||||
|
HashMap::from([("backup".to_string(), path.quote().to_string())])
|
||||||
|
)
|
||||||
|
),
|
||||||
None => println!(),
|
None => println!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use uucore::locale::get_message_with_args;
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
use uucore::mode;
|
use uucore::mode;
|
||||||
|
|
||||||
|
@ -25,7 +27,16 @@ pub fn chmod(path: &Path, mode: u32) -> Result<(), ()> {
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use uucore::{display::Quotable, show_error};
|
use uucore::{display::Quotable, show_error};
|
||||||
fs::set_permissions(path, fs::Permissions::from_mode(mode)).map_err(|err| {
|
fs::set_permissions(path, fs::Permissions::from_mode(mode)).map_err(|err| {
|
||||||
show_error!("{}: chmod failed with error {err}", path.maybe_quote());
|
show_error!(
|
||||||
|
"{}",
|
||||||
|
get_message_with_args(
|
||||||
|
"install-error-chmod-failed-detailed",
|
||||||
|
HashMap::from([
|
||||||
|
("path".to_string(), path.maybe_quote().to_string()),
|
||||||
|
("error".to_string(), err.to_string())
|
||||||
|
])
|
||||||
|
)
|
||||||
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue