use std::path::Path;
use std::process::Command;
fn main() {
let manifest = std::env::var("CARGO_MANIFEST_DIR").unwrap();
println!("cargo:rustc-check-cfg=cfg(holos_repository_tests)");
if Path::new(&manifest)
.join("../holos-tda-check/Cargo.toml")
.is_file()
{
println!("cargo:rustc-cfg=holos_repository_tests");
}
let hash = vcs_info_hash(&manifest)
.or_else(|| git_hash(&manifest))
.unwrap_or_else(|| "unknown".to_string());
println!("cargo:rustc-env=HOLOS_GIT_HASH={hash}");
let profile = std::env::var("PROFILE").unwrap_or_else(|_| "unknown".to_string());
println!("cargo:rustc-env=HOLOS_BUILD_PROFILE={profile}");
}
fn vcs_info_hash(manifest: &str) -> Option<String> {
let text = std::fs::read_to_string(Path::new(manifest).join(".cargo_vcs_info.json")).ok()?;
let i = text.find("\"sha1\":")? + "\"sha1\":".len();
let rest = text[i..].trim_start().strip_prefix('"')?;
let sha: String = rest.chars().take_while(|c| c.is_ascii_hexdigit()).collect();
(sha.len() >= 12).then(|| sha[..12].to_string())
}
fn git_hash(manifest: &str) -> Option<String> {
git_run(manifest, &["ls-files", "--error-unmatch", "Cargo.toml"])?;
watch_head(manifest);
let hash = git_run(manifest, &["rev-parse", "--short=12", "HEAD"])?;
(!hash.is_empty()).then_some(hash)
}
fn watch_head(manifest: &str) {
let Some(head) = git_file(manifest, "HEAD") else {
return;
};
if let Ok(text) = std::fs::read_to_string(&head) {
if let Some(r) = text.trim().strip_prefix("ref: ") {
if let Some(reference) = git_file(manifest, r) {
println!("cargo:rerun-if-changed={reference}");
}
}
}
println!("cargo:rerun-if-changed={head}");
if let Some(packed) = git_file(manifest, "packed-refs") {
println!("cargo:rerun-if-changed={packed}");
}
}
fn git_file(manifest: &str, name: &str) -> Option<String> {
let path = git_run(manifest, &["rev-parse", "--git-path", name])?;
let path = Path::new(manifest).join(path);
if !path.is_file() {
return None;
}
Some(path.to_str()?.to_string())
}
fn git_run(dir: &str, args: &[&str]) -> Option<String> {
let mut cmd = Command::new("git");
cmd.args(["-C", dir]).args(args);
let out = cmd.output().ok().filter(|o| o.status.success())?;
Some(String::from_utf8_lossy(&out.stdout).trim().to_string())
}