From 038ad04ca94d494220cc696066bd623181adb550 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 31 Jul 2025 21:29:46 +0200 Subject: [PATCH] github/action: add jobs to verify that l10n works --- .github/workflows/l10n.yml | 954 +++++++++++++++++++++++++++++++++++++ 1 file changed, 954 insertions(+) create mode 100644 .github/workflows/l10n.yml diff --git a/.github/workflows/l10n.yml b/.github/workflows/l10n.yml new file mode 100644 index 000000000..878630372 --- /dev/null +++ b/.github/workflows/l10n.yml @@ -0,0 +1,954 @@ +name: L10n (Localization) + +# spell-checker: disable + +on: + pull_request: + push: + branches: + - '*' + +env: + # * style job configuration + STYLE_FAIL_ON_FAULT: true ## (bool) fail the build if a style job contains a fault (error or warning); may be overridden on a per-job basis + +permissions: + contents: read # to fetch code (actions/checkout) + +# End the current execution if there is a new changeset in the PR. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + + l10n_build_test: + name: L10n/Build and Test + runs-on: ${{ matrix.job.os }} + env: + SCCACHE_GHA_ENABLED: "true" + RUSTC_WRAPPER: "sccache" + strategy: + fail-fast: false + matrix: + job: + - { os: ubuntu-latest , features: "feat_os_unix" } + - { os: macos-latest , features: "feat_os_macos" } + - { os: windows-latest , features: "feat_os_windows" } + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: dtolnay/rust-toolchain@stable + - uses: taiki-e/install-action@nextest + - uses: Swatinem/rust-cache@v2 + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.9 + - name: Install/setup prerequisites + shell: bash + run: | + ## Install/setup prerequisites + case '${{ matrix.job.os }}' in + ubuntu-*) + # selinux headers needed for testing + sudo apt-get -y update ; sudo apt-get -y install libselinux1-dev + ;; + macos-*) + # needed for testing + brew install coreutils + ;; + esac + - name: Build with l10n + shell: bash + run: | + ## Build with l10n + cargo build --features ${{ matrix.job.features }} + - name: Test l10n functionality + shell: bash + run: | + ## Test l10n functionality + cargo test -p uucore locale + cargo test + env: + RUST_BACKTRACE: "1" + + l10n_fluent_syntax: + name: L10n/Fluent Syntax Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Install Mozilla Fluent Linter + shell: bash + run: | + ## Install Mozilla Fluent Linter + pip install moz-fluent-linter + - name: Find and validate Fluent files + shell: bash + run: | + ## Find and validate Fluent files with Mozilla Fluent Linter + + # Check if any .ftl files exist + fluent_files=$(find . -name "*.ftl" -type f 2>/dev/null || true) + + if [ -z "$fluent_files" ]; then + echo "::notice::No Fluent (.ftl) files found in the repository" + exit 0 + fi + + echo "Found Fluent files:" + echo "$fluent_files" + + # Use Mozilla Fluent Linter for comprehensive validation + echo "Running Mozilla Fluent Linter..." + + has_errors=false + + while IFS= read -r file; do + echo "Checking $file with Mozilla Fluent Linter..." + + # Run fluent-linter on each file + if ! moz-fluent-lint "$file"; then + echo "::error file=$file::Fluent syntax errors found in $file" + has_errors=true + else + echo "✓ Fluent syntax check passed for $file" + fi + + done <<< "$fluent_files" + + if [ "$has_errors" = true ]; then + echo "::error::Fluent linting failed - please fix syntax errors" + exit 1 + fi + + echo "::notice::All Fluent files passed Mozilla Fluent Linter validation" + + l10n_french_integration: + name: L10n/French Integration 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/sccache-action@v0.0.9 + - name: Install/setup prerequisites + shell: bash + run: | + ## Install/setup prerequisites + sudo apt-get -y update ; sudo apt-get -y install libselinux1-dev locales + - name: Generate French locale + shell: bash + run: | + ## Generate French locale for testing + sudo locale-gen --keep-existing fr_FR.UTF-8 + locale -a | grep -i fr || echo "French locale not found, continuing anyway" + - name: Build coreutils with l10n support + shell: bash + run: | + ## Build coreutils with Unix features and l10n support + cargo build --features feat_os_unix --bin coreutils + - name: Test French localization + shell: bash + run: | + ## Test French localization with various commands + export LANG=fr_FR.UTF-8 + export LC_ALL=fr_FR.UTF-8 + + echo "Testing touch --help with French locale..." + help_output=$(cargo run --features feat_os_unix --bin coreutils -- touch --help 2>&1 || echo "Command failed") + echo "Help output: $help_output" + + # Check for specific French strings from touch fr-FR.ftl + french_strings_found=0 + if echo "$help_output" | grep -q "Mettre à jour les temps d'accès"; then + echo "✓ Found French description: 'Mettre à jour les temps d'accès'" + french_strings_found=$((french_strings_found + 1)) + fi + if echo "$help_output" | grep -q "changer seulement le temps d'accès"; then + echo "✓ Found French help text: 'changer seulement le temps d'accès'" + french_strings_found=$((french_strings_found + 1)) + fi + if echo "$help_output" | grep -q "FICHIER"; then + echo "✓ Found French usage pattern: 'FICHIER'" + french_strings_found=$((french_strings_found + 1)) + fi + + echo "Testing ls --help with French locale..." + ls_help=$(cargo run --features feat_os_unix --bin coreutils -- ls --help 2>&1 || echo "Command failed") + echo "ls help output: $ls_help" + + # Check for specific French strings from ls fr-FR.ftl + if echo "$ls_help" | grep -q "Lister le contenu des répertoires"; then + echo "✓ Found French ls description: 'Lister le contenu des répertoires'" + french_strings_found=$((french_strings_found + 1)) + fi + if echo "$ls_help" | grep -q "Afficher les informations d'aide"; then + echo "✓ Found French ls help text: 'Afficher les informations d'aide'" + french_strings_found=$((french_strings_found + 1)) + fi + + echo "Testing base64 --help with French locale..." + base64_help=$(cargo run --features feat_os_unix --bin coreutils -- base64 --help 2>&1 || echo "Command failed") + echo "base64 help output: $base64_help" + + # Check for specific French strings from base64 fr-FR.ftl + if echo "$base64_help" | grep -q "encoder/décoder les données"; then + echo "✓ Found French base64 description: 'encoder/décoder les données'" + french_strings_found=$((french_strings_found + 1)) + fi + + echo "Testing with error messages..." + error_output=$(cargo run --features feat_os_unix --bin coreutils -- ls /nonexistent 2>&1 || echo "Expected error occurred") + echo "Error output: $error_output" + + # Check for French error messages from ls fr-FR.ftl + if echo "$error_output" | grep -q "impossible d'accéder à"; then + echo "✓ Found French error message: 'impossible d'accéder à'" + french_strings_found=$((french_strings_found + 1)) + fi + if echo "$error_output" | grep -q "Aucun fichier ou répertoire de ce type"; then + echo "✓ Found French error text: 'Aucun fichier ou répertoire de ce type'" + french_strings_found=$((french_strings_found + 1)) + fi + + # Test that the binary works and doesn't crash with French locale + version_output=$(cargo run --features feat_os_unix --bin coreutils -- --version 2>&1 || echo "Version command failed") + echo "Version output: $version_output" + + # Final validation - ensure we found at least some French strings + echo "French strings found: $french_strings_found" + if [ "$french_strings_found" -gt 0 ]; then + echo "✓ SUCCESS: French locale integration test passed - found $french_strings_found French strings" + else + echo "✗ ERROR: No French strings were detected, but commands executed successfully" + exit 1 + fi + env: + RUST_BACKTRACE: "1" + + l10n_multicall_binary_install: + name: L10n/Multi-call Binary Install Test + runs-on: ${{ matrix.job.os }} + env: + SCCACHE_GHA_ENABLED: "true" + RUSTC_WRAPPER: "sccache" + strategy: + fail-fast: false + matrix: + job: + - { os: ubuntu-latest , features: "feat_os_unix" } + - { os: macos-latest , features: "feat_os_macos" } + 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/sccache-action@v0.0.9 + - name: Install/setup prerequisites + shell: bash + run: | + ## Install/setup prerequisites + case '${{ matrix.job.os }}' in + ubuntu-*) + sudo apt-get -y update ; sudo apt-get -y install libselinux1-dev build-essential + ;; + macos-*) + brew install coreutils make + ;; + esac + - name: Install via make and test multi-call binary + shell: bash + run: | + ## Install using make and test installed binaries + echo "Installing with make using DESTDIR..." + + # Create installation directory + INSTALL_DIR="$PWD/install-dir" + mkdir -p "$INSTALL_DIR" + mkdir -p "$INSTALL_DIR/usr/bin" + + # Build and install using make with DESTDIR + echo "Building multi-call binary with MULTICALL=y" + echo "Current directory: $PWD" + echo "Installation directory will be: $INSTALL_DIR" + + # First check if binary exists after build + echo "Checking if coreutils was built..." + ls -la target/release/coreutils || echo "No coreutils binary in target/release/" + + make FEATURES="${{ matrix.job.features }}" PROFILE=release MULTICALL=y + + echo "After build, checking target/release/:" + ls -la target/release/ | grep -E "(coreutils|^total)" || echo "Build may have failed" + + echo "Running make install..." + echo "Before install - checking what we have:" + ls -la target/release/coreutils 2>/dev/null || echo "No coreutils in target/release" + + # Run make install with verbose output to see what happens + echo "About to run: make install DESTDIR=\"$INSTALL_DIR\" PREFIX=/usr PROFILE=release MULTICALL=y" + echo "Expected install path: $INSTALL_DIR/usr/bin/coreutils" + + make install DESTDIR="$INSTALL_DIR" PREFIX=/usr PROFILE=release MULTICALL=y || { + echo "Make install failed! Exit code: $?" + echo "Let's see what happened:" + ls -la "$INSTALL_DIR" 2>/dev/null || echo "Install directory doesn't exist" + exit 1 + } + + echo "Make install completed successfully" + + # Debug: Show what was installed + echo "=== Installation Debug ===" + echo "Current directory: $(pwd)" + echo "INSTALL_DIR: $INSTALL_DIR" + echo "Checking if build succeeded..." + if [ -f "target/release/coreutils" ]; then + echo "✓ Build succeeded - coreutils binary exists in target/release/" + ls -la target/release/coreutils + else + echo "✗ Build failed - no coreutils binary in target/release/" + echo "Contents of target/release/:" + ls -la target/release/ | head -20 + exit 1 + fi + + echo "Contents of installation directory:" + find "$INSTALL_DIR" -type f 2>/dev/null | head -20 || echo "No files found in $INSTALL_DIR" + + echo "Checking standard installation paths..." + ls -la "$INSTALL_DIR/usr/bin/" 2>/dev/null || echo "Directory $INSTALL_DIR/usr/bin/ not found" + ls -la "$INSTALL_DIR/usr/local/bin/" 2>/dev/null || echo "Directory $INSTALL_DIR/usr/local/bin/ not found" + ls -la "$INSTALL_DIR/bin/" 2>/dev/null || echo "Directory $INSTALL_DIR/bin/ not found" + + # Find where coreutils was actually installed + echo "Searching for coreutils binary in installation directory..." + COREUTILS_BIN=$(find "$INSTALL_DIR" -name "coreutils" -type f 2>/dev/null | head -1) + if [ -n "$COREUTILS_BIN" ]; then + echo "Found coreutils at: $COREUTILS_BIN" + export COREUTILS_BIN + else + echo "ERROR: coreutils binary not found in installation directory!" + echo "Installation may have failed. Let's check the entire filesystem under install-dir:" + find "$INSTALL_DIR" -type f 2>/dev/null | head -50 + + # As a last resort, check if it's in the build directory + if [ -f "target/release/coreutils" ]; then + echo "Using binary from build directory as fallback" + COREUTILS_BIN="$(pwd)/target/release/coreutils" + export COREUTILS_BIN + else + exit 1 + fi + fi + + echo "Testing installed multi-call binary functionality..." + + # Test calling utilities through coreutils binary + echo "Testing: $COREUTILS_BIN ls --version" + "$COREUTILS_BIN" ls --version + + echo "Testing: $COREUTILS_BIN cat --version" + "$COREUTILS_BIN" cat --version + + echo "Testing: $COREUTILS_BIN touch --version" + "$COREUTILS_BIN" touch --version + + # Test individual binaries (if they exist) + LS_BIN="$INSTALL_DIR/usr/bin/ls" + if [ -f "$LS_BIN" ]; then + echo "Testing individual binary: $LS_BIN --version" + "$LS_BIN" --version + else + echo "Individual ls binary not found (multi-call only mode)" + # Check if symlinks exist + if [ -L "$LS_BIN" ]; then + echo "Found ls as symlink to: $(readlink -f "$LS_BIN")" + fi + fi + + echo "✓ Multi-call binary installation and functionality test passed" + + l10n_installation_test: + name: L10n/Installation Test (Make & Cargo) + runs-on: ${{ matrix.job.os }} + env: + SCCACHE_GHA_ENABLED: "true" + RUSTC_WRAPPER: "sccache" + strategy: + fail-fast: false + matrix: + job: + - { os: ubuntu-latest , features: "feat_os_unix" } + - { os: macos-latest , features: "feat_os_macos" } + 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/sccache-action@v0.0.9 + - name: Install/setup prerequisites + shell: bash + run: | + ## Install/setup prerequisites + case '${{ matrix.job.os }}' in + ubuntu-*) + sudo apt-get -y update ; sudo apt-get -y install libselinux1-dev build-essential locales + # Generate French locale for testing + sudo locale-gen --keep-existing fr_FR.UTF-8 + locale -a | grep -i fr || echo "French locale generation may have failed" + ;; + macos-*) + brew install coreutils make + ;; + esac + - name: Test Make installation + shell: bash + run: | + ## Test installation via make with DESTDIR + echo "Testing make install with l10n features..." + + # Create installation directory + MAKE_INSTALL_DIR="$PWD/make-install-dir" + mkdir -p "$MAKE_INSTALL_DIR" + + # Build and install using make with DESTDIR + make FEATURES="${{ matrix.job.features }}" PROFILE=release MULTICALL=y + make install DESTDIR="$MAKE_INSTALL_DIR" PREFIX=/usr PROFILE=release MULTICALL=y + + # Verify installation + echo "Testing make-installed binaries..." + if [ -f "$MAKE_INSTALL_DIR/usr/bin/coreutils" ]; then + echo "✓ coreutils binary installed via make successfully" + "$MAKE_INSTALL_DIR/usr/bin/coreutils" --version + else + echo "✗ coreutils binary not found after make install" + exit 1 + fi + + # Test utilities + echo "Testing make-installed utilities..." + "$MAKE_INSTALL_DIR/usr/bin/coreutils" ls --version + "$MAKE_INSTALL_DIR/usr/bin/coreutils" cat --version + "$MAKE_INSTALL_DIR/usr/bin/coreutils" touch --version + + # Test basic functionality + echo "test content" > test.txt + if "$MAKE_INSTALL_DIR/usr/bin/coreutils" cat test.txt | grep -q "test content"; then + echo "✓ Basic functionality works" + else + echo "✗ Basic functionality failed" + exit 1 + fi + + # Test French localization with make-installed binary (Ubuntu only) + if [ "${{ matrix.job.os }}" = "ubuntu-latest" ]; then + echo "Testing French localization with make-installed binary..." + + # Set French locale + export LANG=fr_FR.UTF-8 + export LC_ALL=fr_FR.UTF-8 + + echo "Testing ls --help with French locale..." + ls_help=$("$MAKE_INSTALL_DIR/usr/bin/coreutils" ls --help 2>&1 || echo "Command failed") + echo "ls help output (first 10 lines):" + echo "$ls_help" | head -10 + + # Check for specific French strings from ls fr-FR.ftl + french_strings_found=0 + + if echo "$ls_help" | grep -q "Lister le contenu des répertoires"; then + echo "✓ Found French ls description: 'Lister le contenu des répertoires'" + french_strings_found=$((french_strings_found + 1)) + fi + + if echo "$ls_help" | grep -q "Afficher les informations d'aide"; then + echo "✓ Found French ls help text: 'Afficher les informations d'aide'" + french_strings_found=$((french_strings_found + 1)) + fi + + if echo "$ls_help" | grep -q "FICHIER"; then + echo "✓ Found French usage pattern: 'FICHIER'" + french_strings_found=$((french_strings_found + 1)) + fi + + echo "Testing cat --help with French locale..." + cat_help=$("$MAKE_INSTALL_DIR/usr/bin/coreutils" cat --help 2>&1 || echo "Command failed") + echo "cat help output (first 5 lines):" + echo "$cat_help" | head -5 + + if echo "$cat_help" | grep -q "Concaténer"; then + echo "✓ Found French cat description containing: 'Concaténer'" + french_strings_found=$((french_strings_found + 1)) + fi + + echo "Testing error messages with French locale..." + error_output=$("$MAKE_INSTALL_DIR/usr/bin/coreutils" ls /nonexistent_test_directory 2>&1 || echo "Expected error occurred") + echo "Error output: $error_output" + + if echo "$error_output" | grep -q "impossible d'accéder à"; then + echo "✓ Found French error message: 'impossible d'accéder à'" + french_strings_found=$((french_strings_found + 1)) + fi + + # Final validation + echo "French strings found: $french_strings_found" + if [ "$french_strings_found" -gt 0 ]; then + echo "✓ SUCCESS: French localization test passed with make-installed binary - found $french_strings_found French strings" + else + echo "✗ ERROR: No French strings detected with make-installed binary" + exit 1 + fi + else + echo "Skipping French localization test on ${{ matrix.job.os }} (no French locale available)" + fi + + echo "✓ Make installation test passed" + - name: Test Cargo installation + shell: bash + run: | + ## Test installation via cargo install with DESTDIR-like approach + echo "Testing cargo install with l10n features..." + + # Create installation directory + CARGO_INSTALL_DIR="$PWD/cargo-install-dir" + mkdir -p "$CARGO_INSTALL_DIR" + + # Install using cargo with l10n features + cargo install --path . --features ${{ matrix.job.features }} --root "$CARGO_INSTALL_DIR" --locked + + # Verify installation + echo "Testing cargo-installed binaries..." + if [ -f "$CARGO_INSTALL_DIR/bin/coreutils" ]; then + echo "✓ coreutils binary installed successfully" + "$CARGO_INSTALL_DIR/bin/coreutils" --version + else + echo "✗ coreutils binary not found after cargo install" + exit 1 + fi + + # Test utilities + echo "Testing installed utilities..." + "$CARGO_INSTALL_DIR/bin/coreutils" ls --version + "$CARGO_INSTALL_DIR/bin/coreutils" cat --version + "$CARGO_INSTALL_DIR/bin/coreutils" touch --version + + # Test basic functionality + echo "test content" > test.txt + if "$CARGO_INSTALL_DIR/bin/coreutils" cat test.txt | grep -q "test content"; then + echo "✓ Basic functionality works" + else + echo "✗ Basic functionality failed" + exit 1 + fi + + echo "✓ Cargo installation test passed" + - name: Download additional locales from coreutils-l10n + shell: bash + run: | + ## Download additional locale files from coreutils-l10n repository + echo "Downloading additional locale files from coreutils-l10n..." + git clone https://github.com/uutils/coreutils-l10n.git coreutils-l10n-repo + + # Create installation directory + CARGO_INSTALL_DIR="$PWD/cargo-install-dir" + + # Create locale directory for cargo install + LOCALE_DIR="$CARGO_INSTALL_DIR/share/locales" + mkdir -p "$LOCALE_DIR" + + # Debug: Check structure of l10n repo + echo "Checking structure of coreutils-l10n-repo:" + ls -la coreutils-l10n-repo/ | head -10 + echo "Looking for locales directory:" + find coreutils-l10n-repo -name "*.ftl" -type f 2>/dev/null | head -10 || true + echo "Checking specific utilities:" + ls -la coreutils-l10n-repo/src/uu/ls/locales/ 2>/dev/null || echo "No ls directory in correct location" + find coreutils-l10n-repo -path "*/ls/*.ftl" 2>/dev/null | head -5 || echo "No ls ftl files found" + + # Copy non-English locale files from l10n repo + for util_dir in src/uu/*/; do + util_name=$(basename "$util_dir") + l10n_util_dir="coreutils-l10n-repo/src/uu/$util_name/locales" + + if [ -d "$l10n_util_dir" ]; then + echo "Installing locales for $util_name..." + mkdir -p "$LOCALE_DIR/$util_name" + + for locale_file in "$l10n_util_dir"/*.ftl; do + if [ -f "$locale_file" ]; then + filename=$(basename "$locale_file") + # Skip English locale files (they are embedded) + if [ "$filename" != "en-US.ftl" ]; then + cp "$locale_file" "$LOCALE_DIR/$util_name/" + echo " Installed $filename to $LOCALE_DIR/$util_name/" + fi + fi + done + else + # Debug: Show what's not found + if [ "$util_name" = "ls" ] || [ "$util_name" = "cat" ]; then + echo "WARNING: No l10n directory found for $util_name at $l10n_util_dir" + fi + fi + done + + # Debug: Show what was actually installed + echo "Files installed in locale directory:" + find "$LOCALE_DIR" -name "*.ftl" 2>/dev/null | head -10 || true + + # Fallback: If no files were installed from l10n repo, try copying from main repo + if [ -z "$(find "$LOCALE_DIR" -name "*.ftl" 2>/dev/null)" ]; then + echo "No files found from l10n repo, trying fallback from main repository..." + for util_dir in src/uu/*/; do + util_name=$(basename "$util_dir") + if [ -d "$util_dir/locales" ]; then + echo "Copying locales for $util_name from main repo..." + mkdir -p "$LOCALE_DIR/$util_name" + cp "$util_dir/locales"/*.ftl "$LOCALE_DIR/$util_name/" 2>/dev/null || true + fi + done + echo "Files after fallback:" + find "$LOCALE_DIR" -name "*.ftl" 2>/dev/null | head -10 || true + fi + + echo "✓ Additional locale files installed" + - name: Test French localization after cargo install + shell: bash + run: | + ## Test French localization with cargo-installed binary and downloaded locales + echo "Testing French localization with cargo-installed binary..." + + # Set installation directories + CARGO_INSTALL_DIR="$PWD/cargo-install-dir" + LOCALE_DIR="$CARGO_INSTALL_DIR/share/locales" + + echo "Checking installed binary..." + if [ ! -f "$CARGO_INSTALL_DIR/bin/coreutils" ]; then + echo "✗ coreutils binary not found" + exit 1 + fi + + echo "Checking locale files..." + echo "LOCALE_DIR is: $LOCALE_DIR" + echo "Checking if locale directory exists:" + ls -la "$LOCALE_DIR" 2>/dev/null || echo "Locale directory not found" + echo "Contents of locale directory:" + find "$LOCALE_DIR" -name "*.ftl" 2>/dev/null | head -10 || echo "No locale files found" + echo "Looking for ls locale files specifically:" + ls -la "$LOCALE_DIR/ls/" 2>/dev/null || echo "No ls locale directory" + + # Test French localization + export LANG=fr_FR.UTF-8 + export LC_ALL=fr_FR.UTF-8 + + echo "Testing ls --help with French locale..." + ls_help=$("$CARGO_INSTALL_DIR/bin/coreutils" ls --help 2>&1 || echo "Command failed") + echo "ls help output (first 10 lines):" + echo "$ls_help" | head -10 + + # Check for specific French strings from ls fr-FR.ftl + french_strings_found=0 + + if echo "$ls_help" | grep -q "Lister le contenu des répertoires"; then + echo "✓ Found French ls description: 'Lister le contenu des répertoires'" + french_strings_found=$((french_strings_found + 1)) + fi + + if echo "$ls_help" | grep -q "Afficher les informations d'aide"; then + echo "✓ Found French ls help text: 'Afficher les informations d'aide'" + french_strings_found=$((french_strings_found + 1)) + fi + + if echo "$ls_help" | grep -q "FICHIER"; then + echo "✓ Found French usage pattern: 'FICHIER'" + french_strings_found=$((french_strings_found + 1)) + fi + + echo "Testing cat --help with French locale..." + cat_help=$("$CARGO_INSTALL_DIR/bin/coreutils" cat --help 2>&1 || echo "Command failed") + echo "cat help output (first 5 lines):" + echo "$cat_help" | head -5 + + if echo "$cat_help" | grep -q "Concaténer"; then + echo "✓ Found French cat description containing: 'Concaténer'" + french_strings_found=$((french_strings_found + 1)) + fi + + echo "Testing error messages with French locale..." + error_output=$("$CARGO_INSTALL_DIR/bin/coreutils" ls /nonexistent_test_directory 2>&1 || echo "Expected error occurred") + echo "Error output: $error_output" + + if echo "$error_output" | grep -q "impossible d'accéder à"; then + echo "✓ Found French error message: 'impossible d'accéder à'" + french_strings_found=$((french_strings_found + 1)) + fi + + # Verify the binary works in French locale + version_output=$("$CARGO_INSTALL_DIR/bin/coreutils" --version 2>&1) + if [ $? -eq 0 ]; then + echo "✓ Binary executes successfully with French locale" + echo "Version output: $version_output" + else + echo "✗ Binary failed to execute with French locale" + exit 1 + fi + + # Final validation + echo "French strings found: $french_strings_found" + if [ "$french_strings_found" -gt 0 ]; then + echo "✓ SUCCESS: French localization test passed after cargo install - found $french_strings_found French strings" + else + echo "✗ ERROR: No French strings detected with cargo-installed binary" + echo "This indicates an issue with locale loading from downloaded files" + exit 1 + fi + + echo "✓ French localization verification completed" + + l10n_locale_support_verification: + name: L10n/Locale Support Verification + 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/sccache-action@v0.0.9 + - name: Install/setup prerequisites + shell: bash + run: | + ## Install/setup prerequisites including locale support + sudo apt-get -y update + sudo apt-get -y install libselinux1-dev locales build-essential + + # Generate multiple locales for testing + sudo locale-gen --keep-existing en_US.UTF-8 fr_FR.UTF-8 de_DE.UTF-8 es_ES.UTF-8 + locale -a | grep -E "(en_US|fr_FR|de_DE|es_ES)" || echo "Some locales may not be available" + - name: Install binaries with locale support + shell: bash + run: | + ## Install both multi-call and individual binaries using make + echo "Installing binaries with full locale support..." + + # Create installation directory + INSTALL_DIR="$PWD/install-dir" + mkdir -p "$INSTALL_DIR" + + # Build and install using make with DESTDIR + make FEATURES="feat_os_unix" PROFILE=release MULTICALL=y + make install DESTDIR="$INSTALL_DIR" PREFIX=/usr PROFILE=release MULTICALL=y + + # Debug: Show what was installed + echo "Contents of installation directory:" + find "$INSTALL_DIR" -type f -name "coreutils" -o -name "ls" 2>/dev/null | head -20 || true + echo "Looking for binaries in: $INSTALL_DIR/usr/bin/" + ls -la "$INSTALL_DIR/usr/bin/" || echo "Directory not found" + + echo "✓ Installation completed" + - name: Verify locale detection and startup + shell: bash + run: | + ## Test that installed binaries start correctly with different locales + echo "Testing locale detection and startup..." + + # Set installation directory path + INSTALL_DIR="$PWD/install-dir" + + # Test with different locales + locales_to_test=("C" "en_US.UTF-8" "fr_FR.UTF-8") + + for locale in "${locales_to_test[@]}"; do + echo "Testing with locale: $locale" + + # Test multi-call binary startup + if LC_ALL="$locale" "$INSTALL_DIR/usr/bin/coreutils" --version >/dev/null 2>&1; then + echo "✓ Multi-call binary starts successfully with locale: $locale" + else + echo "✗ Multi-call binary failed to start with locale: $locale" + exit 1 + fi + + # Test individual binary startup (if available) + if [ -f "$INSTALL_DIR/usr/bin/ls" ]; then + if LC_ALL="$locale" "$INSTALL_DIR/usr/bin/ls" --version >/dev/null 2>&1; then + echo "✓ Individual binary (ls) starts successfully with locale: $locale" + else + echo "✗ Individual binary (ls) failed to start with locale: $locale" + exit 1 + fi + else + echo "Individual ls binary not found (multi-call only mode)" + fi + + # Test that help text appears (even if not localized) + help_output=$(LC_ALL="$locale" "$INSTALL_DIR/usr/bin/coreutils" ls --help 2>&1) + if echo "$help_output" | grep -q -i "usage\|list"; then + echo "✓ Help text appears correctly with locale: $locale" + else + echo "✗ Help text missing or malformed with locale: $locale" + echo "Help output: $help_output" + exit 1 + fi + done + + echo "✓ All locale startup tests passed" + - name: Test locale-specific functionality + shell: bash + run: | + ## Test locale-specific behavior with installed binaries + echo "Testing locale-specific functionality..." + + # Set installation directory path + INSTALL_DIR="$PWD/install-dir" + + # Test with French locale (if available) + if locale -a | grep -q fr_FR.UTF-8; then + echo "Testing French locale functionality..." + + export LANG=fr_FR.UTF-8 + export LC_ALL=fr_FR.UTF-8 + + # Test that the program runs successfully with French locale + french_version_output=$("$INSTALL_DIR/usr/bin/coreutils" --version 2>&1) + if [ $? -eq 0 ]; then + echo "✓ Program runs successfully with French locale" + echo "Version output: $french_version_output" + else + echo "✗ Program failed with French locale" + echo "Error output: $french_version_output" + exit 1 + fi + + # Test basic functionality with French locale + temp_file=$(mktemp) + echo "test content" > "$temp_file" + + if "$INSTALL_DIR/usr/bin/coreutils" cat "$temp_file" | grep -q "test content"; then + echo "✓ Basic file operations work with French locale" + else + echo "✗ Basic file operations failed with French locale" + exit 1 + fi + + rm -f "$temp_file" + + # Test that French translations are actually working + echo "Testing French translations..." + french_strings_found=0 + + echo "Testing ls --help with French locale..." + ls_help=$("$INSTALL_DIR/usr/bin/coreutils" ls --help 2>&1 || echo "Command failed") + echo "ls help output (first 10 lines):" + echo "$ls_help" | head -10 + + # Check for actual French strings that appear in ls --help output + if echo "$ls_help" | grep -q "Lister le contenu des répertoires"; then + echo "✓ Found French ls description: 'Lister le contenu des répertoires'" + french_strings_found=$((french_strings_found + 1)) + fi + if echo "$ls_help" | grep -q "Ignorer les fichiers et répertoires commençant par"; then + echo "✓ Found French explanation: 'Ignorer les fichiers et répertoires commençant par'" + french_strings_found=$((french_strings_found + 1)) + fi + if echo "$ls_help" | grep -q "Afficher les informations d'aide"; then + echo "✓ Found French help text: 'Afficher les informations d'aide'" + french_strings_found=$((french_strings_found + 1)) + fi + if echo "$ls_help" | grep -q "FICHIER"; then + echo "✓ Found French usage pattern: 'FICHIER'" + french_strings_found=$((french_strings_found + 1)) + fi + if echo "$ls_help" | grep -q "Définir le format d'affichage"; then + echo "✓ Found French option description: 'Définir le format d'affichage'" + french_strings_found=$((french_strings_found + 1)) + fi + + echo "Testing cat --help with French locale..." + cat_help=$("$INSTALL_DIR/usr/bin/coreutils" cat --help 2>&1 || echo "Command failed") + echo "cat help output (first 5 lines):" + echo "$cat_help" | head -5 + + # Check for French strings in cat help + if echo "$cat_help" | grep -q "Concaténer"; then + echo "✓ Found French cat description containing: 'Concaténer'" + french_strings_found=$((french_strings_found + 1)) + fi + + echo "Testing with error messages..." + error_output=$("$INSTALL_DIR/usr/bin/coreutils" ls /nonexistent_directory_for_testing 2>&1 || echo "Expected error occurred") + echo "Error output: $error_output" + + # Check for French error messages + if echo "$error_output" | grep -q "impossible d'accéder à"; then + echo "✓ Found French error message: 'impossible d'accéder à'" + french_strings_found=$((french_strings_found + 1)) + fi + if echo "$error_output" | grep -q "Aucun fichier ou répertoire de ce type"; then + echo "✓ Found French error text: 'Aucun fichier ou répertoire de ce type'" + french_strings_found=$((french_strings_found + 1)) + fi + + # Test version output + echo "Testing --version with French locale..." + version_output=$("$INSTALL_DIR/usr/bin/coreutils" --version 2>&1) + echo "Version output: $version_output" + + # Final validation - ensure we found at least some French strings + echo "French strings found: $french_strings_found" + if [ "$french_strings_found" -gt 0 ]; then + echo "✓ SUCCESS: French locale translation test passed - found $french_strings_found French strings" + else + echo "✗ ERROR: No French strings were detected in installed binaries" + echo "This indicates that French translations are not working properly with installed binaries" + exit 1 + fi + else + echo "French locale not available, skipping French-specific tests" + fi + + # Test with standard build configuration + echo "Testing standard build configuration..." + cd "$GITHUB_WORKSPACE" + + # Create separate installation directory for standard build + STANDARD_BUILD_INSTALL_DIR="$PWD/standard-build-install-dir" + mkdir -p "$STANDARD_BUILD_INSTALL_DIR" + + # Clean and build standard version + make clean + make FEATURES="feat_os_unix" PROFILE=release MULTICALL=y + make install DESTDIR="$STANDARD_BUILD_INSTALL_DIR" PREFIX=/usr PROFILE=release MULTICALL=y + + # Verify standard build binary works + if "$STANDARD_BUILD_INSTALL_DIR/usr/bin/coreutils" --version >/dev/null 2>&1; then + echo "✓ Standard build works correctly" + else + echo "✗ Standard build failed" + exit 1 + fi + + echo "✓ All locale-specific functionality tests passed" + env: + RUST_BACKTRACE: "1"