diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-02-11 23:53:46 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-02-11 23:53:46 +0100 |
commit | 26dacc09837cb5226b7d97ed70a0fbade5e40304 (patch) | |
tree | 1bc71e89ec68c62b1e83ddd8c468cbdd69ed41b5 /src | |
parent | d4df99a3349cf2228a8ee78dea320afef86eb3ba (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.cc | 61 |
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); + +} |