147 lines
4.1 KiB
Bash
147 lines
4.1 KiB
Bash
|
|
# shellcheck shell=bash
|
||
|
|
# adapted from https://github.com/nix-community/nix-direnv/blob/master/direnvrc
|
||
|
|
|
||
|
|
REQUIRED_DIRENV_VERSION="2.21.3"
|
||
|
|
|
||
|
|
_nix_direnv_preflight () {
|
||
|
|
if [[ -z "$direnv" ]]; then
|
||
|
|
printf '%s\n' "\$direnv environment variable was not defined. Was this script run inside direnv?"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -z ${DEVENV_BIN:-} ]]; then
|
||
|
|
DEVENV_BIN=$(command -v devenv)
|
||
|
|
if [[ -z "${DEVENV_BIN}" ]]; then
|
||
|
|
log_error "command not found: devenv, see https://devenv.sh/getting-started/"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
if ! has direnv_version || ! direnv_version "$REQUIRED_DIRENV_VERSION" 2>/dev/null; then
|
||
|
|
log_error "base direnv version is older than the required v$REQUIRED_DIRENV_VERSION."
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
local layout_dir
|
||
|
|
layout_dir=$(direnv_layout_dir)
|
||
|
|
|
||
|
|
if [[ ! -d "$layout_dir" ]]; then
|
||
|
|
mkdir -p "$layout_dir"
|
||
|
|
fi
|
||
|
|
|
||
|
|
export DEVENV_DIRENVRC_VERSION=1
|
||
|
|
export DEVENV_DIRENVRC_ROLLING_UPGRADE=1
|
||
|
|
}
|
||
|
|
|
||
|
|
_nix_export_or_unset() {
|
||
|
|
local key=$1 value=$2
|
||
|
|
if [[ "$value" == __UNSET__ ]]; then
|
||
|
|
unset "$key"
|
||
|
|
else
|
||
|
|
export "$key=$value"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
_nix_import_env() {
|
||
|
|
local env=$1
|
||
|
|
|
||
|
|
# Note which environments are active, but make sure we don't repeat them
|
||
|
|
if [[ ! "''${DIRENV_ACTIVE-}" =~ (^|:)"$PWD"(:|$) ]]; then
|
||
|
|
export DIRENV_ACTIVE="$PWD:''${DIRENV_ACTIVE-}"
|
||
|
|
fi
|
||
|
|
|
||
|
|
local old_nix_build_top=${NIX_BUILD_TOP:-__UNSET__}
|
||
|
|
local old_tmp=${TMP:-__UNSET__}
|
||
|
|
local old_tmpdir=${TMPDIR:-__UNSET__}
|
||
|
|
local old_temp=${TEMP:-__UNSET__}
|
||
|
|
local old_tempdir=${TEMPDIR:-__UNSET__}
|
||
|
|
local old_xdg_data_dirs=${XDG_DATA_DIRS:-}
|
||
|
|
eval "$env"
|
||
|
|
# `nix print-dev-env` will create a temporary directory and use it as TMPDIR
|
||
|
|
# We cannot rely on this directory being available at all times,
|
||
|
|
# as it may be garbage collected.
|
||
|
|
# Instead - just remove it immediately.
|
||
|
|
# Use recursive & force as it may not be empty.
|
||
|
|
if [[ -n "${NIX_BUILD_TOP+x}" && "$NIX_BUILD_TOP" == */nix-shell.* && -d "$NIX_BUILD_TOP" ]]; then
|
||
|
|
rm -rf "$NIX_BUILD_TOP"
|
||
|
|
fi
|
||
|
|
|
||
|
|
_nix_export_or_unset NIX_BUILD_TOP "$old_nix_build_top"
|
||
|
|
_nix_export_or_unset TMP "$old_tmp"
|
||
|
|
_nix_export_or_unset TMPDIR "$old_tmpdir"
|
||
|
|
_nix_export_or_unset TEMP "$old_temp"
|
||
|
|
_nix_export_or_unset TEMPDIR "$old_tempdir"
|
||
|
|
local new_xdg_data_dirs=${XDG_DATA_DIRS:-}
|
||
|
|
export XDG_DATA_DIRS=
|
||
|
|
local IFS=:
|
||
|
|
for dir in $new_xdg_data_dirs${old_xdg_data_dirs:+:}$old_xdg_data_dirs; do
|
||
|
|
dir="${dir%/}" # remove trailing slashes
|
||
|
|
if [[ :$XDG_DATA_DIRS: = *:$dir:* ]]; then
|
||
|
|
continue # already present, skip
|
||
|
|
fi
|
||
|
|
XDG_DATA_DIRS="$XDG_DATA_DIRS${XDG_DATA_DIRS:+:}$dir"
|
||
|
|
done
|
||
|
|
}
|
||
|
|
|
||
|
|
nix_direnv_watch_file() {
|
||
|
|
log_error "nix_direnv_watch_file is deprecated. Use watch_file instead."
|
||
|
|
watch_file "$@"
|
||
|
|
}
|
||
|
|
|
||
|
|
_devenv_watches() {
|
||
|
|
local path=$1
|
||
|
|
local -n _watches=$2
|
||
|
|
if [[ -f "$path" ]]; then
|
||
|
|
while IFS= read -r file; do
|
||
|
|
file=$(printf "$file")
|
||
|
|
_watches+=("$file")
|
||
|
|
done < "$path"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
use_devenv() {
|
||
|
|
_nix_direnv_preflight
|
||
|
|
|
||
|
|
flake_expr="${1:-.}"
|
||
|
|
flake_dir="${flake_expr%#*}"
|
||
|
|
env_deps_path="$flake_dir/.devenv/input-paths.txt"
|
||
|
|
|
||
|
|
local default_watches
|
||
|
|
default_watches=(".envrc" "$HOME/.direnvrc" "$HOME/.config/direnv/direnvrc")
|
||
|
|
|
||
|
|
if [[ -d "$flake_dir" ]]; then
|
||
|
|
default_watches+=("$flake_dir/devenv.nix" "$flake_dir/devenv.lock" "$flake_dir/devenv.yaml" "$flake_dir/devenv.local.nix")
|
||
|
|
|
||
|
|
if [[ -f "$flake_dir/devenv.yaml" ]]; then
|
||
|
|
if ! devenv assemble; then
|
||
|
|
log_error "$(devenv version) failed to parse devenv.yaml, make sure to use version 0.6 or newer and fix the errors above."
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Watch the default files.
|
||
|
|
# Even if evaluation fails, these files should still trigger a reload.
|
||
|
|
watch_file "${default_watches[@]}"
|
||
|
|
|
||
|
|
# Fetch and watch files that affect the env
|
||
|
|
local env_watches
|
||
|
|
_devenv_watches "$env_deps_path" env_watches
|
||
|
|
watch_file "${env_watches[@]}"
|
||
|
|
|
||
|
|
# Build the environment
|
||
|
|
local env
|
||
|
|
if ! env=$("${DEVENV_BIN}" print-dev-env); then
|
||
|
|
log_error "failed to build the devenv environment. devenv.nix may contain errors. see above."
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Re-watch files that affect the env
|
||
|
|
local env_watches
|
||
|
|
_devenv_watches "$env_deps_path" env_watches
|
||
|
|
watch_file "${env_watches[@]}"
|
||
|
|
|
||
|
|
# Import the environment
|
||
|
|
_nix_import_env "$env"
|
||
|
|
}
|