1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
#include "primops.hh"
#include "store-api.hh"
namespace nix {
static void prim_fetchClosure(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
state.forceAttrs(*args[0], pos);
std::optional<StorePath> storePath;
std::optional<std::string> from;
for (auto & attr : *args[0]->attrs) {
if (attr.name == "storePath") {
PathSet context;
storePath = state.coerceToStorePath(*attr.pos, *attr.value, context);
}
else if (attr.name == "from")
from = state.forceStringNoCtx(*attr.value, *attr.pos);
else
throw Error({
.msg = hintfmt("attribute '%s' isn't supported in call to 'fetchClosure'", attr.name),
.errPos = pos
});
}
if (!storePath)
throw Error({
.msg = hintfmt("attribute '%s' is missing in call to 'fetchClosure'", "storePath"),
.errPos = pos
});
if (!from)
throw Error({
.msg = hintfmt("attribute '%s' is missing in call to 'fetchClosure'", "from"),
.errPos = pos
});
// FIXME: only allow some "trusted" store types (like BinaryCacheStore).
auto srcStore = openStore(*from);
copyClosure(*srcStore, *state.store, RealisedPath::Set { *storePath });
/* In pure mode, require a CA path. */
if (evalSettings.pureEval) {
auto info = state.store->queryPathInfo(*storePath);
if (!info->isContentAddressed(*state.store))
throw Error({
.msg = hintfmt("in pure mode, 'fetchClosure' requires a content-addressed path, which '%s' isn't",
state.store->printStorePath(*storePath)),
.errPos = pos
});
}
auto storePathS = state.store->printStorePath(*storePath);
v.mkString(storePathS, {storePathS});
}
static RegisterPrimOp primop_fetchClosure({
.name = "__fetchClosure",
.args = {"args"},
.doc = R"(
)",
.fun = prim_fetchClosure,
});
}
|