Add builtins.hashFile

For text files it is possible to do it like so:
`builtins.hashString "sha256" (builtins.readFile /tmp/a)`
but that doesn't work for binary files.

With builtins.hashFile any kind of file can be conveniently hashed.
This commit is contained in:
Daniel Schaefer 2019-05-03 14:30:29 +02:00
parent f9a2ea4486
commit 3f192ac80c
9 changed files with 39 additions and 1 deletions

View file

@ -705,6 +705,19 @@ builtins.genList (x: x * x) 5
</varlistentry> </varlistentry>
<varlistentry xml:id='builtin-hashFile'>
<term><function>builtins.hashFile</function>
<replaceable>type</replaceable> <replaceable>p</replaceable></term>
<listitem><para>Return a base-16 representation of the
cryptographic hash of the file at path <replaceable>p</replaceable>. The
hash algorithm specified by <replaceable>type</replaceable> must
be one of <literal>"md5"</literal>, <literal>"sha1"</literal>,
<literal>"sha256"</literal> or <literal>"sha512"</literal>.</para></listitem>
</varlistentry>
<varlistentry xml:id='builtin-head'> <varlistentry xml:id='builtin-head'>
<term><function>builtins.head</function> <term><function>builtins.head</function>
<replaceable>list</replaceable></term> <replaceable>list</replaceable></term>

View file

@ -923,6 +923,20 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
mkPath(v, state.checkSourcePath(state.findFile(searchPath, path, pos)).c_str()); mkPath(v, state.checkSourcePath(state.findFile(searchPath, path, pos)).c_str());
} }
/* Return the cryptographic hash of a file in base-16. */
static void prim_hashFile(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
string type = state.forceStringNoCtx(*args[0], pos);
HashType ht = parseHashType(type);
if (ht == htUnknown)
throw Error(format("unknown hash type '%1%', at %2%") % type % pos);
PathSet context; // discarded
Path p = state.coerceToPath(pos, *args[1], context);
mkString(v, hashFile(ht, state.checkSourcePath(p)).to_string(Base16, false), context);
}
/* Read a directory (without . or ..) */ /* Read a directory (without . or ..) */
static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Value & v) static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Value & v)
{ {
@ -2202,6 +2216,7 @@ void EvalState::createBaseEnv()
addPrimOp("__readFile", 1, prim_readFile); addPrimOp("__readFile", 1, prim_readFile);
addPrimOp("__readDir", 1, prim_readDir); addPrimOp("__readDir", 1, prim_readDir);
addPrimOp("__findFile", 2, prim_findFile); addPrimOp("__findFile", 2, prim_findFile);
addPrimOp("__hashFile", 2, prim_hashFile);
// Creating files // Creating files
addPrimOp("__toXML", 1, prim_toXML); addPrimOp("__toXML", 1, prim_toXML);

BIN
tests/lang/binary-data Normal file

Binary file not shown.

View file

@ -0,0 +1,5 @@
let
paths = [ ./this-file-is-definitely-not-there-7392097 "/and/neither/is/this/37293620" ];
in
builtins.concatLists (map (hash: map (builtins.hashFile hash) paths) ["md5" "sha1" "sha256" "sha512"])

View file

@ -1 +0,0 @@
[ "d41d8cd98f00b204e9800998ecf8427e" "6c69ee7f211c640419d5366cc076ae46" "bb3438fbabd460ea6dbd27d153e2233b" "da39a3ee5e6b4b0d3255bfef95601890afd80709" "cd54e8568c1b37cf1e5badb0779bcbf382212189" "6d12e10b1d331dad210e47fd25d4f260802b7e77" "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" "900a4469df00ccbfd0c145c6d1e4b7953dd0afafadd7534e3a4019e8d38fc663" "ad0387b3bd8652f730ca46d25f9c170af0fd589f42e7f23f5a9e6412d97d7e56" "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" "9d0886f8c6b389398a16257bc79780fab9831c7fc11c8ab07fa732cb7b348feade382f92617c9c5305fefba0af02ab5fd39a587d330997ff5bd0db19f7666653" "21644b72aa259e5a588cd3afbafb1d4310f4889680f6c83b9d531596a5a284f34dbebff409d23bcc86aee6bad10c891606f075c6f4755cb536da27db5693f3a7" ]

View file

@ -0,0 +1 @@
[ "d3b07384d113edec49eaa6238ad5ff00" "0f343b0931126a20f133d67c2b018a3b" "f1d2d2f924e986ac86fdf7b36c94bcdf32beec15" "60cacbf3d72e1e7834203da608037b1bf83b40e8" "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c" "5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" "0cf9180a764aba863a67b6d72f0918bc131c6772642cb2dce5a34f0a702f9470ddc2bf125c12198b1995c233c34b4afd346c54a2334c350a948a51b6e8b4e6b6" "8efb4f73c5655351c444eb109230c556d39e2c7624e9c11abc9e3fb4b9b9254218cc5085b454a9698d085cfa92198491f07a723be4574adc70617b73eb0b6461" ]

View file

@ -0,0 +1,4 @@
let
paths = [ ./data ./binary-data ];
in
builtins.concatLists (map (hash: map (builtins.hashFile hash) paths) ["md5" "sha1" "sha256" "sha512"])

View file

@ -0,0 +1 @@
[ "d41d8cd98f00b204e9800998ecf8427e" "6c69ee7f211c640419d5366cc076ae46" "bb3438fbabd460ea6dbd27d153e2233b" "da39a3ee5e6b4b0d3255bfef95601890afd80709" "cd54e8568c1b37cf1e5badb0779bcbf382212189" "6d12e10b1d331dad210e47fd25d4f260802b7e77" "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" "900a4469df00ccbfd0c145c6d1e4b7953dd0afafadd7534e3a4019e8d38fc663" "ad0387b3bd8652f730ca46d25f9c170af0fd589f42e7f23f5a9e6412d97d7e56" "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" "9d0886f8c6b389398a16257bc79780fab9831c7fc11c8ab07fa732cb7b348feade382f92617c9c5305fefba0af02ab5fd39a587d330997ff5bd0db19f7666653" "21644b72aa259e5a588cd3afbafb1d4310f4889680f6c83b9d531596a5a284f34dbebff409d23bcc86aee6bad10c891606f075c6f4755cb536da27db5693f3a7" ]