vios_app 0.1.1

Small JSON vaults: Argon2id + AES-GCM, with optional AAD binding.
Documentation
// build.rs
use std::{
    env,
    process::Command,
    time::{SystemTime, UNIX_EPOCH},
};

fn main() {
    // Rebuild triggers (best-effort; harmless if not a git repo)
    println!("cargo:rerun-if-changed=.git/HEAD");
    println!("cargo:rerun-if-changed=.git/refs/heads");
    println!("cargo:rerun-if-changed=.git/packed-refs");
    println!("cargo:rerun-if-env-changed=TARGET");
    println!("cargo:rerun-if-env-changed=PROFILE");

    // --- Git metadata (optional) ---
    if let Some(sha) = run_and_trim("git", &["rev-parse", "--short", "HEAD"]) {
        println!("cargo:rustc-env=GIT_SHA={sha}");
    }
    if let Some(branch) = run_and_trim("git", &["rev-parse", "--abbrev-ref", "HEAD"]) {
        println!("cargo:rustc-env=GIT_BRANCH={branch}");
    }
    println!("cargo:rustc-env=GIT_DIRTY={}", git_dirty_flag());

    // --- rustc version (optional) ---
    if let Some(ver) = run_and_trim("rustc", &["-V"]) {
        println!("cargo:rustc-env=RUSTC_VERSION={ver}");
    }

    // --- Cargo env passthrough ---
    if let Ok(t) = env::var("TARGET") {
        println!("cargo:rustc-env=TARGET_TRIPLE={t}");
    }
    if let Ok(p) = env::var("PROFILE") {
        println!("cargo:rustc-env=BUILD_PROFILE={p}");
    }
    if let Ok(n) = env::var("CARGO_PKG_NAME") {
        println!("cargo:rustc-env=BUILD_PKG_NAME={n}");
    }
    if let Ok(v) = env::var("CARGO_PKG_VERSION") {
        println!("cargo:rustc-env=BUILD_PKG_VERSION={v}");
    }

    // --- Build timestamp (UNIX seconds, std-only) ---
    println!("cargo:rustc-env=BUILD_TIME_UNIX={}", now_unix_secs());
}

fn run_and_trim(cmd: &str, args: &[&str]) -> Option<String> {
    let output = Command::new(cmd).args(args).output().ok()?;
    if !output.status.success() {
        return None;
    }
    let s = String::from_utf8_lossy(&output.stdout).trim().to_string();
    if s.is_empty() {
        None
    } else {
        Some(s)
    }
}

fn git_dirty_flag() -> &'static str {
    if let Ok(status) = Command::new("git").args(["diff", "--quiet"]).status() {
        return if status.success() { "clean" } else { "dirty" };
    }
    if let Some(out) = run_and_trim("git", &["status", "--porcelain"]) {
        return if out.is_empty() { "clean" } else { "dirty" };
    }
    "unknown"
}

fn now_unix_secs() -> String {
    let secs = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap_or_default()
        .as_secs();
    secs.to_string()
}