diff --git a/crates/re_build_tools/src/hashing.rs b/crates/re_build_tools/src/hashing.rs index 1c9f8fd5aed3..f734651b8fa4 100644 --- a/crates/re_build_tools/src/hashing.rs +++ b/crates/re_build_tools/src/hashing.rs @@ -5,6 +5,8 @@ use std::{fs, io}; use anyhow::Context as _; use sha2::{Digest, Sha256}; +use crate::{rerun_if_changed, rerun_if_changed_or_doesnt_exist}; + // --- fn encode_hex(bytes: &[u8]) -> String { @@ -18,7 +20,7 @@ fn encode_hex(bytes: &[u8]) -> String { /// Walks the directory at `path` in filename order. /// /// If `extensions` is specified, only files with the right extensions will be iterated. -/// Specified extensions should include the dot, e.g. `.fbs`. +/// Specified extensions should _not_ include the leading dot, e.g. `fbs` rather than `.fbs`. pub fn iter_dir<'a>( path: impl AsRef, extensions: Option<&'a [&'a str]>, @@ -28,9 +30,9 @@ pub fn iter_dir<'a>( let is_interesting = extensions.map_or(true, |extensions| { extensions.iter().any(|ext| { entry - .file_name() - .to_str() - .map_or(false, |s| s.ends_with(ext)) + .path() + .extension() + .map_or(false, |ext2| *ext == ext2.to_string_lossy()) }) }); is_dir || is_interesting @@ -48,6 +50,8 @@ pub fn iter_dir<'a>( /// Given a file path, computes the sha256 hash of its contents and returns an hexadecimal string /// for it. /// +/// This will automatically emit a `rerun-if-changed` clause for the specified file. +/// /// Panics if the file doesn't exist. pub fn compute_file_hash(path: impl AsRef) -> String { let mut hasher = Sha256::new(); @@ -60,6 +64,8 @@ pub fn compute_file_hash(path: impl AsRef) -> String { .with_context(|| format!("couldn't copy from {path:?}")) .unwrap(); + rerun_if_changed(path); + encode_hex(hasher.finalize().as_slice()) } @@ -68,8 +74,10 @@ pub fn compute_file_hash(path: impl AsRef) -> String { /// /// This includes files in sub-directories (i.e. it's recursive). /// -/// If `extensions` is specified, only files with the right extensions will be hashed. -/// Specified extensions should include the dot, e.g. `.fbs`. +/// This will automatically emit a `rerun-if-changed` clause for all the files that were hashed. +/// +/// If `extensions` is specified, only files with the right extensions will be iterated. +/// Specified extensions should _not_ include the leading dot, e.g. `fbs` rather than `.fbs`. pub fn compute_dir_hash<'a>(path: impl AsRef, extensions: Option<&'a [&'a str]>) -> String { let mut hasher = Sha256::new(); @@ -81,6 +89,8 @@ pub fn compute_dir_hash<'a>(path: impl AsRef, extensions: Option<&'a [&'a io::copy(&mut file, &mut hasher) .with_context(|| format!("couldn't copy from {filepath:?}")) .unwrap(); + + rerun_if_changed(path); } encode_hex(hasher.finalize().as_slice()) @@ -90,6 +100,8 @@ pub fn compute_dir_hash<'a>(path: impl AsRef, extensions: Option<&'a [&'a /// returns an hexadecimal string for it. /// /// This includes the source code of all its direct and indirect dependencies. +/// +/// This will automatically emit a `rerun-if-changed` clause for all the files that were hashed. pub fn compute_crate_hash(pkg_name: impl AsRef) -> String { use cargo_metadata::{CargoOpt, MetadataCommand}; let metadata = MetadataCommand::new() @@ -126,6 +138,9 @@ pub fn compute_strings_hash(strs: &[&str]) -> String { /// Writes the given `hash` at the specified `path`. /// +/// `hash` should have been computed using of the methods in this module: [`compute_file_hash`], +/// [`compute_dir_hash`], [`compute_crate_hash`]. +/// /// Panics on I/O errors. /// /// Use [`read_versioning_hash`] to read it back. @@ -148,9 +163,16 @@ pub fn write_versioning_hash(path: impl AsRef, hash: impl AsRef) { /// Reads back a versioning hash that was written with [`write_versioning_hash`]. /// +/// This will automatically emit a `rerun-if-changed` clause for the specified filepath. +/// /// Returns `None` on error. pub fn read_versioning_hash(path: impl AsRef) -> Option { let path = path.as_ref(); + + // NOTE: It's important we trigger if the file doesn't exist, as this means the user explicitly + // deleted the versioning file, i.e. they're trying to force a rebuild. + rerun_if_changed_or_doesnt_exist(path); + std::fs::read_to_string(path).ok().and_then(|contents| { contents .lines()