fn content_hash_dependency_key()

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)
}