aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/primops
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-03-21 11:31:01 +0100
committerEelco Dolstra <edolstra@gmail.com>2022-03-24 21:33:33 +0100
commitf4bafc412fac79ce07c89f8d3ab9bd1c32f7b9cd (patch)
treef654e7d9857563f8a703e281e4875a365446fc25 /src/libexpr/primops
parentc9148f4ece638a08e912ac53e1d2e1d111e46beb (diff)
Add builtins.fetchClosure
This allows closures to be imported at evaluation time, without requiring the user to configure substituters. E.g. builtins.fetchClosure { storePath = /nix/store/f89g6yi63m1ywfxj96whv5sxsm74w5ka-python3.9-sqlparse-0.4.2; from = "https://cache.ngi0.nixos.org"; }
Diffstat (limited to 'src/libexpr/primops')
-rw-r--r--src/libexpr/primops/fetchClosure.cc62
-rw-r--r--src/libexpr/primops/fetchTree.cc4
2 files changed, 64 insertions, 2 deletions
diff --git a/src/libexpr/primops/fetchClosure.cc b/src/libexpr/primops/fetchClosure.cc
new file mode 100644
index 000000000..4bcc716db
--- /dev/null
+++ b/src/libexpr/primops/fetchClosure.cc
@@ -0,0 +1,62 @@
+#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 });
+
+ auto storePathS = state.store->printStorePath(*storePath);
+
+ v.mkString(storePathS, {storePathS});
+
+ // FIXME: in pure mode, require a CA path or a NAR hash of the
+ // top-level path.
+}
+
+static RegisterPrimOp primop_fetchClosure({
+ .name = "__fetchClosure",
+ .args = {"args"},
+ .doc = R"(
+ )",
+ .fun = prim_fetchClosure,
+});
+
+}
diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc
index 9c2da2178..42c98e312 100644
--- a/src/libexpr/primops/fetchTree.cc
+++ b/src/libexpr/primops/fetchTree.cc
@@ -145,7 +145,7 @@ static void fetchTree(
if (!params.allowNameArgument)
if (auto nameIter = attrs.find("name"); nameIter != attrs.end())
throw Error({
- .msg = hintfmt("attribute 'name' isn’t supported in call to 'fetchTree'"),
+ .msg = hintfmt("attribute 'name' isn't supported in call to 'fetchTree'"),
.errPos = pos
});
@@ -329,7 +329,7 @@ static RegisterPrimOp primop_fetchTarball({
.fun = prim_fetchTarball,
});
-static void prim_fetchGit(EvalState &state, const Pos &pos, Value **args, Value &v)
+static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
fetchTree(state, pos, args, v, "git", FetchTreeParams { .emptyRevFallback = true, .allowNameArgument = true });
}