-
-
Notifications
You must be signed in to change notification settings - Fork 24
/
envrc.bash
175 lines (139 loc) · 5.31 KB
/
envrc.bash
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
165
166
167
168
169
170
171
172
173
174
175
#!/usr/bin/env bash
# ^ shebang is unused as this file is sourced, but present for editor
# integration. Note: Direnv guarantees it *will* be parsed using bash.
function punt () {
:
}
# move "origPreHook" "preHook" "$@";;
move() {
srcvarname=$1 # example: varname might contain the string "origPATH"
# drop off the source variable name
shift
destvarname=$1 # example: destvarname might contain the string "PATH"
# drop off the destination variable name
shift
# like: export origPATH="...some-value..."
export "${@?}";
# set $original to the contents of the variable $srcvarname
# refers to
eval "$destvarname=\"${!srcvarname}\""
# mark the destvarname as exported so direnv picks it up
# (shellcheck: we do want to export the content of destvarname!)
# shellcheck disable=SC2163
export "$destvarname"
# remove the export from above, ie: export origPATH...
unset "$srcvarname"
}
function prepend() {
varname=$1 # example: varname might contain the string "PATH"
# drop off the varname
shift
separator=$1 # example: separator would usually be the string ":"
# drop off the separator argument, so the remaining arguments
# are the arguments to export
shift
# set $original to the contents of the the variable $varname
# refers to
original="${!varname}"
# effectfully accept the new variable's contents
export "${@?}";
# re-set $varname's variable to the contents of varname's
# reference, plus the current (updated on the export) contents.
# however, exclude the ${separator} unless ${original} starts
# with a value
eval "$varname=\"${!varname}${original:+${separator}${original}}\""
}
function append() {
varname=$1 # example: varname might contain the string "PATH"
# drop off the varname
shift
separator=$1 # example: separator would usually be the string ":"
# drop off the separator argument, so the remaining arguments
# are the arguments to export
shift
# set $original to the contents of the the variable $varname
# refers to
original="${!varname:-}"
# effectfully accept the new variable's contents
export "${@?}";
# re-set $varname's variable to the contents of varname's
# reference, plus the current (updated on the export) contents.
# however, exclude the ${separator} unless ${original} starts
# with a value
eval "$varname=${original:+${original}${separator}}${!varname}"
}
varmap() {
if [ -f "$EVALUATION_ROOT/varmap-v1" ]; then
# Capture the name of the variable being set
IFS="=" read -r -a cur_varname <<< "$1"
# With IFS='' and the `read` delimiter being '', we achieve
# splitting on \0 bytes while also preserving leading
# whitespace:
#
# bash-3.2$ printf ' <- leading space\0bar\0baz\0' \
# | (while IFS='' read -d $'\0' -r x; do echo ">$x<"; done)
# > <- leading space<
# >bar<
# >baz<```
while IFS='' read -r -d '' map_instruction \
&& IFS='' read -r -d '' map_variable \
&& IFS='' read -r -d '' map_separator; do
unset IFS
if [ "$map_variable" == "${cur_varname[0]}" ]; then
if [ "$map_instruction" == "append" ]; then
append "$map_variable" "$map_separator" "$@"
return
fi
fi
done < "$EVALUATION_ROOT/varmap-v1"
fi
export "${@?}"
}
function declare() {
if [ "$1" == "-x" ]; then shift; fi
# Some variables require special handling.
#
# - punt: don't set the variable at all
# - prepend: take the new value, and put it before the current value.
case "$1" in
# vars from: https://github.com/NixOS/nix/blob/92d08c02c84be34ec0df56ed718526c382845d1a/src/nix-build/nix-build.cc#L100
"HOME="*) punt;;
"USER="*) punt;;
"LOGNAME="*) punt;;
"DISPLAY="*) punt;;
"PATH="*) prepend "PATH" ":" "$@";;
"TERM="*) punt;;
"IN_NIX_SHELL="*) punt;;
"TZ="*) punt;;
"PAGER="*) punt;;
"NIX_BUILD_SHELL="*) punt;;
"SHLVL="*) punt;;
# vars from: https://github.com/NixOS/nix/blob/92d08c02c84be34ec0df56ed718526c382845d1a/src/nix-build/nix-build.cc#L385
"TEMPDIR="*) punt;;
"TMPDIR="*) punt;;
"TEMP="*) punt;;
"TMP="*) punt;;
# vars from: https://github.com/NixOS/nix/blob/92d08c02c84be34ec0df56ed718526c382845d1a/src/nix-build/nix-build.cc#L421
"NIX_ENFORCE_PURITY="*) punt;;
# vars from: https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html (last checked: 2019-09-26)
# reported in https://github.com/target/lorri/issues/153
"OLDPWD="*) punt;;
"PWD="*) punt;;
"SHELL="*) punt;;
# https://github.com/target/lorri/issues/97
"preHook="*) punt;;
"origPreHook="*) move "origPreHook" "preHook" "$@";;
*) varmap "$@" ;;
esac
}
export IN_NIX_SHELL=impure
if [ -f "$EVALUATION_ROOT/bash-export" ]; then
# shellcheck disable=SC1090
# shellcheck disable=SC1091
source "$EVALUATION_ROOT/bash-export"
elif [ -f "$EVALUATION_ROOT" ]; then
# shellcheck disable=SC1090
# shellcheck disable=SC1091
source "$EVALUATION_ROOT"
fi
unset declare