use std::path::PathBuf;
use std::process::Command;
const STRATA_PACKS: [&str; 6] = [
"strata-cas-pack",
"strata-protocol-pack",
"strata-signer-pack",
"strata-stratus-pack",
"strata-temprun-pack",
"strata-valve-pack",
];
const ZERO_DIGEST: &str = "0000000000000000000000000000000000000000000000000000000000000000";
fn main() {
println!("cargo:rerun-if-env-changed=GGEN_STRATA_ROOT");
println!("cargo:rerun-if-changed=build.rs");
let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap_or_default());
let strata_root = std::env::var("GGEN_STRATA_ROOT").ok().map(PathBuf::from).or_else(
|| {
manifest_dir
.ancestors()
.nth(3)
.map(|p| p.join("strata"))
.filter(|p| p.is_dir())
},
);
let (commit_sha, source) = match Command::new("git")
.args(["rev-parse", "HEAD"])
.current_dir(&manifest_dir)
.output()
{
Ok(out) if out.status.success() => {
let sha = String::from_utf8_lossy(&out.stdout).trim().to_string();
if sha.len() == 40 && sha.chars().all(|c| c.is_ascii_hexdigit()) {
(sha, "git")
} else {
("unknown".to_string(), "crates.io")
}
}
_ => ("unknown".to_string(), "crates.io"),
};
println!("cargo:rustc-env=GGEN_BUILD_COMMIT_SHA={commit_sha}");
println!("cargo:rustc-env=GGEN_BUILD_SOURCE={source}");
let pack_roots: Vec<PathBuf> = strata_root
.as_ref()
.map(|root| {
let mut v = vec![root.join("packs")];
if let Some(mkt) = root.parent().map(|p| p.join("ggen-marketplace").join("packs")) {
v.push(mkt);
}
v
})
.unwrap_or_default();
let pack_toml = |name: &str| -> Option<(PathBuf, Vec<u8>)> {
pack_roots
.iter()
.map(|r| r.join(name).join("pack.toml"))
.find_map(|p| std::fs::read(&p).ok().map(|b| (p, b)))
};
let mut pack_binding = String::new();
let mut hasher = blake3::Hasher::new();
hasher.update(commit_sha.as_bytes());
for name in STRATA_PACKS {
let (path, digest) = match pack_toml(name) {
Some((path, bytes)) => {
let d = blake3::hash(&bytes).to_hex().to_string();
(path, d)
}
None => (PathBuf::from("build.rs"), ZERO_DIGEST.to_string()),
};
println!("cargo:rerun-if-changed={}", path.display());
if !pack_binding.is_empty() {
pack_binding.push(';');
}
pack_binding.push_str(name);
pack_binding.push('=');
pack_binding.push_str(&digest);
hasher.update(name.as_bytes());
hasher.update(digest.as_bytes());
}
println!("cargo:rustc-env=GGEN_BUILD_STRATA_PACKS={pack_binding}");
let triple_count = strata_root
.as_ref()
.and_then(|root| std::fs::read_to_string(root.join("ontology.ttl")).ok())
.map_or(0, |ttl| {
ttl.lines()
.filter(|line| !line.trim_start().starts_with('#'))
.filter(|line| line.trim_end().ends_with('.') && !line.trim().is_empty())
.count()
});
println!("cargo:rustc-env=GGEN_BUILD_ONTOLOGY_TRIPLES={triple_count}");
if let Some(root) = &strata_root {
println!("cargo:rerun-if-changed={}", root.join("ontology.ttl").display());
}
hasher.update(triple_count.to_string().as_bytes());
let provenance_hex = hasher.finalize().to_hex().to_string();
println!("cargo:rustc-env=GGEN_BUILD_PROVENANCE_HEX={provenance_hex}");
}