Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions .github/workflows/l10n.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,176 @@ jobs:

echo "::notice::All Fluent files passed Mozilla Fluent Linter validation"

l10n_clap_error_localization:
name: L10n/Clap Error Localization Test
runs-on: ubuntu-latest
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Run sccache-cache
uses: mozilla-actions/[email protected]
- name: Install/setup prerequisites
shell: bash
run: |
sudo apt-get -y update ; sudo apt-get -y install libselinux1-dev locales
sudo locale-gen --keep-existing fr_FR.UTF-8
locale -a | grep -i fr || exit 1
- name: Build coreutils with clap localization support
shell: bash
run: |
cargo build --features feat_os_unix --bin coreutils
- name: Test English clap error localization
shell: bash
run: |
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

# Test invalid argument error - should show colored error message
echo "Testing invalid argument error..."
error_output=$(cargo run --features feat_os_unix --bin coreutils -- cp --invalid-arg 2>&1 || echo "Expected error occurred")
echo "Error output: $error_output"

# Check for expected English clap error patterns
english_errors_found=0

if echo "$error_output" | grep -q "error.*unexpected argument"; then
echo "✓ Found English clap error message pattern"
english_errors_found=$((english_errors_found + 1))
fi

if echo "$error_output" | grep -q "Usage:"; then
echo "✓ Found English usage pattern"
english_errors_found=$((english_errors_found + 1))
fi

if echo "$error_output" | grep -q "For more information.*--help"; then
echo "✓ Found English help suggestion"
english_errors_found=$((english_errors_found + 1))
fi

# Test typo suggestion
echo "Testing typo suggestion..."
typo_output=$(cargo run --features feat_os_unix --bin coreutils -- ls --verbos 2>&1 || echo "Expected error occurred")
echo "Typo output: $typo_output"

if echo "$typo_output" | grep -q "similar.*verbose"; then
echo "✓ Found English typo suggestion"
english_errors_found=$((english_errors_found + 1))
fi

echo "English clap errors found: $english_errors_found"
if [ "$english_errors_found" -ge 2 ]; then
echo "✓ SUCCESS: English clap error localization working"
else
echo "✗ ERROR: English clap error localization not working properly"
exit 1
fi
env:
RUST_BACKTRACE: "1"

- name: Test French clap error localization
shell: bash
run: |
export LANG=fr_FR.UTF-8
export LC_ALL=fr_FR.UTF-8

# Test invalid argument error - should show French colored error message
echo "Testing invalid argument error in French..."
error_output=$(cargo run --features feat_os_unix --bin coreutils -- cp --invalid-arg 2>&1 || echo "Expected error occurred")
echo "French error output: $error_output"

# Check for expected French clap error patterns
french_errors_found=0

if echo "$error_output" | grep -q "erreur.*argument inattendu"; then
echo "✓ Found French clap error message: 'erreur: argument inattendu'"
french_errors_found=$((french_errors_found + 1))
fi

if echo "$error_output" | grep -q "conseil.*pour passer.*comme valeur"; then
echo "✓ Found French tip message: 'conseil: pour passer ... comme valeur'"
french_errors_found=$((french_errors_found + 1))
fi

if echo "$error_output" | grep -q "Utilisation:"; then
echo "✓ Found French usage pattern: 'Utilisation:'"
french_errors_found=$((french_errors_found + 1))
fi

if echo "$error_output" | grep -q "Pour plus d'informations.*--help"; then
echo "✓ Found French help suggestion: 'Pour plus d'informations'"
french_errors_found=$((french_errors_found + 1))
fi

# Test typo suggestion in French
echo "Testing typo suggestion in French..."
typo_output=$(cargo run --features feat_os_unix --bin coreutils -- ls --verbos 2>&1 || echo "Expected error occurred")
echo "French typo output: $typo_output"

if echo "$typo_output" | grep -q "conseil.*similaire.*verbose"; then
echo "✓ Found French typo suggestion with 'conseil'"
french_errors_found=$((french_errors_found + 1))
fi

echo "French clap errors found: $french_errors_found"
if [ "$french_errors_found" -ge 2 ]; then
echo "✓ SUCCESS: French clap error localization working - found $french_errors_found French patterns"
else
echo "✗ ERROR: French clap error localization not working properly"
echo "Note: This might be expected if French common locale files are not available"
# Don't fail the build - French clap localization might not be fully set up yet
echo "::warning::French clap error localization not working, but continuing"
fi

# Test that colors are working (ANSI escape codes)
echo "Testing ANSI color codes in error output..."
if echo "$error_output" | grep -q $'\x1b\[3[0-7]m'; then
echo "✓ Found ANSI color codes in error output"
else
echo "✗ No ANSI color codes found - colors may not be working"
echo "::warning::ANSI color codes not detected in clap error output"
fi
env:
RUST_BACKTRACE: "1"

- name: Test clap localization with multiple utilities
shell: bash
run: |
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

utilities_to_test=("ls" "cat" "touch" "cp" "mv")
utilities_passed=0

for util in "${utilities_to_test[@]}"; do
echo "Testing $util with invalid argument..."
util_error=$(cargo run --features feat_os_unix --bin coreutils -- "$util" --nonexistent-flag 2>&1 || echo "Expected error occurred")

if echo "$util_error" | grep -q "error.*unexpected argument"; then
echo "✓ $util: clap localization working"
utilities_passed=$((utilities_passed + 1))
else
echo "✗ $util: clap localization not working"
echo "Output: $util_error"
fi
done

echo "Utilities with working clap localization: $utilities_passed/${#utilities_to_test[@]}"
if [ "$utilities_passed" -ge 3 ]; then
echo "✓ SUCCESS: Clap localization working across multiple utilities"
else
echo "✗ ERROR: Clap localization not working for enough utilities"
exit 1
fi
env:
RUST_BACKTRACE: "1"

l10n_french_integration:
name: L10n/French Integration Test
runs-on: ubuntu-latest
Expand Down
3 changes: 2 additions & 1 deletion .vscode/cSpell.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"src/uu/dd/test-resources/**",
"vendor/**",
"**/*.svg",
"src/uu/*/locales/*.ftl"
"src/uu/*/locales/*.ftl",
"src/uucore/locales/*.ftl"
],

"enableGlobDot": true,
Expand Down
8 changes: 8 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,14 @@ endif

ifeq ($(LOCALES),y)
locales:
@# Copy uucore common locales
@if [ -d "$(BASEDIR)/src/uucore/locales" ]; then \
mkdir -p "$(BUILDDIR)/locales/uucore"; \
for locale_file in "$(BASEDIR)"/src/uucore/locales/*.ftl; do \
$(INSTALL) -v "$$locale_file" "$(BUILDDIR)/locales/uucore/"; \
done; \
fi; \
# Copy utility-specific locales
@for prog in $(INSTALLEES); do \
if [ -d "$(BASEDIR)/src/uu/$$prog/locales" ]; then \
mkdir -p "$(BUILDDIR)/locales/$$prog"; \
Expand Down
4 changes: 3 additions & 1 deletion src/uu/arch/src/arch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
use platform_info::*;

use clap::Command;
use uucore::LocalizedCommand;
use uucore::error::{UResult, USimpleError};
use uucore::translate;

#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
uu_app().try_get_matches_from(args)?;
uu_app().get_matches_from_localized(args);

let uts =
PlatformInfo::new().map_err(|_e| USimpleError::new(1, translate!("cannot-get-system")))?;
Expand All @@ -23,6 +24,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
pub fn uu_app() -> Command {
Command::new(uucore::util_name())
.version(uucore::crate_version!())
.help_template(uucore::localized_help_template(uucore::util_name()))
.about(translate!("arch-about"))
.after_help(translate!("arch-after-help"))
.infer_long_args(true)
Expand Down
8 changes: 5 additions & 3 deletions src/uu/base32/src/base_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ use clap::{Arg, ArgAction, Command};
use std::fs::File;
use std::io::{self, ErrorKind, Read, Seek, SeekFrom};
use std::path::{Path, PathBuf};
use uucore::LocalizedCommand;
use uucore::display::Quotable;
use uucore::encoding::{
BASE2LSBF, BASE2MSBF, Format, Z85Wrapper,
BASE2LSBF, BASE2MSBF, EncodingWrapper, Format, SupportsFastDecodeAndEncode, Z85Wrapper,
for_base_common::{BASE32, BASE32HEX, BASE64, BASE64_NOPAD, BASE64URL, HEXUPPER_PERMISSIVE},
};
use uucore::encoding::{EncodingWrapper, SupportsFastDecodeAndEncode};
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
use uucore::format_usage;
use uucore::translate;
Expand Down Expand Up @@ -100,12 +100,14 @@ pub fn parse_base_cmd_args(
usage: &str,
) -> UResult<Config> {
let command = base_app(about, usage);
Config::from(&command.try_get_matches_from(args)?)
let matches = command.get_matches_from_localized(args);
Config::from(&matches)
}

pub fn base_app(about: &'static str, usage: &str) -> Command {
Command::new(uucore::util_name())
.version(uucore::crate_version!())
.help_template(uucore::localized_help_template(uucore::util_name()))
.about(about)
.override_usage(format_usage(usage))
.infer_long_args(true)
Expand Down
4 changes: 3 additions & 1 deletion src/uu/basename/src/basename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use uucore::error::{UResult, UUsageError};
use uucore::format_usage;
use uucore::line_ending::LineEnding;

use uucore::LocalizedCommand;
use uucore::translate;

pub mod options {
Expand All @@ -29,7 +30,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
//
// Argument parsing
//
let matches = uu_app().try_get_matches_from(args)?;
let matches = uu_app().get_matches_from_localized(args);

let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO));

Expand Down Expand Up @@ -81,6 +82,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
pub fn uu_app() -> Command {
Command::new(uucore::util_name())
.version(uucore::crate_version!())
.help_template(uucore::localized_help_template(uucore::util_name()))
.about(translate!("basename-about"))
.override_usage(format_usage(&translate!("basename-usage")))
.infer_long_args(true)
Expand Down
4 changes: 3 additions & 1 deletion src/uu/cat/src/cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use std::os::unix::fs::FileTypeExt;
#[cfg(unix)]
use std::os::unix::net::UnixStream;
use thiserror::Error;
use uucore::LocalizedCommand;
use uucore::display::Quotable;
use uucore::error::UResult;
#[cfg(not(target_os = "windows"))]
Expand Down Expand Up @@ -230,7 +231,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
libc::signal(libc::SIGPIPE, libc::SIG_DFL);
}

let matches = uu_app().try_get_matches_from(args)?;
let matches = uu_app().get_matches_from_localized(args);

let number_mode = if matches.get_flag(options::NUMBER_NONBLANK) {
NumberingMode::NonEmpty
Expand Down Expand Up @@ -286,6 +287,7 @@ pub fn uu_app() -> Command {
.version(uucore::crate_version!())
.override_usage(format_usage(&translate!("cat-usage")))
.about(translate!("cat-about"))
.help_template(uucore::localized_help_template(uucore::util_name()))
.infer_long_args(true)
.args_override_self(true)
.arg(
Expand Down
4 changes: 3 additions & 1 deletion src/uu/chcon/src/chcon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#![allow(clippy::upper_case_acronyms)]

use clap::builder::ValueParser;
use uucore::LocalizedCommand;
use uucore::error::{UResult, USimpleError, UUsageError};
use uucore::translate;
use uucore::{display::Quotable, format_usage, show_error, show_warning};
Expand Down Expand Up @@ -156,6 +157,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
pub fn uu_app() -> Command {
Command::new(uucore::util_name())
.version(uucore::crate_version!())
.help_template(uucore::localized_help_template(uucore::util_name()))
.about(translate!("chcon-about"))
.override_usage(format_usage(&translate!("chcon-usage")))
.infer_long_args(true)
Expand Down Expand Up @@ -303,7 +305,7 @@ struct Options {
}

fn parse_command_line(config: Command, args: impl uucore::Args) -> Result<Options> {
let matches = config.try_get_matches_from(args)?;
let matches = config.get_matches_from_localized(args);

let verbose = matches.get_flag(options::VERBOSE);

Expand Down
1 change: 1 addition & 0 deletions src/uu/chgrp/src/chgrp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
pub fn uu_app() -> Command {
Command::new(uucore::util_name())
.version(uucore::crate_version!())
.help_template(uucore::localized_help_template(uucore::util_name()))
.about(translate!("chgrp-about"))
.override_usage(format_usage(&translate!("chgrp-usage")))
.infer_long_args(true)
Expand Down
4 changes: 3 additions & 1 deletion src/uu/chmod/src/chmod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::fs;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::path::Path;
use thiserror::Error;
use uucore::LocalizedCommand;
use uucore::display::Quotable;
use uucore::error::{ExitCode, UError, UResult, USimpleError, UUsageError, set_exit_code};
use uucore::fs::display_permissions_unix;
Expand Down Expand Up @@ -112,7 +113,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let (parsed_cmode, args) = extract_negative_modes(args.skip(1)); // skip binary name
let matches = uu_app()
.after_help(translate!("chmod-after-help"))
.try_get_matches_from(args)?;
.get_matches_from_localized(args);

let changes = matches.get_flag(options::CHANGES);
let quiet = matches.get_flag(options::QUIET);
Expand Down Expand Up @@ -177,6 +178,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
pub fn uu_app() -> Command {
Command::new(uucore::util_name())
.version(uucore::crate_version!())
.help_template(uucore::localized_help_template(uucore::util_name()))
.about(translate!("chmod-about"))
.override_usage(format_usage(&translate!("chmod-usage")))
.args_override_self(true)
Expand Down
1 change: 1 addition & 0 deletions src/uu/chown/src/chown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
pub fn uu_app() -> Command {
Command::new(uucore::util_name())
.version(uucore::crate_version!())
.help_template(uucore::localized_help_template(uucore::util_name()))
.about(translate!("chown-about"))
.override_usage(format_usage(&translate!("chown-usage")))
.infer_long_args(true)
Expand Down
1 change: 1 addition & 0 deletions src/uu/chroot/src/chroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
pub fn uu_app() -> Command {
Command::new(uucore::util_name())
.version(uucore::crate_version!())
.help_template(uucore::localized_help_template(uucore::util_name()))
.about(translate!("chroot-about"))
.override_usage(format_usage(&translate!("chroot-usage")))
.infer_long_args(true)
Expand Down
Loading
Loading