in focus/internals/src/lib/index/content_hash.rs [166:209]
fn content_hash_dependency_key(ctx: &HashContext, key: DependencyKey) -> Result<ContentHash> {
debug!(?key, "Hashing dependency key");
{
let cache = &mut ctx.caches.borrow_mut().dependency_key_cache;
if let Some(hash) = cache.get(&key) {
return Ok(hash.to_owned());
}
}
let (kind, maybe_label, values_to_hash) = get_dependencies(ctx, &key)?;
let mut buf = String::new();
write!(&mut buf, "DependencyKeyV{VERSION}::{kind}(")?;
if let Some(label) = maybe_label {
write!(&mut buf, "{label}, ")?;
}
let hashes = values_to_hash
.into_iter()
.map(|key_or_hash| match key_or_hash {
KeyOrPath::Key(dep_key) => content_hash_dependency_key(ctx, dep_key),
KeyOrPath::Path(path) => content_hash_tree_path(ctx, path),
})
.collect::<Result<Vec<_>>>()?;
for hash in hashes {
write!(&mut buf, "{hash}, ")?;
}
write!(&mut buf, ")")?;
let hash = git2::Oid::hash_object(git2::ObjectType::Blob, buf.as_bytes())
.map_err(Error::HashObject)?;
let hash = ContentHash(hash);
if let Some(old_value) = ctx
.caches
.borrow_mut()
.dependency_key_cache
.insert(key.to_owned(), hash.clone())
{
if old_value != hash {
error!(?key, ?old_value, new_value = ?hash, "Non-deterministic content hashing for dependency key");
}
}
Ok(hash)
}