From dc9dd3fb7081b54a28140d8ede2ccda418a5589c Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 22 Jun 2025 19:26:09 +0200 Subject: [PATCH] l10n: port ls for translation + add french Co-authored-by: Daniel Hofstetter --- src/uu/ls/locales/en-US.ftl | 116 +++++++++++++++ src/uu/ls/locales/fr-FR.ftl | 120 +++++++++++++++ src/uu/ls/src/ls.rs | 286 ++++++++++++++++-------------------- tests/by-util/test_ls.rs | 1 + 4 files changed, 367 insertions(+), 156 deletions(-) create mode 100644 src/uu/ls/locales/fr-FR.ftl diff --git a/src/uu/ls/locales/en-US.ftl b/src/uu/ls/locales/en-US.ftl index b21aefa22..308e9d6d7 100644 --- a/src/uu/ls/locales/en-US.ftl +++ b/src/uu/ls/locales/en-US.ftl @@ -2,3 +2,119 @@ ls-about = List directory contents. Ignore files and directories starting with a '.' by default ls-usage = ls [OPTION]... [FILE]... ls-after-help = The TIME_STYLE argument can be full-iso, long-iso, iso, locale or +FORMAT. FORMAT is interpreted like in date. Also the TIME_STYLE environment variable sets the default style to use. + +# Error messages +ls-error-invalid-line-width = invalid line width: {$width} +ls-error-general-io = general io error: {$error} +ls-error-cannot-access-no-such-file = cannot access '{$path}': No such file or directory +ls-error-cannot-access-operation-not-permitted = cannot access '{$path}': Operation not permitted +ls-error-cannot-open-directory-permission-denied = cannot open directory '{$path}': Permission denied +ls-error-cannot-open-file-permission-denied = cannot open file '{$path}': Permission denied +ls-error-cannot-open-directory-bad-descriptor = cannot open directory '{$path}': Bad file descriptor +ls-error-unknown-io-error = unknown io error: '{$path}', '{$error}' +ls-error-invalid-block-size = invalid --block-size argument {$size} +ls-error-dired-and-zero-incompatible = --dired and --zero are incompatible +ls-error-not-listing-already-listed = {$path}: not listing already-listed directory +ls-error-invalid-time-style = invalid --time-style argument {$style} + Possible values are: {$values} + + For more information try --help + +# Help messages +ls-help-print-help = Print help information. +ls-help-set-display-format = Set the display format. +ls-help-display-files-columns = Display the files in columns. +ls-help-display-detailed-info = Display detailed information. +ls-help-list-entries-rows = List entries in rows instead of in columns. +ls-help-assume-tab-stops = Assume tab stops at each COLS instead of 8 +ls-help-list-entries-commas = List entries separated by commas. +ls-help-list-entries-nul = List entries separated by ASCII NUL characters. +ls-help-generate-dired-output = generate output designed for Emacs' dired (Directory Editor) mode +ls-help-hyperlink-filenames = hyperlink file names WHEN +ls-help-list-one-file-per-line = List one file per line. +ls-help-long-format-no-group = Long format without group information. + Identical to --format=long with --no-group. +ls-help-long-no-owner = Long format without owner information. +ls-help-long-numeric-uid-gid = -l with numeric UIDs and GIDs. +ls-help-set-quoting-style = Set quoting style. +ls-help-literal-quoting-style = Use literal quoting style. Equivalent to `--quoting-style=literal` +ls-help-escape-quoting-style = Use escape quoting style. Equivalent to `--quoting-style=escape` +ls-help-c-quoting-style = Use C quoting style. Equivalent to `--quoting-style=c` +ls-help-replace-control-chars = Replace control characters with '?' if they are not escaped. +ls-help-show-control-chars = Show control characters 'as is' if they are not escaped. +ls-help-show-time-field = Show time in : + access time (-u): atime, access, use; + change time (-t): ctime, status. + modification time: mtime, modification. + birth time: birth, creation; +ls-help-time-change = If the long listing format (e.g., -l, -o) is being used, print the + status change time (the 'ctime' in the inode) instead of the modification + time. When explicitly sorting by time (--sort=time or -t) or when not + using a long listing format, sort according to the status change time. +ls-help-time-access = If the long listing format (e.g., -l, -o) is being used, print the + status access time instead of the modification time. When explicitly + sorting by time (--sort=time or -t) or when not using a long listing + format, sort according to the access time. +ls-help-hide-pattern = do not list implied entries matching shell PATTERN (overridden by -a or -A) +ls-help-ignore-pattern = do not list implied entries matching shell PATTERN +ls-help-ignore-backups = Ignore entries which end with ~. +ls-help-sort-by-field = Sort by : name, none (-U), time (-t), size (-S), extension (-X) or width +ls-help-sort-by-size = Sort by file size, largest first. +ls-help-sort-by-time = Sort by modification time (the 'mtime' in the inode), newest first. +ls-help-sort-by-version = Natural sort of (version) numbers in the filenames. +ls-help-sort-by-extension = Sort alphabetically by entry extension. +ls-help-sort-none = Do not sort; list the files in whatever order they are stored in the + directory. This is especially useful when listing very large directories, + since not doing any sorting can be noticeably faster. +ls-help-dereference-all = When showing file information for a symbolic link, show information for the + file the link references rather than the link itself. +ls-help-dereference-dir-args = Do not follow symlinks except when they link to directories and are + given as command line arguments. +ls-help-dereference-args = Do not follow symlinks except when given as command line arguments. +ls-help-no-group = Do not show group in long format. +ls-help-author = Show author in long format. On the supported platforms, + the author always matches the file owner. +ls-help-all-files = Do not ignore hidden files (files with names that start with '.'). +ls-help-almost-all = In a directory, do not ignore all file names that start with '.', + only ignore '.' and '..'. +ls-help-directory = Only list the names of directories, rather than listing directory contents. + This will not follow symbolic links unless one of `--dereference-command-line + (-H)`, `--dereference (-L)`, or `--dereference-command-line-symlink-to-dir` is + specified. +ls-help-human-readable = Print human readable file sizes (e.g. 1K 234M 56G). +ls-help-kibibytes = default to 1024-byte blocks for file system usage; used only with -s and per + directory totals +ls-help-si = Print human readable file sizes using powers of 1000 instead of 1024. +ls-help-block-size = scale sizes by BLOCK_SIZE when printing them +ls-help-print-inode = print the index number of each file +ls-help-reverse-sort = Reverse whatever the sorting method is e.g., list files in reverse + alphabetical order, youngest first, smallest first, or whatever. +ls-help-recursive = List the contents of all directories recursively. +ls-help-terminal-width = Assume that the terminal is COLS columns wide. +ls-help-allocation-size = print the allocated size of each file, in blocks +ls-help-color-output = Color output based on file type. +ls-help-indicator-style = Append indicator with style WORD to entry names: + none (default), slash (-p), file-type (--file-type), classify (-F) +ls-help-classify = Append a character to each file name indicating the file type. Also, for + regular files that are executable, append '*'. The file type indicators are + '/' for directories, '@' for symbolic links, '|' for FIFOs, '=' for sockets, + '>' for doors, and nothing for regular files. when may be omitted, or one of: + none - Do not classify. This is the default. + auto - Only classify if standard output is a terminal. + always - Always classify. + Specifying --classify and no when is equivalent to --classify=always. This will + not follow symbolic links listed on the command line unless the + --dereference-command-line (-H), --dereference (-L), or + --dereference-command-line-symlink-to-dir options are specified. +ls-help-file-type = Same as --classify, but do not append '*' +ls-help-slash-directories = Append / indicator to directories. +ls-help-time-style = time/date format with -l; see TIME_STYLE below +ls-help-full-time = like -l --time-style=full-iso +ls-help-context = print any security context of each file +ls-help-group-directories-first = group directories before files; can be augmented with + a --sort option, but any use of --sort=none (-U) disables grouping +ls-invalid-quoting-style = {$program}: Ignoring invalid value of environment variable QUOTING_STYLE: '{$style}' +ls-invalid-columns-width = ignoring invalid width in environment variable COLUMNS: {$width} +ls-invalid-ignore-pattern = Invalid pattern for ignore: {$pattern} +ls-invalid-hide-pattern = Invalid pattern for hide: {$pattern} +ls-total = total {$size} diff --git a/src/uu/ls/locales/fr-FR.ftl b/src/uu/ls/locales/fr-FR.ftl new file mode 100644 index 000000000..9aa81bd28 --- /dev/null +++ b/src/uu/ls/locales/fr-FR.ftl @@ -0,0 +1,120 @@ +ls-about = Lister le contenu des répertoires. + Ignorer les fichiers et répertoires commençant par un '.' par défaut +ls-usage = ls [OPTION]... [FICHIER]... +ls-after-help = L'argument TIME_STYLE peut être full-iso, long-iso, iso, locale ou +FORMAT. FORMAT est interprété comme dans date. De plus, la variable d'environnement TIME_STYLE définit le style par défaut à utiliser. + +# Messages d'erreur +ls-error-invalid-line-width = largeur de ligne invalide : {$width} +ls-error-general-io = erreur d'E/S générale : {$error} +ls-error-cannot-access-no-such-file = impossible d'accéder à '{$path}' : Aucun fichier ou répertoire de ce type +ls-error-cannot-access-operation-not-permitted = impossible d'accéder à '{$path}' : Opération non autorisée +ls-error-cannot-open-directory-permission-denied = impossible d'ouvrir le répertoire '{$path}' : Permission refusée +ls-error-cannot-open-file-permission-denied = impossible d'ouvrir le fichier '{$path}' : Permission refusée +ls-error-cannot-open-directory-bad-descriptor = impossible d'ouvrir le répertoire '{$path}' : Mauvais descripteur de fichier +ls-error-unknown-io-error = erreur d'E/S inconnue : '{$path}', '{$error}' +ls-error-invalid-block-size = argument --block-size invalide {$size} +ls-error-dired-and-zero-incompatible = --dired et --zero sont incompatibles +ls-error-not-listing-already-listed = {$path} : ne liste pas un répertoire déjà listé +ls-error-invalid-time-style = argument --time-style invalide {$style} + Les valeurs possibles sont : {$values} + + Pour plus d'informations, essayez --help + +# Messages d'aide +ls-help-print-help = Afficher les informations d'aide. +ls-help-set-display-format = Définir le format d'affichage. +ls-help-display-files-columns = Afficher les fichiers en colonnes. +ls-help-display-detailed-info = Afficher des informations détaillées. +ls-help-list-entries-rows = Lister les entrées en lignes au lieu de colonnes. +ls-help-assume-tab-stops = Supposer des arrêts de tabulation à chaque COLS au lieu de 8 +ls-help-list-entries-commas = Lister les entrées séparées par des virgules. +ls-help-list-entries-nul = Lister les entrées séparées par des caractères NUL ASCII. +ls-help-generate-dired-output = générer une sortie conçue pour le mode dired (Directory Editor) d'Emacs +ls-help-hyperlink-filenames = créer des hyperliens pour les noms de fichiers QUAND +ls-help-list-one-file-per-line = Lister un fichier par ligne. +ls-help-long-format-no-group = Format long sans informations de groupe. + Identique à --format=long avec --no-group. +ls-help-long-no-owner = Format long sans informations de propriétaire. +ls-help-long-numeric-uid-gid = -l avec des UID et GID numériques. +ls-help-set-quoting-style = Définir le style de citation. +ls-help-literal-quoting-style = Utiliser le style de citation littéral. Équivalent à `--quoting-style=literal` +ls-help-escape-quoting-style = Utiliser le style de citation d'échappement. Équivalent à `--quoting-style=escape` +ls-help-c-quoting-style = Utiliser le style de citation C. Équivalent à `--quoting-style=c` +ls-help-replace-control-chars = Remplacer les caractères de contrôle par '?' s'ils ne sont pas échappés. +ls-help-show-control-chars = Afficher les caractères de contrôle 'tels quels' s'ils ne sont pas échappés. +ls-help-show-time-field = Afficher l'heure dans : + heure d'accès (-u) : atime, access, use ; + heure de changement (-t) : ctime, status. + heure de modification : mtime, modification. + heure de création : birth, creation ; +ls-help-time-change = Si le format de liste long (par ex., -l, -o) est utilisé, afficher + l'heure de changement de statut (le 'ctime' dans l'inode) au lieu de l'heure + de modification. Lors du tri explicite par heure (--sort=time ou -t) ou lors + de l'absence de format de liste long, trier selon l'heure de changement de statut. +ls-help-time-access = Si le format de liste long (par ex., -l, -o) est utilisé, afficher + l'heure d'accès au statut au lieu de l'heure de modification. Lors du tri + explicite par heure (--sort=time ou -t) ou lors de l'absence de format de + liste long, trier selon l'heure d'accès. +ls-help-hide-pattern = ne pas lister les entrées implicites correspondant au MOTIF shell (surchargé par -a ou -A) +ls-help-ignore-pattern = ne pas lister les entrées implicites correspondant au MOTIF shell +ls-help-ignore-backups = Ignorer les entrées qui se terminent par ~. +ls-help-sort-by-field = Trier par : name, none (-U), time (-t), size (-S), extension (-X) ou width +ls-help-sort-by-size = Trier par taille de fichier, le plus grand en premier. +ls-help-sort-by-time = Trier par heure de modification (le 'mtime' dans l'inode), le plus récent en premier. +ls-help-sort-by-version = Tri naturel des numéros (de version) dans les noms de fichiers. +ls-help-sort-by-extension = Trier alphabétiquement par extension d'entrée. +ls-help-sort-none = Ne pas trier ; lister les fichiers dans l'ordre où ils sont stockés dans le + répertoire. Ceci est particulièrement utile lors de l'affichage de très grands répertoires, + car ne pas trier peut être sensiblement plus rapide. +ls-help-dereference-all = Lors de l'affichage d'informations de fichier pour un lien symbolique, afficher les informations pour le + fichier référencé par le lien plutôt que le lien lui-même. +ls-help-dereference-dir-args = Ne pas suivre les liens symboliques sauf quand ils pointent vers des répertoires et sont + donnés comme arguments de ligne de commande. +ls-help-dereference-args = Ne pas suivre les liens symboliques sauf quand ils sont donnés comme arguments de ligne de commande. +ls-help-no-group = Ne pas afficher le groupe en format long. +ls-help-author = Afficher l'auteur en format long. Sur les plateformes supportées, + l'auteur correspond toujours au propriétaire du fichier. +ls-help-all-files = Ne pas ignorer les fichiers cachés (fichiers dont les noms commencent par '.'). +ls-help-almost-all = Dans un répertoire, ne pas ignorer tous les noms de fichiers qui commencent par '.', + ignorer seulement '.' et '..'. +ls-help-directory = Lister seulement les noms des répertoires, plutôt que le contenu des répertoires. + Ceci ne suivra pas les liens symboliques à moins qu'une des options + `--dereference-command-line (-H)`, `--dereference (-L)`, ou + `--dereference-command-line-symlink-to-dir` soit spécifiée. +ls-help-human-readable = Afficher les tailles de fichiers lisibles par l'homme (par ex. 1K 234M 56G). +ls-help-kibibytes = par défaut aux blocs de 1024 octets pour l'utilisation du système de fichiers ; utilisé seulement avec -s et par + totaux de répertoire +ls-help-si = Afficher les tailles de fichiers lisibles par l'homme utilisant des puissances de 1000 au lieu de 1024. +ls-help-block-size = dimensionner les tailles par BLOCK_SIZE lors de l'affichage +ls-help-print-inode = afficher le numéro d'index de chaque fichier +ls-help-reverse-sort = Inverser quelle que soit la méthode de tri, par ex., lister les fichiers en ordre + alphabétique inverse, le plus jeune en premier, le plus petit en premier, ou autre. +ls-help-recursive = Lister le contenu de tous les répertoires récursivement. +ls-help-terminal-width = Supposer que le terminal a COLS colonnes de largeur. +ls-help-allocation-size = afficher la taille allouée de chaque fichier, en blocs +ls-help-color-output = Colorier la sortie basée sur le type de fichier. +ls-help-indicator-style = Ajouter un indicateur avec le style WORD aux noms d'entrée : + none (par défaut), slash (-p), file-type (--file-type), classify (-F) +ls-help-classify = Ajouter un caractère à chaque nom de fichier indiquant le type de fichier. Aussi, pour + les fichiers réguliers qui sont exécutables, ajouter '*'. Les indicateurs de type de fichier sont + '/' pour les répertoires, '@' pour les liens symboliques, '|' pour les FIFOs, '=' pour les sockets, + '>' pour les portes, et rien pour les fichiers réguliers. when peut être omis, ou un de : + none - Ne pas classifier. C'est la valeur par défaut. + auto - Classifier seulement si la sortie standard est un terminal. + always - Toujours classifier. + Spécifier --classify et aucun when est équivalent à --classify=always. Ceci ne + suivra pas les liens symboliques listés sur la ligne de commande à moins que les + options --dereference-command-line (-H), --dereference (-L), ou + --dereference-command-line-symlink-to-dir soient spécifiées. +ls-help-file-type = Identique à --classify, mais ne pas ajouter '*' +ls-help-slash-directories = Ajouter l'indicateur / aux répertoires. +ls-help-time-style = format de date/heure avec -l ; voir TIME_STYLE ci-dessous +ls-help-full-time = comme -l --time-style=full-iso +ls-help-context = afficher tout contexte de sécurité de chaque fichier +ls-help-group-directories-first = grouper les répertoires avant les fichiers ; peut être augmenté avec + une option --sort, mais toute utilisation de --sort=none (-U) désactive le groupement +ls-invalid-quoting-style = {$program} : Ignorer la valeur invalide de la variable d'environnement QUOTING_STYLE : '{$style}' +ls-invalid-columns-width = ignorer la largeur invalide dans la variable d'environnement COLUMNS : {$width} +ls-invalid-ignore-pattern = Motif invalide pour ignore : {$pattern} +ls-invalid-hide-pattern = Motif invalide pour hide : {$pattern} +ls-total = total {$size} diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index e6188410b..41cd92010 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -6,6 +6,8 @@ // spell-checker:ignore (ToDO) somegroup nlink tabsize dired subdired dtype colorterm stringly nohash strtime use std::iter; +#[cfg(unix)] +use std::os::unix::fs::{FileTypeExt, MetadataExt}; #[cfg(windows)] use std::os::windows::fs::MetadataExt; use std::{cell::LazyCell, cell::OnceCell, num::IntErrorKind}; @@ -18,12 +20,10 @@ use std::{ path::{Path, PathBuf}, time::{Duration, SystemTime, UNIX_EPOCH}, }; -#[cfg(unix)] use std::{ - collections::HashMap, - os::unix::fs::{FileTypeExt, MetadataExt}, + collections::{HashMap, HashSet}, + io::IsTerminal, }; -use std::{collections::HashSet, io::IsTerminal}; use ansi_width::ansi_width; use clap::{ @@ -60,7 +60,7 @@ use uucore::libc::{S_IXGRP, S_IXOTH, S_IXUSR}; ))] use uucore::libc::{dev_t, major, minor}; use uucore::line_ending::LineEnding; -use uucore::locale::get_message; +use uucore::locale::{get_message, get_message_with_args}; use uucore::quoting_style::{self, QuotingStyle, escape_name}; use uucore::{ display::Quotable, @@ -79,11 +79,6 @@ use dired::{DiredOutput, is_dired_arg_present}; mod colors; use colors::{StyleManager, color_name}; -#[cfg(not(feature = "selinux"))] -static CONTEXT_HELP_TEXT: &str = "print any security context of each file (not enabled)"; -#[cfg(feature = "selinux")] -static CONTEXT_HELP_TEXT: &str = "print any security context of each file"; - pub mod options { pub mod format { pub static ONE_LINE: &str = "1"; @@ -177,39 +172,39 @@ const DEFAULT_FILE_SIZE_BLOCK_SIZE: u64 = 1; #[derive(Error, Debug)] enum LsError { - #[error("invalid line width: '{0}'")] + #[error("{}", get_message_with_args("ls-error-invalid-line-width", HashMap::from([("width".to_string(), format!("'{}'", _0))])))] InvalidLineWidth(String), - #[error("general io error: {0}")] + #[error("{}", get_message_with_args("ls-error-general-io", HashMap::from([("error".to_string(), _0.to_string())])))] IOError(#[from] std::io::Error), #[error("{}", match .1.kind() { - ErrorKind::NotFound => format!("cannot access '{}': No such file or directory", .0.to_string_lossy()), + ErrorKind::NotFound => get_message_with_args("ls-error-cannot-access-no-such-file", HashMap::from([("path".to_string(), .0.to_string_lossy().to_string())])), ErrorKind::PermissionDenied => match .1.raw_os_error().unwrap_or(1) { - 1 => format!("cannot access '{}': Operation not permitted", .0.to_string_lossy()), + 1 => get_message_with_args("ls-error-cannot-access-operation-not-permitted", HashMap::from([("path".to_string(), .0.to_string_lossy().to_string())])), _ => if .0.is_dir() { - format!("cannot open directory '{}': Permission denied", .0.to_string_lossy()) + get_message_with_args("ls-error-cannot-open-directory-permission-denied", HashMap::from([("path".to_string(), .0.to_string_lossy().to_string())])) } else { - format!("cannot open file '{}': Permission denied", .0.to_string_lossy()) + get_message_with_args("ls-error-cannot-open-file-permission-denied", HashMap::from([("path".to_string(), .0.to_string_lossy().to_string())])) }, }, _ => match .1.raw_os_error().unwrap_or(1) { - 9 => format!("cannot open directory '{}': Bad file descriptor", .0.to_string_lossy()), - _ => format!("unknown io error: '{:?}', '{:?}'", .0.to_string_lossy(), .1), + 9 => get_message_with_args("ls-error-cannot-open-directory-bad-descriptor", HashMap::from([("path".to_string(), .0.to_string_lossy().to_string())])), + _ => get_message_with_args("ls-error-unknown-io-error", HashMap::from([("path".to_string(), .0.to_string_lossy().to_string()), ("error".to_string(), format!("{:?}", .1))])), }, })] IOErrorContext(PathBuf, std::io::Error, bool), - #[error("invalid --block-size argument '{0}'")] + #[error("{}", get_message_with_args("ls-error-invalid-block-size", HashMap::from([("size".to_string(), format!("'{}'", _0))])))] BlockSizeParseError(String), - #[error("--dired and --zero are incompatible")] + #[error("{}", get_message("ls-error-dired-and-zero-incompatible"))] DiredAndZeroAreIncompatible, - #[error("{}: not listing already-listed directory", .0.to_string_lossy())] + #[error("{}", get_message_with_args("ls-error-not-listing-already-listed", HashMap::from([("path".to_string(), .0.to_string_lossy().to_string())])))] AlreadyListedError(PathBuf), - #[error("invalid --time-style argument {}\nPossible values are: {:?}\n\nFor more information try --help", .0.quote(), .1)] + #[error("{}", get_message_with_args("ls-error-invalid-time-style", HashMap::from([("style".to_string(), .0.quote().to_string()), ("values".to_string(), format!("{:?}", .1))])))] TimeStyleParseError(String, Vec), } @@ -669,8 +664,17 @@ fn extract_quoting_style(options: &clap::ArgMatches, show_control: bool) -> Quot match match_quoting_style_name(style.as_str(), show_control) { Some(qs) => return qs, None => eprintln!( - "{}: Ignoring invalid value of environment variable QUOTING_STYLE: '{style}'", - std::env::args().next().unwrap_or_else(|| "ls".to_string()), + "{}", + get_message_with_args( + "ls-invalid-quoting-style", + HashMap::from([ + ( + "program".to_string(), + std::env::args().next().unwrap_or_else(|| "ls".to_string()) + ), + ("style".to_string(), style.clone()) + ]) + ) ), } } @@ -747,8 +751,11 @@ fn parse_width(width_match: Option<&String>) -> Result { Some(columns) => columns, None => { show_error!( - "ignoring invalid width in environment variable COLUMNS: {}", - columns.quote() + "{}", + get_message_with_args( + "ls-invalid-columns-width", + HashMap::from([("width".to_string(), columns.quote().to_string())]) + ) ); DEFAULT_TERM_WIDTH } @@ -966,7 +973,13 @@ impl Config { Ok(p) => { ignore_patterns.push(p); } - Err(_) => show_warning!("Invalid pattern for ignore: {}", pattern.quote()), + Err(_) => show_warning!( + "{}", + get_message_with_args( + "ls-invalid-ignore-pattern", + HashMap::from([("pattern".to_string(), pattern.quote().to_string())]) + ) + ), } } @@ -980,7 +993,13 @@ impl Config { Ok(p) => { ignore_patterns.push(p); } - Err(_) => show_warning!("Invalid pattern for hide: {}", pattern.quote()), + Err(_) => show_warning!( + "{}", + get_message_with_args( + "ls-invalid-hide-pattern", + HashMap::from([("pattern".to_string(), pattern.quote().to_string())]) + ) + ), } } } @@ -1184,14 +1203,14 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::HELP) .long(options::HELP) - .help("Print help information.") + .help(get_message("ls-help-print-help")) .action(ArgAction::Help), ) // Format arguments .arg( Arg::new(options::FORMAT) .long(options::FORMAT) - .help("Set the display format.") + .help(get_message("ls-help-set-display-format")) .value_parser(ShortcutValueParser::new([ "long", "verbose", @@ -1216,7 +1235,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::format::COLUMNS) .short('C') - .help("Display the files in columns.") + .help(get_message("ls-help-display-files-columns")) .overrides_with_all([ options::FORMAT, options::format::COLUMNS, @@ -1230,7 +1249,7 @@ pub fn uu_app() -> Command { Arg::new(options::format::LONG) .short('l') .long(options::format::LONG) - .help("Display detailed information.") + .help(get_message("ls-help-display-detailed-info")) .overrides_with_all([ options::FORMAT, options::format::COLUMNS, @@ -1243,7 +1262,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::format::ACROSS) .short('x') - .help("List entries in rows instead of in columns.") + .help(get_message("ls-help-list-entries-rows")) .overrides_with_all([ options::FORMAT, options::format::COLUMNS, @@ -1259,12 +1278,12 @@ pub fn uu_app() -> Command { .long(options::format::TAB_SIZE) .env("TABSIZE") .value_name("COLS") - .help("Assume tab stops at each COLS instead of 8"), + .help(get_message("ls-help-assume-tab-stops")), ) .arg( Arg::new(options::format::COMMAS) .short('m') - .help("List entries separated by commas.") + .help(get_message("ls-help-list-entries-commas")) .overrides_with_all([ options::FORMAT, options::format::COLUMNS, @@ -1278,21 +1297,21 @@ pub fn uu_app() -> Command { Arg::new(options::ZERO) .long(options::ZERO) .overrides_with(options::ZERO) - .help("List entries separated by ASCII NUL characters.") + .help(get_message("ls-help-list-entries-nul")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::DIRED) .long(options::DIRED) .short('D') - .help("generate output designed for Emacs' dired (Directory Editor) mode") + .help(get_message("ls-help-generate-dired-output")) .action(ArgAction::SetTrue) .overrides_with(options::HYPERLINK), ) .arg( Arg::new(options::HYPERLINK) .long(options::HYPERLINK) - .help("hyperlink file names WHEN") + .help(get_message("ls-help-hyperlink-filenames")) .value_parser(ShortcutValueParser::new([ PossibleValue::new("always").alias("yes").alias("force"), PossibleValue::new("auto").alias("tty").alias("if-tty"), @@ -1314,36 +1333,33 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::format::ONE_LINE) .short('1') - .help("List one file per line.") + .help(get_message("ls-help-list-one-file-per-line")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::format::LONG_NO_GROUP) .short('o') - .help( - "Long format without group information. \ - Identical to --format=long with --no-group.", - ) + .help(get_message("ls-help-long-format-no-group")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::format::LONG_NO_OWNER) .short('g') - .help("Long format without owner information.") + .help(get_message("ls-help-long-no-owner")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::format::LONG_NUMERIC_UID_GID) .short('n') .long(options::format::LONG_NUMERIC_UID_GID) - .help("-l with numeric UIDs and GIDs.") + .help(get_message("ls-help-long-numeric-uid-gid")) .action(ArgAction::SetTrue), ) // Quoting style .arg( Arg::new(options::QUOTING_STYLE) .long(options::QUOTING_STYLE) - .help("Set quoting style.") + .help(get_message("ls-help-set-quoting-style")) .value_parser(ShortcutValueParser::new([ PossibleValue::new("literal"), PossibleValue::new("shell"), @@ -1365,7 +1381,7 @@ pub fn uu_app() -> Command { .short('N') .long(options::quoting::LITERAL) .alias("l") - .help("Use literal quoting style. Equivalent to `--quoting-style=literal`") + .help(get_message("ls-help-literal-quoting-style")) .overrides_with_all([ options::QUOTING_STYLE, options::quoting::LITERAL, @@ -1378,7 +1394,7 @@ pub fn uu_app() -> Command { Arg::new(options::quoting::ESCAPE) .short('b') .long(options::quoting::ESCAPE) - .help("Use escape quoting style. Equivalent to `--quoting-style=escape`") + .help(get_message("ls-help-escape-quoting-style")) .overrides_with_all([ options::QUOTING_STYLE, options::quoting::LITERAL, @@ -1391,7 +1407,7 @@ pub fn uu_app() -> Command { Arg::new(options::quoting::C) .short('Q') .long(options::quoting::C) - .help("Use C quoting style. Equivalent to `--quoting-style=c`") + .help(get_message("ls-help-c-quoting-style")) .overrides_with_all([ options::QUOTING_STYLE, options::quoting::LITERAL, @@ -1405,14 +1421,14 @@ pub fn uu_app() -> Command { Arg::new(options::HIDE_CONTROL_CHARS) .short('q') .long(options::HIDE_CONTROL_CHARS) - .help("Replace control characters with '?' if they are not escaped.") + .help(get_message("ls-help-replace-control-chars")) .overrides_with_all([options::HIDE_CONTROL_CHARS, options::SHOW_CONTROL_CHARS]) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::SHOW_CONTROL_CHARS) .long(options::SHOW_CONTROL_CHARS) - .help("Show control characters 'as is' if they are not escaped.") + .help(get_message("ls-help-show-control-chars")) .overrides_with_all([options::HIDE_CONTROL_CHARS, options::SHOW_CONTROL_CHARS]) .action(ArgAction::SetTrue), ) @@ -1420,13 +1436,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::TIME) .long(options::TIME) - .help( - "Show time in :\n\ - \taccess time (-u): atime, access, use;\n\ - \tchange time (-t): ctime, status.\n\ - \tmodification time: mtime, modification.\n\ - \tbirth time: birth, creation;", - ) + .help(get_message("ls-help-show-time-field")) .value_name("field") .value_parser(ShortcutValueParser::new([ PossibleValue::new("atime").alias("access").alias("use"), @@ -1441,24 +1451,14 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::time::CHANGE) .short('c') - .help( - "If the long listing format (e.g., -l, -o) is being used, print the \ - status change time (the 'ctime' in the inode) instead of the modification \ - time. When explicitly sorting by time (--sort=time or -t) or when not \ - using a long listing format, sort according to the status change time.", - ) + .help(get_message("ls-help-time-change")) .overrides_with_all([options::TIME, options::time::ACCESS, options::time::CHANGE]) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::time::ACCESS) .short('u') - .help( - "If the long listing format (e.g., -l, -o) is being used, print the \ - status access time instead of the modification time. When explicitly \ - sorting by time (--sort=time or -t) or when not using a long listing \ - format, sort according to the access time.", - ) + .help(get_message("ls-help-time-access")) .overrides_with_all([options::TIME, options::time::ACCESS, options::time::CHANGE]) .action(ArgAction::SetTrue), ) @@ -1468,9 +1468,7 @@ pub fn uu_app() -> Command { .long(options::HIDE) .action(ArgAction::Append) .value_name("PATTERN") - .help( - "do not list implied entries matching shell PATTERN (overridden by -a or -A)", - ), + .help(get_message("ls-help-hide-pattern")), ) .arg( Arg::new(options::IGNORE) @@ -1478,22 +1476,30 @@ pub fn uu_app() -> Command { .long(options::IGNORE) .action(ArgAction::Append) .value_name("PATTERN") - .help("do not list implied entries matching shell PATTERN"), + .help(get_message("ls-help-ignore-pattern")), ) .arg( Arg::new(options::IGNORE_BACKUPS) .short('B') .long(options::IGNORE_BACKUPS) - .help("Ignore entries which end with ~.") + .help(get_message("ls-help-ignore-backups")) .action(ArgAction::SetTrue), ) // Sort arguments .arg( Arg::new(options::SORT) .long(options::SORT) - .help("Sort by : name, none (-U), time (-t), size (-S), extension (-X) or width") + .help(get_message("ls-help-sort-by-field")) .value_name("field") - .value_parser(ShortcutValueParser::new(["name", "none", "time", "size", "version", "extension", "width"])) + .value_parser(ShortcutValueParser::new([ + "name", + "none", + "time", + "size", + "version", + "extension", + "width", + ])) .require_equals(true) .overrides_with_all([ options::SORT, @@ -1507,7 +1513,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::sort::SIZE) .short('S') - .help("Sort by file size, largest first.") + .help(get_message("ls-help-sort-by-size")) .overrides_with_all([ options::SORT, options::sort::SIZE, @@ -1521,7 +1527,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::sort::TIME) .short('t') - .help("Sort by modification time (the 'mtime' in the inode), newest first.") + .help(get_message("ls-help-sort-by-time")) .overrides_with_all([ options::SORT, options::sort::SIZE, @@ -1535,7 +1541,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::sort::VERSION) .short('v') - .help("Natural sort of (version) numbers in the filenames.") + .help(get_message("ls-help-sort-by-version")) .overrides_with_all([ options::SORT, options::sort::SIZE, @@ -1549,7 +1555,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::sort::EXTENSION) .short('X') - .help("Sort alphabetically by entry extension.") + .help(get_message("ls-help-sort-by-extension")) .overrides_with_all([ options::SORT, options::sort::SIZE, @@ -1563,11 +1569,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::sort::NONE) .short('U') - .help( - "Do not sort; list the files in whatever order they are stored in the \ - directory. This is especially useful when listing very large directories, \ - since not doing any sorting can be noticeably faster.", - ) + .help(get_message("ls-help-sort-none")) .overrides_with_all([ options::SORT, options::sort::SIZE, @@ -1583,10 +1585,7 @@ pub fn uu_app() -> Command { Arg::new(options::dereference::ALL) .short('L') .long(options::dereference::ALL) - .help( - "When showing file information for a symbolic link, show information for the \ - file the link references rather than the link itself.", - ) + .help(get_message("ls-help-dereference-all")) .overrides_with_all([ options::dereference::ALL, options::dereference::DIR_ARGS, @@ -1597,10 +1596,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::dereference::DIR_ARGS) .long(options::dereference::DIR_ARGS) - .help( - "Do not follow symlinks except when they link to directories and are \ - given as command line arguments.", - ) + .help(get_message("ls-help-dereference-dir-args")) .overrides_with_all([ options::dereference::ALL, options::dereference::DIR_ARGS, @@ -1612,7 +1608,7 @@ pub fn uu_app() -> Command { Arg::new(options::dereference::ARGS) .short('H') .long(options::dereference::ARGS) - .help("Do not follow symlinks except when given as command line arguments.") + .help(get_message("ls-help-dereference-args")) .overrides_with_all([ options::dereference::ALL, options::dereference::DIR_ARGS, @@ -1625,13 +1621,15 @@ pub fn uu_app() -> Command { Arg::new(options::NO_GROUP) .long(options::NO_GROUP) .short('G') - .help("Do not show group in long format.") + .help(get_message("ls-help-no-group")) + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new(options::AUTHOR) + .long(options::AUTHOR) + .help(get_message("ls-help-author")) .action(ArgAction::SetTrue), ) - .arg(Arg::new(options::AUTHOR).long(options::AUTHOR).help( - "Show author in long format. On the supported platforms, \ - the author always matches the file owner.", - ).action(ArgAction::SetTrue)) // Other Flags .arg( Arg::new(options::files::ALL) @@ -1639,7 +1637,7 @@ pub fn uu_app() -> Command { .long(options::files::ALL) // Overrides -A (as the order matters) .overrides_with_all([options::files::ALL, options::files::ALMOST_ALL]) - .help("Do not ignore hidden files (files with names that start with '.').") + .help(get_message("ls-help-all-files")) .action(ArgAction::SetTrue), ) .arg( @@ -1648,29 +1646,21 @@ pub fn uu_app() -> Command { .long(options::files::ALMOST_ALL) // Overrides -a (as the order matters) .overrides_with_all([options::files::ALL, options::files::ALMOST_ALL]) - .help( - "In a directory, do not ignore all file names that start with '.', \ - only ignore '.' and '..'.", - ) + .help(get_message("ls-help-almost-all")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::DIRECTORY) .short('d') .long(options::DIRECTORY) - .help( - "Only list the names of directories, rather than listing directory contents. \ - This will not follow symbolic links unless one of `--dereference-command-line \ - (-H)`, `--dereference (-L)`, or `--dereference-command-line-symlink-to-dir` is \ - specified.", - ) + .help(get_message("ls-help-directory")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::size::HUMAN_READABLE) .short('h') .long(options::size::HUMAN_READABLE) - .help("Print human readable file sizes (e.g. 1K 234M 56G).") + .help(get_message("ls-help-human-readable")) .overrides_with_all([options::size::BLOCK_SIZE, options::size::SI]) .action(ArgAction::SetTrue), ) @@ -1678,16 +1668,13 @@ pub fn uu_app() -> Command { Arg::new(options::size::KIBIBYTES) .short('k') .long(options::size::KIBIBYTES) - .help( - "default to 1024-byte blocks for file system usage; used only with -s and per \ - directory totals", - ) + .help(get_message("ls-help-kibibytes")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::size::SI) .long(options::size::SI) - .help("Print human readable file sizes using powers of 1000 instead of 1024.") + .help(get_message("ls-help-si")) .overrides_with_all([options::size::BLOCK_SIZE, options::size::HUMAN_READABLE]) .action(ArgAction::SetTrue), ) @@ -1696,51 +1683,48 @@ pub fn uu_app() -> Command { .long(options::size::BLOCK_SIZE) .require_equals(true) .value_name("BLOCK_SIZE") - .help("scale sizes by BLOCK_SIZE when printing them") + .help(get_message("ls-help-block-size")) .overrides_with_all([options::size::SI, options::size::HUMAN_READABLE]), ) .arg( Arg::new(options::INODE) .short('i') .long(options::INODE) - .help("print the index number of each file") + .help(get_message("ls-help-print-inode")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::REVERSE) .short('r') .long(options::REVERSE) - .help( - "Reverse whatever the sorting method is e.g., list files in reverse \ - alphabetical order, youngest first, smallest first, or whatever.", - ) + .help(get_message("ls-help-reverse-sort")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::RECURSIVE) .short('R') .long(options::RECURSIVE) - .help("List the contents of all directories recursively.") + .help(get_message("ls-help-recursive")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::WIDTH) .long(options::WIDTH) .short('w') - .help("Assume that the terminal is COLS columns wide.") + .help(get_message("ls-help-terminal-width")) .value_name("COLS"), ) .arg( Arg::new(options::size::ALLOCATION_SIZE) .short('s') .long(options::size::ALLOCATION_SIZE) - .help("print the allocated size of each file, in blocks") + .help(get_message("ls-help-allocation-size")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::COLOR) .long(options::COLOR) - .help("Color output based on file type.") + .help(get_message("ls-help-color-output")) .value_parser(ShortcutValueParser::new([ PossibleValue::new("always").alias("yes").alias("force"), PossibleValue::new("auto").alias("tty").alias("if-tty"), @@ -1752,11 +1736,13 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::INDICATOR_STYLE) .long(options::INDICATOR_STYLE) - .help( - "Append indicator with style WORD to entry names: \ - none (default), slash (-p), file-type (--file-type), classify (-F)", - ) - .value_parser(ShortcutValueParser::new(["none", "slash", "file-type", "classify"])) + .help(get_message("ls-help-indicator-style")) + .value_parser(ShortcutValueParser::new([ + "none", + "slash", + "file-type", + "classify", + ])) .overrides_with_all([ options::indicator_style::FILE_TYPE, options::indicator_style::SLASH, @@ -1773,19 +1759,7 @@ pub fn uu_app() -> Command { Arg::new(options::indicator_style::CLASSIFY) .short('F') .long(options::indicator_style::CLASSIFY) - .help( - "Append a character to each file name indicating the file type. Also, for \ - regular files that are executable, append '*'. The file type indicators are \ - '/' for directories, '@' for symbolic links, '|' for FIFOs, '=' for sockets, \ - '>' for doors, and nothing for regular files. when may be omitted, or one of:\n\ - \tnone - Do not classify. This is the default.\n\ - \tauto - Only classify if standard output is a terminal.\n\ - \talways - Always classify.\n\ - Specifying --classify and no when is equivalent to --classify=always. This will \ - not follow symbolic links listed on the command line unless the \ - --dereference-command-line (-H), --dereference (-L), or \ - --dereference-command-line-symlink-to-dir options are specified.", - ) + .help(get_message("ls-help-classify")) .value_name("when") .value_parser(ShortcutValueParser::new([ PossibleValue::new("always").alias("yes").alias("force"), @@ -1805,7 +1779,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::indicator_style::FILE_TYPE) .long(options::indicator_style::FILE_TYPE) - .help("Same as --classify, but do not append '*'") + .help(get_message("ls-help-file-type")) .overrides_with_all([ options::indicator_style::FILE_TYPE, options::indicator_style::SLASH, @@ -1817,7 +1791,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::indicator_style::SLASH) .short('p') - .help("Append / indicator to directories.") + .help(get_message("ls-help-slash-directories")) .overrides_with_all([ options::indicator_style::FILE_TYPE, options::indicator_style::SLASH, @@ -1830,7 +1804,7 @@ pub fn uu_app() -> Command { //This still needs support for posix-* Arg::new(options::TIME_STYLE) .long(options::TIME_STYLE) - .help("time/date format with -l; see TIME_STYLE below") + .help(get_message("ls-help-time-style")) .value_name("TIME_STYLE") .env("TIME_STYLE") .value_parser(NonEmptyStringValueParser::new()) @@ -1840,23 +1814,20 @@ pub fn uu_app() -> Command { Arg::new(options::FULL_TIME) .long(options::FULL_TIME) .overrides_with(options::FULL_TIME) - .help("like -l --time-style=full-iso") + .help(get_message("ls-help-full-time")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::CONTEXT) .short('Z') .long(options::CONTEXT) - .help(CONTEXT_HELP_TEXT) + .help(get_message("ls-help-context")) .action(ArgAction::SetTrue), ) .arg( Arg::new(options::GROUP_DIRECTORIES_FIRST) .long(options::GROUP_DIRECTORIES_FIRST) - .help( - "group directories before files; can be augmented with \ - a --sort option, but any use of --sort=none (-U) disables grouping", - ) + .help(get_message("ls-help-group-directories-first")) .action(ArgAction::SetTrue), ) // Positional arguments @@ -2482,8 +2453,11 @@ fn return_total( dired::indent(out)?; } Ok(format!( - "total {}{}", - display_size(total_size, config), + "{}{}", + get_message_with_args( + "ls-total", + HashMap::from([("size".to_string(), display_size(total_size, config))]) + ), config.line_ending )) } diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index a8b0aa372..a0da1400b 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -106,6 +106,7 @@ fn test_invalid_value_time_style() { .arg("-g") .arg("--time-style=definitely_invalid_value") .fails_with_code(2) + .stderr_contains("time-style argument 'definitely_invalid_value'") .no_stdout(); // If it only looks temporarily like it might be used, no error: new_ucmd!()