use std::process::Command;
fn main() {
println!("cargo:rustc-env=NEWGIT_BUILD={}", build_stamp());
println!("cargo:rerun-if-changed=../../.git/HEAD");
println!("cargo:rerun-if-changed=../../.git/refs/heads");
println!("cargo:rerun-if-changed=.cargo_vcs_info.json");
println!("cargo:rerun-if-env-changed=NEWGIT_BUILD");
}
fn build_stamp() -> String {
if let Ok(stamp) = std::env::var("NEWGIT_BUILD")
&& !stamp.trim().is_empty()
{
return stamp;
}
if let Some(commit) = packaged_commit() {
return commit;
}
let Some(commit) = git(&["rev-parse", "--short=12", "HEAD"]) else {
return "unknown".to_owned();
};
let dirty = git(&["status", "--porcelain"]).is_some_and(|out| !out.is_empty());
if dirty {
format!("{commit}-dirty")
} else {
commit
}
}
fn packaged_commit() -> Option<String> {
let raw = std::fs::read_to_string(".cargo_vcs_info.json").ok()?;
let after = raw.split_once("\"sha1\"")?.1.split_once(':')?.1;
let sha = after.split('"').nth(1)?;
if sha.len() != 40 || !sha.chars().all(|c| c.is_ascii_hexdigit()) {
return None;
}
let dirty = raw
.split_once("\"dirty\"")
.and_then(|(_, rest)| rest.split_once(':'))
.is_some_and(|(_, value)| value.trim_start().starts_with("true"));
if dirty {
Some(format!("{}-dirty", &sha[..12]))
} else {
Some(sha[..12].to_owned())
}
}
fn git(args: &[&str]) -> Option<String> {
let output = Command::new("git").args(args).output().ok()?;
if !output.status.success() {
return None;
}
Some(String::from_utf8_lossy(&output.stdout).trim().to_owned())
}