Introduce flake URIs

This commit is contained in:
Eelco Dolstra 2018-11-30 16:11:15 +01:00
parent 7a5cf31060
commit ef4cf4e681
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE

View file

@ -4,6 +4,7 @@
#include "download.hh" #include "download.hh"
#include <queue> #include <queue>
#include <regex>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
namespace nix { namespace nix {
@ -67,16 +68,39 @@ struct Flake
Value * vProvides; // FIXME: gc Value * vProvides; // FIXME: gc
}; };
static Flake fetchFlake(EvalState & state, const std::string & flakeUri) std::regex flakeRegex("^flake:([a-zA-Z][a-zA-Z0-9_-]+)$");
static Path fetchFlake(EvalState & state, const std::string & flakeUri)
{ {
std::smatch match;
if (std::regex_match(flakeUri, match, flakeRegex)) {
auto flakeName = match[1];
auto registry = state.getFlakeRegistry();
auto i = registry.entries.find(flakeName);
if (i == registry.entries.end())
throw Error("unknown flake '%s'", flakeName);
return fetchFlake(state, i->second.uri);
}
else if (hasPrefix(flakeUri, "/") || hasPrefix(flakeUri, "git://")) {
auto gitInfo = exportGit(state.store, flakeUri, {}, "", "source");
return gitInfo.storePath;
}
else
throw Error("unsupported flake URI '%s'", flakeUri);
}
static Flake getFlake(EvalState & state, const std::string & flakeUri)
{
auto flakePath = fetchFlake(state, flakeUri);
state.store->assertStorePath(flakePath);
Flake flake; Flake flake;
auto gitInfo = exportGit(state.store, flakeUri, {}, "", "source");
state.store->assertStorePath(gitInfo.storePath);
Value vInfo; Value vInfo;
state.evalFile(gitInfo.storePath + "/flake.nix", vInfo); state.evalFile(flakePath + "/flake.nix", vInfo);
state.forceAttrs(vInfo); state.forceAttrs(vInfo);
@ -106,8 +130,6 @@ static Flake fetchFlake(EvalState & state, const std::string & flakeUri)
static std::map<std::string, Flake> resolveFlakes(EvalState & state, const StringSet & flakeUris) static std::map<std::string, Flake> resolveFlakes(EvalState & state, const StringSet & flakeUris)
{ {
auto registry = state.getFlakeRegistry();
std::map<std::string, Flake> done; std::map<std::string, Flake> done;
std::queue<std::string> todo; std::queue<std::string> todo;
for (auto & i : flakeUris) todo.push(i); for (auto & i : flakeUris) todo.push(i);
@ -117,14 +139,10 @@ static std::map<std::string, Flake> resolveFlakes(EvalState & state, const Strin
todo.pop(); todo.pop();
if (done.count(flakeUri)) continue; if (done.count(flakeUri)) continue;
auto flake = fetchFlake(state, flakeUri); auto flake = getFlake(state, flakeUri);
for (auto & require : flake.requires) { for (auto & require : flake.requires)
auto i = registry.entries.find(require); todo.push(require);
if (i == registry.entries.end())
throw Error("unknown flake '%s'", require);
todo.push(i->second.uri);
}
done.emplace(flake.name, flake); done.emplace(flake.name, flake);
} }