Merge pull request #487 from nix-community/GH-486

Issue a warning if we are falling back to the old shell environment
This commit is contained in:
Jörg Thalheim 2024-04-23 14:06:45 +02:00 committed by GitHub
commit 08ee0797f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 43 additions and 31 deletions

View file

@ -275,20 +275,21 @@ nix invocation.
#### Tracked files #### Tracked files
`nix-direnv` makes a performance trade-off and only considers changes in a As a convenience, `nix-direnv` adds common files to direnv's watched file list
limited number of files when deciding to update its cache. automatically.
- for `use nix` this is: The list of additionally tracked files is as follows:
- for `use nix`:
- `~/.direnvrc` - `~/.direnvrc`
- `~/.config/direnv/direnvrc` - `~/.config/direnv/direnvrc`
- `.envrc`, - `.envrc`,
- A single nix file. In order of preference: - A single nix file. In order of preference:
- The file argument to `use nix` - The file argument to `use nix`
- `shell.nix` if it exists
- `default.nix` if it exists - `default.nix` if it exists
- `shell.nix` if it exists
- for `use flake` this is: - for `use flake`:
- `~/.direnvrc` - `~/.direnvrc`
- `~/.config/direnv/direnvrc` - `~/.config/direnv/direnvrc`
- `.envrc` - `.envrc`
@ -296,30 +297,30 @@ limited number of files when deciding to update its cache.
- `flake.lock` - `flake.lock`
- `devshell.toml` if it exists - `devshell.toml` if it exists
To add more files to be checked use `watch_file` like this Users are free to use direnv's builtin `watch_file` function to track additional
files. `watch_file` must be invoked before either `use flake` or `use nix` to
take effect.
```shell #### Environment Variables
watch_file your-file.nix
use nix # or use flake
```
Or - if you don't mind the overhead (runtime and conceptual) of watching all nix-direnv sets the following environment variables for user consumption. All
nix-files: other environment variables are either a product of the underlying nix
invocation or are purely incidental and should not be relied upon.
```shell - `NIX_DIRENV_DID_FALLBACK`: Set when the current revision of your nix shell or
watch_file $(find . -name "*.nix" -printf '"%p" ') flake's devShell are invalid and nix-direnv has loaded the last known working
``` shell.
Note that this will re-execute direnv for any nix change, regardless of whether
that change is meaningful for the devShell in use.
`watch_file` must be invoked before either `use flake` or `use nix` to take
effect.
## General direnv tips ## General direnv tips
- [Changing where direnv stores its cache](https://github.com/direnv/direnv/wiki/Customizing-cache-location) - [Changing where direnv stores its cache][cache_location]
- [Quickly setting up direnv in a new nix project](https://github.com/nix-community/nix-direnv/wiki/Shell-integration) - [Quickly setting up direnv in a new nix project][new_project]
- [Disable the diff notice (requires direnv 2.34+)][hide_diff_notice]: Note that
this goes into direnv's TOML configuration!
[cache_location]: https://github.com/direnv/direnv/wiki/Customizing-cache-location
[new_project]: https://github.com/nix-community/nix-direnv/wiki/Shell-integration
[hide_diff_notice]: https://direnv.net/man/direnv.toml.1.html#codehideenvdiffcode
## Other projects in the field ## Other projects in the field

View file

@ -298,6 +298,7 @@ use_flake() {
local tmp_profile_rc local tmp_profile_rc
local tmp_profile="${layout_dir}/flake-tmp-profile.$$" local tmp_profile="${layout_dir}/flake-tmp-profile.$$"
if tmp_profile_rc=$(_nix print-dev-env --profile "$tmp_profile" "$@"); then if tmp_profile_rc=$(_nix print-dev-env --profile "$tmp_profile" "$@"); then
# If we've gotten here, the user's current devShell is valid and we should cache it
_nix_clean_old_gcroots "$layout_dir" _nix_clean_old_gcroots "$layout_dir"
# We need to update our cache # We need to update our cache
@ -318,13 +319,20 @@ use_flake() {
flake_input_paths="${flake_input_paths/${store_path}/}" flake_input_paths="${flake_input_paths/${store_path}/}"
done done
_nix_direnv_info "renewed cache" _nix_direnv_info "Renewed cache"
else
# The user's current flake failed to evaluate,
# 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
fi fi
fi fi
else else
if [[ -e ${profile_rc} ]]; then if [[ -e ${profile_rc} ]]; then
# Our cache is valid, use that # Our cache is valid, use that
_nix_direnv_info "using cached dev shell" _nix_direnv_info "Using cached dev shell"
else else
# We don't have a profile_rc to use! # We don't have a profile_rc to use!
_nix_direnv_error "use_flake failed - Is your flake's devShell working?" _nix_direnv_error "use_flake failed - Is your flake's devShell working?"
@ -469,12 +477,15 @@ use_nix() {
echo "$tmp_profile_rc" >"$profile_rc" echo "$tmp_profile_rc" >"$profile_rc"
_nix_add_gcroot "$tmp_profile" "$profile" _nix_add_gcroot "$tmp_profile" "$profile"
rm -f "$tmp_profile" "$tmp_profile"* rm -f "$tmp_profile" "$tmp_profile"*
_nix_direnv_info "renewed cache" _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
fi fi
fi fi
else else
if [[ -e ${profile_rc} ]]; then if [[ -e ${profile_rc} ]]; then
_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?"
return 1 return 1

View file

@ -43,7 +43,7 @@
}; };
devShells.default = pkgs.callPackage ./shell.nix { devShells.default = pkgs.callPackage ./shell.nix {
packages = [ config.treefmt.build.wrapper ]; packages = [ config.treefmt.build.wrapper pkgs.shellcheck ];
}; };
checks = checks =

View file

@ -24,7 +24,7 @@ def common_test(direnv_project: DirenvProject) -> None:
) )
sys.stderr.write(out1.stderr) sys.stderr.write(out1.stderr)
assert out1.returncode == 0 assert out1.returncode == 0
assert "renewed cache" in out1.stderr assert "Renewed cache" in out1.stderr
assert "Executing shellHook." in out1.stderr assert "Executing shellHook." in out1.stderr
run(["nix-collect-garbage"]) run(["nix-collect-garbage"])
@ -37,7 +37,7 @@ def common_test(direnv_project: DirenvProject) -> None:
) )
sys.stderr.write(out2.stderr) sys.stderr.write(out2.stderr)
assert out2.returncode == 0 assert out2.returncode == 0
assert "using cached dev shell" in out2.stderr assert "Using cached dev shell" in out2.stderr
assert "Executing shellHook." in out2.stderr assert "Executing shellHook." in out2.stderr

View file

@ -30,7 +30,7 @@ def direnv_exec(
sys.stderr.write(out.stderr) sys.stderr.write(out.stderr)
assert out.returncode == 0 assert out.returncode == 0
assert out.stdout == "OK\n" assert out.stdout == "OK\n"
assert "renewed cache" in out.stderr assert "Renewed cache" in out.stderr
@pytest.mark.parametrize("strict_env", [False, True]) @pytest.mark.parametrize("strict_env", [False, True])