use std::path::Path;
use std::process::Command;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("cargo:rerun-if-changed=proto/peerman.proto");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=frontend/src");
println!("cargo:rerun-if-changed=frontend/package.json");
println!("cargo:rerun-if-changed=frontend/vite.config.ts");
tonic_build::configure()
.build_server(true)
.build_client(true)
.compile_protos(&["proto/peerman.proto"], &["proto"])?;
let frontend_dir = Path::new("frontend");
let dist_dir = frontend_dir.join("dist");
if std::env::var("SKIP_FRONTEND_BUILD").is_ok() {
println!("cargo:warning=SKIP_FRONTEND_BUILD set, skipping frontend build");
if !dist_dir.exists() {
std::fs::create_dir_all(&dist_dir)?;
std::fs::write(dist_dir.join("index.html"), "<!-- placeholder -->")?;
}
return Ok(());
}
if frontend_dir.join("package.json").exists() {
println!("cargo:warning=Building frontend with pnpm...");
let install = Command::new("pnpm")
.args(["install", "--frozen-lockfile"])
.current_dir(frontend_dir)
.status();
if install.is_err() {
println!(
"cargo:warning=pnpm not available, skipping frontend build (use pre-built dist/)"
);
if !dist_dir.exists() {
std::fs::create_dir_all(&dist_dir)?;
std::fs::write(dist_dir.join("index.html"), "<!-- placeholder -->")?;
}
return Ok(());
}
let status = Command::new("pnpm")
.args(["run", "build"])
.current_dir(frontend_dir)
.status();
match status {
Ok(s) if s.success() => println!("cargo:warning=Frontend build succeeded"),
Ok(s) => panic!("Frontend build failed with exit code: {:?}", s.code()),
Err(_) => panic!("pnpm build command failed"),
}
}
Ok(())
}