Fixes for PR review:

- Always create the nix-direnv-reload script
- Use 0/1 for booleans
- Avoid crashing when profile_rc does not exist
- Use better internal variable name for manual mode
- Make use_nix work
- Avoid unneccessary forks
- Fix shellcheck failures
- Update mtime on profile rc files to avoid confusion about if the files
  are up to date
- Add instructions to README.md
This commit is contained in:
Andreas Pelme 2023-06-16 21:38:16 +02:00 committed by Mic92
parent 1df80c4c3a
commit 6b5822b75b
2 changed files with 86 additions and 42 deletions

View file

@ -291,6 +291,26 @@ This leads to some limitations in what we can reasonably parse.
Currently, all single-word arguments and some well-known double arguments Currently, all single-word arguments and some well-known double arguments
will be interpeted or passed along. will be interpeted or passed along.
#### 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
nix environment is no longer up to date. You can then decide yourself when you
want to reload the nix environment.
To activate manual mode, use `nix_direnv_manual_reload` in your `.envrc` like this:
```shell
nix_direnv_manual_reload
use nix # or use flake
```
To reload your nix environment, use the `nix-direnv-reload` command:
```console
$ nix-direnv-reload
```
##### Known arguments ##### Known arguments
- `-p`: Starts a list of packages to install; consumes all remaining arguments - `-p`: Starts a list of packages to install; consumes all remaining arguments

108
direnvrc
View file

@ -34,11 +34,24 @@ _nix_direnv_preflight () {
local layout_dir local layout_dir
layout_dir=$(direnv_layout_dir) layout_dir=$(direnv_layout_dir)
if [[ ! -d "$layout_dir" ]]; then if [[ ! -d "$layout_dir/bin" ]]; then
mkdir -p "$layout_dir" mkdir -p "$layout_dir/bin"
fi fi
# shellcheck disable=SC2016
echo > "${layout_dir}/bin/nix-direnv-reload" '#!/usr/bin/env bash
dir="$(realpath $(dirname ${BASH_SOURCE[0]})/../..)"
_nix_direnv_force_reload=1 direnv exec "$dir" true
direnv reload
# direnv reload updates the mtime of .envrc. Also update the timestamp of the
# profile_rc file to keep track that we actually are up to date.
touch $dir/.direnv/{nix,flake}-profile-*.rc
'
if [[ ! -x "${layout_dir}/bin/nix-direnv-reload" ]]; then
chmod +x "${layout_dir}/bin/nix-direnv-reload"
fi
PATH_add "${layout_dir}/bin"
} }
# Usage: nix_direnv_version <version_at_least> # Usage: nix_direnv_version <version_at_least>
@ -100,6 +113,12 @@ _nix_import_env() {
local old_temp=${TEMP:-__UNSET__} local old_temp=${TEMP:-__UNSET__}
local old_tempdir=${TEMPDIR:-__UNSET__} local old_tempdir=${TEMPDIR:-__UNSET__}
local old_xdg_data_dirs=${XDG_DATA_DIRS:-} local old_xdg_data_dirs=${XDG_DATA_DIRS:-}
# On the first run in manual mode, the profile_rc does not exist.
if [[ ! -e "$profile_rc" ]]; then
return
fi
eval "$(< "$profile_rc")" eval "$(< "$profile_rc")"
# `nix print-dev-env` will create a temporary directory and use it as TMPDIR # `nix print-dev-env` will create a temporary directory and use it as TMPDIR
# We cannot rely on this directory being availble at all times, # We cannot rely on this directory being availble at all times,
@ -164,11 +183,12 @@ nix_direnv_watch_file() {
nix_watches+=("$@") nix_watches+=("$@")
} }
auto_reload=t _nix_direnv_manual_reload=0
nix_direnv_manual_reload() { nix_direnv_manual_reload() {
auto_reload=f _nix_direnv_manual_reload=1
} }
use_flake() { use_flake() {
_nix_direnv_preflight _nix_direnv_preflight
@ -199,24 +219,19 @@ use_flake() {
fi fi
done done
if [[ "$auto_reload" == "f" ]]; then
mkdir -p "${layout_dir}/bin"
echo '#!/usr/bin/env bash' > "${layout_dir}/bin/nix-direnv-reload"
echo 'dir="$(realpath $(dirname ${BASH_SOURCE[0]})/../..)"' >> "${layout_dir}/bin/nix-direnv-reload"
echo 'nix_direnv_reload=t direnv exec "$dir" true' >> "${layout_dir}/bin/nix-direnv-reload"
echo 'direnv reload' >> "${layout_dir}/bin/nix-direnv-reload"
chmod +x "${layout_dir}/bin/nix-direnv-reload"
PATH_add "${layout_dir}/bin"
fi
if [[ ! -e "$profile" if [[ ! -e "$profile"
|| ! -e "$profile_rc" || ! -e "$profile_rc"
|| "$need_update" == "1" || "$need_update" == "1"
]]; ]];
then then
if [[ "$auto_reload" == "f" && -z "$nix_direnv_reload" ]]; if [[ "$_nix_direnv_manual_reload" == "1" && -z "$_nix_direnv_force_reload" ]]; then
then if [[ -e "$profile_rc" ]]; then
log_status "nix-direnv: cache is out of date. use \"nix-direnv-reload\" to reload." log_status "nix-direnv: cache is out of date. use \"nix-direnv-reload\" to reload"
else
log_status "nix-direnv: cache does not exist. use \"nix-direnv-reload\" to create it"
fi
else else
_nix_clean_old_gcroots "$layout_dir" _nix_clean_old_gcroots "$layout_dir"
@ -365,35 +380,44 @@ use_nix() {
|| "$need_update" -eq "1" || "$need_update" -eq "1"
]]; ]];
then then
_nix_clean_old_gcroots "$layout_dir" if [[ "$_nix_direnv_manual_reload" == "1" && -z "$_nix_direnv_force_reload" ]]; then
if [[ -e "$profile_rc" ]]; then
local tmp_profile="${layout_dir}/flake-profile.$$" log_status "nix-direnv: cache is out of date. use \"nix-direnv-reload\" to reload"
local tmp_profile_rc
if [[ "$packages" != "" ]]; then
extra_args+=("--expr" "with import <nixpkgs> {}; mkShell { buildInputs = [ $packages ]; }")
else
# figure out what attribute we should build
if [[ "$attribute" == "" ]]; then
extra_args+=("--file" "$nixfile")
else else
extra_args+=("--expr" "(import ${nixfile} {}).${attribute}") log_status "nix-direnv: cache does not exist. use \"nix-direnv-reload\" to create it"
fi fi
else
_nix_clean_old_gcroots "$layout_dir"
local tmp_profile="${layout_dir}/flake-profile.$$"
local tmp_profile_rc
if [[ "$packages" != "" ]]; then
extra_args+=("--expr" "with import <nixpkgs> {}; mkShell { buildInputs = [ $packages ]; }")
else
# figure out what attribute we should build
if [[ "$attribute" == "" ]]; then
extra_args+=("--file" "$nixfile")
else
extra_args+=("--expr" "(import ${nixfile} {}).${attribute}")
fi
fi
tmp_profile_rc=$("${NIX_BIN_PREFIX}nix" \
print-dev-env \
--extra-experimental-features "nix-command flakes" \
--profile "$tmp_profile" \
--impure \
"${extra_args[@]}")
local drv
drv=$(_nix_direnv_realpath "$tmp_profile")
echo "$tmp_profile_rc" > "$profile_rc"
rm -f "$tmp_profile" "$tmp_profile"*
_nix_add_gcroot "$drv" "$profile"
log_status "nix-direnv: renewed cache"
fi fi
tmp_profile_rc=$("${NIX_BIN_PREFIX}nix" \
print-dev-env \
--extra-experimental-features "nix-command flakes" \
--profile "$tmp_profile" \
--impure \
"${extra_args[@]}")
local drv
drv=$(_nix_direnv_realpath "$tmp_profile")
echo "$tmp_profile_rc" > "$profile_rc"
rm -f "$tmp_profile" "$tmp_profile"*
_nix_add_gcroot "$drv" "$profile"
log_status "nix-direnv: renewed cache"
else else
log_status "nix-direnv: using cached dev shell" log_status "nix-direnv: using cached dev shell"
fi fi