use std::process::Command;
fn main() {
let commit = env_override("WT_BUILD_SHA").or_else(|| {
git(&["rev-parse", "--short=12", "HEAD"]).map(|sha| {
if is_dirty() {
format!("{sha}-dirty")
} else {
sha
}
})
});
let commit_date = git(&["log", "-1", "--format=%cI"]);
emit("WT_COMMIT_HASH", commit.as_deref().unwrap_or("unknown"));
emit(
"WT_COMMIT_DATE",
commit_date.as_deref().unwrap_or("unknown"),
);
emit("WT_BUILD_PROFILE", &env_or("PROFILE", "unknown"));
emit("WT_RUSTC_VERSION", &rustc_version());
emit("WT_BUILD_TIMESTAMP", &build_timestamp());
if let Some(git_dir) = git(&["rev-parse", "--absolute-git-dir"]) {
println!("cargo::rerun-if-changed={git_dir}/HEAD");
}
println!("cargo::rerun-if-changed=build.rs");
println!("cargo::rerun-if-env-changed=SOURCE_DATE_EPOCH");
println!("cargo::rerun-if-env-changed=WT_BUILD_SHA");
}
fn env_override(key: &str) -> Option<String> {
std::env::var(key)
.ok()
.map(|value| value.trim().to_string())
.filter(|value| !value.is_empty())
}
fn emit(key: &str, value: &str) {
println!("cargo::rustc-env={key}={value}");
}
fn git(args: &[&str]) -> Option<String> {
let output = Command::new("git").args(args).output().ok()?;
if !output.status.success() {
return None;
}
let text = String::from_utf8(output.stdout).ok()?;
let trimmed = text.trim();
if trimmed.is_empty() {
None
} else {
Some(trimmed.to_string())
}
}
fn is_dirty() -> bool {
Command::new("git")
.args(["status", "--porcelain"])
.output()
.map(|o| o.status.success() && !o.stdout.is_empty())
.unwrap_or(false)
}
fn rustc_version() -> String {
let rustc = env_or("RUSTC", "rustc");
Command::new(rustc)
.arg("--version")
.output()
.ok()
.filter(|o| o.status.success())
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|s| s.trim().to_string())
.unwrap_or_else(|| "unknown".to_string())
}
fn build_timestamp() -> String {
let ts = match std::env::var("SOURCE_DATE_EPOCH")
.ok()
.and_then(|s| s.parse().ok())
{
Some(epoch) => jiff::Timestamp::from_second(epoch).ok(),
None => Some(jiff::Timestamp::now()),
};
ts.map(|t| t.strftime("%Y-%m-%dT%H:%M:%SZ").to_string())
.unwrap_or_else(|| "unknown".to_string())
}
fn env_or(key: &str, default: &str) -> String {
std::env::var(key).unwrap_or_else(|_| default.to_string())
}