1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-26 07:31:15 +02:00

fetchTree: Do not re-fetch paths already present

This commit is contained in:
Robert Hensing 2022-02-27 15:25:22 +01:00
parent 1c985428c4
commit 158280d8e9
3 changed files with 32 additions and 4 deletions

View file

@ -185,6 +185,13 @@ static void prim_fetchTree(EvalState & state, const Pos & pos, Value * * args, V
// FIXME: document
static RegisterPrimOp primop_fetchTree("fetchTree", 1, prim_fetchTree);
static void setStorePath(EvalState &state, const StorePath &storePath, Value &v) {
state.allowPath(storePath);
auto path = state.store->printStorePath(storePath);
v.mkString(path, PathSet({path}));
}
static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
const std::string & who, bool unpack, std::string name)
{
@ -203,6 +210,8 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
url = state.forceStringNoCtx(*attr.value, *attr.pos);
else if (n == "sha256")
expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256);
else if (n == "narHash")
expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256);
else if (n == "name")
name = state.forceStringNoCtx(*attr.value, *attr.pos);
else
@ -230,6 +239,20 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
if (evalSettings.pureEval && !expectedHash)
throw Error("in pure evaluation mode, '%s' requires a 'sha256' argument", who);
// early exit if pinned and already in the store
if (expectedHash && expectedHash->type == htSHA256) {
auto expectedPath =
unpack
? state.store->makeFixedOutputPath(FileIngestionMethod::Recursive, *expectedHash, name, {})
: state.store->makeFixedOutputPath(FileIngestionMethod::Flat, *expectedHash, name, {});
auto validPaths = state.store->queryValidPaths({expectedPath}, NoSubstitute);
if (!validPaths.empty()) {
setStorePath(state, expectedPath, v);
return;
}
}
auto storePath =
unpack
? fetchers::downloadTarball(state.store, *url, name, (bool) expectedHash).first.storePath
@ -244,10 +267,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
*url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true));
}
state.allowPath(storePath);
auto path = state.store->printStorePath(storePath);
v.mkString(path, PathSet({path}));
setStorePath(state, storePath, v);
}
static void prim_fetchurl(EvalState & state, const Pos & pos, Value * * args, Value & v)