fabro/lib/foundation/build-support/git_metadata.rs
2026-07-23 17:59:34 -04:00

67 lines
1.9 KiB
Rust

use std::path::{Path, PathBuf};
use std::process::Command;
#[derive(Debug, Eq, PartialEq)]
pub struct BuildGitMetadata {
pub rerun_paths: Vec<PathBuf>,
pub short_sha: String,
}
pub fn collect_from(package_dir: &Path) -> BuildGitMetadata {
let mut rerun_paths = Vec::new();
if let Some(head_path) = git_output(package_dir, ["rev-parse", "--git-path", "HEAD"]) {
rerun_paths.push(PathBuf::from(head_path));
}
if let Some(head_ref) = git_output(package_dir, ["symbolic-ref", "-q", "HEAD"]) {
if let Some(ref_path) = git_output(package_dir, ["rev-parse", "--git-path", &head_ref]) {
rerun_paths.push(PathBuf::from(ref_path));
}
}
let short_sha = git_output(package_dir, ["rev-list", "-1", "HEAD"])
.map(|sha| {
if sha.len() >= 7 {
sha[..7].to_string()
} else {
sha
}
})
.unwrap_or_default();
BuildGitMetadata {
rerun_paths,
short_sha,
}
}
#[expect(
clippy::disallowed_methods,
reason = "Build scripts read Cargo-provided PROFILE outside application runtime configuration."
)]
pub fn cargo_profile() -> String {
std::env::var("PROFILE").unwrap_or_default()
}
#[expect(
clippy::disallowed_methods,
reason = "Build scripts run outside Tokio and need synchronous git probes for embedded build metadata."
)]
fn git_output<const N: usize>(package_dir: &Path, args: [&str; N]) -> Option<String> {
Command::new("git")
.current_dir(package_dir)
.args(args)
.output()
.ok()
.and_then(|output| {
if output.status.success() {
String::from_utf8(output.stdout)
.ok()
.map(|output| output.trim().to_string())
} else {
None
}
})
.filter(|output| !output.is_empty())
}