From 272b58220d17bc862f646dbc2cb38eea126001c0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 12 Feb 2019 21:05:44 +0100 Subject: Enforce use of immutable flakes in pure mode ... plus a temporary hack to allow impure flakes at top-level for the default installation source. --- src/libexpr/primops/flake.cc | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'src/libexpr/primops/flake.cc') 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 resolveFlakes(EvalState & state, const std::vector & flakeRefs) +static std::map resolveFlake(EvalState & state, + const FlakeRef & topRef, bool impureTopRef) { std::map done; - std::queue todo; - for (auto & i : flakeRefs) todo.push(i); + std::queue> 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.data)) { @@ -179,12 +180,15 @@ static std::map 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 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(); -- cgit v1.2.3