fn main() {
build_ui();
embed_assets();
}
fn build_ui() {
println!("cargo:rerun-if-changed=src/");
println!("cargo:rerun-if-changed=ui/src/");
println!("cargo:rerun-if-changed=ui/index.html");
println!("cargo:rerun-if-changed=ui/package.json");
println!("cargo:rerun-if-changed=ui/vite.config.js");
println!("cargo:rerun-if-changed=ui/svelte.config.js");
let path = std::env::var("PATH").unwrap_or_default();
let path = format!("/opt/homebrew/bin:/usr/local/bin:{path}");
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_default();
if manifest_dir.contains("/target/package/") {
return;
}
let pnpm_found = std::process::Command::new("pnpm")
.arg("--version")
.env("PATH", &path)
.output()
.map(|o| o.status.success())
.unwrap_or(false);
if !pnpm_found {
if !std::path::Path::new("ui/dist/index.html").exists() {
panic!(
"pnpm not found and ui/dist/index.html is missing; \
run: pnpm --dir ui install && pnpm --dir ui build"
);
}
return;
}
let installed = std::process::Command::new("pnpm")
.args(["--dir", "ui", "install", "--frozen-lockfile"])
.env("PATH", &path)
.status()
.map(|s| s.success())
.unwrap_or(false);
let built = installed
&& std::process::Command::new("pnpm")
.args(["--dir", "ui", "build"])
.env("PATH", &path)
.status()
.map(|s| s.success())
.unwrap_or(false);
if !built {
panic!(
"UI build failed; run manually: \
pnpm --dir ui install && pnpm --dir ui build"
);
}
}
fn embed_assets() {
let dir =
std::path::Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()).join("ui/dist/assets");
let mut names: Vec<String> = std::fs::read_dir(&dir)
.unwrap_or_else(|e| panic!("reading {}: {e}; build the UI first", dir.display()))
.filter_map(|entry| entry.ok())
.filter(|entry| entry.path().is_file())
.map(|entry| entry.file_name().to_string_lossy().into_owned())
.collect();
names.sort();
let mut out = String::from("pub static UI_ASSETS: &[(&str, &[u8])] = &[\n");
for name in &names {
out.push_str(&format!(
" ({name:?}, include_bytes!({:?})),\n",
dir.join(name).display().to_string()
));
}
out.push_str("];\n");
let dest = std::path::Path::new(&std::env::var("OUT_DIR").unwrap()).join("ui_assets.rs");
std::fs::write(&dest, out).unwrap_or_else(|e| panic!("writing {}: {e}", dest.display()));
}