From 6997988d1bdcbb0558d6239d1b83294d9472f53a Mon Sep 17 00:00:00 2001 From: Arthur Noel Date: Thu, 23 Nov 2023 20:37:03 +0000 Subject: [PATCH] drop nix_direnv_watch_file - instead parse DIRENV_WATCHES fixes #408 --- README.md | 8 ++++---- default.nix | 6 ++++-- direnvrc | 45 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 113b7e9..a9149e9 100644 --- a/README.md +++ b/README.md @@ -314,23 +314,23 @@ when deciding to update its cache. * `flake.lock` * `devshell.toml` if it exists -To add more files to be checked use `nix_direnv_watch_file` like this +To add more files to be checked use `watch_file` like this ```shell -nix_direnv_watch_file your-file.nix +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-files: ```shell -nix_direnv_watch_file $(find . -name "*.nix" -printf '"%p" ') +watch_file $(find . -name "*.nix" -printf '"%p" ') ``` Note that this will re-execute direnv for any nix change, regardless of whether that change is meaningful for the devShell in use. -`nix_direnv_watch_file` must be invoked before either `use flake` or `use nix` to take effect. +`watch_file` must be invoked before either `use flake` or `use nix` to take effect. ## General direnv tips diff --git a/default.nix b/default.nix index b287a36..fffb0eb 100644 --- a/default.nix +++ b/default.nix @@ -1,4 +1,4 @@ -{ stdenv, nix, gnugrep, lib }: +{ stdenv, nix, gnugrep, gzip, jq, lib }: stdenv.mkDerivation { name = "nix-direnv"; @@ -8,7 +8,9 @@ stdenv.mkDerivation { postPatch = '' sed -i "2iNIX_BIN_PREFIX=${nix}/bin/" direnvrc substituteInPlace direnvrc \ - --replace "grep" "${gnugrep}/bin/grep" + --replace "grep" "${gnugrep}/bin/grep" \ + --replace gzip "${gzip}/bin/gzip" \ + --replace JQ= "JQ=${jq}/bin/jq" ''; installPhase = '' diff --git a/direnvrc b/direnvrc index 6e622ea..02485f9 100644 --- a/direnvrc +++ b/direnvrc @@ -197,8 +197,39 @@ _nix_argsum_suffix() { } nix_direnv_watch_file() { + # shellcheck disable=2016 + log_error '`nix_direnv_watch_file` is deprecated - use `watch_file`' watch_file "$@" - nix_watches+=("$@") +} + +# set by nix build - see ./default.nix +JQ= + +_jq() { + if [[ -n $JQ ]] + then + $JQ "$@" + elif has jq + then + jq "$@" + else + nix-shell --packages jq --run "$(join_args jq "$@")" + fi +} + +_nix_direnv_watches() { + local -n _watches=$1 + # DIRENV_WATCHES is json | gzip (without header and trailer) | base64url + # allow files under $XDG_DATA_HOME/direenv/allow are filtered out as not relevant + # gzip header: https://datatracker.ietf.org/doc/html/rfc1952#page-6 + mapfile -td "" _watches < <( + # shellcheck disable=2016 + tr -- "-_" "+/" <<< "$DIRENV_WATCHES" \ + | base64 --decode \ + | (echo -ne "\x1f\x8b\x08\x00\x00\x00\x00\x00"; cat /dev/stdin) \ + | (gzip --decompress 2>/dev/null || true) \ + | _jq --join-output '.[] | select(.Exists ) | .Path | select(. | test($ENV.XDG_DATA_HOME + "/direnv/allow") | not) | (. + "\u0000")' + ) } _nix_direnv_manual_reload=0 @@ -229,7 +260,7 @@ use_flake() { files_to_watch+=("$flake_dir/flake.nix" "$flake_dir/flake.lock" "$flake_dir/devshell.toml") fi - nix_direnv_watch_file "${files_to_watch[@]}" + watch_file "${files_to_watch[@]}" local layout_dir profile layout_dir=$(direnv_layout_dir) @@ -238,8 +269,10 @@ use_flake() { local flake_inputs="${layout_dir}/flake-inputs/" local need_update=0 + local watches + _nix_direnv_watches watches local file= - for file in "${nix_watches[@]}"; do + for file in "${watches[@]}"; do if [[ "$file" -nt "$profile_rc" ]]; then need_update=1 break @@ -388,11 +421,13 @@ use_nix() { esac done - nix_direnv_watch_file "$HOME/.direnvrc" "$HOME/.config/direnv/direnvrc" ".envrc" "shell.nix" "default.nix" + watch_file "$HOME/.direnvrc" "$HOME/.config/direnv/direnvrc" ".envrc" "shell.nix" "default.nix" local need_update=0 + local watches + _nix_direnv_watches watches local file= - for file in "${nix_watches[@]}"; do + for file in "${watches[@]}"; do if [[ "$file" -nt "$profile_rc" ]]; then need_update=1 break