use std::{
env, fs,
path::{Path, PathBuf},
process::Command,
};
pub fn compile_translations(po_dir: impl AsRef<Path>, locale_dir: impl AsRef<Path>) {
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap_or_default());
let abs = |p: &Path| if p.is_absolute() { p.to_path_buf() } else { manifest_dir.join(p) };
let po_dir = abs(po_dir.as_ref());
let locale_dir = abs(locale_dir.as_ref());
let domain = env::var("CARGO_PKG_NAME").unwrap_or_default();
println!("cargo:rerun-if-changed={}", po_dir.display());
println!("cargo:rerun-if-changed={}", locale_dir.display());
if let Ok(profile) = env::var("PROFILE") {
println!("cargo:rustc-env=PROFILE={profile}");
}
let entries = match fs::read_dir(&po_dir) {
Ok(e) => e,
Err(e) => {
println!("cargo:warning=patois-build: could not read {}: {e}", po_dir.display());
return;
}
};
for entry in entries {
let path = match entry {
Ok(e) => e.path(),
Err(e) => {
println!("cargo:warning=patois-build: {e}");
continue;
}
};
if path.extension().and_then(|e| e.to_str()) != Some("po") {
continue;
}
let lang = match path.file_stem().and_then(|s| s.to_str()) {
Some(l) => l.to_string(),
None => continue,
};
println!("cargo:rerun-if-changed={}", path.display());
let out_dir = locale_dir.join(&lang).join("LC_MESSAGES");
if let Err(e) = fs::create_dir_all(&out_dir) {
println!("cargo:warning=patois-build: could not create {}: {e}", out_dir.display());
continue;
}
run_msgfmt(&path, &out_dir.join(format!("{domain}.mo")));
}
}
fn run_msgfmt(input: &Path, output: &Path) {
match Command::new("msgfmt").arg("--use-fuzzy").arg("--no-hash").arg(input).arg("-o").arg(output).status() {
Ok(s) if s.success() => {}
Ok(s) => println!("cargo:warning=patois-build: msgfmt exited with {s} compiling {}", input.display()),
Err(e) => println!("cargo:warning=patois-build: msgfmt not available ({e}); install gettext tools"),
}
}