Gunnar

nordisk/korp-collectors

build.rs

//! Pure-filesystem git-hash stamp — **zero shell, zero `Command`, zero `git`**
//! (the pure-Rust / zero-shell LAW). We read `.git` state off disk ourselves and
//! export the resolved commit as `COLLECTORS_GIT_HASH`, which `--version`/`-V` and
//! the daemon health surface surface at runtime.
//!
//! Handles: a normal `.git` directory, a `.git` **file** (worktree / submodule:
//! `gitdir: <path>`), a symbolic `HEAD` (`ref: refs/heads/<branch>`) resolved
//! against loose refs OR `packed-refs`, a **detached** HEAD (raw 40-hex sha), and
//! the worktree `commondir` split (HEAD lives in the per-worktree gitdir, refs in
//! the common dir). Anything unresolvable falls back to `unknown` — the build
//! never fails for want of a hash.

use std::fs;
use std::path::{Path, PathBuf};

fn main() {
    let manifest_dir =
        PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into()));
    let hash = resolve_git_hash(&manifest_dir).unwrap_or_else(|| "unknown".to_string());
    println!("cargo:rustc-env=COLLECTORS_GIT_HASH={hash}");
}

/// Resolve HEAD to a commit sha using only filesystem reads. `None` → caller
/// falls back to `unknown`.
fn resolve_git_hash(manifest_dir: &Path) -> Option<String> {
    let git_dir = locate_git_dir(manifest_dir)?;
    // The common dir holds packed-refs + refs/heads when HEAD lives in a worktree
    // gitdir. `commondir` is a one-line file (relative to `git_dir` or absolute).
    let common_dir = match fs::read_to_string(git_dir.join("commondir")) {
        Ok(rel) => {
            let rel = rel.trim();
            let p = PathBuf::from(rel);
            if p.is_absolute() { p } else { git_dir.join(p) }
        }
        Err(_) => git_dir.clone(),
    };

    let head_path = git_dir.join("HEAD");
    rerun_if_changed(&head_path);
    let head = fs::read_to_string(&head_path).ok()?;
    let head = head.trim();

    if let Some(reference) = head.strip_prefix("ref:") {
        let reference = reference.trim();
        // Prefer a loose ref in the worktree gitdir, then the common dir, then
        // packed-refs.
        for base in [&git_dir, &common_dir] {
            let loose = base.join(reference);
            if let Ok(sha) = fs::read_to_string(&loose) {
                rerun_if_changed(&loose);
                let sha = sha.trim();
                if !sha.is_empty() {
                    return Some(sha.to_string());
                }
            }
        }
        // packed-refs: lines of `<sha> <refname>`, skip `#` comments and `^` peels.
        let packed = common_dir.join("packed-refs");
        rerun_if_changed(&packed);
        let packed = fs::read_to_string(&packed).ok()?;
        for line in packed.lines() {
            let line = line.trim();
            if line.is_empty() || line.starts_with('#') || line.starts_with('^') {
                continue;
            }
            if let Some((sha, name)) = line.split_once(' ') {
                if name.trim() == reference {
                    return Some(sha.trim().to_string());
                }
            }
        }
        None
    } else if is_hex_sha(head) {
        // Detached HEAD — the raw commit sha.
        Some(head.to_string())
    } else {
        None
    }
}

/// Find the real git dir for `manifest_dir`. `.git` is normally a directory but is
/// a `gitdir: <path>` pointer file inside a worktree or submodule.
fn locate_git_dir(manifest_dir: &Path) -> Option<PathBuf> {
    let dot_git = manifest_dir.join(".git");
    let meta = fs::metadata(&dot_git).ok()?;
    if meta.is_dir() {
        return Some(dot_git);
    }
    if meta.is_file() {
        let contents = fs::read_to_string(&dot_git).ok()?;
        let rel = contents.trim().strip_prefix("gitdir:")?.trim();
        let p = PathBuf::from(rel);
        return Some(if p.is_absolute() {
            p
        } else {
            manifest_dir.join(p)
        });
    }
    None
}

fn is_hex_sha(s: &str) -> bool {
    s.len() >= 7 && s.chars().all(|c| c.is_ascii_hexdigit())
}

fn rerun_if_changed(p: &Path) {
    // Only meaningful for paths that exist; harmless otherwise (cargo just watches
    // for it to appear).
    println!("cargo:rerun-if-changed={}", p.display());
}