-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnz
executable file
·307 lines (271 loc) · 8.12 KB
/
nz
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
#!/usr/bin/env bash
set -e
set -o pipefail
NZ_DEPS=("curl" "jq" "basename" "tar" "find" "readlink")
NZ_DEP_ERR=100
NZ_ARCH_OS="unknown"
NZ_PLATFORM_ERR=101
NZ_JSON_URL="https://ziglang.org/download/index.json"
NZ_DIR="$HOME/.night.zig"
NZ_VERSION="0.2.0"
NZ_USAGE="
USAGE:
nz <SUBCOMMAND>
SUBCOMMANDS:
update Update both zig nightly toolchain & nz itself
update nightly Update zig nightly toolchain only
update nz Update nz itself only
cleanup Remove outdated nightly toolchains
version Show nz version info
help Show this message
"
#https://stackoverflow.com/a/33297950
function check_dep {
local dep="$1"
if command -v "$dep" >/dev/null 2>&1 ; then
return 0
else
return "$NZ_DEP_ERR"
fi
}
function script_echo {
printf '[night.zig] %b\n' "$1"
}
function check_deps {
for dep in "${NZ_DEPS[@]}"; do
if check_dep "$dep"; then
:
else
>&2 script_echo "Dependency ${dep} is not installed. Exiting now..."
exit "$NZ_DEP_ERR"
fi
done
}
function arch_info {
local arch
local uname_m
uname_m="$(uname -m)"
if [[ "$uname_m" == "arm64" ]]; then
arch="aarch64"
elif [[ "$uname_m" == "amd64" ]]; then
arch="x86_64"
elif [[ "$uname_m" == "x86_64" ]]; then
arch="x86_64"
elif [[ "$uname_m" == "i386" ]]; then
arch="x86"
elif [[ "$uname_m" == "riscv64" ]]; then
arch="riscv64"
elif [[ "$uname_m" == "powerpc" ]]; then
arch="powerpc"
elif [[ "$uname_m" == "ppc64el" ]]; then
arch="powerpc64le"
else
arch="unknown"
fi
echo "$arch"
}
# https://stackoverflow.com/a/8597411
function os_info {
local os
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
os="linux"
elif [[ "$OSTYPE" == "darwin"* ]]; then
os="macos"
elif [[ "$OSTYPE" == "cygwin" ]]; then
# POSIX compatibility layer and Linux environment emulation for Windows
os="windows"
elif [[ "$OSTYPE" == "msys" ]]; then
# Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
os="windows"
elif [[ "$OSTYPE" == "win32" ]]; then
# I'm not sure this can happen.
os="windows"
elif [[ "$OSTYPE" == "freebsd"* ]]; then
os="unknown"
else
os="unknown"
fi
echo "$os"
}
function validate_platform {
NZ_ARCH_OS="$(arch_info)-$(os_info)"
if [[ "$NZ_ARCH_OS" == *"unknown"* ]]; then
>&2 script_echo "No prebuilt nightly binary available for ${NZ_ARCH_OS}. Exiting now..."
exit "$NZ_PLATFORM_ERR"
else
:
fi
}
function nightly_needs_update {
local upstream_ver="$1"
local latest_dir_name="$(basename "$(readlink -f "$NZ_DIR"/latest)")"
if [[ "$latest_dir_name" == *"$upstream_ver"* ]]; then
return 1
else
return 0
fi
}
# works for both macOS and linux
# https://unix.stackexchange.com/a/84980
function mktempdir {
mktemp -d 2>/dev/null || mktemp -d -t 'tmpdir'
}
function fetch_tar {
local tar_url="$1"
local tar_name="$(basename "$tar_url")"
local temp_dir="$(mktempdir)"
script_echo "Fetching nightly tar ball...\n"
curl --output-dir "$temp_dir" --output "$tar_name" "$tar_url"
script_echo "Fetch completed.\n"
echo "$temp_dir/$tar_name"
}
function unpack_tar {
local tar_path="$1"
mkdir -p "$NZ_DIR"
local containing_dir="$(tar -tf "$tar_path" | head -1)"
local new_install_dir_name="${containing_dir%/}"
script_echo "Extracting nightly tar ball...\n"
tar -xf "$tar_path" -C "$NZ_DIR"
script_echo "Extraction completed.\n"
echo "$new_install_dir_name"
}
function config_latest {
script_echo "Configuring latest nightly...\n"
local new_install_dir_name="$1"
(
cd "$NZ_DIR"
rm -f latest
ln -s "$new_install_dir_name" latest
)
script_echo "Latest nightly configured.\n"
}
function install_nightly {
local tar_url="$1"
local tar_path="$(fetch_tar "$tar_url" | tee /dev/tty | tail -n 1)"
local new_install_dir_name="$(unpack_tar "$tar_path" | tee /dev/tty | tail -n 1)"
config_latest "$new_install_dir_name"
}
function update_nightly_if_necessary {
script_echo "Checking upstream nightly version...\n"
local json="$(curl "$NZ_JSON_URL")"
local upstream_ver="$(jq -n "$json" | jq -r ".master.version")"
if nightly_needs_update "$upstream_ver"; then
script_echo "Your nighly is outdated, updating now...\n"
local tar_url="$(jq -n "$json" | jq -r ".master.\"$NZ_ARCH_OS\".tarball")"
install_nightly "$tar_url"
script_echo "Nightly update completed.\n"
else
script_echo "Your nightly is already up to date. Skip updating...\n"
fi
}
function deploy_nz {
# I know it's confusing naming
# so the full path of `nz` is:
# ~/.night.zig/nz/nz
local nz_bin_dir="$NZ_DIR"/nz
mkdir -p "$nz_bin_dir"
rm -f "$nz_bin_dir"/nz
script_echo "Deploying latest nz...\n"
curl --output-dir "$nz_bin_dir" --output "nz" "https://raw.githubusercontent.com/jsomedon/night.zig/main/nz"
chmod +x "$nz_bin_dir"/nz
script_echo "Latest nz deployed successfully.\n"
}
function rm_outdated_nightly {
script_echo "Cleaning up outdated nightly bins...\n"
(
cd "$NZ_DIR"
local to_be_removed=$(find "." -maxdepth 1 ! -name "nz" ! -name "latest" ! -name "$(basename "$(readlink -f latest)")" ! -name ".")
for tbr in $to_be_removed; do
echo "removing ${NZ_DIR}/$(basename "$tbr")..."
rm -rf "$tbr"
done
)
script_echo "Cleanup completed.\n"
}
function show_version {
script_echo "version $NZ_VERSION"
}
function deploy_nightly {
local json="$(curl "$NZ_JSON_URL")"
local tar_url="$(jq -n "$json" | jq -r ".master.\"$NZ_ARCH_OS\".tarball")"
script_echo "Deploying latest nightly...\n"
install_nightly "$tar_url"
script_echo "Latest nightly deployed successfully.\n"
}
function path_needs_config {
local path=$1
if [[ "$PATH" == *"$path"* ]]; then
return 1
else
return 0
fi
}
function config_path {
local path=$1
script_echo "Adding ${path} to \$PATH...\n"
# script_echo "You should config your \$PATH; put this line in your shell's profile file:"
# script_echo "export PATH=${path}:\$PATH\n"
local os="$(os_info)"
local bash_profile
if [[ "$os" == "macos" ]];then
bash_profile="${HOME}/.bash_profile"
elif [[ "$os" == "linux" ]];then
bash_profile="${HOME}/.bashrc"
else
script_echo "\$PATH auto configuration is not supported on this system: ${os}"
script_echo "You should manually configure your \$PATH; put this line in your shell's profile file:"
script_echo "export PATH=${path}:\$PATH\n"
return 0
fi
echo "export PATH=${path}:\$PATH" >> "$bash_profile"
script_echo "Added ${path} to \$PATH.\n"
}
function config_path_if_necessary {
local path=$1
if path_needs_config "$path"; then
config_path "$path"
else
:
fi
}
function show_help {
show_version
printf "%s" "$NZ_USAGE"
}
function main {
check_deps
validate_platform
if [[ $# -eq 0 ]]; then
show_help
elif [[ $1 == "update" ]]; then
if [[ $# -eq 1 ]]; then
update_nightly_if_necessary
deploy_nz
elif [[ $# -eq 2 ]]; then
if [[ $2 == "nightly" ]]; then
update_nightly_if_necessary
elif [[ $2 == "nz" ]]; then
deploy_nz
else
show_help
fi
else
show_help
fi
elif [[ $1 == "cleanup" ]]; then
rm_outdated_nightly
elif [[ $1 == "version" ]]; then
show_version
elif [[ $1 == "_bootstrap" ]]; then
# hidden option, only used upon first time install
script_echo "Starting fresh installation...\n"
deploy_nightly
deploy_nz
script_echo "Installation completed.\n"
config_path_if_necessary "$NZ_DIR"/latest
config_path_if_necessary "$NZ_DIR"/nz
else
show_help
fi
}
main "$@"