diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index 59362c018..313f3bdbd 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -628,8 +628,13 @@ void callFlake(EvalState & state, static void prim_getFlake(EvalState & state, const Pos & pos, Value * * args, Value & v) { + auto flakeRefS = state.forceStringNoCtx(*args[0], pos); + auto flakeRef = parseFlakeRef(flakeRefS); + if (evalSettings.pureEval && !flakeRef.input->isImmutable()) + throw Error("cannot call 'getFlake' on mutable flake reference '%s', at %s (use --impure to override)", flakeRefS, pos); + callFlake(state, - lockFlake(state, parseFlakeRef(state.forceStringNoCtx(*args[0], pos)), + lockFlake(state, flakeRef, LockFlags { .updateLockFile = false, .useRegistries = !evalSettings.pureEval, diff --git a/tests/flakes.sh b/tests/flakes.sh index 43dbc95e8..050dbf127 100644 --- a/tests/flakes.sh +++ b/tests/flakes.sh @@ -194,6 +194,13 @@ nix build -o $TEST_ROOT/result git+file://$flake1Dir nix build -o $flake1Dir/result git+file://$flake1Dir nix path-info $flake1Dir/result +# 'getFlake' on a mutable flakeref should fail in pure mode, but succeed in impure mode. +(! nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"$flake1Dir\").defaultPackage.$system") +nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"$flake1Dir\").defaultPackage.$system" --impure + +# 'getFlake' on an immutable flakeref should succeed even in pure mode. +nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"git+file://$flake1Dir?rev=$hash2\").defaultPackage.$system" + # Building a flake with an unlocked dependency should fail in pure mode. (! nix build -o $TEST_ROOT/result flake2#bar --no-registries) (! nix eval --expr "builtins.getFlake \"$flake2Dir\"")