use std::collections::BTreeSet;
use std::path::{Path, PathBuf};
fn main() {
let hash = source_hash();
println!("cargo:rustc-env=RYO_COMMIT_HASH={}", hash);
println!("cargo:rerun-if-changed=../");
}
fn source_hash() -> String {
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let crates_dir = Path::new(&manifest_dir).parent().unwrap();
let files = collect_source_files(crates_dir);
let mut context = md5::Context::new();
for file in &files {
if let Ok(content) = std::fs::read(file) {
let rel_path = file.strip_prefix(crates_dir).unwrap_or(file);
context.consume(rel_path.to_string_lossy().as_bytes());
context.consume(&content);
}
}
let digest = context.compute();
format!("{:x}", digest)[..8].to_string()
}
fn collect_source_files(dir: &Path) -> BTreeSet<PathBuf> {
let mut files = BTreeSet::new();
collect_recursive(dir, &mut files);
files
}
fn collect_recursive(dir: &Path, files: &mut BTreeSet<PathBuf>) {
let Ok(entries) = std::fs::read_dir(dir) else {
return;
};
for entry in entries.flatten() {
let path = entry.path();
if let Some(name) = path.file_name().and_then(|n| n.to_str()) {
if name.starts_with('.') || name == "target" {
continue;
}
}
if path.is_dir() {
collect_recursive(&path, files);
} else if let Some(ext) = path.extension() {
if ext == "rs" || path.file_name().is_some_and(|n| n == "Cargo.toml") {
files.insert(path);
}
} else if path.file_name().is_some_and(|n| n == "Cargo.toml") {
files.insert(path);
}
}
}