diff --git a/.envrc b/.envrc index 1639dfc..1bb3edd 100644 --- a/.envrc +++ b/.envrc @@ -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 diff --git a/README.md b/README.md index 13f805f..655b436 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/direnvrc b/direnvrc index cad58f7..c68edf6 100644 --- a/direnvrc +++ b/direnvrc @@ -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 diff --git a/shell.nix b/shell.nix index 409fd63..1c7f3f8 100644 --- a/shell.nix +++ b/shell.nix @@ -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; [ diff --git a/tests/default.nix b/tests/default.nix index 77a7607..91e7830 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -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} diff --git a/tests/test_fallback.bats b/tests/test_fallback.bats new file mode 100644 index 0000000..29372b9 --- /dev/null +++ b/tests/test_fallback.bats @@ -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" +}