Skip to content

Commit 9aaf603

Browse files
authored
Merge pull request #8571 from sylvestre/issue-8569
manage the locales when the program is coming from crates.io
2 parents 56bbc14 + ec37f1b commit 9aaf603

File tree

3 files changed

+125
-1
lines changed

3 files changed

+125
-1
lines changed

.github/workflows/l10n.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,29 @@ jobs:
11181118
env:
11191119
RUST_BACKTRACE: "1"
11201120

1121+
l10n_embedded_locale_regression_test:
1122+
name: L10n/Embedded Locale Regression Test
1123+
runs-on: ubuntu-latest
1124+
env:
1125+
SCCACHE_GHA_ENABLED: "true"
1126+
RUSTC_WRAPPER: "sccache"
1127+
steps:
1128+
- uses: actions/checkout@v5
1129+
with:
1130+
persist-credentials: false
1131+
- uses: dtolnay/rust-toolchain@stable
1132+
- uses: Swatinem/rust-cache@v2
1133+
- name: Run sccache-cache
1134+
uses: mozilla-actions/[email protected]
1135+
- name: Install/setup prerequisites
1136+
shell: bash
1137+
run: |
1138+
sudo apt-get -y update && sudo apt-get -y install libselinux1-dev
1139+
- name: Test embedded locale functionality for individual utilities
1140+
shell: bash
1141+
run: |
1142+
bash util/test_locale_regression.sh
1143+
11211144
l10n_locale_embedding_regression_test:
11221145
name: L10n/Locale Embedding Regression Test
11231146
runs-on: ubuntu-latest

src/uucore/build.rs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
1212
let out_dir = env::var("OUT_DIR")?;
1313

1414
let mut embedded_file = File::create(Path::new(&out_dir).join("embedded_locales.rs"))?;
15-
1615
writeln!(embedded_file, "// Generated at compile time - do not edit")?;
1716
writeln!(
1817
embedded_file,
@@ -78,6 +77,14 @@ fn detect_target_utility() -> Option<String> {
7877
}
7978
}
8079

80+
// Auto-detect utility name from CARGO_PKG_NAME if it's a uu_* package
81+
if let Ok(pkg_name) = env::var("CARGO_PKG_NAME") {
82+
if let Some(util_name) = pkg_name.strip_prefix("uu_") {
83+
println!("cargo:warning=Auto-detected utility name: {}", util_name);
84+
return Some(util_name.to_string());
85+
}
86+
}
87+
8188
// Check for a build configuration file in the target directory
8289
if let Ok(target_dir) = env::var("CARGO_TARGET_DIR") {
8390
let config_path = std::path::Path::new(&target_dir).join("uucore_target_util.txt");
@@ -156,6 +163,9 @@ fn embed_all_utilities_locales(
156163
// Discover all uu_* directories
157164
let src_uu_dir = project_root.join("src/uu");
158165
if !src_uu_dir.exists() {
166+
// When src/uu doesn't exist (e.g., standalone uucore from crates.io),
167+
// embed a static list of utility locales that are commonly used
168+
embed_static_utility_locales(embedded_file)?;
159169
return Ok(());
160170
}
161171

@@ -202,3 +212,60 @@ fn embed_all_utilities_locales(
202212
embedded_file.flush()?;
203213
Ok(())
204214
}
215+
216+
fn embed_static_utility_locales(
217+
embedded_file: &mut std::fs::File,
218+
) -> Result<(), Box<dyn std::error::Error>> {
219+
use std::env;
220+
221+
writeln!(
222+
embedded_file,
223+
" // Static utility locales for crates.io builds"
224+
)?;
225+
226+
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap_or_default();
227+
let Some(registry_dir) = Path::new(&manifest_dir).parent() else {
228+
return Ok(()); // nothing to scan
229+
};
230+
231+
// First, try to embed uucore locales - critical for common translations like "Usage:"
232+
let uucore_locale_file = Path::new(&manifest_dir).join("locales/en-US.ftl");
233+
if uucore_locale_file.is_file() {
234+
let content = std::fs::read_to_string(&uucore_locale_file)?;
235+
writeln!(embedded_file, " // Common uucore locale")?;
236+
writeln!(
237+
embedded_file,
238+
" locales.insert(\"uucore/en-US.ftl\", r###\"{content}\"###);"
239+
)?;
240+
writeln!(embedded_file)?;
241+
}
242+
243+
// Collect and sort for deterministic builds
244+
let mut entries: Vec<_> = std::fs::read_dir(registry_dir)?
245+
.filter_map(Result::ok)
246+
.collect();
247+
entries.sort_by_key(|e| e.file_name());
248+
249+
for entry in entries {
250+
let file_name = entry.file_name();
251+
if let Some(dir_name) = file_name.to_str() {
252+
// Match uu_<util>-<version>
253+
if let Some((util_part, _)) = dir_name.split_once('-') {
254+
if let Some(util_name) = util_part.strip_prefix("uu_") {
255+
let locale_file = entry.path().join("locales/en-US.ftl");
256+
if locale_file.is_file() {
257+
let content = std::fs::read_to_string(&locale_file)?;
258+
writeln!(embedded_file, " // Locale for {util_name}")?;
259+
writeln!(
260+
embedded_file,
261+
" locales.insert(\"{util_name}/en-US.ftl\", r###\"{content}\"###);"
262+
)?;
263+
writeln!(embedded_file)?;
264+
}
265+
}
266+
}
267+
}
268+
}
269+
270+
Ok(())
271+
}

util/test_locale_regression.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/bin/bash
2+
3+
echo "Testing embedded locale functionality to prevent crates.io regression..."
4+
INSTALL_DIR="$(pwd)/test-install-dir"
5+
rm -rf "$INSTALL_DIR"
6+
mkdir -p "$INSTALL_DIR"
7+
utilities_to_test=("cp" "mv" "ln")
8+
9+
for util in "${utilities_to_test[@]}"; do
10+
echo "Testing $util..."
11+
cargo install --path "src/uu/$util" --root "$INSTALL_DIR" --force --quiet
12+
binary_path="$INSTALL_DIR/bin/$util"
13+
help_output=$("$binary_path" --help 2>&1)
14+
15+
# Check for regression indicators
16+
if echo "$help_output" | grep -q "common-usage"; then
17+
echo "✗ CRITICAL REGRESSION: $util shows untranslated 'common-usage' key"
18+
echo "Help output:"
19+
echo "$help_output"
20+
exit 1
21+
fi
22+
23+
# Verify proper "Usage:" label
24+
if echo "$help_output" | grep -q "Usage:"; then
25+
echo "$util shows properly translated 'Usage:' label"
26+
else
27+
echo "✗ CRITICAL REGRESSION: $util missing 'Usage:' label"
28+
echo "Help output:"
29+
echo "$help_output"
30+
exit 1
31+
fi
32+
done
33+
34+
echo "All tests passed!"

0 commit comments

Comments
 (0)