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;
This commit is contained in:
Eelco Dolstra 2020-01-31 20:50:46 +01:00
parent 185c3c8240
commit 54037f4e2d
2 changed files with 44 additions and 17 deletions

View file

@ -77,10 +77,15 @@ static FlakeInput parseFlakeInput(EvalState & state,
auto sFlake = state.symbols.create("flake"); auto sFlake = state.symbols.create("flake");
auto sFollows = state.symbols.create("follows"); auto sFollows = state.symbols.create("follows");
fetchers::Input::Attrs attrs;
std::optional<std::string> url;
for (Attr attr : *(value->attrs)) { for (Attr attr : *(value->attrs)) {
try {
if (attr.name == sUrl || attr.name == sUri) { if (attr.name == sUrl || attr.name == sUri) {
expectType(state, tString, *attr.value, *attr.pos); expectType(state, tString, *attr.value, *attr.pos);
input.ref = parseFlakeRef(attr.value->string.s); url = attr.value->string.s;
attrs.emplace("url", *url);
} else if (attr.name == sFlake) { } else if (attr.name == sFlake) {
expectType(state, tBool, *attr.value, *attr.pos); expectType(state, tBool, *attr.value, *attr.pos);
input.isFlake = attr.value->boolean; input.isFlake = attr.value->boolean;
@ -88,14 +93,33 @@ static FlakeInput parseFlakeInput(EvalState & state,
input.overrides = parseFlakeInputs(state, attr.value, *attr.pos); input.overrides = parseFlakeInputs(state, attr.value, *attr.pos);
} else if (attr.name == sFollows) { } else if (attr.name == sFollows) {
expectType(state, tString, *attr.value, *attr.pos); expectType(state, tString, *attr.value, *attr.pos);
try {
input.follows = parseInputPath(attr.value->string.s); input.follows = parseInputPath(attr.value->string.s);
} catch (Error & e) { } else {
e.addPrefix("in flake attribute at '%s':\n"); state.forceValue(*attr.value);
if (attr.value->type == tString)
attrs.emplace(attr.name, attr.value->string.s);
else
throw Error("unsupported attribute type");
} }
} else } catch (Error & e) {
throw Error("flake input '%s' has an unsupported attribute '%s', at %s", e.addPrefix(fmt("in flake attribute '%s' at '%s':\n", attr.name, *attr.pos));
inputName, 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; return input;

View file

@ -468,7 +468,10 @@ cat > $flake3Dir/flake.nix <<EOF
{ {
edition = 201909; edition = 201909;
inputs.foo.url = flake:flake1; inputs.foo = {
type = "indirect";
id = "flake1";
};
inputs.bar.follows = "foo"; inputs.bar.follows = "foo";
outputs = { self, foo, bar }: { outputs = { self, foo, bar }: {