manage the locales when the program is coming from crates.io

Closes: #8569
This commit is contained in:
Sylvestre Ledru 2025-09-07 17:09:13 +02:00
parent 56bbc14279
commit ec37f1beca
3 changed files with 125 additions and 1 deletions

View file

@ -1118,6 +1118,29 @@ jobs:
env:
RUST_BACKTRACE: "1"
l10n_embedded_locale_regression_test:
name: L10n/Embedded Locale Regression Test
runs-on: ubuntu-latest
env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"
steps:
- uses: actions/checkout@v5
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: |
sudo apt-get -y update && sudo apt-get -y install libselinux1-dev
- name: Test embedded locale functionality for individual utilities
shell: bash
run: |
bash util/test_locale_regression.sh
l10n_locale_embedding_regression_test:
name: L10n/Locale Embedding Regression Test
runs-on: ubuntu-latest

View file

@ -12,7 +12,6 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
let out_dir = env::var("OUT_DIR")?;
let mut embedded_file = File::create(Path::new(&out_dir).join("embedded_locales.rs"))?;
writeln!(embedded_file, "// Generated at compile time - do not edit")?;
writeln!(
embedded_file,
@ -78,6 +77,14 @@ fn detect_target_utility() -> Option<String> {
}
}
// Auto-detect utility name from CARGO_PKG_NAME if it's a uu_* package
if let Ok(pkg_name) = env::var("CARGO_PKG_NAME") {
if let Some(util_name) = pkg_name.strip_prefix("uu_") {
println!("cargo:warning=Auto-detected utility name: {}", util_name);
return Some(util_name.to_string());
}
}
// Check for a build configuration file in the target directory
if let Ok(target_dir) = env::var("CARGO_TARGET_DIR") {
let config_path = std::path::Path::new(&target_dir).join("uucore_target_util.txt");
@ -156,6 +163,9 @@ fn embed_all_utilities_locales(
// Discover all uu_* directories
let src_uu_dir = project_root.join("src/uu");
if !src_uu_dir.exists() {
// When src/uu doesn't exist (e.g., standalone uucore from crates.io),
// embed a static list of utility locales that are commonly used
embed_static_utility_locales(embedded_file)?;
return Ok(());
}
@ -202,3 +212,60 @@ fn embed_all_utilities_locales(
embedded_file.flush()?;
Ok(())
}
fn embed_static_utility_locales(
embedded_file: &mut std::fs::File,
) -> Result<(), Box<dyn std::error::Error>> {
use std::env;
writeln!(
embedded_file,
" // Static utility locales for crates.io builds"
)?;
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap_or_default();
let Some(registry_dir) = Path::new(&manifest_dir).parent() else {
return Ok(()); // nothing to scan
};
// First, try to embed uucore locales - critical for common translations like "Usage:"
let uucore_locale_file = Path::new(&manifest_dir).join("locales/en-US.ftl");
if uucore_locale_file.is_file() {
let content = std::fs::read_to_string(&uucore_locale_file)?;
writeln!(embedded_file, " // Common uucore locale")?;
writeln!(
embedded_file,
" locales.insert(\"uucore/en-US.ftl\", r###\"{content}\"###);"
)?;
writeln!(embedded_file)?;
}
// Collect and sort for deterministic builds
let mut entries: Vec<_> = std::fs::read_dir(registry_dir)?
.filter_map(Result::ok)
.collect();
entries.sort_by_key(|e| e.file_name());
for entry in entries {
let file_name = entry.file_name();
if let Some(dir_name) = file_name.to_str() {
// Match uu_<util>-<version>
if let Some((util_part, _)) = dir_name.split_once('-') {
if let Some(util_name) = util_part.strip_prefix("uu_") {
let locale_file = entry.path().join("locales/en-US.ftl");
if locale_file.is_file() {
let content = std::fs::read_to_string(&locale_file)?;
writeln!(embedded_file, " // Locale for {util_name}")?;
writeln!(
embedded_file,
" locales.insert(\"{util_name}/en-US.ftl\", r###\"{content}\"###);"
)?;
writeln!(embedded_file)?;
}
}
}
}
}
Ok(())
}

34
util/test_locale_regression.sh Executable file
View file

@ -0,0 +1,34 @@
#!/bin/bash
echo "Testing embedded locale functionality to prevent crates.io regression..."
INSTALL_DIR="$(pwd)/test-install-dir"
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"
utilities_to_test=("cp" "mv" "ln")
for util in "${utilities_to_test[@]}"; do
echo "Testing $util..."
cargo install --path "src/uu/$util" --root "$INSTALL_DIR" --force --quiet
binary_path="$INSTALL_DIR/bin/$util"
help_output=$("$binary_path" --help 2>&1)
# Check for regression indicators
if echo "$help_output" | grep -q "common-usage"; then
echo "✗ CRITICAL REGRESSION: $util shows untranslated 'common-usage' key"
echo "Help output:"
echo "$help_output"
exit 1
fi
# Verify proper "Usage:" label
if echo "$help_output" | grep -q "Usage:"; then
echo "$util shows properly translated 'Usage:' label"
else
echo "✗ CRITICAL REGRESSION: $util missing 'Usage:' label"
echo "Help output:"
echo "$help_output"
exit 1
fi
done
echo "All tests passed!"