Merge pull request #605 from nix-community/disallow_fallback

Disallow fallback
This commit is contained in:
Jörg Thalheim 2025-08-29 18:49:15 +00:00 committed by GitHub
commit 8a5cf83e26
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 72 additions and 36 deletions

3
.envrc
View file

@ -6,4 +6,7 @@ watch_file direnvrc
# shellcheck disable=SC2046
watch_file $(find . -name "*.nix")
# This is not in shell.nix because accessing the working path requires impure eval
export DIRENVRC="$PWD/direnvrc"
use flake

View file

@ -250,7 +250,20 @@ This leads to some limitations in what we can reasonably parse.
Currently, all single-word arguments and some well-known double arguments will
be interpreted or passed along.
#### Manual reload of the nix environment
#### Fine-grained behavior control
##### Disabling devShell fallback
By default, nix-direnv will reload a previously working devShell if it discovers
that a new verison does not evaluate. This can be disabled by calling
`nix_direnv_disallow_fallback` in `.envrc`, like so:
```shell
nix_direnv_disallow_fallback
use nix # or use flake
```
##### Manual reload of the nix environment
To avoid delays and time consuming rebuilds at unexpected times, you can use
nix-direnv in the "manual reload" mode. nix-direnv will then tell you when the

View file

@ -244,6 +244,12 @@ nix_direnv_manual_reload() {
_nix_direnv_manual_reload=1
}
: "${_nix_direnv_allow_fallback:=1}"
nix_direnv_disallow_fallback() {
_nix_direnv_info "Fallback disallowed"
_nix_direnv_allow_fallback=0
}
_nix_direnv_warn_manual_reload() {
if [[ -e $1 ]]; then
_nix_direnv_warning 'cache is out of date. use "nix-direnv-reload" to reload'
@ -336,8 +342,12 @@ use_flake() {
# but there is already a prior profile_rc,
# which is probably more useful than nothing.
# Fallback to use that (which means just leaving profile_rc alone!)
_nix_direnv_warning "Evaluating current devShell failed. Falling back to previous environment!"
export NIX_DIRENV_DID_FALLBACK=1
if [[ $_nix_direnv_allow_fallback -eq 1 ]]; then
_nix_direnv_warning "Evaluating current devShell failed. Falling back to previous environment!"
export NIX_DIRENV_DID_FALLBACK=1
else
return 1
fi
fi
fi
else
@ -493,8 +503,13 @@ use_nix() {
rm -f "$tmp_profile" "$tmp_profile"*
_nix_direnv_info "Renewed cache"
else
_nix_direnv_warning "Evaluating current nix shell failed. Falling back to previous environment!"
export NIX_DIRENV_DID_FALLBACK=1
if [[ $_nix_direnv_allow_fallback -eq 1 ]]; then
_nix_direnv_warning "Evaluating current nix shell failed. Falling back to previous environment!"
export NIX_DIRENV_DID_FALLBACK=1
else
unset IN_NIX_SHELL
return 1
fi
fi
fi
else
@ -502,6 +517,7 @@ use_nix() {
_nix_direnv_info "Using cached dev shell"
else
_nix_direnv_error "use_nix failed - Is your nix shell working?"
unset IN_NIX_SHELL
return 1
fi
fi

View file

@ -9,7 +9,6 @@ let
in
pkgs.mkShell {
DIRENV_STDLIB = "${test_pkgs.direnv-stdlib}";
DIRENVRC = "${nix-direnv}/share/nix-direnv/direnvrc";
BATS_LIB_PATH = lib.strings.makeSearchPath "" (
with test_pkgs;
[

View file

@ -7,6 +7,7 @@
fetchurl,
findutils,
gnugrep,
gnused,
lib,
nix-direnv,
nixVersions,
@ -31,6 +32,7 @@ let
coreutils
findutils
gnugrep
gnused
]
}
export DIRENV_STDLIB=${direnv-stdlib}
@ -38,7 +40,7 @@ let
export BATS_LIB_PATH="${bats-support}:${bats-assert}"
echo run unittest
${lib.getExe' bats "bats"} -x --verbose-run tests/
${lib.getExe' bats "bats"} tests/
'';
test-runner-stable = mkTestRunner "stable";
test-runner-latest = mkTestRunner "latest";

32
tests/test_fallback.bats Normal file
View file

@ -0,0 +1,32 @@
# -*- mode: bash-ts -*-
function setup {
load "util"
_common_setup
}
function teardown {
_common_teardown
}
function test_fallback_allowed() { # @test
write_envrc "strict_env\nwatch_file shell.nix\nuse flake"
run_in_direnv 'hello'
sed -i.bk 's|inherit shellHook|inherit doesntExist|' "$TESTDIR/shell.nix"
run --separate-stderr direnv exec "$TESTDIR" "hello"
assert_stderr -p "Falling back to previous environment"
}
function test_fallback_disallowed() { # @test
write_envrc "strict_env\nwatch_file shell.nix\nnix_direnv_disallow_fallback\nuse flake"
run_in_direnv 'hello'
sed -i.bk 's|inherit shellHook|inherit doesntExist|' "$TESTDIR/shell.nix"
run --separate-stderr direnv exec "$TESTDIR" "hello"
refute_stderr -p "Falling back to previous environment"
}

View file

@ -44,13 +44,6 @@ function assert_use_flake_layout_dir_shape {
}
# tests ===================================
function use_nix_no_strict { # @test
write_envrc "use nix"
assert_run_output
assert_gcroot
assert_use_nix_layout_dir_shape
}
function use_nix_strict { # @test
write_envrc "strict_env\nuse nix"
assert_run_output
@ -58,13 +51,6 @@ function use_nix_strict { # @test
assert_use_nix_layout_dir_shape
}
function use_flake_no_strict { # @test
write_envrc "use flake"
assert_run_output
assert_gcroot
assert_use_flake_layout_dir_shape
}
function use_flake_strict { # @test
write_envrc "strict_env\nuse flake"
assert_run_output

View file

@ -17,13 +17,6 @@ function use_nix_attrs_strict { # @test
assert_output -e "subshell: OK$"
}
function use_nix_attrs_no_strict { # @test
write_envrc "use nix -A subshell"
# shellcheck disable=SC2016
run_in_direnv 'echo "subshell: $THIS_IS_A_SUBSHELL"'
assert_output -e "subshell: OK$"
}
function use_nix_no_nix_path_strict { # @test
unset NIX_PATH
write_envrc "strict_env\nuse nix --argstr someArg OK"
@ -32,14 +25,6 @@ function use_nix_no_nix_path_strict { # @test
assert_output -e "someArg: OK$"
}
function use_nix_no_nix_path_no_strict { # @test
unset NIX_PATH
write_envrc "use nix --argstr someArg OK"
# shellcheck disable=SC2016
run_in_direnv 'echo "someArg: $SHOULD_BE_SET"'
assert_output -e "someArg: OK$"
}
function use_nix_no_files { # @test
write_envrc "use nix -p hello"
(