feat(tvix/eval): implement builtins.hashFile

The primary addition is the `builtin_hashFile` function which attempts
value-path coercion and on success reads the file to a nix_string.
Similar to the `builtins_hashString` implementation, the hash is then
derived using the `hash_nix_string` function in the introduced hash
module which has extracted hashing functionality initially specified in
cl/11005.

Change-Id: I5e3ef0317223af99488ebb79efc2fb49b4cbc1b6
Reviewed-on: https://cl.tvl.fyi/c/depot/+/11007
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
This commit is contained in:
Padraic-O-Mhuiris 2024-02-22 15:33:29 +00:00 committed by Pádraic Ó Mhuiris
parent 5acaa672ac
commit e0ffb4d47a
6 changed files with 42 additions and 25 deletions

View file

@ -5,14 +5,9 @@
use bstr::{ByteSlice, ByteVec};
use builtin_macros::builtins;
use data_encoding::HEXLOWER;
use genawaiter::rc::Gen;
use imbl::OrdMap;
use md5::Md5;
use regex::Regex;
use sha1::Sha1;
use sha2::digest::Output;
use sha2::{Digest, Sha256, Sha512};
use std::cmp::{self, Ordering};
use std::collections::VecDeque;
use std::collections::{BTreeMap, HashSet};
@ -24,12 +19,14 @@ use crate::vm::generators::{self, GenCo};
use crate::warnings::WarningKind;
use crate::{
self as tvix_eval,
builtins::hash::hash_nix_string,
errors::{CatchableErrorKind, ErrorKind},
value::{CoercionKind, NixAttrs, NixList, NixString, Thunk, Value},
};
use self::versions::{VersionPart, VersionPartsIter};
mod hash;
mod to_xml;
mod versions;
@ -692,23 +689,7 @@ mod pure_builtins {
#[builtin("hashString")]
#[allow(non_snake_case)]
async fn builtin_hashString(co: GenCo, algo: Value, s: Value) -> Result<Value, ErrorKind> {
fn hash<D: Digest>(b: &[u8]) -> Output<D> {
let mut hasher = D::new();
hasher.update(b);
hasher.finalize()
}
let s = s.to_str()?;
let encoded_hash = match algo.to_str()?.as_bytes() {
b"md5" => HEXLOWER.encode(hash::<Md5>(&s).as_bstr()),
b"sha1" => HEXLOWER.encode(hash::<Sha1>(&s).as_bstr()),
b"sha256" => HEXLOWER.encode(hash::<Sha256>(&s).as_bstr()),
b"sha512" => HEXLOWER.encode(hash::<Sha512>(&s).as_bstr()),
_ => return Err(ErrorKind::UnknownHashType(s.into())),
};
Ok(Value::from(encoded_hash))
hash_nix_string(algo.to_str()?, s.to_str()?).map(Value::from)
}
#[builtin("head")]