aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/flake/flake.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-01-31 20:50:46 +0100
committerEelco Dolstra <edolstra@gmail.com>2020-01-31 20:50:46 +0100
commit54037f4e2d0045aacd044b714e4bf77d0924f249 (patch)
tree3b28d0ec7ec19f4b19e0b6be6de8c6b5e079e438 /src/libexpr/flake/flake.cc
parent185c3c824015f03027b77b85221df32cdb16e759 (diff)
Allow flake input specification via attributes rather than a URL
E.g. inputs.dwarffs = { type = "github"; owner = "edolstra"; repo = "dwarffs"; }; rather than inputs.dwarffs.url = github:edolstra/dwarffs;
Diffstat (limited to 'src/libexpr/flake/flake.cc')
-rw-r--r--src/libexpr/flake/flake.cc56
1 files changed, 40 insertions, 16 deletions
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index c40a903b9..be14c9af3 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -77,25 +77,49 @@ static FlakeInput parseFlakeInput(EvalState & state,
auto sFlake = state.symbols.create("flake");
auto sFollows = state.symbols.create("follows");
+ fetchers::Input::Attrs attrs;
+ std::optional<std::string> url;
+
for (Attr attr : *(value->attrs)) {
- if (attr.name == sUrl || attr.name == sUri) {
- expectType(state, tString, *attr.value, *attr.pos);
- input.ref = parseFlakeRef(attr.value->string.s);
- } else if (attr.name == sFlake) {
- expectType(state, tBool, *attr.value, *attr.pos);
- input.isFlake = attr.value->boolean;
- } else if (attr.name == sInputs) {
- input.overrides = parseFlakeInputs(state, attr.value, *attr.pos);
- } else if (attr.name == sFollows) {
- expectType(state, tString, *attr.value, *attr.pos);
- try {
+ try {
+ if (attr.name == sUrl || attr.name == sUri) {
+ expectType(state, tString, *attr.value, *attr.pos);
+ url = attr.value->string.s;
+ attrs.emplace("url", *url);
+ } else if (attr.name == sFlake) {
+ expectType(state, tBool, *attr.value, *attr.pos);
+ input.isFlake = attr.value->boolean;
+ } else if (attr.name == sInputs) {
+ input.overrides = parseFlakeInputs(state, attr.value, *attr.pos);
+ } else if (attr.name == sFollows) {
+ expectType(state, tString, *attr.value, *attr.pos);
input.follows = parseInputPath(attr.value->string.s);
- } catch (Error & e) {
- e.addPrefix("in flake attribute at '%s':\n");
+ } else {
+ state.forceValue(*attr.value);
+ if (attr.value->type == tString)
+ attrs.emplace(attr.name, attr.value->string.s);
+ else
+ throw Error("unsupported attribute type");
}
- } else
- throw Error("flake input '%s' has an unsupported attribute '%s', at %s",
- inputName, attr.name, *attr.pos);
+ } catch (Error & e) {
+ e.addPrefix(fmt("in flake attribute '%s' at '%s':\n", attr.name, *attr.pos));
+ throw;
+ }
+ }
+
+ if (attrs.count("type"))
+ try {
+ input.ref = FlakeRef::fromAttrs(attrs);
+ } catch (Error & e) {
+ e.addPrefix(fmt("in flake input at '%s':\n", pos));
+ throw;
+ }
+ else {
+ attrs.erase("url");
+ if (!attrs.empty())
+ throw Error("unexpected flake input attribute '%s', at %s", attrs.begin()->first, pos);
+ if (url)
+ input.ref = parseFlakeRef(*url);
}
return input;