use std::env;
use std::path::Path;
use std::process::Command;
use std::fs;
fn main() {
println!("cargo:rerun-if-changed=../web/src");
println!("cargo:rerun-if-changed=../web/package.json");
if env::var("CARGO_FEATURE_EMBED_ASSETS").is_ok() {
let web_dir = Path::new("../web");
let dist_dir = web_dir.join("dist");
let local_dist = Path::new("web-dist");
let local_monaco = Path::new("monaco-editor");
if web_dir.exists() {
let needs_build = !dist_dir.exists()
|| !dist_dir.join("index.html").exists()
|| env::var("FORCE_FRONTEND_BUILD").is_ok();
if needs_build {
println!("cargo:warning=Building frontend assets for embedding...");
let output = Command::new("npm")
.args(&["run", "build"])
.current_dir(web_dir)
.output()
.expect("Failed to execute npm run build");
if !output.status.success() {
panic!(
"Failed to build frontend:\nstdout: {}\nstderr: {}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
}
println!("cargo:warning=Frontend build completed successfully");
}
if !local_dist.exists() {
println!("cargo:warning=Copying frontend assets for packaging...");
if let Err(e) = copy_dir_all(&dist_dir, local_dist) {
println!("cargo:warning=Failed to copy dist: {}", e);
}
}
} else {
println!("cargo:warning=Using pre-copied assets for packaging");
}
}
}
fn copy_dir_all(src: &Path, dst: &Path) -> std::io::Result<()> {
fs::create_dir_all(dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let ty = entry.file_type()?;
if ty.is_dir() {
copy_dir_all(&entry.path(), &dst.join(entry.file_name()))?;
} else {
fs::copy(entry.path(), dst.join(entry.file_name()))?;
}
}
Ok(())
}