use std::process::Command; fn main() { println!("cargo:rerun-if-env-changed=METACRATE_RUST_COMMIT"); println!("cargo:rerun-if-changed=../.git/HEAD"); println!("cargo:rerun-if-changed=../.git/packed-refs"); if let Some(reference) = git_reference() { println!("cargo:rerun-if-changed=../.git/{reference}"); } let commit = std::env::var("METACRATE_RUST_COMMIT") .ok() .filter(|value| valid_commit(value)) .or_else(git_commit) .unwrap_or_else(|| "unavailable".to_owned()); println!("cargo:rustc-env=METACRATE_RUST_COMMIT={commit}"); } fn git_reference() -> Option { let output = Command::new("git") .args(["symbolic-ref", "--quiet", "HEAD"]) .output() .ok()?; let reference = String::from_utf8(output.stdout).ok()?; let reference = reference.trim(); (output.status.success() && reference.starts_with("refs/") && reference .bytes() .all(|byte| byte.is_ascii_alphanumeric() || b"/-_.".contains(&byte))) .then(|| reference.to_owned()) } fn git_commit() -> Option { let output = Command::new("git") .args(["rev-parse", "--verify", "HEAD"]) .output() .ok()?; let commit = String::from_utf8(output.stdout).ok()?; let commit = commit.trim(); (output.status.success() && valid_commit(commit)).then(|| commit.to_owned()) } fn valid_commit(value: &str) -> bool { matches!(value.len(), 40 | 64) && value.bytes().all(|byte| byte.is_ascii_hexdigit()) }