Allow users to opt out of devShell fallback

This commit is contained in:
Bryan Bennett 2025-08-28 15:03:07 -04:00
parent c0270d9f3c
commit 94fc26eaa2
6 changed files with 71 additions and 6 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!)
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
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}

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"
}