Use ambient Nix when available, with a two stage fallback

First, we try to use the ambient Nix version.
Then, we try to use $NIX_DIRENV_FALLBACK_NIX, which is set by default,
but can also be overridden by the user.
Only then, if neither is available, we fail.

Fixes #451.
This commit is contained in:
K900 2024-08-21 16:50:26 +03:00
parent cff4f3cb0f
commit 94def84445
3 changed files with 62 additions and 17 deletions

View file

@ -29,8 +29,10 @@ _nix_direnv_warning() {
_nix_direnv_error() { log_error "${_NIX_DIRENV_LOG_PREFIX}$*"; }
_nix_direnv_nix=""
_nix() {
nix --extra-experimental-features "nix-command flakes" "$@"
${_nix_direnv_nix} --extra-experimental-features "nix-command flakes" "$@"
}
_require_version() {
@ -53,6 +55,34 @@ _require_cmd_version() {
_require_version "$cmd" "${BASH_REMATCH[1]}" "$required"
}
_nix_direnv_resolve_nix() {
local ambient_nix
if ambient_nix=$(command -v nix); then
if _require_cmd_version "${ambient_nix}" "${NIX_MIN_VERSION}"; then
echo "${ambient_nix}"
return 0
else
_nix_direnv_warning "Nix version in PATH is too old, wanted ${NIX_MIN_VERSION}+, got $(${ambient_nix} --version), will attempt fallback"
fi
else
_nix_direnv_warning "Could not find Nix in PATH, will attempt fallback"
fi
if [ -n "${NIX_DIRENV_FALLBACK_NIX}" ]; then
if _require_cmd_version "${NIX_DIRENV_FALLBACK_NIX}" "${NIX_MIN_VERSION}"; then
echo "${NIX_DIRENV_FALLBACK_NIX}"
return 0
else
_nix_direnv_error "Fallback Nix version is too old, wanted ${NIX_MIN_VERSION}+, got $(${NIX_DIRENV_FALLBACK_NIX} --version)"
return 1
fi
else
_nix_direnv_error "Could not find fallback Nix binary, please add Nix to PATH or set NIX_DIRENV_FALLBACK_NIX"
return 1
fi
}
_nix_direnv_preflight() {
if [[ -z $direnv ]]; then
# shellcheck disable=2016
@ -66,12 +96,16 @@ _nix_direnv_preflight() {
# _require_cmd_version because _require_cmd_version uses =~ operator which would be
# a syntax error on bash < 3
if ! _require_version bash "$BASH_VERSION" "$BASH_MIN_VERSION" ||
! _require_cmd_version "$direnv" "$DIRENV_MIN_VERSION" || # direnv stdlib defines $direnv
! _require_cmd_version nix "$NIX_MIN_VERSION"; then
# direnv stdlib defines $direnv
! _require_cmd_version "$direnv" "$DIRENV_MIN_VERSION"; then
return 1
fi
fi
if ! _nix_direnv_nix=$(_nix_direnv_resolve_nix); then
return 1
fi
local layout_dir
layout_dir=$(direnv_layout_dir)