-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy path.envrc
164 lines (140 loc) · 4.76 KB
/
.envrc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# Derived from https://github.com/nix-community/nix-direnv/blob/master/direnvrc
# shellcheck shell=bash
_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
local old_path=${PATH:-}
local old_term=${TERM:-__UNSET__}
local old_shell=${SHELL:-__UNSET__}
local old_tmpdir=${TMPDIR:-__UNSET__}
local old_ssl_cert_file=${SSL_CERT_FILE:-__UNSET__}
local old_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
_nix_export_or_unset SSL_CERT_FILE "$old_ssl_cert_file"
fi
if [[ "${NIX_SSL_CERT_FILE:-}" = /no-cert-file.crt ]]; then
_nix_export_or_unset NIX_SSL_CERT_FILE "$old_nix_ssl_cert_file"
fi
export PATH=$PATH${old_path:+":"}$old_path
_nix_export_or_unset TERM "$old_term"
_nix_export_or_unset SHELL "$old_shell"
_nix_export_or_unset TEMPDIR "$old_tmpdir"
# 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
_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"
}
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")
# show original shell hook output
echo "$tmp" | perl -nle 'print if m{(?<=_____direnv_____).*}'
echo "$tmp" | perl -nle 'print $& while m{(?<=_____direnv_____).*}g' > "$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
}
use_nix