2022-03-21 12:31:01 +02:00
|
|
|
#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);
|
|
|
|
|
2022-03-21 15:34:45 +02:00
|
|
|
std::optional<std::string> fromStoreUrl;
|
|
|
|
std::optional<StorePath> fromPath;
|
2022-03-21 12:31:01 +02:00
|
|
|
|
|
|
|
for (auto & attr : *args[0]->attrs) {
|
2022-03-21 15:34:45 +02:00
|
|
|
if (attr.name == "fromPath") {
|
2022-03-21 12:31:01 +02:00
|
|
|
PathSet context;
|
2022-03-21 15:34:45 +02:00
|
|
|
fromPath = state.coerceToStorePath(*attr.pos, *attr.value, context);
|
2022-03-21 12:31:01 +02:00
|
|
|
}
|
|
|
|
|
2022-03-21 15:34:45 +02:00
|
|
|
else if (attr.name == "fromStore")
|
|
|
|
fromStoreUrl = state.forceStringNoCtx(*attr.value, *attr.pos);
|
2022-03-21 12:31:01 +02:00
|
|
|
|
|
|
|
else
|
|
|
|
throw Error({
|
|
|
|
.msg = hintfmt("attribute '%s' isn't supported in call to 'fetchClosure'", attr.name),
|
|
|
|
.errPos = pos
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-03-21 15:34:45 +02:00
|
|
|
if (!fromPath)
|
2022-03-21 12:31:01 +02:00
|
|
|
throw Error({
|
2022-03-21 15:34:45 +02:00
|
|
|
.msg = hintfmt("attribute '%s' is missing in call to 'fetchClosure'", "fromPath"),
|
2022-03-21 12:31:01 +02:00
|
|
|
.errPos = pos
|
|
|
|
});
|
|
|
|
|
2022-03-21 15:34:45 +02:00
|
|
|
if (!fromStoreUrl)
|
2022-03-21 12:31:01 +02:00
|
|
|
throw Error({
|
2022-03-21 15:34:45 +02:00
|
|
|
.msg = hintfmt("attribute '%s' is missing in call to 'fetchClosure'", "fromStore"),
|
2022-03-21 12:31:01 +02:00
|
|
|
.errPos = pos
|
|
|
|
});
|
|
|
|
|
|
|
|
// FIXME: only allow some "trusted" store types (like BinaryCacheStore).
|
2022-03-21 15:34:45 +02:00
|
|
|
auto fromStore = openStore(*fromStoreUrl);
|
2022-03-21 12:31:01 +02:00
|
|
|
|
2022-03-21 15:34:45 +02:00
|
|
|
copyClosure(*fromStore, *state.store, RealisedPath::Set { *fromPath });
|
2022-03-21 12:31:01 +02:00
|
|
|
|
2022-03-21 15:00:54 +02:00
|
|
|
/* In pure mode, require a CA path. */
|
|
|
|
if (evalSettings.pureEval) {
|
2022-03-21 15:34:45 +02:00
|
|
|
auto info = state.store->queryPathInfo(*fromPath);
|
2022-03-21 15:00:54 +02:00
|
|
|
if (!info->isContentAddressed(*state.store))
|
|
|
|
throw Error({
|
|
|
|
.msg = hintfmt("in pure mode, 'fetchClosure' requires a content-addressed path, which '%s' isn't",
|
2022-03-21 15:34:45 +02:00
|
|
|
state.store->printStorePath(*fromPath)),
|
2022-03-21 15:00:54 +02:00
|
|
|
.errPos = pos
|
|
|
|
});
|
|
|
|
}
|
2022-03-21 12:31:01 +02:00
|
|
|
|
2022-03-21 15:34:45 +02:00
|
|
|
auto fromPathS = state.store->printStorePath(*fromPath);
|
|
|
|
v.mkString(fromPathS, {fromPathS});
|
2022-03-21 12:31:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static RegisterPrimOp primop_fetchClosure({
|
|
|
|
.name = "__fetchClosure",
|
|
|
|
.args = {"args"},
|
|
|
|
.doc = R"(
|
|
|
|
)",
|
|
|
|
.fun = prim_fetchClosure,
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|