diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2019-02-12 21:05:44 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2019-02-12 21:07:48 +0100 |
commit | 272b58220d17bc862f646dbc2cb38eea126001c0 (patch) | |
tree | bad4b4a1d2e3b41b56d9c27073a57e53eb2146d5 /src/libexpr/primops/flake.cc | |
parent | ba05f29838b3bafe28c3ea491be711229298cb1b (diff) |
Enforce use of immutable flakes in pure mode
... plus a temporary hack to allow impure flakes at top-level for the
default installation source.
Diffstat (limited to 'src/libexpr/primops/flake.cc')
-rw-r--r-- | src/libexpr/primops/flake.cc | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/libexpr/primops/flake.cc b/src/libexpr/primops/flake.cc index 4d027558d..1e70ccbd6 100644 --- a/src/libexpr/primops/flake.cc +++ b/src/libexpr/primops/flake.cc @@ -162,16 +162,17 @@ static Flake getFlake(EvalState & state, const FlakeRef & flakeRef) return flake; } -/* Given a set of flake references, recursively fetch them and their +/* Given a flake reference, recursively fetch it and its dependencies. */ -static std::map<FlakeId, Flake> resolveFlakes(EvalState & state, const std::vector<FlakeRef> & flakeRefs) +static std::map<FlakeId, Flake> resolveFlake(EvalState & state, + const FlakeRef & topRef, bool impureTopRef) { std::map<FlakeId, Flake> done; - std::queue<FlakeRef> todo; - for (auto & i : flakeRefs) todo.push(i); + std::queue<std::tuple<FlakeRef, bool>> todo; + todo.push({topRef, impureTopRef}); while (!todo.empty()) { - auto flakeRef = todo.front(); + auto [flakeRef, impureRef] = todo.front(); todo.pop(); if (auto refData = std::get_if<FlakeRef::IsFlakeId>(&flakeRef.data)) { @@ -179,12 +180,15 @@ static std::map<FlakeId, Flake> resolveFlakes(EvalState & state, const std::vect flakeRef = lookupFlake(state, flakeRef); } + if (evalSettings.pureEval && !flakeRef.isImmutable() && !impureRef) + throw Error("mutable flake '%s' is not allowed in pure mode; use --no-pure-eval to disable", flakeRef.to_string()); + auto flake = getFlake(state, flakeRef); if (done.count(flake.id)) continue; for (auto & require : flake.requires) - todo.push(require); + todo.push({require, false}); done.emplace(flake.id, flake); } @@ -194,9 +198,19 @@ static std::map<FlakeId, Flake> resolveFlakes(EvalState & state, const std::vect static void prim_getFlake(EvalState & state, const Pos & pos, Value * * args, Value & v) { - auto flakeUri = FlakeRef(state.forceStringNoCtx(*args[0], pos)); + auto flakeUri = state.forceStringNoCtx(*args[0], pos); + + // FIXME: temporary hack to make the default installation source + // work. + bool impure = false; + if (hasPrefix(flakeUri, "impure:")) { + flakeUri = std::string(flakeUri, 7); + impure = true; + } + + auto flakeRef = FlakeRef(flakeUri); - auto flakes = resolveFlakes(state, {flakeUri}); + auto flakes = resolveFlake(state, flakeUri, impure); auto vResult = state.allocValue(); |