# shellcheck shell=bash _nix_import_env() { local env=$1 local term_backup=$TERM path_backup=$PATH if [[ -n ${TMPDIR+x} ]]; then local tmp_backup=$TMPDIR fi local impure_ssl_cert_file=${SSL_CERT_FILE:-__UNSET__} local impure_nix_ssl_cert_file=${NIX_SSL_CERT_FILE:-__UNSET__} eval "$env" # `nix-shell --pure` sets invalid ssl certificate paths if [[ "${SSL_CERT_FILE:-}" = /no-cert-file.crt ]]; then if [[ $impure_ssl_cert_file == __UNSET__ ]]; then unset SSL_CERT_FILE else export SSL_CERT_FILE=$impure_ssl_cert_file fi fi if [[ "${NIX_SSL_CERT_FILE:-}" = /no-cert-file.crt ]]; then if [[ $impure_nix_ssl_cert_file == __UNSET__ ]]; then unset NIX_SSL_CERT_FILE else export NIX_SSL_CERT_FILE=${impure_nix_ssl_cert_file} fi fi export PATH=$PATH:$path_backup TERM=$term_backup if [[ -n ${tmp_backup+x} ]]; then export TMPDIR=${tmp_backup} else unset TMPDIR fi # misleading since we are in an impure shell now export IN_NIX_SHELL=impure } _nix_add_gcroot() { local storepath=$1 local symlink=$2 local stripped_pwd=${PWD/\//} local escaped_pwd=${stripped_pwd//-/--} local escaped_pwd=${escaped_pwd//\//-} ln -fs "$storepath" "$symlink" ln -fs "$symlink" "/nix/var/nix/gcroots/per-user/$USER/$escaped_pwd" } use_flake() { watch_file flake.nix watch_file flake.lock local profile="$(direnv_layout_dir)/flake-profile" local profile_rc="${profile}.rc" if [[ ! -e "$profile" ]] || \ [[ ! -e "$profile_rc" ]] || \ [[ "$HOME/.direnvrc" -nt "$profile_rc" ]] || \ [[ .envrc -nt "$profile_rc" ]] || \ [[ flake.nix -nt "$profile_rc" ]] || \ [[ flake.lock -nt "$profile_rc" ]]; then local tmp_profile="$(direnv_layout_dir)/flake-profile.$$" [[ -d "$(direnv_layout_dir)" ]] || mkdir "$(direnv_layout_dir)" local tmp_profile_rc=$(nix print-dev-env --profile "$tmp_profile") drv=$(realpath "$tmp_profile") echo "$tmp_profile_rc" > "$profile_rc" rm -f "$tmp_profile" "$tmp_profile"* _nix_add_gcroot "$drv" "$profile" log_status renewed cache else log_status using cached dev shell 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__} eval "$(< "$profile_rc")" # nix print-env-dev will create a temporary directory and use it a TMPDIR, # we cannot rely on this directory beeing not deleted at some point, # hence we are just removing it right away. if [[ "$NIX_BUILD_TOP" == */nix-shell.* && -d "$NIX_BUILD_TOP" ]]; then rmdir "$NIX_BUILD_TOP" fi if [[ "$old_nix_build_top" == __UNSET__ ]]; then unset NIX_BUILD_TOP else export NIX_BUILD_TOP=$old_nix_build_top fi if [[ "$old_tmp" == __UNSET__ ]]; then unset TMP else export TMP=$old_temp fi if [[ "$old_tmpdir" == __UNSET__ ]]; then unset TMPDIR else export TMPDIR=$old_tmpdir fi if [[ "$old_temp" == __UNSET__ ]]; then unset TEMP else export TEMP=$old_temp fi if [[ "$old_tempdir" == __UNSET__ ]]; then unset TEMPDIR else export TEMPDIR=$old_tempdir fi } use_nix() { local path direnv_dir path=$(nix-instantiate --find-file nixpkgs) direnv_dir=$(direnv_layout_dir) if [[ "${direnv:-}" == "" ]]; then log_status "\$direnv environment variable was not defined. Was this script run inside direnv?" fi local version if [[ -f "${path}/.version-suffix" ]]; then version=$(< "${path}/.version-suffix") elif [[ -f "${path}/.git/HEAD" ]]; then local head read -r head < "${path}/.git/HEAD" local regex="ref: (.*)" if [[ "$head" =~ $regex ]]; then read -r version < ".git/${BASH_REMATCH[1]}" else version="$head" fi fi local cache="$direnv_dir/cache-${version:-unknown}" local update_drv=0 if [[ ! -e "$cache" ]] || \ [[ "$HOME/.direnvrc" -nt "$cache" ]] || \ [[ .envrc -nt "$cache" ]] || \ [[ default.nix -nt "$cache" ]] || \ [[ shell.nix -nt "$cache" ]]; then [[ -d "$direnv_dir" ]] || mkdir "$direnv_dir" local dump_cmd tmp dump_cmd="echo -n _____direnv_____; \"$direnv\" dump bash" tmp=$(nix-shell --show-trace --pure "$@" --run "$dump_cmd" \ | grep -oP '(?<=_____direnv_____).*') echo "$tmp" > "$cache" update_drv=1 else log_status using cached derivation fi log_status eval "$cache" read -r cache_content < "$cache" _nix_import_env "$cache_content" # This part is based on https://discourse.nixos.org/t/what-is-the-best-dev-workflow-around-nix-shell/418/4 if [[ "${out:-}" != "" ]] && (( update_drv )); then local drv_link="${direnv_dir}/drv" drv drv=$(nix show-derivation "$out" | grep -E -o -m1 '/nix/store/.*.drv') _nix_add_gcroot "$drv" "$drv_link" log_status renewed cache and derivation link fi if [[ "$#" == 0 ]]; then watch_file default.nix watch_file shell.nix fi }