l10n: port df for translation + add french

This commit is contained in:
Sylvestre Ledru 2025-06-22 00:59:44 +02:00
parent 1675c3e981
commit b30e6f8be7
5 changed files with 222 additions and 61 deletions

View file

@ -25,6 +25,7 @@ getrandom
globset
indicatif
itertools
iuse
langid
lscolors
mdbook

View file

@ -8,3 +8,53 @@ df-after-help = Display values are in units of the first available SIZE from --b
SIZE is an integer and optional unit (example: 10M is 10*1024*1024).
Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB,... (powers
of 1000).
# Help messages
df-help-print-help = Print help information.
df-help-all = include dummy file systems
df-help-block-size = scale sizes by SIZE before printing them; e.g. '-BM' prints sizes in units of 1,048,576 bytes
df-help-total = produce a grand total
df-help-human-readable = print sizes in human readable format (e.g., 1K 234M 2G)
df-help-si = likewise, but use powers of 1000 not 1024
df-help-inodes = list inode information instead of block usage
df-help-kilo = like --block-size=1K
df-help-local = limit listing to local file systems
df-help-no-sync = do not invoke sync before getting usage info (default)
df-help-output = use output format defined by FIELD_LIST, or print all fields if FIELD_LIST is omitted.
df-help-portability = use the POSIX output format
df-help-sync = invoke sync before getting usage info (non-windows only)
df-help-type = limit listing to file systems of type TYPE
df-help-print-type = print file system type
df-help-exclude-type = limit listing to file systems not of type TYPE
# Error messages
df-error-block-size-too-large = --block-size argument '{ $size }' too large
df-error-invalid-block-size = invalid --block-size argument { $size }
df-error-invalid-suffix = invalid suffix in --block-size argument { $size }
df-error-field-used-more-than-once = option --output: field { $field } used more than once
df-error-filesystem-type-both-selected-and-excluded = file system type { $type } both selected and excluded
df-error-no-such-file-or-directory = { $path }: No such file or directory
df-error-no-file-systems-processed = no file systems processed
df-error-cannot-access-over-mounted = cannot access { $path }: over-mounted by another device
df-error-cannot-read-table-of-mounted-filesystems = cannot read table of mounted file systems
df-error-inodes-not-supported-windows = { $program }: doesn't support -i option
# Headers
df-header-filesystem = Filesystem
df-header-size = Size
df-header-used = Used
df-header-avail = Avail
df-header-available = Available
df-header-use-percent = Use%
df-header-capacity = Capacity
df-header-mounted-on = Mounted on
df-header-inodes = Inodes
df-header-iused = IUsed
df-header-iavail = IFree
df-header-iuse-percent = IUse%
df-header-file = File
df-header-type = Type
# Other
df-total = total
df-blocks-suffix = -blocks

View file

@ -0,0 +1,60 @@
df-about = afficher des informations sur le système de fichiers sur lequel chaque FICHIER réside,
ou tous les systèmes de fichiers par défaut.
df-usage = df [OPTION]... [FICHIER]...
df-after-help = Les valeurs affichées sont en unités de la première TAILLE disponible de --block-size,
et des variables d'environnement DF_BLOCK_SIZE, BLOCK_SIZE et BLOCKSIZE.
Sinon, les unités par défaut sont 1024 octets (ou 512 si POSIXLY_CORRECT est défini).
TAILLE est un entier et une unité optionnelle (exemple : 10M est 10*1024*1024).
Les unités sont K, M, G, T, P, E, Z, Y (puissances de 1024) ou KB, MB,... (puissances
de 1000).
# Messages d'aide
df-help-print-help = afficher les informations d'aide.
df-help-all = inclure les systèmes de fichiers factices
df-help-block-size = mettre les tailles à l'échelle par TAILLE avant de les afficher ; par ex. '-BM' affiche les tailles en unités de 1 048 576 octets
df-help-total = produire un total général
df-help-human-readable = afficher les tailles dans un format lisible par l'homme (par ex., 1K 234M 2G)
df-help-si = pareillement, mais utiliser les puissances de 1000 pas 1024
df-help-inodes = lister les informations d'inode au lieu de l'utilisation des blocs
df-help-kilo = comme --block-size=1K
df-help-local = limiter l'affichage aux systèmes de fichiers locaux
df-help-no-sync = ne pas invoquer sync avant d'obtenir les informations d'utilisation (par défaut)
df-help-output = utiliser le format de sortie défini par LISTE_CHAMPS, ou afficher tous les champs si LISTE_CHAMPS est omise.
df-help-portability = utiliser le format de sortie POSIX
df-help-sync = invoquer sync avant d'obtenir les informations d'utilisation (non-windows seulement)
df-help-type = limiter l'affichage aux systèmes de fichiers de type TYPE
df-help-print-type = afficher le type de système de fichiers
df-help-exclude-type = limiter l'affichage aux systèmes de fichiers pas de type TYPE
# Messages d'erreur
df-error-block-size-too-large = argument --block-size '{ $size }' trop grand
df-error-invalid-block-size = argument --block-size invalide { $size }
df-error-invalid-suffix = suffixe invalide dans l'argument --block-size { $size }
df-error-field-used-more-than-once = option --output : champ { $field } utilisé plus d'une fois
df-error-filesystem-type-both-selected-and-excluded = type de système de fichiers { $type } à la fois sélectionné et exclu
df-error-no-such-file-or-directory = { $path } : aucun fichier ou répertoire de ce type
df-error-no-file-systems-processed = aucun système de fichiers traité
df-error-cannot-access-over-mounted = impossible d'accéder à { $path } : sur-monté par un autre périphérique
df-error-cannot-read-table-of-mounted-filesystems = impossible de lire la table des systèmes de fichiers montés
df-error-inodes-not-supported-windows = { $program } : ne supporte pas l'option -i
# En-têtes du tableau
df-header-filesystem = Sys. de fichiers
df-header-size = Taille
df-header-used = Utilisé
df-header-avail = Disp.
df-header-available = Disponible
df-header-use-percent = Util%
df-header-capacity = Capacité
df-header-mounted-on = Monté sur
df-header-inodes = Inodes
df-header-iused = IUtil
df-header-iavail = ILibre
df-header-iuse-percent = IUtil%
df-header-file = Fichier
df-header-type = Type
# Autres messages
df-total = total
df-blocks-suffix = -blocs

View file

@ -29,7 +29,8 @@ use crate::filesystem::Filesystem;
use crate::filesystem::FsError;
use crate::table::Table;
use uucore::locale::get_message;
use std::collections::HashMap;
use uucore::locale::{get_message, get_message_with_args};
static OPT_HELP: &str = "help";
static OPT_ALL: &str = "all";
@ -115,25 +116,28 @@ impl Default for Options {
enum OptionsError {
// TODO This needs to vary based on whether `--block-size`
// or `-B` were provided.
#[error("--block-size argument '{0}' too large")]
#[error("{}", get_message_with_args("df-error-block-size-too-large", HashMap::from([("size".to_string(), .0.clone())])))]
BlockSizeTooLarge(String),
// TODO This needs to vary based on whether `--block-size`
// or `-B` were provided.,
#[error("invalid --block-size argument {0}")]
#[error("{}", get_message_with_args("df-error-invalid-block-size", HashMap::from([("size".to_string(), .0.clone())])))]
InvalidBlockSize(String),
// TODO This needs to vary based on whether `--block-size`
// or `-B` were provided.
#[error("invalid suffix in --block-size argument {0}")]
#[error("{}", get_message_with_args("df-error-invalid-suffix", HashMap::from([("size".to_string(), .0.clone())])))]
InvalidSuffix(String),
/// An error getting the columns to display in the output table.
#[error("option --output: field {0} used more than once")]
#[error("{}", get_message_with_args("df-error-field-used-more-than-once", HashMap::from([("field".to_string(), format!("{}", .0))])))]
ColumnError(ColumnError),
#[error("{}", .0.iter()
.map(|t| format!("file system type {} both selected and excluded", t.quote()))
#[error(
"{}",
.0.iter()
.map(|t| get_message_with_args("df-error-filesystem-type-both-selected-and-excluded", HashMap::from([("type".to_string(), t.quote().to_string())])))
.collect::<Vec<_>>()
.join(format!("\n{}: ", uucore::util_name()).as_str()))]
.join(format!("\n{}: ", uucore::util_name()).as_str())
)]
FilesystemTypeBothSelectedAndExcluded(Vec<String>),
}
@ -359,26 +363,35 @@ where
Err(FsError::InvalidPath) => {
show!(USimpleError::new(
1,
format!("{}: No such file or directory", path.as_ref().display())
get_message_with_args(
"df-error-no-such-file-or-directory",
HashMap::from([("path".to_string(), path.as_ref().display().to_string())])
)
));
}
Err(FsError::MountMissing) => {
show!(USimpleError::new(1, "no file systems processed"));
show!(USimpleError::new(
1,
get_message("df-error-no-file-systems-processed")
));
}
#[cfg(not(windows))]
Err(FsError::OverMounted) => {
show!(USimpleError::new(
1,
format!(
"cannot access {}: over-mounted by another device",
path.as_ref().quote()
get_message_with_args(
"df-error-cannot-access-over-mounted",
HashMap::from([("path".to_string(), path.as_ref().quote().to_string())])
)
));
}
}
}
if get_exit_code() == 0 && result.is_empty() {
show!(USimpleError::new(1, "no file systems processed"));
show!(USimpleError::new(
1,
get_message("df-error-no-file-systems-processed")
));
return Ok(result);
}
@ -405,7 +418,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
#[cfg(windows)]
{
if matches.get_flag(OPT_INODES) {
println!("{}: doesn't support -i option", uucore::util_name());
println!(
"{}",
get_message_with_args(
"df-error-inodes-not-supported-windows",
HashMap::from([("program".to_string(), uucore::util_name().to_string())])
)
);
return Ok(());
}
}
@ -415,12 +434,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let filesystems: Vec<Filesystem> = match matches.get_many::<String>(OPT_PATHS) {
None => {
let filesystems = get_all_filesystems(&opt).map_err(|e| {
let context = "cannot read table of mounted file systems";
let context = get_message("df-error-cannot-read-table-of-mounted-filesystems");
USimpleError::new(e.code(), format!("{context}: {e}"))
})?;
if filesystems.is_empty() {
return Err(USimpleError::new(1, "no file systems processed"));
return Err(USimpleError::new(
1,
get_message("df-error-no-file-systems-processed"),
));
}
filesystems
@ -428,7 +450,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Some(paths) => {
let paths: Vec<_> = paths.collect();
let filesystems = get_named_filesystems(&paths, &opt).map_err(|e| {
let context = "cannot read table of mounted file systems";
let context = get_message("df-error-cannot-read-table-of-mounted-filesystems");
USimpleError::new(e.code(), format!("{context}: {e}"))
})?;
@ -458,7 +480,7 @@ pub fn uu_app() -> Command {
.arg(
Arg::new(OPT_HELP)
.long(OPT_HELP)
.help("Print help information.")
.help(get_message("df-help-print-help"))
.action(ArgAction::Help),
)
.arg(
@ -466,7 +488,7 @@ pub fn uu_app() -> Command {
.short('a')
.long("all")
.overrides_with(OPT_ALL)
.help("include dummy file systems")
.help(get_message("df-help-all"))
.action(ArgAction::SetTrue),
)
.arg(
@ -475,16 +497,13 @@ pub fn uu_app() -> Command {
.long("block-size")
.value_name("SIZE")
.overrides_with_all([OPT_KILO, OPT_BLOCKSIZE])
.help(
"scale sizes by SIZE before printing them; e.g.\
'-BM' prints sizes in units of 1,048,576 bytes",
),
.help(get_message("df-help-block-size")),
)
.arg(
Arg::new(OPT_TOTAL)
.long("total")
.overrides_with(OPT_TOTAL)
.help("produce a grand total")
.help(get_message("df-help-total"))
.action(ArgAction::SetTrue),
)
.arg(
@ -492,7 +511,7 @@ pub fn uu_app() -> Command {
.short('h')
.long("human-readable")
.overrides_with_all([OPT_HUMAN_READABLE_DECIMAL, OPT_HUMAN_READABLE_BINARY])
.help("print sizes in human readable format (e.g., 1K 234M 2G)")
.help(get_message("df-help-human-readable"))
.action(ArgAction::SetTrue),
)
.arg(
@ -500,7 +519,7 @@ pub fn uu_app() -> Command {
.short('H')
.long("si")
.overrides_with_all([OPT_HUMAN_READABLE_BINARY, OPT_HUMAN_READABLE_DECIMAL])
.help("likewise, but use powers of 1000 not 1024")
.help(get_message("df-help-si"))
.action(ArgAction::SetTrue),
)
.arg(
@ -508,13 +527,13 @@ pub fn uu_app() -> Command {
.short('i')
.long("inodes")
.overrides_with(OPT_INODES)
.help("list inode information instead of block usage")
.help(get_message("df-help-inodes"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(OPT_KILO)
.short('k')
.help("like --block-size=1K")
.help(get_message("df-help-kilo"))
.overrides_with_all([OPT_BLOCKSIZE, OPT_KILO])
.action(ArgAction::SetTrue),
)
@ -523,14 +542,14 @@ pub fn uu_app() -> Command {
.short('l')
.long("local")
.overrides_with(OPT_LOCAL)
.help("limit listing to local file systems")
.help(get_message("df-help-local"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(OPT_NO_SYNC)
.long("no-sync")
.overrides_with_all([OPT_SYNC, OPT_NO_SYNC])
.help("do not invoke sync before getting usage info (default)")
.help(get_message("df-help-no-sync"))
.action(ArgAction::SetTrue),
)
.arg(
@ -545,24 +564,21 @@ pub fn uu_app() -> Command {
.default_missing_values(OUTPUT_FIELD_LIST)
.default_values(["source", "size", "used", "avail", "pcent", "target"])
.conflicts_with_all([OPT_INODES, OPT_PORTABILITY, OPT_PRINT_TYPE])
.help(
"use the output format defined by FIELD_LIST, \
or print all fields if FIELD_LIST is omitted.",
),
.help(get_message("df-help-output")),
)
.arg(
Arg::new(OPT_PORTABILITY)
.short('P')
.long("portability")
.overrides_with(OPT_PORTABILITY)
.help("use the POSIX output format")
.help(get_message("df-help-portability"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(OPT_SYNC)
.long("sync")
.overrides_with_all([OPT_NO_SYNC, OPT_SYNC])
.help("invoke sync before getting usage info (non-windows only)")
.help(get_message("df-help-sync"))
.action(ArgAction::SetTrue),
)
.arg(
@ -572,14 +588,14 @@ pub fn uu_app() -> Command {
.value_parser(ValueParser::os_string())
.value_name("TYPE")
.action(ArgAction::Append)
.help("limit listing to file systems of type TYPE"),
.help(get_message("df-help-type")),
)
.arg(
Arg::new(OPT_PRINT_TYPE)
.short('T')
.long("print-type")
.overrides_with(OPT_PRINT_TYPE)
.help("print file system type")
.help(get_message("df-help-print-type"))
.action(ArgAction::SetTrue),
)
.arg(
@ -590,7 +606,7 @@ pub fn uu_app() -> Command {
.value_parser(ValueParser::os_string())
.value_name("TYPE")
.use_value_delimiter(true)
.help("limit listing to file systems not of type TYPE"),
.help(get_message("df-help-exclude-type")),
)
.arg(
Arg::new(OPT_PATHS)

View file

@ -14,6 +14,7 @@ use crate::columns::{Alignment, Column};
use crate::filesystem::Filesystem;
use crate::{BlockSize, Options};
use uucore::fsext::{FsUsage, MountInfo};
use uucore::locale::get_message;
use std::fmt;
use std::ops::AddAssign;
@ -106,7 +107,7 @@ impl AddAssign for Row {
let inodes_used = self.inodes_used + rhs.inodes_used;
*self = Self {
file: None,
fs_device: "total".into(),
fs_device: get_message("df-total"),
fs_type: "-".into(),
fs_mount: "-".into(),
bytes,
@ -261,7 +262,7 @@ impl<'a> RowFormatter<'a> {
let string = match column {
Column::Source => {
if self.is_total_row {
"total".to_string()
get_message("df-total")
} else {
self.row.fs_device.to_string()
}
@ -273,7 +274,7 @@ impl<'a> RowFormatter<'a> {
Column::Target => {
if self.is_total_row && !self.options.columns.contains(&Column::Source) {
"total".to_string()
get_message("df-total")
} else {
self.row.fs_mount.to_string()
}
@ -325,32 +326,38 @@ impl Header {
for column in &options.columns {
let header = match column {
Column::Source => String::from("Filesystem"),
Column::Source => get_message("df-header-filesystem"),
Column::Size => match options.header_mode {
HeaderMode::HumanReadable => String::from("Size"),
HeaderMode::HumanReadable => get_message("df-header-size"),
HeaderMode::PosixPortability => {
format!("{}-blocks", options.block_size.as_u64())
format!(
"{}{}",
options.block_size.as_u64(),
get_message("df-blocks-suffix")
)
}
_ => format!("{}-blocks", options.block_size),
_ => format!("{}{}", options.block_size, get_message("df-blocks-suffix")),
},
Column::Used => String::from("Used"),
Column::Used => get_message("df-header-used"),
Column::Avail => match options.header_mode {
HeaderMode::HumanReadable | HeaderMode::Output => String::from("Avail"),
_ => String::from("Available"),
HeaderMode::HumanReadable | HeaderMode::Output => {
get_message("df-header-avail")
}
_ => get_message("df-header-available"),
},
Column::Pcent => match options.header_mode {
HeaderMode::PosixPortability => String::from("Capacity"),
_ => String::from("Use%"),
HeaderMode::PosixPortability => get_message("df-header-capacity"),
_ => get_message("df-header-use-percent"),
},
Column::Target => String::from("Mounted on"),
Column::Itotal => String::from("Inodes"),
Column::Iused => String::from("IUsed"),
Column::Iavail => String::from("IFree"),
Column::Ipcent => String::from("IUse%"),
Column::File => String::from("File"),
Column::Fstype => String::from("Type"),
Column::Target => get_message("df-header-mounted-on"),
Column::Itotal => get_message("df-header-inodes"),
Column::Iused => get_message("df-header-iused"),
Column::Iavail => get_message("df-header-iavail"),
Column::Ipcent => get_message("df-header-iuse-percent"),
Column::File => get_message("df-header-file"),
Column::Fstype => get_message("df-header-type"),
#[cfg(target_os = "macos")]
Column::Capacity => String::from("Capacity"),
Column::Capacity => get_message("df-header-capacity"),
};
headers.push(header);
@ -383,7 +390,7 @@ impl Table {
//
// This accumulator is computed in case we need to display the
// total counts in the last row of the table.
let mut total = Row::new("total");
let mut total = Row::new(&get_message("df-total"));
for filesystem in filesystems {
// If the filesystem is not empty, or if the options require
@ -471,12 +478,20 @@ impl fmt::Display for Table {
mod tests {
use std::vec;
use uucore::locale::setup_localization;
use crate::blocks::HumanReadable;
use crate::columns::Column;
use crate::table::{Header, HeaderMode, Row, RowFormatter, Table};
use crate::{BlockSize, Options};
fn init() {
unsafe {
std::env::set_var("LANG", "C");
}
let _ = setup_localization("df");
}
const COLUMNS_WITH_FS_TYPE: [Column; 7] = [
Column::Source,
Column::Fstype,
@ -521,7 +536,9 @@ mod tests {
#[test]
fn test_default_header() {
init();
let options = Options::default();
assert_eq!(
Header::get_headers(&options),
vec!(
@ -537,6 +554,7 @@ mod tests {
#[test]
fn test_header_with_fs_type() {
init();
let options = Options {
columns: COLUMNS_WITH_FS_TYPE.to_vec(),
..Default::default()
@ -557,6 +575,7 @@ mod tests {
#[test]
fn test_header_with_inodes() {
init();
let options = Options {
columns: COLUMNS_WITH_INODES.to_vec(),
..Default::default()
@ -576,6 +595,7 @@ mod tests {
#[test]
fn test_header_with_block_size_1024() {
init();
let options = Options {
block_size: BlockSize::Bytes(3 * 1024),
..Default::default()
@ -595,6 +615,7 @@ mod tests {
#[test]
fn test_human_readable_header() {
init();
let options = Options {
header_mode: HeaderMode::HumanReadable,
..Default::default()
@ -607,6 +628,7 @@ mod tests {
#[test]
fn test_posix_portability_header() {
init();
let options = Options {
header_mode: HeaderMode::PosixPortability,
..Default::default()
@ -626,6 +648,7 @@ mod tests {
#[test]
fn test_output_header() {
init();
let options = Options {
header_mode: HeaderMode::Output,
..Default::default()
@ -645,6 +668,7 @@ mod tests {
#[test]
fn test_row_formatter() {
init();
let options = Options {
block_size: BlockSize::Bytes(1),
..Default::default()
@ -669,6 +693,7 @@ mod tests {
#[test]
fn test_row_formatter_with_fs_type() {
init();
let options = Options {
columns: COLUMNS_WITH_FS_TYPE.to_vec(),
block_size: BlockSize::Bytes(1),
@ -695,6 +720,7 @@ mod tests {
#[test]
fn test_row_formatter_with_inodes() {
init();
let options = Options {
columns: COLUMNS_WITH_INODES.to_vec(),
block_size: BlockSize::Bytes(1),
@ -720,6 +746,7 @@ mod tests {
#[test]
fn test_row_formatter_with_bytes_and_inodes() {
init();
let options = Options {
columns: vec![Column::Size, Column::Itotal],
block_size: BlockSize::Bytes(100),
@ -736,6 +763,7 @@ mod tests {
#[test]
fn test_row_formatter_with_human_readable_si() {
init();
let options = Options {
human_readable: Some(HumanReadable::Decimal),
columns: COLUMNS_WITH_FS_TYPE.to_vec(),
@ -762,6 +790,7 @@ mod tests {
#[test]
fn test_row_formatter_with_human_readable_binary() {
init();
let options = Options {
human_readable: Some(HumanReadable::Binary),
columns: COLUMNS_WITH_FS_TYPE.to_vec(),
@ -788,6 +817,7 @@ mod tests {
#[test]
fn test_row_formatter_with_round_up_usage() {
init();
let options = Options {
columns: vec![Column::Pcent],
..Default::default()
@ -802,6 +832,7 @@ mod tests {
#[test]
fn test_row_formatter_with_round_up_byte_values() {
init();
fn get_formatted_values(bytes: u64, bytes_used: u64, bytes_avail: u64) -> Vec<String> {
let options = Options {
block_size: BlockSize::Bytes(1000),
@ -826,6 +857,7 @@ mod tests {
#[test]
fn test_row_converter_with_invalid_numbers() {
init();
// copy from wsl linux
let d = crate::Filesystem {
file: None,
@ -857,6 +889,7 @@ mod tests {
#[test]
fn test_table_column_width_computation_include_total_row() {
init();
let d1 = crate::Filesystem {
file: None,
mount_info: crate::MountInfo {
@ -915,6 +948,7 @@ mod tests {
#[test]
fn test_row_accumulation_u64_overflow() {
init();
let total = u64::MAX as u128;
let used1 = 3000u128;
let used2 = 50000u128;