# 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" }