use std::env;
use std::path::PathBuf;
fn main() {
println!("cargo:rerun-if-env-changed=CARGO_MANIFEST_DIR");
let manifest_dir = PathBuf::from(
env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is set by cargo for build scripts"),
);
let workspace_root = find_workspace_root(&manifest_dir).unwrap_or_else(|| {
panic!(
"could not locate the DOMicile workspace root by walking up from {}. \
Expected a Cargo.toml with a [workspace] table somewhere above this crate.",
manifest_dir.display()
)
});
println!("cargo:rerun-if-changed={}", workspace_root.join("Cargo.toml").display());
let shim_path = workspace_root
.join("scripts")
.join("runtime")
.join("domi-server.js");
println!("cargo:rerun-if-changed={}", shim_path.display());
let bytes = std::fs::read(&shim_path).unwrap_or_else(|e| {
panic!(
"domi-server.js shim not found at {}: {e}. \
The Rust crate embeds the JS shim at compile time; \
the file must live at <workspace-root>/scripts/runtime/domi-server.js.",
shim_path.display()
)
});
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR is set by cargo"));
let declared_len = bytes.len();
std::fs::write(
out_dir.join("shim_length.rs"),
format!("pub const SHIM_BYTES_LEN: usize = {declared_len};\n"),
)
.expect("write shim_length.rs");
std::fs::write(
out_dir.join("shim_token.rs"),
format!(
"pub const SHIM_BYTES: &[u8] = include_bytes!(\"{}\");\n",
shim_path.display()
),
)
.expect("write shim_token.rs");
}
fn find_workspace_root(start: &std::path::Path) -> Option<PathBuf> {
let mut current = start.parent().map(PathBuf::from);
while let Some(dir) = current {
let manifest = dir.join("Cargo.toml");
if manifest.is_file() && has_workspace_table(&manifest) {
return Some(dir);
}
current = dir.parent().map(PathBuf::from);
}
None
}
fn has_workspace_table(manifest: &std::path::Path) -> bool {
std::fs::read_to_string(manifest)
.map(|s| s.contains("[workspace]"))
.unwrap_or(false)
}