diff options
Diffstat (limited to 'src/libexpr/primops')
-rw-r--r-- | src/libexpr/primops/flake.cc | 102 | ||||
-rw-r--r-- | src/libexpr/primops/flake.hh | 12 |
2 files changed, 67 insertions, 47 deletions
diff --git a/src/libexpr/primops/flake.cc b/src/libexpr/primops/flake.cc index 257b81887..0d762f2a1 100644 --- a/src/libexpr/primops/flake.cc +++ b/src/libexpr/primops/flake.cc @@ -14,6 +14,10 @@ namespace nix { +using namespace flake; + +namespace flake { + /* Read a registry. */ std::shared_ptr<FlakeRegistry> readRegistry(const Path & path) { @@ -133,24 +137,6 @@ void writeLockFile(const LockFile & lockFile, const Path & path) writeFile(path, json.dump(4) + "\n"); // '4' = indentation in json file } -std::shared_ptr<FlakeRegistry> EvalState::getGlobalFlakeRegistry() -{ - std::call_once(_globalFlakeRegistryInit, [&]() { - auto path = evalSettings.flakeRegistry; - - if (!hasPrefix(path, "/")) { - CachedDownloadRequest request(evalSettings.flakeRegistry); - request.name = "flake-registry.json"; - request.gcRoot = true; - path = getDownloader()->downloadCached(store, request).path; - } - - _globalFlakeRegistry = readRegistry(path); - }); - - return _globalFlakeRegistry; -} - Path getUserRegistryPath() { return getHome() + "/.config/nix/registry.json"; @@ -170,17 +156,6 @@ std::shared_ptr<FlakeRegistry> getFlagRegistry(RegistryOverrides registryOverrid return flagRegistry; } -// This always returns a vector with flakeReg, userReg, globalReg. -// If one of them doesn't exist, the registry is left empty but does exist. -const Registries EvalState::getFlakeRegistries() -{ - Registries registries; - registries.push_back(getFlagRegistry(registryOverrides)); - registries.push_back(getUserRegistry()); - registries.push_back(getGlobalFlakeRegistry()); - return registries; -} - static FlakeRef lookupFlake(EvalState & state, const FlakeRef & flakeRef, const Registries & registries, std::vector<FlakeRef> pastSearches = {}); @@ -327,7 +302,9 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowe state.forceAttrs(vInfo); - if (auto epoch = vInfo.attrs->get(state.symbols.create("epoch"))) { + auto sEpoch = state.symbols.create("epoch"); + + if (auto epoch = vInfo.attrs->get(sEpoch)) { flake.epoch = state.forceInt(*(**epoch).value, *(**epoch).pos); if (flake.epoch > 2019) throw Error("flake '%s' requires unsupported epoch %d; please upgrade Nix", flakeRef, flake.epoch); @@ -342,14 +319,18 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowe if (auto description = vInfo.attrs->get(state.sDescription)) flake.description = state.forceStringNoCtx(*(**description).value, *(**description).pos); - if (auto requires = vInfo.attrs->get(state.symbols.create("requires"))) { + auto sRequires = state.symbols.create("requires"); + + if (auto requires = vInfo.attrs->get(sRequires)) { state.forceList(*(**requires).value, *(**requires).pos); for (unsigned int n = 0; n < (**requires).value->listSize(); ++n) flake.requires.push_back(FlakeRef(state.forceStringNoCtx( *(**requires).value->listElems()[n], *(**requires).pos))); } - if (std::optional<Attr *> nonFlakeRequires = vInfo.attrs->get(state.symbols.create("nonFlakeRequires"))) { + auto sNonFlakeRequires = state.symbols.create("nonFlakeRequires"); + + if (std::optional<Attr *> nonFlakeRequires = vInfo.attrs->get(sNonFlakeRequires)) { state.forceAttrs(*(**nonFlakeRequires).value, *(**nonFlakeRequires).pos); for (Attr attr : *(*(**nonFlakeRequires).value).attrs) { std::string myNonFlakeUri = state.forceStringNoCtx(*attr.value, *attr.pos); @@ -358,12 +339,25 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowe } } - if (auto provides = vInfo.attrs->get(state.symbols.create("provides"))) { + auto sProvides = state.symbols.create("provides"); + + if (auto provides = vInfo.attrs->get(sProvides)) { state.forceFunction(*(**provides).value, *(**provides).pos); flake.vProvides = (**provides).value; } else throw Error("flake '%s' lacks attribute 'provides'", flakeRef); + for (auto & attr : *vInfo.attrs) { + if (attr.name != sEpoch && + attr.name != state.sName && + attr.name != state.sDescription && + attr.name != sRequires && + attr.name != sNonFlakeRequires && + attr.name != sProvides) + throw Error("flake '%s' has an unsupported attribute '%s', at %s", + flakeRef, attr.name, *attr.pos); + } + return flake; } @@ -572,18 +566,11 @@ void callFlake(EvalState & state, const ResolvedFlake & resFlake, Value & v) v.attrs->sort(); } -// Return the `provides` of the top flake, while assigning to `v` the provides -// of the dependencies as well. -void makeFlakeValue(EvalState & state, const FlakeRef & flakeRef, HandleLockFile handle, Value & v) -{ - callFlake(state, resolveFlake(state, flakeRef, handle), v); -} - // This function is exposed to be used in nix files. static void prim_getFlake(EvalState & state, const Pos & pos, Value * * args, Value & v) { - makeFlakeValue(state, state.forceStringNoCtx(*args[0], pos), - evalSettings.pureEval ? AllPure : UseUpdatedLockFile, v); + callFlake(state, resolveFlake(state, state.forceStringNoCtx(*args[0], pos), + evalSettings.pureEval ? AllPure : UseUpdatedLockFile), v); } static RegisterPrimOp r2("getFlake", 1, prim_getFlake); @@ -618,3 +605,34 @@ void gitCloneFlake(FlakeRef flakeRef, EvalState & state, Registries registries, } } + +std::shared_ptr<flake::FlakeRegistry> EvalState::getGlobalFlakeRegistry() +{ + std::call_once(_globalFlakeRegistryInit, [&]() { + auto path = evalSettings.flakeRegistry; + + if (!hasPrefix(path, "/")) { + CachedDownloadRequest request(evalSettings.flakeRegistry); + request.name = "flake-registry.json"; + request.gcRoot = true; + path = getDownloader()->downloadCached(store, request).path; + } + + _globalFlakeRegistry = readRegistry(path); + }); + + return _globalFlakeRegistry; +} + +// This always returns a vector with flakeReg, userReg, globalReg. +// If one of them doesn't exist, the registry is left empty but does exist. +const Registries EvalState::getFlakeRegistries() +{ + Registries registries; + registries.push_back(getFlagRegistry(registryOverrides)); + registries.push_back(getUserRegistry()); + registries.push_back(getGlobalFlakeRegistry()); + return registries; +} + +} diff --git a/src/libexpr/primops/flake.hh b/src/libexpr/primops/flake.hh index 0e2706e32..340b97c65 100644 --- a/src/libexpr/primops/flake.hh +++ b/src/libexpr/primops/flake.hh @@ -5,13 +5,15 @@ namespace nix { +struct Value; +class EvalState; + +namespace flake { + static const size_t FLAG_REGISTRY = 0; static const size_t USER_REGISTRY = 1; static const size_t GLOBAL_REGISTRY = 2; -struct Value; -class EvalState; - struct FlakeRegistry { std::map<FlakeRef, FlakeRef> entries; @@ -73,8 +75,6 @@ enum HandleLockFile : unsigned int , UseNewLockFile // `RecreateLockFile` without writing to file }; -void makeFlakeValue(EvalState &, const FlakeRef &, HandleLockFile, Value &); - std::shared_ptr<FlakeRegistry> readRegistry(const Path &); void writeRegistry(const FlakeRegistry &, const Path &); @@ -143,3 +143,5 @@ void updateLockFile(EvalState &, const FlakeRef & flakeRef, bool recreateLockFil void gitCloneFlake(FlakeRef flakeRef, EvalState &, Registries, const Path & destDir); } + +} |