From 159b5815b527f466578a2d28fbf832617cc45b88 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Mon, 31 Jan 2022 18:03:24 +0100 Subject: [PATCH] repl: `--option pure-eval true` actually enables pure eval mode To quote Eelco in #5867: > Unfortunately we can't do > > evalSettings.pureEval.setDefault(false); > > because then we have to do the same in main.cc (where > pureEval is set to true), and that would allow pure-eval > to be disabled globally from nix.conf. Instead, a command should specify that it should be impure by default. Then, `evalSettings.pureEval` will be set to `false;` unless it's overridden by e.g. a CLI flag. In that case it's IMHO OK to be (theoretically) able to override `pure-eval` via `nix.conf` because it doesn't have an effect on commands where `forceImpureByDefault` returns `false` (i.e. everything where pure eval actually matters). Closes #5867 --- src/libcmd/repl.cc | 7 +++++-- src/libutil/args.hh | 2 ++ src/nix/main.cc | 3 +++ tests/repl.sh | 5 +++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 458e824c5..3c89a8ea3 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -1039,6 +1039,11 @@ struct CmdRepl : StoreCommand, MixEvalArgs }); } + bool forceImpureByDefault() override + { + return true; + } + std::string description() override { return "start an interactive environment for evaluating Nix expressions"; @@ -1053,8 +1058,6 @@ struct CmdRepl : StoreCommand, MixEvalArgs void run(ref store) override { - evalSettings.pureEval = false; - auto evalState = make_ref(searchPath, store); auto repl = std::make_unique(evalState); diff --git a/src/libutil/args.hh b/src/libutil/args.hh index fdd036f9a..07c017719 100644 --- a/src/libutil/args.hh +++ b/src/libutil/args.hh @@ -25,6 +25,8 @@ public: /* Return a short one-line description of the command. */ virtual std::string description() { return ""; } + virtual bool forceImpureByDefault() { return false; } + /* Return documentation about this command, in Markdown format. */ virtual std::string doc() { return ""; } diff --git a/src/nix/main.cc b/src/nix/main.cc index dadb54306..f398e3118 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -380,6 +380,9 @@ void mainWrapped(int argc, char * * argv) settings.ttlPositiveNarInfoCache = 0; } + if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) { + evalSettings.pureEval = false; + } args.command->second->prepare(); args.command->second->run(); } diff --git a/tests/repl.sh b/tests/repl.sh index b6937b9e9..9e6a59f18 100644 --- a/tests/repl.sh +++ b/tests/repl.sh @@ -42,6 +42,11 @@ testRepl () { echo "$replOutput" echo "$replOutput" | grep -qs "while evaluating the file" \ || fail "nix repl --show-trace doesn't show the trace" + + nix repl "${nixArgs[@]}" --option pure-eval true 2>&1 <<< "builtins.currentSystem" \ + | grep "attribute 'currentSystem' missing" + nix repl "${nixArgs[@]}" 2>&1 <<< "builtins.currentSystem" \ + | grep "$(nix-instantiate --eval -E 'builtins.currentSystem')" } # Simple test, try building a drv