Add legacy setting: nix-shell-always-looks-for-shell-nix

This commit is contained in:
Robert Hensing 2024-07-06 22:58:15 +02:00
parent 73602a7c6f
commit 2f1fada76b
6 changed files with 60 additions and 5 deletions

View file

@ -11,6 +11,8 @@
#include "command.hh" #include "command.hh"
#include "tarball.hh" #include "tarball.hh"
#include "fetch-to-store.hh" #include "fetch-to-store.hh"
#include "compatibility-settings.hh"
#include "eval-settings.hh"
namespace nix { namespace nix {
@ -33,6 +35,11 @@ EvalSettings evalSettings {
static GlobalConfig::Register rEvalSettings(&evalSettings); static GlobalConfig::Register rEvalSettings(&evalSettings);
CompatibilitySettings compatibilitySettings {};
static GlobalConfig::Register rCompatibilitySettings(&compatibilitySettings);
MixEvalArgs::MixEvalArgs() MixEvalArgs::MixEvalArgs()
{ {
addFlag({ addFlag({

View file

@ -13,6 +13,7 @@ namespace nix {
class Store; class Store;
class EvalState; class EvalState;
struct EvalSettings; struct EvalSettings;
struct CompatibilitySettings;
class Bindings; class Bindings;
struct SourcePath; struct SourcePath;
@ -21,6 +22,11 @@ struct SourcePath;
*/ */
extern EvalSettings evalSettings; extern EvalSettings evalSettings;
/**
* Settings that control behaviors that have changed since Nix 2.3.
*/
extern CompatibilitySettings compatibilitySettings;
struct MixEvalArgs : virtual Args, virtual MixRepair struct MixEvalArgs : virtual Args, virtual MixRepair
{ {
static constexpr auto category = "Common evaluation options"; static constexpr auto category = "Common evaluation options";

View file

@ -0,0 +1,19 @@
#pragma once
#include "config.hh"
namespace nix {
struct CompatibilitySettings : public Config
{
CompatibilitySettings() = default;
Setting<bool> nixShellAlwaysLooksForShellNix{this, true, "nix-shell-always-looks-for-shell-nix", R"(
Before Nix 2.24, [`nix-shell`](@docroot@/command-ref/nix-shell.md) would only look at `shell.nix` if it was in the working directory - when no file was specified.
Since Nix 2.24, `nix-shell` always looks for a `shell.nix`, whether that's in the working directory, or in a directory that was passed as an argument.
You may set this to `false` to revert to the Nix 2.3 behavior.
)"};
};
};

View file

@ -97,6 +97,7 @@ headers = [config_h] + files(
'command-installable-value.hh', 'command-installable-value.hh',
'command.hh', 'command.hh',
'common-eval-args.hh', 'common-eval-args.hh',
'compatibility-settings.hh',
'editor-for.hh', 'editor-for.hh',
'installable-attr-path.hh', 'installable-attr-path.hh',
'installable-derived-path.hh', 'installable-derived-path.hh',

View file

@ -26,6 +26,7 @@
#include "legacy.hh" #include "legacy.hh"
#include "users.hh" #include "users.hh"
#include "network-proxy.hh" #include "network-proxy.hh"
#include "compatibility-settings.hh"
using namespace nix; using namespace nix;
using namespace std::string_literals; using namespace std::string_literals;
@ -100,7 +101,13 @@ static SourcePath resolveShellExprPath(SourcePath path)
auto resolvedOrDir = resolveExprPath(path, false); auto resolvedOrDir = resolveExprPath(path, false);
if (resolvedOrDir.resolveSymlinks().lstat().type == SourceAccessor::tDirectory) { if (resolvedOrDir.resolveSymlinks().lstat().type == SourceAccessor::tDirectory) {
if ((resolvedOrDir / "shell.nix").pathExists()) { if ((resolvedOrDir / "shell.nix").pathExists()) {
if (compatibilitySettings.nixShellAlwaysLooksForShellNix) {
return resolvedOrDir / "shell.nix"; return resolvedOrDir / "shell.nix";
} else {
warn("Skipping '%1%', because the setting '%2%' is disabled. This is a deprecated behavior. Consider enabling '%2%'.",
resolvedOrDir / "shell.nix",
"nix-shell-always-looks-for-shell-nix");
}
} }
if ((resolvedOrDir / "default.nix").pathExists()) { if ((resolvedOrDir / "default.nix").pathExists()) {
return resolvedOrDir / "default.nix"; return resolvedOrDir / "default.nix";
@ -302,12 +309,18 @@ static void main_nix_build(int argc, char * * argv)
fromArgs = true; fromArgs = true;
remainingArgs = {joined.str()}; remainingArgs = {joined.str()};
} else if (!fromArgs && remainingArgs.empty()) { } else if (!fromArgs && remainingArgs.empty()) {
if (isNixShell && !compatibilitySettings.nixShellAlwaysLooksForShellNix && std::filesystem::exists("shell.nix")) {
// If we're in 2.3 compatibility mode, we need to look for shell.nix
// now, because it won't be done later.
remainingArgs = {"shell.nix"};
} else {
remainingArgs = {"."}; remainingArgs = {"."};
// Instead of letting it throw later, we throw here to give a more relevant error message // Instead of letting it throw later, we throw here to give a more relevant error message
if (isNixShell && !std::filesystem::exists("shell.nix") && !std::filesystem::exists("default.nix")) if (isNixShell && !std::filesystem::exists("shell.nix") && !std::filesystem::exists("default.nix"))
throw Error("no argument specified and no '%s' or '%s' file found in the working directory", "shell.nix", "default.nix"); throw Error("no argument specified and no '%s' or '%s' file found in the working directory", "shell.nix", "default.nix");
} }
}
if (isNixShell) if (isNixShell)
setEnv("IN_NIX_SHELL", pure ? "pure" : "impure"); setEnv("IN_NIX_SHELL", pure ? "pure" : "impure");

View file

@ -21,6 +21,10 @@ output=$(nix-shell --pure "$shellDotNix" -A shellDrv --run \
[ "$output" = " - foo - bar - true" ] [ "$output" = " - foo - bar - true" ]
output=$(nix-shell --pure "$shellDotNix" -A shellDrv --option nix-shell-always-looks-for-shell-nix false --run \
'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX - $TEST_inNixShell"')
[ "$output" = " - foo - bar - true" ]
# Test --keep # Test --keep
output=$(nix-shell --pure --keep SELECTED_IMPURE_VAR "$shellDotNix" -A shellDrv --run \ output=$(nix-shell --pure --keep SELECTED_IMPURE_VAR "$shellDotNix" -A shellDrv --run \
'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX - $SELECTED_IMPURE_VAR"') 'echo "$IMPURE_VAR - $VAR_FROM_STDENV_SETUP - $VAR_FROM_NIX - $SELECTED_IMPURE_VAR"')
@ -101,6 +105,11 @@ nix-shell $TEST_ROOT/lookup-test -A shellDrv --run 'echo "it works"' | grepQuiet
# https://github.com/NixOS/nix/issues/4529 # https://github.com/NixOS/nix/issues/4529
nix-shell -I "testRoot=$TEST_ROOT" '<testRoot/lookup-test>' -A shellDrv --run 'echo "it works"' | grepQuiet "it works" nix-shell -I "testRoot=$TEST_ROOT" '<testRoot/lookup-test>' -A shellDrv --run 'echo "it works"' | grepQuiet "it works"
expectStderr 1 nix-shell $TEST_ROOT/lookup-test -A shellDrv --run 'echo "it works"' --option nix-shell-always-looks-for-shell-nix false \
| grepQuiet -F "do not load default.nix!" # we did, because we chose to enable legacy behavior
expectStderr 1 nix-shell $TEST_ROOT/lookup-test -A shellDrv --run 'echo "it works"' --option nix-shell-always-looks-for-shell-nix false \
| grepQuiet "Skipping .*lookup-test/shell\.nix.*, because the setting .*nix-shell-always-looks-for-shell-nix.* is disabled. This is a deprecated behavior\. Consider enabling .*nix-shell-always-looks-for-shell-nix.*"
( (
cd $TEST_ROOT/empty; cd $TEST_ROOT/empty;
expectStderr 1 nix-shell | \ expectStderr 1 nix-shell | \