aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-02-11 23:53:46 +0100
committerEelco Dolstra <edolstra@gmail.com>2020-02-11 23:53:46 +0100
commit26dacc09837cb5226b7d97ed70a0fbade5e40304 (patch)
tree1bc71e89ec68c62b1e83ddd8c468cbdd69ed41b5 /src
parentd4df99a3349cf2228a8ee78dea320afef86eb3ba (diff)
Add fetchTree builtin function
This allows all supported fetchers to be used, e.g. builtins.fetchTree { type = "github"; owner = "NixOS"; repo = "nix"; rev = "d4df99a3349cf2228a8ee78dea320afef86eb3ba"; }
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/primops/fetchTree.cc61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc
new file mode 100644
index 000000000..ccb0cacd5
--- /dev/null
+++ b/src/libexpr/primops/fetchTree.cc
@@ -0,0 +1,61 @@
+#include "primops.hh"
+#include "eval-inline.hh"
+#include "store-api.hh"
+#include "fetchers/fetchers.hh"
+#include "fetchers/registry.hh"
+
+namespace nix {
+
+static void prim_fetchTree(EvalState & state, const Pos & pos, Value * * args, Value & v)
+{
+ std::shared_ptr<const fetchers::Input> input;
+ PathSet context;
+
+ state.forceValue(*args[0]);
+
+ if (args[0]->type == tAttrs) {
+ state.forceAttrs(*args[0], pos);
+
+ fetchers::Input::Attrs attrs;
+
+ for (auto & attr : *args[0]->attrs) {
+ state.forceValue(*attr.value);
+ if (attr.value->type == tString)
+ attrs.emplace(attr.name, attr.value->string.s);
+ else
+ throw Error("unsupported attribute type");
+ }
+
+ if (!attrs.count("type"))
+ throw Error("attribute 'type' is missing in call to 'fetchTree', at %s", pos);
+
+ input = fetchers::inputFromAttrs(attrs);
+ } else
+ input = fetchers::inputFromURL(state.coerceToString(pos, *args[0], context, false, false));
+
+ if (!evalSettings.pureEval && !input->isDirect())
+ input = lookupInRegistries(state.store, input);
+
+ if (evalSettings.pureEval && !input->isImmutable())
+ throw Error("in pure evaluation mode, 'fetchTree' requires an immutable input");
+
+ auto [tree, input2] = input->fetchTree(state.store);
+
+ state.mkAttrs(v, 8);
+ auto storePath = state.store->printStorePath(tree.storePath);
+ mkString(*state.allocAttr(v, state.sOutPath), storePath, PathSet({storePath}));
+ if (input2->getRev()) {
+ mkString(*state.allocAttr(v, state.symbols.create("rev")), input2->getRev()->gitRev());
+ mkString(*state.allocAttr(v, state.symbols.create("shortRev")), input2->getRev()->gitShortRev());
+ }
+ if (tree.info.revCount)
+ mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *tree.info.revCount);
+ v.attrs->sort();
+
+ if (state.allowedPaths)
+ state.allowedPaths->insert(tree.actualPath);
+}
+
+static RegisterPrimOp r("fetchTree", 1, prim_fetchTree);
+
+}