@@ -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+ }
0 commit comments