nix: Enable pure mode by default

We want to encourage a brave new world of hermetic evaluation for
source-level reproducibility, so flakes should not poke around in the
filesystem outside of their explicit dependencies.

Note that the default installation source remains impure in that it
can refer to mutable flakes, so "nix build nixpkgs.hello" still works
(and fetches the latest nixpkgs, unless it has been pinned by the
user).

A problem with pure evaluation is that builtins.currentSystem is
unavailable. For the moment, I've hard-coded "x86_64-linux" in the
nixpkgs flake. Eventually, "system" should be a flake function
argument.
This commit is contained in:
Eelco Dolstra 2019-02-12 20:35:03 +01:00
parent 91a6a47b0e
commit ba05f29838
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
6 changed files with 38 additions and 30 deletions

View file

@ -1,3 +0,0 @@
builtins.mapAttrs (flakeName: flakeInfo:
(getFlake flakeInfo.uri).${flakeName}.provides.packages or {})
builtins.flakeRegistry

View file

@ -3,8 +3,7 @@ corepkgs_FILES = \
unpack-channel.nix \ unpack-channel.nix \
derivation.nix \ derivation.nix \
fetchurl.nix \ fetchurl.nix \
imported-drv-to-derivation.nix \ imported-drv-to-derivation.nix
default-installation-source.nix
$(foreach file,config.nix $(corepkgs_FILES),$(eval $(call install-data-in,$(d)/$(file),$(datadir)/nix/corepkgs))) $(foreach file,config.nix $(corepkgs_FILES),$(eval $(call install-data-in,$(d)/$(file),$(datadir)/nix/corepkgs)))

View file

@ -318,6 +318,8 @@ public:
const FlakeRegistry & getFlakeRegistry(); const FlakeRegistry & getFlakeRegistry();
Value * makeFlakeRegistryValue();
private: private:
std::unique_ptr<FlakeRegistry> _flakeRegistry; std::unique_ptr<FlakeRegistry> _flakeRegistry;
std::once_flag _flakeRegistryInit; std::once_flag _flakeRegistryInit;

View file

@ -16,50 +16,49 @@ const FlakeRegistry & EvalState::getFlakeRegistry()
{ {
_flakeRegistry = std::make_unique<FlakeRegistry>(); _flakeRegistry = std::make_unique<FlakeRegistry>();
if (!evalSettings.pureEval) {
#if 0 #if 0
auto registryUri = "file:///home/eelco/Dev/gists/nix-flakes/registry.json"; auto registryUri = "file:///home/eelco/Dev/gists/nix-flakes/registry.json";
auto registryFile = getDownloader()->download(DownloadRequest(registryUri)); auto registryFile = getDownloader()->download(DownloadRequest(registryUri));
#endif #endif
auto registryFile = readFile(settings.nixDataDir + "/nix/flake-registry.json"); auto registryFile = readFile(settings.nixDataDir + "/nix/flake-registry.json");
auto json = nlohmann::json::parse(registryFile); auto json = nlohmann::json::parse(registryFile);
auto version = json.value("version", 0); auto version = json.value("version", 0);
if (version != 1) if (version != 1)
throw Error("flake registry '%s' has unsupported version %d", registryFile, version); throw Error("flake registry '%s' has unsupported version %d", registryFile, version);
auto flakes = json["flakes"]; auto flakes = json["flakes"];
for (auto i = flakes.begin(); i != flakes.end(); ++i) { for (auto i = flakes.begin(); i != flakes.end(); ++i) {
FlakeRegistry::Entry entry{FlakeRef(i->value("uri", ""))}; FlakeRegistry::Entry entry{FlakeRef(i->value("uri", ""))};
_flakeRegistry->entries.emplace(i.key(), entry); _flakeRegistry->entries.emplace(i.key(), entry);
}
} }
}); });
return *_flakeRegistry; return *_flakeRegistry;
} }
static void prim_flakeRegistry(EvalState & state, const Pos & pos, Value * * args, Value & v) Value * EvalState::makeFlakeRegistryValue()
{ {
auto registry = state.getFlakeRegistry(); auto v = allocValue();
state.mkAttrs(v, registry.entries.size()); auto registry = getFlakeRegistry();
mkAttrs(*v, registry.entries.size());
for (auto & entry : registry.entries) { for (auto & entry : registry.entries) {
auto vEntry = state.allocAttr(v, entry.first); auto vEntry = allocAttr(*v, entry.first);
state.mkAttrs(*vEntry, 2); mkAttrs(*vEntry, 2);
mkString(*state.allocAttr(*vEntry, state.symbols.create("uri")), entry.second.ref.to_string()); mkString(*allocAttr(*vEntry, symbols.create("uri")), entry.second.ref.to_string());
vEntry->attrs->sort(); vEntry->attrs->sort();
} }
v.attrs->sort(); v->attrs->sort();
}
static RegisterPrimOp r1("__flakeRegistry", 0, prim_flakeRegistry); return v;
}
static FlakeRef lookupFlake(EvalState & state, const FlakeRef & flakeRef) static FlakeRef lookupFlake(EvalState & state, const FlakeRef & flakeRef)
{ {
@ -129,6 +128,9 @@ static Flake getFlake(EvalState & state, const FlakeRef & flakeRef)
auto flakePath = fetchFlake(state, flakeRef); auto flakePath = fetchFlake(state, flakeRef);
state.store->assertStorePath(flakePath); state.store->assertStorePath(flakePath);
if (state.allowedPaths)
state.allowedPaths->insert(flakePath);
Flake flake; Flake flake;
Value vInfo; Value vInfo;

View file

@ -30,8 +30,15 @@ Value * SourceExprCommand::getSourceExpr(EvalState & state)
if (file != "") if (file != "")
state.evalFile(lookupFileArg(state, file), *vSourceExpr); state.evalFile(lookupFileArg(state, file), *vSourceExpr);
else else {
state.evalFile(lookupFileArg(state, "<nix/default-installation-source.nix>"), *vSourceExpr); auto fun = state.parseExprFromString(
"builtins.mapAttrs (flakeName: flakeInfo:"
" (getFlake flakeInfo.uri).${flakeName}.provides.packages or {})", "/");
auto vFun = state.allocValue();
state.eval(fun, *vFun);
auto vRegistry = state.makeFlakeRegistryValue();
mkApp(*vSourceExpr, *vFun, *vRegistry);
}
return vSourceExpr; return vSourceExpr;
} }

View file

@ -97,6 +97,7 @@ void mainWrapped(int argc, char * * argv)
verbosity = lvlError; verbosity = lvlError;
settings.verboseBuild = false; settings.verboseBuild = false;
evalSettings.pureEval = true;
NixArgs args; NixArgs args;