crates/knut-bifrost/build.rs
//! Build script: stamp the commit identity into the binary.
//!
//! Emits `cargo:rustc-env=KNUT_GIT_HASH=<short sha>` — the short git commit the
//! binary was built from — read from git metadata as **plain files only**: NO
//! `git`, NO `std::process::Command`, NO shell (the nordisk pure-Rust zero-shell
//! law — build code is production code; it must not shell out). `knut-bifrost`
//! is a workspace member (`crates/knut-bifrost`), so the emitter walks up from
//! `CARGO_MANIFEST_DIR` to find the repo `.git`. Handles a normal `.git` dir, a
//! linked-worktree `.git` FILE (`gitdir:` → its own HEAD, shared `commondir` for
//! refs), a detached HEAD, loose refs, and `packed-refs`. Falls back to
//! `unknown` so `env!("KNUT_GIT_HASH")` always resolves (e.g. a tarball build).
fn main() {
emit_git_hash();
println!("cargo:rerun-if-changed=build.rs");
}
fn emit_git_hash() {
use std::path::{Path, PathBuf};
fn find_git_dir(start: &Path) -> Option<PathBuf> {
let mut cur = Some(start);
while let Some(d) = cur {
let g = d.join(".git");
if g.is_dir() {
return Some(g);
}
if g.is_file() {
if let Ok(s) = std::fs::read_to_string(&g) {
if let Some(p) = s.lines().find_map(|l| l.strip_prefix("gitdir:")) {
return Some(PathBuf::from(p.trim()));
}
}
}
cur = d.parent();
}
None
}
fn resolve(git_dir: &Path) -> Option<String> {
let head_path = git_dir.join("HEAD");
let head = std::fs::read_to_string(&head_path).ok()?;
println!("cargo:rerun-if-changed={}", head_path.display());
let head = head.trim();
// Shared common dir (linked worktree keeps refs/packed-refs there).
let common = std::fs::read_to_string(git_dir.join("commondir"))
.ok()
.map(|s| git_dir.join(s.trim()))
.and_then(|p| std::fs::canonicalize(&p).ok())
.unwrap_or_else(|| git_dir.to_path_buf());
if let Some(reference) = head.strip_prefix("ref:") {
let reference = reference.trim();
let loose = common.join(reference);
if let Ok(s) = std::fs::read_to_string(&loose) {
println!("cargo:rerun-if-changed={}", loose.display());
return Some(s.trim().to_string());
}
let packed_path = common.join("packed-refs");
println!("cargo:rerun-if-changed={}", packed_path.display());
let packed = std::fs::read_to_string(&packed_path).ok()?;
return packed.lines().find_map(|l| {
let l = l.trim();
if l.starts_with('#') || l.starts_with('^') {
return None;
}
let (sha, name) = l.split_once(' ')?;
(name == reference).then(|| sha.to_string())
});
}
// Detached HEAD: the file IS the object id.
Some(head.to_string())
}
let manifest = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR set by cargo");
let hash = find_git_dir(Path::new(&manifest))
.and_then(|g| resolve(&g))
.map(|sha| sha.chars().take(7).collect::<String>())
.filter(|s| s.len() == 7 && s.bytes().all(|b| b.is_ascii_hexdigit()))
.unwrap_or_else(|| "unknown".to_string());
println!("cargo:rustc-env=KNUT_GIT_HASH={hash}");
}