use std::path::{Path, PathBuf};
use sha2::{Digest, Sha256};
fn main() {
let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let crates_dir = manifest_dir.parent().expect("crate dir has a parent");
let roots = [
crates_dir.join("harn-lexer").join("src"),
crates_dir.join("harn-parser").join("src"),
crates_dir.join("harn-ir").join("src"),
manifest_dir.join("src").join("compiler"),
];
let single_files = [manifest_dir.join("src").join("chunk.rs")];
let mut files = Vec::new();
for root in &roots {
collect_rs_files(root, &mut files);
}
for file in &single_files {
if file.is_file() {
files.push(file.clone());
}
}
files.sort();
let mut hasher = Sha256::new();
for path in &files {
println!("cargo:rerun-if-changed={}", path.display());
hasher.update(path.to_string_lossy().as_bytes());
hasher.update([0u8]);
if let Ok(bytes) = std::fs::read(path) {
hasher.update(&bytes);
}
}
for root in &roots {
println!("cargo:rerun-if-changed={}", root.display());
}
let digest = hasher.finalize();
let hex: String = digest.iter().map(|byte| format!("{byte:02x}")).collect();
println!("cargo:rustc-env=HARN_CODEGEN_FINGERPRINT={hex}");
}
fn collect_rs_files(dir: &Path, out: &mut Vec<PathBuf>) {
let Ok(entries) = std::fs::read_dir(dir) else {
return;
};
for entry in entries.flatten() {
let path = entry.path();
if path.is_dir() {
collect_rs_files(&path, out);
} else if path.extension().is_some_and(|ext| ext == "rs") {
out.push(path);
}
}
}