Registry: Use attr notation instead of URLs

This commit is contained in:
Eelco Dolstra 2020-02-06 14:27:31 +01:00
parent be2580be01
commit 379852a152
5 changed files with 110 additions and 47 deletions
src
libexpr/flake
libstore/fetchers
tests

View file

@ -8,18 +8,7 @@ namespace nix::flake {
FlakeRef flakeRefFromJson(const nlohmann::json & json)
{
fetchers::Input::Attrs attrs;
for (auto & i : json.items()) {
if (i.value().is_number())
attrs.emplace(i.key(), i.value().get<int64_t>());
else if (i.value().is_string())
attrs.emplace(i.key(), i.value().get<std::string>());
else
throw Error("unsupported input attribute type in lock file");
}
return FlakeRef::fromAttrs(attrs);
return FlakeRef::fromAttrs(jsonToAttrs(json));
}
FlakeRef getFlakeRef(

View file

@ -37,6 +37,22 @@ std::unique_ptr<Input> inputFromAttrs(const Input::Attrs & attrs)
throw Error("input '%s' is unsupported", attrsToJson(attrs));
}
Input::Attrs jsonToAttrs(const nlohmann::json & json)
{
fetchers::Input::Attrs attrs;
for (auto & i : json.items()) {
if (i.value().is_number())
attrs.emplace(i.key(), i.value().get<int64_t>());
else if (i.value().is_string())
attrs.emplace(i.key(), i.value().get<std::string>());
else
throw Error("unsupported input attribute type in lock file");
}
return attrs;
}
nlohmann::json attrsToJson(const fetchers::Input::Attrs & attrs)
{
nlohmann::json json;

View file

@ -98,6 +98,8 @@ std::unique_ptr<Input> inputFromAttrs(const Input::Attrs & attrs);
void registerInputScheme(std::unique_ptr<InputScheme> && fetcher);
Input::Attrs jsonToAttrs(const nlohmann::json & json);
nlohmann::json attrsToJson(const Input::Attrs & attrs);
std::optional<std::string> maybeGetStrAttr(const Input::Attrs & attrs, const std::string & name);

View file

@ -19,31 +19,51 @@ std::shared_ptr<Registry> Registry::read(
auto json = nlohmann::json::parse(readFile(path));
auto version = json.value("version", 0);
if (version != 1)
// FIXME: remove soon
if (version == 1) {
auto flakes = json["flakes"];
for (auto i = flakes.begin(); i != flakes.end(); ++i) {
auto url = i->value("url", i->value("uri", ""));
if (url.empty())
throw Error("flake registry '%s' lacks a 'url' attribute for entry '%s'",
path, i.key());
registry->entries.push_back(
{inputFromURL(i.key()), inputFromURL(url)});
}
}
else if (version == 2) {
for (auto & i : json["flakes"])
registry->entries.push_back(
{ inputFromAttrs(jsonToAttrs(i["from"]))
, inputFromAttrs(jsonToAttrs(i["to"]))
});
}
else
throw Error("flake registry '%s' has unsupported version %d", path, version);
auto flakes = json["flakes"];
for (auto i = flakes.begin(); i != flakes.end(); ++i) {
// FIXME: remove 'uri' soon.
auto url = i->value("url", i->value("uri", ""));
if (url.empty())
throw Error("flake registry '%s' lacks a 'url' attribute for entry '%s'",
path, i.key());
registry->entries.push_back(
{inputFromURL(i.key()), inputFromURL(url)});
}
return registry;
}
void Registry::write(const Path & path)
{
nlohmann::json arr;
for (auto & elem : entries) {
nlohmann::json obj;
obj["from"] = attrsToJson(elem.first->toAttrs());
obj["to"] = attrsToJson(elem.second->toAttrs());
arr.emplace_back(std::move(obj));
}
nlohmann::json json;
json["version"] = 1;
for (auto & elem : entries)
json["flakes"][elem.first->to_string()] = { {"url", elem.second->to_string()} };
json["version"] = 2;
json["flakes"] = std::move(arr);
createDirs(dirOf(path));
writeFile(path, json.dump(4));
writeFile(path, json.dump(2));
}
void Registry::add(

View file

@ -94,27 +94,63 @@ git -C $nonFlakeDir commit -m 'Initial'
cat > $registry <<EOF
{
"flakes": {
"flake:flake1": {
"url": "git+file://$flake1Dir"
},
"flake:flake2": {
"url": "git+file://$flake2Dir"
},
"flake:flake3": {
"url": "git+file://$flake3Dir"
},
"flake:flake4": {
"url": "flake:flake3"
},
"flake:flake5": {
"url": "hg+file://$flake5Dir"
},
"flake:nixpkgs": {
"url": "flake:flake1"
}
"version": 2,
"flakes": [
{ "from": {
"type": "indirect",
"id": "flake1"
},
"to": {
"type": "git",
"url": "file://$flake1Dir"
}
},
"version": 1
{ "from": {
"type": "indirect",
"id": "flake2"
},
"to": {
"type": "git",
"url": "file://$flake2Dir"
}
},
{ "from": {
"type": "indirect",
"id": "flake3"
},
"to": {
"type": "git",
"url": "file://$flake3Dir"
}
},
{ "from": {
"type": "indirect",
"id": "flake4"
},
"to": {
"type": "indirect",
"id": "flake3"
}
},
{ "from": {
"type": "indirect",
"id": "flake5"
},
"to": {
"type": "hg",
"url": "file://$flake5Dir"
}
},
{ "from": {
"type": "indirect",
"id": "nixpkgs"
},
"to": {
"type": "indirect",
"id": "flake1"
}
}
]
}
EOF