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 # shellcheck disable=SC2046
watch_file $(find . -name "*.nix") 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 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 Currently, all single-word arguments and some well-known double arguments will
be interpreted or passed along. 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 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 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_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() { _nix_direnv_warn_manual_reload() {
if [[ -e $1 ]]; then if [[ -e $1 ]]; then
_nix_direnv_warning 'cache is out of date. use "nix-direnv-reload" to reload' _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, # but there is already a prior profile_rc,
# which is probably more useful than nothing. # which is probably more useful than nothing.
# Fallback to use that (which means just leaving profile_rc alone!) # Fallback to use that (which means just leaving profile_rc alone!)
_nix_direnv_warning "Evaluating current devShell failed. Falling back to previous environment!" if [[ $_nix_direnv_allow_fallback -eq 1 ]]; then
export NIX_DIRENV_DID_FALLBACK=1 _nix_direnv_warning "Evaluating current devShell failed. Falling back to previous environment!"
export NIX_DIRENV_DID_FALLBACK=1
else
return 1
fi
fi fi
fi fi
else else
@ -493,8 +503,13 @@ use_nix() {
rm -f "$tmp_profile" "$tmp_profile"* rm -f "$tmp_profile" "$tmp_profile"*
_nix_direnv_info "Renewed cache" _nix_direnv_info "Renewed cache"
else else
_nix_direnv_warning "Evaluating current nix shell failed. Falling back to previous environment!" if [[ $_nix_direnv_allow_fallback -eq 1 ]]; then
export NIX_DIRENV_DID_FALLBACK=1 _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
fi fi
else else
@ -502,6 +517,7 @@ use_nix() {
_nix_direnv_info "Using cached dev shell" _nix_direnv_info "Using cached dev shell"
else else
_nix_direnv_error "use_nix failed - Is your nix shell working?" _nix_direnv_error "use_nix failed - Is your nix shell working?"
unset IN_NIX_SHELL
return 1 return 1
fi fi
fi fi

View file

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

View file

@ -7,6 +7,7 @@
fetchurl, fetchurl,
findutils, findutils,
gnugrep, gnugrep,
gnused,
lib, lib,
nix-direnv, nix-direnv,
nixVersions, nixVersions,
@ -31,6 +32,7 @@ let
coreutils coreutils
findutils findutils
gnugrep gnugrep
gnused
] ]
} }
export DIRENV_STDLIB=${direnv-stdlib} 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"
}