SuperMiner commited on
Commit
fd45fd1
·
1 Parent(s): 2dd230d
Files changed (1) hide show
  1. assets/uv-installer.sh +2080 -0
assets/uv-installer.sh ADDED
@@ -0,0 +1,2080 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ # shellcheck shell=dash
3
+ # shellcheck disable=SC2039 # local is non-POSIX
4
+ #
5
+ # Licensed under the MIT license
6
+ # <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7
+ # option. This file may not be copied, modified, or distributed
8
+ # except according to those terms.
9
+
10
+ # This runs on Unix shells like bash/dash/ksh/zsh. It uses the common `local`
11
+ # extension. Note: Most shells limit `local` to 1 var per line, contra bash.
12
+
13
+ # Some versions of ksh have no `local` keyword. Alias it to `typeset`, but
14
+ # beware this makes variables global with f()-style function syntax in ksh93.
15
+ # mksh has this alias by default.
16
+ has_local() {
17
+ # shellcheck disable=SC2034 # deliberately unused
18
+ local _has_local
19
+ }
20
+
21
+ has_local 2>/dev/null || alias local=typeset
22
+
23
+ set -u
24
+
25
+ APP_NAME="uv"
26
+ APP_VERSION="0.8.22"
27
+ # Look for GitHub Enterprise-style base URL first
28
+ if [ -n "${UV_INSTALLER_GHE_BASE_URL:-}" ]; then
29
+ INSTALLER_BASE_URL="$UV_INSTALLER_GHE_BASE_URL"
30
+ else
31
+ INSTALLER_BASE_URL="${UV_INSTALLER_GITHUB_BASE_URL:-https://github.com}"
32
+ fi
33
+ if [ -n "${UV_DOWNLOAD_URL:-}" ]; then
34
+ ARTIFACT_DOWNLOAD_URL="$UV_DOWNLOAD_URL"
35
+ elif [ -n "${INSTALLER_DOWNLOAD_URL:-}" ]; then
36
+ ARTIFACT_DOWNLOAD_URL="$INSTALLER_DOWNLOAD_URL"
37
+ else
38
+ ARTIFACT_DOWNLOAD_URL="${INSTALLER_BASE_URL}/astral-sh/uv/releases/download/0.8.22"
39
+ fi
40
+ if [ -n "${UV_PRINT_VERBOSE:-}" ]; then
41
+ PRINT_VERBOSE="$UV_PRINT_VERBOSE"
42
+ else
43
+ PRINT_VERBOSE=${INSTALLER_PRINT_VERBOSE:-0}
44
+ fi
45
+ if [ -n "${UV_PRINT_QUIET:-}" ]; then
46
+ PRINT_QUIET="$UV_PRINT_QUIET"
47
+ else
48
+ PRINT_QUIET=${INSTALLER_PRINT_QUIET:-0}
49
+ fi
50
+ if [ -n "${UV_NO_MODIFY_PATH:-}" ]; then
51
+ NO_MODIFY_PATH="$UV_NO_MODIFY_PATH"
52
+ else
53
+ NO_MODIFY_PATH=${INSTALLER_NO_MODIFY_PATH:-0}
54
+ fi
55
+ if [ "${UV_DISABLE_UPDATE:-0}" = "1" ]; then
56
+ INSTALL_UPDATER=0
57
+ else
58
+ INSTALL_UPDATER=1
59
+ fi
60
+ UNMANAGED_INSTALL="${UV_UNMANAGED_INSTALL:-}"
61
+ if [ -n "${UNMANAGED_INSTALL}" ]; then
62
+ NO_MODIFY_PATH=1
63
+ INSTALL_UPDATER=0
64
+ fi
65
+ AUTH_TOKEN="${UV_GITHUB_TOKEN:-}"
66
+
67
+ read -r RECEIPT <<EORECEIPT
68
+ {"binaries":["CARGO_DIST_BINS"],"binary_aliases":{},"cdylibs":["CARGO_DIST_DYLIBS"],"cstaticlibs":["CARGO_DIST_STATICLIBS"],"install_layout":"unspecified","install_prefix":"AXO_INSTALL_PREFIX","modify_path":true,"provider":{"source":"cargo-dist","version":"0.30.0"},"source":{"app_name":"uv","name":"uv","owner":"astral-sh","release_type":"github"},"version":"0.8.22"}
69
+ EORECEIPT
70
+
71
+ # Some Linux distributions don't set HOME
72
+ # https://github.com/astral-sh/uv/issues/6965#issuecomment-2915796022
73
+ get_home() {
74
+ if [ -n "${HOME:-}" ]; then
75
+ echo "$HOME"
76
+ elif [ -n "${USER:-}" ]; then
77
+ getent passwd "$USER" | cut -d: -f6
78
+ else
79
+ getent passwd "$(id -un)" | cut -d: -f6
80
+ fi
81
+ }
82
+ # The HOME reference to show in user output. If `$HOME` isn't set, we show the absolute path instead.
83
+ get_home_expression() {
84
+ if [ -n "${HOME:-}" ]; then
85
+ # shellcheck disable=SC2016
86
+ echo '$HOME'
87
+ elif [ -n "${USER:-}" ]; then
88
+ getent passwd "$USER" | cut -d: -f6
89
+ else
90
+ getent passwd "$(id -un)" | cut -d: -f6
91
+ fi
92
+ }
93
+ INFERRED_HOME=$(get_home)
94
+ # shellcheck disable=SC2034
95
+ INFERRED_HOME_EXPRESSION=$(get_home_expression)
96
+ RECEIPT_HOME="${XDG_CONFIG_HOME:-$INFERRED_HOME/.config}/uv"
97
+
98
+ usage() {
99
+ # print help (this cat/EOF stuff is a "heredoc" string)
100
+ cat <<EOF
101
+ uv-installer.sh
102
+
103
+ The installer for uv 0.8.22
104
+
105
+ This script detects what platform you're on and fetches an appropriate archive from
106
+ https://github.com/astral-sh/uv/releases/download/0.8.22
107
+ then unpacks the binaries and installs them to the first of the following locations
108
+
109
+ \$XDG_BIN_HOME
110
+ \$XDG_DATA_HOME/../bin
111
+ \$HOME/.local/bin
112
+
113
+ It will then add that dir to PATH by adding the appropriate line to your shell profiles.
114
+
115
+ USAGE:
116
+ uv-installer.sh [OPTIONS]
117
+
118
+ OPTIONS:
119
+ -v, --verbose
120
+ Enable verbose output
121
+
122
+ -q, --quiet
123
+ Disable progress output
124
+
125
+ --no-modify-path
126
+ Don't configure the PATH environment variable
127
+
128
+ -h, --help
129
+ Print help information
130
+ EOF
131
+ }
132
+
133
+ download_binary_and_run_installer() {
134
+ downloader --check
135
+ need_cmd uname
136
+ need_cmd mktemp
137
+ need_cmd chmod
138
+ need_cmd mkdir
139
+ need_cmd rm
140
+ need_cmd tar
141
+ need_cmd grep
142
+ need_cmd cat
143
+
144
+ for arg in "$@"; do
145
+ case "$arg" in
146
+ --help)
147
+ usage
148
+ exit 0
149
+ ;;
150
+ --quiet)
151
+ PRINT_QUIET=1
152
+ ;;
153
+ --verbose)
154
+ PRINT_VERBOSE=1
155
+ ;;
156
+ --no-modify-path)
157
+ say "--no-modify-path has been deprecated; please set UV_NO_MODIFY_PATH=1 in the environment"
158
+ NO_MODIFY_PATH=1
159
+ ;;
160
+ *)
161
+ OPTIND=1
162
+ if [ "${arg%%--*}" = "" ]; then
163
+ err "unknown option $arg"
164
+ fi
165
+ while getopts :hvq sub_arg "$arg"; do
166
+ case "$sub_arg" in
167
+ h)
168
+ usage
169
+ exit 0
170
+ ;;
171
+ v)
172
+ # user wants to skip the prompt --
173
+ # we don't need /dev/tty
174
+ PRINT_VERBOSE=1
175
+ ;;
176
+ q)
177
+ # user wants to skip the prompt --
178
+ # we don't need /dev/tty
179
+ PRINT_QUIET=1
180
+ ;;
181
+ *)
182
+ err "unknown option -$OPTARG"
183
+ ;;
184
+ esac
185
+ done
186
+ ;;
187
+ esac
188
+ done
189
+
190
+ get_architecture || return 1
191
+ local _true_arch="$RETVAL"
192
+ assert_nz "$_true_arch" "arch"
193
+ local _cur_arch="$_true_arch"
194
+
195
+
196
+ # look up what archives support this platform
197
+ local _artifact_name
198
+ _artifact_name="$(select_archive_for_arch "$_true_arch")" || return 1
199
+ local _bins
200
+ local _zip_ext
201
+ local _arch
202
+ local _checksum_style
203
+ local _checksum_value
204
+
205
+ # destructure selected archive info into locals
206
+ case "$_artifact_name" in
207
+ "uv-aarch64-apple-darwin.tar.gz")
208
+ _arch="aarch64-apple-darwin"
209
+ _zip_ext=".tar.gz"
210
+ _bins="uv uvx"
211
+ _bins_js_array='"uv","uvx"'
212
+ _libs=""
213
+ _libs_js_array=""
214
+ _staticlibs=""
215
+ _staticlibs_js_array=""
216
+ _updater_name=""
217
+ _updater_bin=""
218
+ ;;
219
+ "uv-aarch64-pc-windows-msvc.zip")
220
+ _arch="aarch64-pc-windows-msvc"
221
+ _zip_ext=".zip"
222
+ _bins="uv.exe uvx.exe uvw.exe"
223
+ _bins_js_array='"uv.exe","uvx.exe","uvw.exe"'
224
+ _libs=""
225
+ _libs_js_array=""
226
+ _staticlibs=""
227
+ _staticlibs_js_array=""
228
+ _updater_name=""
229
+ _updater_bin=""
230
+ ;;
231
+ "uv-aarch64-unknown-linux-gnu.tar.gz")
232
+ _arch="aarch64-unknown-linux-gnu"
233
+ _zip_ext=".tar.gz"
234
+ _bins="uv uvx"
235
+ _bins_js_array='"uv","uvx"'
236
+ _libs=""
237
+ _libs_js_array=""
238
+ _staticlibs=""
239
+ _staticlibs_js_array=""
240
+ _updater_name=""
241
+ _updater_bin=""
242
+ ;;
243
+ "uv-aarch64-unknown-linux-musl.tar.gz")
244
+ _arch="aarch64-unknown-linux-musl-static"
245
+ _zip_ext=".tar.gz"
246
+ _bins="uv uvx"
247
+ _bins_js_array='"uv","uvx"'
248
+ _libs=""
249
+ _libs_js_array=""
250
+ _staticlibs=""
251
+ _staticlibs_js_array=""
252
+ _updater_name=""
253
+ _updater_bin=""
254
+ ;;
255
+ "uv-arm-unknown-linux-musleabihf.tar.gz")
256
+ _arch="arm-unknown-linux-musl-staticeabihf"
257
+ _zip_ext=".tar.gz"
258
+ _bins="uv uvx"
259
+ _bins_js_array='"uv","uvx"'
260
+ _libs=""
261
+ _libs_js_array=""
262
+ _staticlibs=""
263
+ _staticlibs_js_array=""
264
+ _updater_name=""
265
+ _updater_bin=""
266
+ ;;
267
+ "uv-armv7-unknown-linux-gnueabihf.tar.gz")
268
+ _arch="armv7-unknown-linux-gnueabihf"
269
+ _zip_ext=".tar.gz"
270
+ _bins="uv uvx"
271
+ _bins_js_array='"uv","uvx"'
272
+ _libs=""
273
+ _libs_js_array=""
274
+ _staticlibs=""
275
+ _staticlibs_js_array=""
276
+ _updater_name=""
277
+ _updater_bin=""
278
+ ;;
279
+ "uv-armv7-unknown-linux-musleabihf.tar.gz")
280
+ _arch="armv7-unknown-linux-musl-staticeabihf"
281
+ _zip_ext=".tar.gz"
282
+ _bins="uv uvx"
283
+ _bins_js_array='"uv","uvx"'
284
+ _libs=""
285
+ _libs_js_array=""
286
+ _staticlibs=""
287
+ _staticlibs_js_array=""
288
+ _updater_name=""
289
+ _updater_bin=""
290
+ ;;
291
+ "uv-i686-pc-windows-msvc.zip")
292
+ _arch="i686-pc-windows-msvc"
293
+ _zip_ext=".zip"
294
+ _bins="uv.exe uvx.exe uvw.exe"
295
+ _bins_js_array='"uv.exe","uvx.exe","uvw.exe"'
296
+ _libs=""
297
+ _libs_js_array=""
298
+ _staticlibs=""
299
+ _staticlibs_js_array=""
300
+ _updater_name=""
301
+ _updater_bin=""
302
+ ;;
303
+ "uv-i686-unknown-linux-gnu.tar.gz")
304
+ _arch="i686-unknown-linux-gnu"
305
+ _zip_ext=".tar.gz"
306
+ _bins="uv uvx"
307
+ _bins_js_array='"uv","uvx"'
308
+ _libs=""
309
+ _libs_js_array=""
310
+ _staticlibs=""
311
+ _staticlibs_js_array=""
312
+ _updater_name=""
313
+ _updater_bin=""
314
+ ;;
315
+ "uv-i686-unknown-linux-musl.tar.gz")
316
+ _arch="i686-unknown-linux-musl-static"
317
+ _zip_ext=".tar.gz"
318
+ _bins="uv uvx"
319
+ _bins_js_array='"uv","uvx"'
320
+ _libs=""
321
+ _libs_js_array=""
322
+ _staticlibs=""
323
+ _staticlibs_js_array=""
324
+ _updater_name=""
325
+ _updater_bin=""
326
+ ;;
327
+ "uv-powerpc64-unknown-linux-gnu.tar.gz")
328
+ _arch="powerpc64-unknown-linux-gnu"
329
+ _zip_ext=".tar.gz"
330
+ _bins="uv uvx"
331
+ _bins_js_array='"uv","uvx"'
332
+ _libs=""
333
+ _libs_js_array=""
334
+ _staticlibs=""
335
+ _staticlibs_js_array=""
336
+ _updater_name=""
337
+ _updater_bin=""
338
+ ;;
339
+ "uv-powerpc64le-unknown-linux-gnu.tar.gz")
340
+ _arch="powerpc64le-unknown-linux-gnu"
341
+ _zip_ext=".tar.gz"
342
+ _bins="uv uvx"
343
+ _bins_js_array='"uv","uvx"'
344
+ _libs=""
345
+ _libs_js_array=""
346
+ _staticlibs=""
347
+ _staticlibs_js_array=""
348
+ _updater_name=""
349
+ _updater_bin=""
350
+ ;;
351
+ "uv-riscv64gc-unknown-linux-gnu.tar.gz")
352
+ _arch="riscv64gc-unknown-linux-gnu"
353
+ _zip_ext=".tar.gz"
354
+ _bins="uv uvx"
355
+ _bins_js_array='"uv","uvx"'
356
+ _libs=""
357
+ _libs_js_array=""
358
+ _staticlibs=""
359
+ _staticlibs_js_array=""
360
+ _updater_name=""
361
+ _updater_bin=""
362
+ ;;
363
+ "uv-s390x-unknown-linux-gnu.tar.gz")
364
+ _arch="s390x-unknown-linux-gnu"
365
+ _zip_ext=".tar.gz"
366
+ _bins="uv uvx"
367
+ _bins_js_array='"uv","uvx"'
368
+ _libs=""
369
+ _libs_js_array=""
370
+ _staticlibs=""
371
+ _staticlibs_js_array=""
372
+ _updater_name=""
373
+ _updater_bin=""
374
+ ;;
375
+ "uv-x86_64-apple-darwin.tar.gz")
376
+ _arch="x86_64-apple-darwin"
377
+ _zip_ext=".tar.gz"
378
+ _bins="uv uvx"
379
+ _bins_js_array='"uv","uvx"'
380
+ _libs=""
381
+ _libs_js_array=""
382
+ _staticlibs=""
383
+ _staticlibs_js_array=""
384
+ _updater_name=""
385
+ _updater_bin=""
386
+ ;;
387
+ "uv-x86_64-pc-windows-msvc.zip")
388
+ _arch="x86_64-pc-windows-msvc"
389
+ _zip_ext=".zip"
390
+ _bins="uv.exe uvx.exe uvw.exe"
391
+ _bins_js_array='"uv.exe","uvx.exe","uvw.exe"'
392
+ _libs=""
393
+ _libs_js_array=""
394
+ _staticlibs=""
395
+ _staticlibs_js_array=""
396
+ _updater_name=""
397
+ _updater_bin=""
398
+ ;;
399
+ "uv-x86_64-unknown-linux-gnu.tar.gz")
400
+ _arch="x86_64-unknown-linux-gnu"
401
+ _zip_ext=".tar.gz"
402
+ _bins="uv uvx"
403
+ _bins_js_array='"uv","uvx"'
404
+ _libs=""
405
+ _libs_js_array=""
406
+ _staticlibs=""
407
+ _staticlibs_js_array=""
408
+ _updater_name=""
409
+ _updater_bin=""
410
+ ;;
411
+ "uv-x86_64-unknown-linux-musl.tar.gz")
412
+ _arch="x86_64-unknown-linux-musl-static"
413
+ _zip_ext=".tar.gz"
414
+ _bins="uv uvx"
415
+ _bins_js_array='"uv","uvx"'
416
+ _libs=""
417
+ _libs_js_array=""
418
+ _staticlibs=""
419
+ _staticlibs_js_array=""
420
+ _updater_name=""
421
+ _updater_bin=""
422
+ ;;
423
+ *)
424
+ err "internal installer error: selected download $_artifact_name doesn't exist!?"
425
+ ;;
426
+ esac
427
+
428
+
429
+ # Replace the placeholder binaries with the calculated array from above
430
+ RECEIPT="$(echo "$RECEIPT" | sed s/'"CARGO_DIST_BINS"'/"$_bins_js_array"/)"
431
+ RECEIPT="$(echo "$RECEIPT" | sed s/'"CARGO_DIST_DYLIBS"'/"$_libs_js_array"/)"
432
+ RECEIPT="$(echo "$RECEIPT" | sed s/'"CARGO_DIST_STATICLIBS"'/"$_staticlibs_js_array"/)"
433
+
434
+ # download the archive
435
+ local _url="$ARTIFACT_DOWNLOAD_URL/$_artifact_name"
436
+ local _dir
437
+ _dir="$(ensure mktemp -d)" || return 1
438
+ local _file="$_dir/input$_zip_ext"
439
+
440
+ say "downloading $APP_NAME $APP_VERSION ${_arch}" 1>&2
441
+ say_verbose " from $_url" 1>&2
442
+ say_verbose " to $_file" 1>&2
443
+
444
+ ensure mkdir -p "$_dir"
445
+
446
+ if ! downloader "$_url" "$_file"; then
447
+ say "failed to download $_url"
448
+ say "this may be a standard network error, but it may also indicate"
449
+ say "that $APP_NAME's release process is not working. When in doubt"
450
+ say "please feel free to open an issue!"
451
+ exit 1
452
+ fi
453
+
454
+ if [ -n "${_checksum_style:-}" ]; then
455
+ verify_checksum "$_file" "$_checksum_style" "$_checksum_value"
456
+ else
457
+ say "no checksums to verify"
458
+ fi
459
+
460
+ # ...and then the updater, if it exists
461
+ if [ -n "$_updater_name" ] && [ "$INSTALL_UPDATER" = "1" ]; then
462
+ local _updater_url="$ARTIFACT_DOWNLOAD_URL/$_updater_name"
463
+ # This renames the artifact while doing the download, removing the
464
+ # target triple and leaving just the appname-update format
465
+ local _updater_file="$_dir/$APP_NAME-update"
466
+
467
+ if ! downloader "$_updater_url" "$_updater_file"; then
468
+ say "failed to download $_updater_url"
469
+ say "this may be a standard network error, but it may also indicate"
470
+ say "that $APP_NAME's release process is not working. When in doubt"
471
+ say "please feel free to open an issue!"
472
+ exit 1
473
+ fi
474
+
475
+ # Add the updater to the list of binaries to install
476
+ _bins="$_bins $APP_NAME-update"
477
+ fi
478
+
479
+ # unpack the archive
480
+ case "$_zip_ext" in
481
+ ".zip")
482
+ ensure unzip -q "$_file" -d "$_dir"
483
+ ;;
484
+
485
+ ".tar."*)
486
+ ensure tar xf "$_file" --strip-components 1 -C "$_dir"
487
+ ;;
488
+ *)
489
+ err "unknown archive format: $_zip_ext"
490
+ ;;
491
+ esac
492
+
493
+ install "$_dir" "$_bins" "$_libs" "$_staticlibs" "$_arch" "$@"
494
+ local _retval=$?
495
+ if [ "$_retval" != 0 ]; then
496
+ return "$_retval"
497
+ fi
498
+
499
+ ignore rm -rf "$_dir"
500
+
501
+ # Install the install receipt
502
+ if [ "$INSTALL_UPDATER" = "1" ]; then
503
+ if ! mkdir -p "$RECEIPT_HOME"; then
504
+ err "unable to create receipt directory at $RECEIPT_HOME"
505
+ else
506
+ echo "$RECEIPT" > "$RECEIPT_HOME/$APP_NAME-receipt.json"
507
+ # shellcheck disable=SC2320
508
+ local _retval=$?
509
+ fi
510
+ else
511
+ local _retval=0
512
+ fi
513
+
514
+ return "$_retval"
515
+ }
516
+
517
+ # Replaces $HOME with the variable name for display to the user,
518
+ # only if $HOME is defined.
519
+ replace_home() {
520
+ local _str="$1"
521
+
522
+ if [ -n "${HOME:-}" ]; then
523
+ echo "$_str" | sed "s,$HOME,\$HOME,"
524
+ else
525
+ echo "$_str"
526
+ fi
527
+ }
528
+
529
+ json_binary_aliases() {
530
+ local _arch="$1"
531
+
532
+ case "$_arch" in
533
+ "aarch64-apple-darwin")
534
+ echo '{}'
535
+ ;;
536
+ "aarch64-pc-windows-gnu")
537
+ echo '{}'
538
+ ;;
539
+ "aarch64-unknown-linux-gnu")
540
+ echo '{}'
541
+ ;;
542
+ "aarch64-unknown-linux-musl-dynamic")
543
+ echo '{}'
544
+ ;;
545
+ "aarch64-unknown-linux-musl-static")
546
+ echo '{}'
547
+ ;;
548
+ "arm-unknown-linux-gnueabihf")
549
+ echo '{}'
550
+ ;;
551
+ "arm-unknown-linux-musl-dynamiceabihf")
552
+ echo '{}'
553
+ ;;
554
+ "arm-unknown-linux-musl-staticeabihf")
555
+ echo '{}'
556
+ ;;
557
+ "armv7-unknown-linux-gnueabihf")
558
+ echo '{}'
559
+ ;;
560
+ "armv7-unknown-linux-musl-dynamiceabihf")
561
+ echo '{}'
562
+ ;;
563
+ "armv7-unknown-linux-musl-staticeabihf")
564
+ echo '{}'
565
+ ;;
566
+ "i686-pc-windows-gnu")
567
+ echo '{}'
568
+ ;;
569
+ "i686-unknown-linux-gnu")
570
+ echo '{}'
571
+ ;;
572
+ "i686-unknown-linux-musl-dynamic")
573
+ echo '{}'
574
+ ;;
575
+ "i686-unknown-linux-musl-static")
576
+ echo '{}'
577
+ ;;
578
+ "powerpc64-unknown-linux-gnu")
579
+ echo '{}'
580
+ ;;
581
+ "powerpc64le-unknown-linux-gnu")
582
+ echo '{}'
583
+ ;;
584
+ "riscv64gc-unknown-linux-gnu")
585
+ echo '{}'
586
+ ;;
587
+ "s390x-unknown-linux-gnu")
588
+ echo '{}'
589
+ ;;
590
+ "x86_64-apple-darwin")
591
+ echo '{}'
592
+ ;;
593
+ "x86_64-pc-windows-gnu")
594
+ echo '{}'
595
+ ;;
596
+ "x86_64-unknown-linux-gnu")
597
+ echo '{}'
598
+ ;;
599
+ "x86_64-unknown-linux-musl-dynamic")
600
+ echo '{}'
601
+ ;;
602
+ "x86_64-unknown-linux-musl-static")
603
+ echo '{}'
604
+ ;;
605
+ *)
606
+ echo '{}'
607
+ ;;
608
+ esac
609
+ }
610
+
611
+ aliases_for_binary() {
612
+ local _bin="$1"
613
+ local _arch="$2"
614
+
615
+ case "$_arch" in
616
+ "aarch64-apple-darwin")
617
+ case "$_bin" in
618
+ *)
619
+ echo ""
620
+ ;;
621
+ esac
622
+ ;;
623
+ "aarch64-pc-windows-gnu")
624
+ case "$_bin" in
625
+ *)
626
+ echo ""
627
+ ;;
628
+ esac
629
+ ;;
630
+ "aarch64-unknown-linux-gnu")
631
+ case "$_bin" in
632
+ *)
633
+ echo ""
634
+ ;;
635
+ esac
636
+ ;;
637
+ "aarch64-unknown-linux-musl-dynamic")
638
+ case "$_bin" in
639
+ *)
640
+ echo ""
641
+ ;;
642
+ esac
643
+ ;;
644
+ "aarch64-unknown-linux-musl-static")
645
+ case "$_bin" in
646
+ *)
647
+ echo ""
648
+ ;;
649
+ esac
650
+ ;;
651
+ "arm-unknown-linux-gnueabihf")
652
+ case "$_bin" in
653
+ *)
654
+ echo ""
655
+ ;;
656
+ esac
657
+ ;;
658
+ "arm-unknown-linux-musl-dynamiceabihf")
659
+ case "$_bin" in
660
+ *)
661
+ echo ""
662
+ ;;
663
+ esac
664
+ ;;
665
+ "arm-unknown-linux-musl-staticeabihf")
666
+ case "$_bin" in
667
+ *)
668
+ echo ""
669
+ ;;
670
+ esac
671
+ ;;
672
+ "armv7-unknown-linux-gnueabihf")
673
+ case "$_bin" in
674
+ *)
675
+ echo ""
676
+ ;;
677
+ esac
678
+ ;;
679
+ "armv7-unknown-linux-musl-dynamiceabihf")
680
+ case "$_bin" in
681
+ *)
682
+ echo ""
683
+ ;;
684
+ esac
685
+ ;;
686
+ "armv7-unknown-linux-musl-staticeabihf")
687
+ case "$_bin" in
688
+ *)
689
+ echo ""
690
+ ;;
691
+ esac
692
+ ;;
693
+ "i686-pc-windows-gnu")
694
+ case "$_bin" in
695
+ *)
696
+ echo ""
697
+ ;;
698
+ esac
699
+ ;;
700
+ "i686-unknown-linux-gnu")
701
+ case "$_bin" in
702
+ *)
703
+ echo ""
704
+ ;;
705
+ esac
706
+ ;;
707
+ "i686-unknown-linux-musl-dynamic")
708
+ case "$_bin" in
709
+ *)
710
+ echo ""
711
+ ;;
712
+ esac
713
+ ;;
714
+ "i686-unknown-linux-musl-static")
715
+ case "$_bin" in
716
+ *)
717
+ echo ""
718
+ ;;
719
+ esac
720
+ ;;
721
+ "powerpc64-unknown-linux-gnu")
722
+ case "$_bin" in
723
+ *)
724
+ echo ""
725
+ ;;
726
+ esac
727
+ ;;
728
+ "powerpc64le-unknown-linux-gnu")
729
+ case "$_bin" in
730
+ *)
731
+ echo ""
732
+ ;;
733
+ esac
734
+ ;;
735
+ "riscv64gc-unknown-linux-gnu")
736
+ case "$_bin" in
737
+ *)
738
+ echo ""
739
+ ;;
740
+ esac
741
+ ;;
742
+ "s390x-unknown-linux-gnu")
743
+ case "$_bin" in
744
+ *)
745
+ echo ""
746
+ ;;
747
+ esac
748
+ ;;
749
+ "x86_64-apple-darwin")
750
+ case "$_bin" in
751
+ *)
752
+ echo ""
753
+ ;;
754
+ esac
755
+ ;;
756
+ "x86_64-pc-windows-gnu")
757
+ case "$_bin" in
758
+ *)
759
+ echo ""
760
+ ;;
761
+ esac
762
+ ;;
763
+ "x86_64-unknown-linux-gnu")
764
+ case "$_bin" in
765
+ *)
766
+ echo ""
767
+ ;;
768
+ esac
769
+ ;;
770
+ "x86_64-unknown-linux-musl-dynamic")
771
+ case "$_bin" in
772
+ *)
773
+ echo ""
774
+ ;;
775
+ esac
776
+ ;;
777
+ "x86_64-unknown-linux-musl-static")
778
+ case "$_bin" in
779
+ *)
780
+ echo ""
781
+ ;;
782
+ esac
783
+ ;;
784
+ *)
785
+ echo ""
786
+ ;;
787
+ esac
788
+ }
789
+
790
+ select_archive_for_arch() {
791
+ local _true_arch="$1"
792
+ local _archive
793
+
794
+ # try each archive, checking runtime conditions like libc versions
795
+ # accepting the first one that matches, as it's the best match
796
+ case "$_true_arch" in
797
+ "aarch64-apple-darwin")
798
+ _archive="uv-aarch64-apple-darwin.tar.gz"
799
+ if [ -n "$_archive" ]; then
800
+ echo "$_archive"
801
+ return 0
802
+ fi
803
+ _archive="uv-x86_64-apple-darwin.tar.gz"
804
+ if [ -n "$_archive" ]; then
805
+ echo "$_archive"
806
+ return 0
807
+ fi
808
+ ;;
809
+ "aarch64-pc-windows-gnu")
810
+ _archive="uv-aarch64-pc-windows-msvc.zip"
811
+ if [ -n "$_archive" ]; then
812
+ echo "$_archive"
813
+ return 0
814
+ fi
815
+ ;;
816
+ "aarch64-pc-windows-msvc")
817
+ _archive="uv-aarch64-pc-windows-msvc.zip"
818
+ if [ -n "$_archive" ]; then
819
+ echo "$_archive"
820
+ return 0
821
+ fi
822
+ _archive="uv-x86_64-pc-windows-msvc.zip"
823
+ if [ -n "$_archive" ]; then
824
+ echo "$_archive"
825
+ return 0
826
+ fi
827
+ _archive="uv-i686-pc-windows-msvc.zip"
828
+ if [ -n "$_archive" ]; then
829
+ echo "$_archive"
830
+ return 0
831
+ fi
832
+ ;;
833
+ "aarch64-unknown-linux-gnu")
834
+ _archive="uv-aarch64-unknown-linux-gnu.tar.gz"
835
+ if ! check_glibc "2" "28"; then
836
+ _archive=""
837
+ fi
838
+ if [ -n "$_archive" ]; then
839
+ echo "$_archive"
840
+ return 0
841
+ fi
842
+ _archive="uv-aarch64-unknown-linux-musl.tar.gz"
843
+ if [ -n "$_archive" ]; then
844
+ echo "$_archive"
845
+ return 0
846
+ fi
847
+ ;;
848
+ "aarch64-unknown-linux-musl-dynamic")
849
+ _archive="uv-aarch64-unknown-linux-musl.tar.gz"
850
+ if [ -n "$_archive" ]; then
851
+ echo "$_archive"
852
+ return 0
853
+ fi
854
+ ;;
855
+ "aarch64-unknown-linux-musl-static")
856
+ _archive="uv-aarch64-unknown-linux-musl.tar.gz"
857
+ if [ -n "$_archive" ]; then
858
+ echo "$_archive"
859
+ return 0
860
+ fi
861
+ ;;
862
+ "arm-unknown-linux-gnueabihf")
863
+ _archive="uv-arm-unknown-linux-musleabihf.tar.gz"
864
+ if [ -n "$_archive" ]; then
865
+ echo "$_archive"
866
+ return 0
867
+ fi
868
+ ;;
869
+ "arm-unknown-linux-musl-dynamiceabihf")
870
+ _archive="uv-arm-unknown-linux-musleabihf.tar.gz"
871
+ if [ -n "$_archive" ]; then
872
+ echo "$_archive"
873
+ return 0
874
+ fi
875
+ ;;
876
+ "arm-unknown-linux-musl-staticeabihf")
877
+ _archive="uv-arm-unknown-linux-musleabihf.tar.gz"
878
+ if [ -n "$_archive" ]; then
879
+ echo "$_archive"
880
+ return 0
881
+ fi
882
+ ;;
883
+ "armv7-unknown-linux-gnueabihf")
884
+ _archive="uv-armv7-unknown-linux-gnueabihf.tar.gz"
885
+ if ! check_glibc "2" "17"; then
886
+ _archive=""
887
+ fi
888
+ if [ -n "$_archive" ]; then
889
+ echo "$_archive"
890
+ return 0
891
+ fi
892
+ _archive="uv-armv7-unknown-linux-musleabihf.tar.gz"
893
+ if [ -n "$_archive" ]; then
894
+ echo "$_archive"
895
+ return 0
896
+ fi
897
+ ;;
898
+ "armv7-unknown-linux-musl-dynamiceabihf")
899
+ _archive="uv-armv7-unknown-linux-musleabihf.tar.gz"
900
+ if [ -n "$_archive" ]; then
901
+ echo "$_archive"
902
+ return 0
903
+ fi
904
+ ;;
905
+ "armv7-unknown-linux-musl-staticeabihf")
906
+ _archive="uv-armv7-unknown-linux-musleabihf.tar.gz"
907
+ if [ -n "$_archive" ]; then
908
+ echo "$_archive"
909
+ return 0
910
+ fi
911
+ ;;
912
+ "i686-pc-windows-gnu")
913
+ _archive="uv-i686-pc-windows-msvc.zip"
914
+ if [ -n "$_archive" ]; then
915
+ echo "$_archive"
916
+ return 0
917
+ fi
918
+ ;;
919
+ "i686-pc-windows-msvc")
920
+ _archive="uv-i686-pc-windows-msvc.zip"
921
+ if [ -n "$_archive" ]; then
922
+ echo "$_archive"
923
+ return 0
924
+ fi
925
+ ;;
926
+ "i686-unknown-linux-gnu")
927
+ _archive="uv-i686-unknown-linux-gnu.tar.gz"
928
+ if ! check_glibc "2" "17"; then
929
+ _archive=""
930
+ fi
931
+ if [ -n "$_archive" ]; then
932
+ echo "$_archive"
933
+ return 0
934
+ fi
935
+ _archive="uv-i686-unknown-linux-musl.tar.gz"
936
+ if [ -n "$_archive" ]; then
937
+ echo "$_archive"
938
+ return 0
939
+ fi
940
+ ;;
941
+ "i686-unknown-linux-musl-dynamic")
942
+ _archive="uv-i686-unknown-linux-musl.tar.gz"
943
+ if [ -n "$_archive" ]; then
944
+ echo "$_archive"
945
+ return 0
946
+ fi
947
+ ;;
948
+ "i686-unknown-linux-musl-static")
949
+ _archive="uv-i686-unknown-linux-musl.tar.gz"
950
+ if [ -n "$_archive" ]; then
951
+ echo "$_archive"
952
+ return 0
953
+ fi
954
+ ;;
955
+ "powerpc64-unknown-linux-gnu")
956
+ _archive="uv-powerpc64-unknown-linux-gnu.tar.gz"
957
+ if ! check_glibc "2" "17"; then
958
+ _archive=""
959
+ fi
960
+ if [ -n "$_archive" ]; then
961
+ echo "$_archive"
962
+ return 0
963
+ fi
964
+ ;;
965
+ "powerpc64le-unknown-linux-gnu")
966
+ _archive="uv-powerpc64le-unknown-linux-gnu.tar.gz"
967
+ if ! check_glibc "2" "17"; then
968
+ _archive=""
969
+ fi
970
+ if [ -n "$_archive" ]; then
971
+ echo "$_archive"
972
+ return 0
973
+ fi
974
+ ;;
975
+ "riscv64gc-unknown-linux-gnu")
976
+ _archive="uv-riscv64gc-unknown-linux-gnu.tar.gz"
977
+ if ! check_glibc "2" "31"; then
978
+ _archive=""
979
+ fi
980
+ if [ -n "$_archive" ]; then
981
+ echo "$_archive"
982
+ return 0
983
+ fi
984
+ ;;
985
+ "s390x-unknown-linux-gnu")
986
+ _archive="uv-s390x-unknown-linux-gnu.tar.gz"
987
+ if ! check_glibc "2" "17"; then
988
+ _archive=""
989
+ fi
990
+ if [ -n "$_archive" ]; then
991
+ echo "$_archive"
992
+ return 0
993
+ fi
994
+ ;;
995
+ "x86_64-apple-darwin")
996
+ _archive="uv-x86_64-apple-darwin.tar.gz"
997
+ if [ -n "$_archive" ]; then
998
+ echo "$_archive"
999
+ return 0
1000
+ fi
1001
+ ;;
1002
+ "x86_64-pc-windows-gnu")
1003
+ _archive="uv-x86_64-pc-windows-msvc.zip"
1004
+ if [ -n "$_archive" ]; then
1005
+ echo "$_archive"
1006
+ return 0
1007
+ fi
1008
+ ;;
1009
+ "x86_64-pc-windows-msvc")
1010
+ _archive="uv-x86_64-pc-windows-msvc.zip"
1011
+ if [ -n "$_archive" ]; then
1012
+ echo "$_archive"
1013
+ return 0
1014
+ fi
1015
+ _archive="uv-i686-pc-windows-msvc.zip"
1016
+ if [ -n "$_archive" ]; then
1017
+ echo "$_archive"
1018
+ return 0
1019
+ fi
1020
+ ;;
1021
+ "x86_64-unknown-linux-gnu")
1022
+ _archive="uv-x86_64-unknown-linux-gnu.tar.gz"
1023
+ if ! check_glibc "2" "17"; then
1024
+ _archive=""
1025
+ fi
1026
+ if [ -n "$_archive" ]; then
1027
+ echo "$_archive"
1028
+ return 0
1029
+ fi
1030
+ _archive="uv-x86_64-unknown-linux-musl.tar.gz"
1031
+ if [ -n "$_archive" ]; then
1032
+ echo "$_archive"
1033
+ return 0
1034
+ fi
1035
+ ;;
1036
+ "x86_64-unknown-linux-musl-dynamic")
1037
+ _archive="uv-x86_64-unknown-linux-musl.tar.gz"
1038
+ if [ -n "$_archive" ]; then
1039
+ echo "$_archive"
1040
+ return 0
1041
+ fi
1042
+ ;;
1043
+ "x86_64-unknown-linux-musl-static")
1044
+ _archive="uv-x86_64-unknown-linux-musl.tar.gz"
1045
+ if [ -n "$_archive" ]; then
1046
+ echo "$_archive"
1047
+ return 0
1048
+ fi
1049
+ ;;
1050
+ *)
1051
+ err "there isn't a download for your platform $_true_arch"
1052
+ ;;
1053
+ esac
1054
+ err "no compatible downloads were found for your platform $_true_arch"
1055
+ }
1056
+
1057
+ check_glibc() {
1058
+ local _min_glibc_major="$1"
1059
+ local _min_glibc_series="$2"
1060
+
1061
+ # Parsing version out from line 1 like:
1062
+ # ldd (Ubuntu GLIBC 2.35-0ubuntu3.1) 2.35
1063
+ _local_glibc="$(ldd --version | awk -F' ' '{ if (FNR<=1) print $NF }')"
1064
+
1065
+ if [ "$(echo "${_local_glibc}" | awk -F. '{ print $1 }')" = "$_min_glibc_major" ] && [ "$(echo "${_local_glibc}" | awk -F. '{ print $2 }')" -ge "$_min_glibc_series" ]; then
1066
+ return 0
1067
+ else
1068
+ say "System glibc version (\`${_local_glibc}') is too old; checking alternatives" >&2
1069
+ return 1
1070
+ fi
1071
+ }
1072
+
1073
+ # See discussion of late-bound vs early-bound for why we use single-quotes with env vars
1074
+ # shellcheck disable=SC2016
1075
+ install() {
1076
+ # This code needs to both compute certain paths for itself to write to, and
1077
+ # also write them to shell/rc files so that they can look them up to e.g.
1078
+ # add them to PATH. This requires an active distinction between paths
1079
+ # and expressions that can compute them.
1080
+ #
1081
+ # The distinction lies in when we want env-vars to be evaluated. For instance
1082
+ # if we determine that we want to install to $HOME/.myapp, which do we add
1083
+ # to e.g. $HOME/.profile:
1084
+ #
1085
+ # * early-bound: export PATH="/home/myuser/.myapp:$PATH"
1086
+ # * late-bound: export PATH="$HOME/.myapp:$PATH"
1087
+ #
1088
+ # In this case most people would prefer the late-bound version, but in other
1089
+ # cases the early-bound version might be a better idea. In particular when using
1090
+ # other env-vars than $HOME, they are more likely to be only set temporarily
1091
+ # for the duration of this install script, so it's more advisable to erase their
1092
+ # existence with early-bounding.
1093
+ #
1094
+ # This distinction is handled by "double-quotes" (early) vs 'single-quotes' (late).
1095
+ #
1096
+ # However if we detect that "$SOME_VAR/..." is a subdir of $HOME, we try to rewrite
1097
+ # it to be '$HOME/...' to get the best of both worlds.
1098
+ #
1099
+ # This script has a few different variants, the most complex one being the
1100
+ # CARGO_HOME version which attempts to install things to Cargo's bin dir,
1101
+ # potentially setting up a minimal version if the user hasn't ever installed Cargo.
1102
+ #
1103
+ # In this case we need to:
1104
+ #
1105
+ # * Install to $HOME/.cargo/bin/
1106
+ # * Create a shell script at $HOME/.cargo/env that:
1107
+ # * Checks if $HOME/.cargo/bin/ is on PATH
1108
+ # * and if not prepends it to PATH
1109
+ # * Edits $INFERRED_HOME/.profile to run $HOME/.cargo/env (if the line doesn't exist)
1110
+ #
1111
+ # To do this we need these 4 values:
1112
+
1113
+ # The actual path we're going to install to
1114
+ local _install_dir
1115
+ # The directory C dynamic/static libraries install to
1116
+ local _lib_install_dir
1117
+ # The install prefix we write to the receipt.
1118
+ # For organized install methods like CargoHome, which have
1119
+ # subdirectories, this is the root without `/bin`. For other
1120
+ # methods, this is the same as `_install_dir`.
1121
+ local _receipt_install_dir
1122
+ # Path to the an shell script that adds install_dir to PATH
1123
+ local _env_script_path
1124
+ # Potentially-late-bound version of install_dir to write env_script
1125
+ local _install_dir_expr
1126
+ # Potentially-late-bound version of env_script_path to write to rcfiles like $HOME/.profile
1127
+ local _env_script_path_expr
1128
+ # Forces the install to occur at this path, not the default
1129
+ local _force_install_dir
1130
+ # Which install layout to use - "flat" or "hierarchical"
1131
+ local _install_layout="unspecified"
1132
+ # A list of binaries which are shadowed in the PATH
1133
+ local _shadowed_bins=""
1134
+
1135
+ # Check the newer app-specific variable before falling back
1136
+ # to the older generic one
1137
+ if [ -n "${UV_INSTALL_DIR:-}" ]; then
1138
+ _force_install_dir="$UV_INSTALL_DIR"
1139
+ _install_layout="flat"
1140
+ elif [ -n "${CARGO_DIST_FORCE_INSTALL_DIR:-}" ]; then
1141
+ _force_install_dir="$CARGO_DIST_FORCE_INSTALL_DIR"
1142
+ _install_layout="flat"
1143
+ elif [ -n "$UNMANAGED_INSTALL" ]; then
1144
+ _force_install_dir="$UNMANAGED_INSTALL"
1145
+ _install_layout="flat"
1146
+ fi
1147
+
1148
+ # Check if the install layout should be changed from `flat` to `cargo-home`
1149
+ # for backwards compatible updates of applications that switched layouts.
1150
+ if [ -n "${_force_install_dir:-}" ]; then
1151
+ if [ "$_install_layout" = "flat" ]; then
1152
+ # If the install directory is targeting the Cargo home directory, then
1153
+ # we assume this application was previously installed that layout
1154
+ if [ "$_force_install_dir" = "${CARGO_HOME:-${INFERRED_HOME:-}/.cargo}" ]; then
1155
+ _install_layout="cargo-home"
1156
+ fi
1157
+ fi
1158
+ fi
1159
+
1160
+ # Before actually consulting the configured install strategy, see
1161
+ # if we're overriding it.
1162
+ if [ -n "${_force_install_dir:-}" ]; then
1163
+ case "$_install_layout" in
1164
+ "hierarchical")
1165
+ _install_dir="$_force_install_dir/bin"
1166
+ _lib_install_dir="$_force_install_dir/lib"
1167
+ _receipt_install_dir="$_force_install_dir"
1168
+ _env_script_path="$_force_install_dir/env"
1169
+ _install_dir_expr="$(replace_home "$_force_install_dir/bin")"
1170
+ _env_script_path_expr="$(replace_home "$_force_install_dir/env")"
1171
+ ;;
1172
+ "cargo-home")
1173
+ _install_dir="$_force_install_dir/bin"
1174
+ _lib_install_dir="$_force_install_dir/bin"
1175
+ _receipt_install_dir="$_force_install_dir"
1176
+ _env_script_path="$_force_install_dir/env"
1177
+ _install_dir_expr="$(replace_home "$_force_install_dir/bin")"
1178
+ _env_script_path_expr="$(replace_home "$_force_install_dir/env")"
1179
+ ;;
1180
+ "flat")
1181
+ _install_dir="$_force_install_dir"
1182
+ _lib_install_dir="$_force_install_dir"
1183
+ _receipt_install_dir="$_install_dir"
1184
+ _env_script_path="$_force_install_dir/env"
1185
+ _install_dir_expr="$(replace_home "$_force_install_dir")"
1186
+ _env_script_path_expr="$(replace_home "$_force_install_dir/env")"
1187
+ ;;
1188
+ *)
1189
+ err "Unrecognized install layout: $_install_layout"
1190
+ ;;
1191
+ esac
1192
+ fi
1193
+ if [ -z "${_install_dir:-}" ]; then
1194
+ _install_layout="flat"
1195
+ # Install to $XDG_BIN_HOME
1196
+ if [ -n "${XDG_BIN_HOME:-}" ]; then
1197
+ _install_dir="$XDG_BIN_HOME"
1198
+ _lib_install_dir="$_install_dir"
1199
+ _receipt_install_dir="$_install_dir"
1200
+ _env_script_path="$XDG_BIN_HOME/env"
1201
+ _install_dir_expr="$(replace_home "$_install_dir")"
1202
+ _env_script_path_expr="$(replace_home "$_env_script_path")"
1203
+ fi
1204
+ fi
1205
+ if [ -z "${_install_dir:-}" ]; then
1206
+ _install_layout="flat"
1207
+ # Install to $XDG_DATA_HOME/../bin
1208
+ if [ -n "${XDG_DATA_HOME:-}" ]; then
1209
+ _install_dir="$XDG_DATA_HOME/../bin"
1210
+ _lib_install_dir="$_install_dir"
1211
+ _receipt_install_dir="$_install_dir"
1212
+ _env_script_path="$XDG_DATA_HOME/../bin/env"
1213
+ _install_dir_expr="$(replace_home "$_install_dir")"
1214
+ _env_script_path_expr="$(replace_home "$_env_script_path")"
1215
+ fi
1216
+ fi
1217
+ if [ -z "${_install_dir:-}" ]; then
1218
+ _install_layout="flat"
1219
+ # Install to $HOME/.local/bin
1220
+ if [ -n "${INFERRED_HOME:-}" ]; then
1221
+ _install_dir="$INFERRED_HOME/.local/bin"
1222
+ _lib_install_dir="$INFERRED_HOME/.local/bin"
1223
+ _receipt_install_dir="$_install_dir"
1224
+ _env_script_path="$INFERRED_HOME/.local/bin/env"
1225
+ _install_dir_expr="$INFERRED_HOME_EXPRESSION/.local/bin"
1226
+ _env_script_path_expr="$INFERRED_HOME_EXPRESSION/.local/bin/env"
1227
+ fi
1228
+ fi
1229
+
1230
+ if [ -z "$_install_dir_expr" ]; then
1231
+ err "could not find a valid path to install to!"
1232
+ fi
1233
+
1234
+ # Identical to the sh version, just with a .fish file extension
1235
+ # We place it down here to wait until it's been assigned in every
1236
+ # path.
1237
+ _fish_env_script_path="${_env_script_path}.fish"
1238
+ _fish_env_script_path_expr="${_env_script_path_expr}.fish"
1239
+
1240
+ # Replace the temporary cargo home with the calculated one
1241
+ RECEIPT=$(echo "$RECEIPT" | sed "s,AXO_INSTALL_PREFIX,$_receipt_install_dir,")
1242
+ # Also replace the aliases with the arch-specific one
1243
+ RECEIPT=$(echo "$RECEIPT" | sed "s'\"binary_aliases\":{}'\"binary_aliases\":$(json_binary_aliases "$_arch")'")
1244
+ # And replace the install layout
1245
+ RECEIPT=$(echo "$RECEIPT" | sed "s'\"install_layout\":\"unspecified\"'\"install_layout\":\"$_install_layout\"'")
1246
+ if [ "$NO_MODIFY_PATH" = "1" ]; then
1247
+ RECEIPT=$(echo "$RECEIPT" | sed "s'\"modify_path\":true'\"modify_path\":false'")
1248
+ fi
1249
+
1250
+ say "installing to $_install_dir"
1251
+ ensure mkdir -p "$_install_dir"
1252
+ ensure mkdir -p "$_lib_install_dir"
1253
+
1254
+ # copy all the binaries to the install dir
1255
+ local _src_dir="$1"
1256
+ local _bins="$2"
1257
+ local _libs="$3"
1258
+ local _staticlibs="$4"
1259
+ local _arch="$5"
1260
+ for _bin_name in $_bins; do
1261
+ local _bin="$_src_dir/$_bin_name"
1262
+ ensure mv "$_bin" "$_install_dir"
1263
+ # unzip seems to need this chmod
1264
+ ensure chmod +x "$_install_dir/$_bin_name"
1265
+ for _dest in $(aliases_for_binary "$_bin_name" "$_arch"); do
1266
+ ln -sf "$_install_dir/$_bin_name" "$_install_dir/$_dest"
1267
+ done
1268
+ say " $_bin_name"
1269
+ done
1270
+ # Like the above, but no aliases
1271
+ for _lib_name in $_libs; do
1272
+ local _lib="$_src_dir/$_lib_name"
1273
+ ensure mv "$_lib" "$_lib_install_dir"
1274
+ # unzip seems to need this chmod
1275
+ ensure chmod +x "$_lib_install_dir/$_lib_name"
1276
+ say " $_lib_name"
1277
+ done
1278
+ for _lib_name in $_staticlibs; do
1279
+ local _lib="$_src_dir/$_lib_name"
1280
+ ensure mv "$_lib" "$_lib_install_dir"
1281
+ # unzip seems to need this chmod
1282
+ ensure chmod +x "$_lib_install_dir/$_lib_name"
1283
+ say " $_lib_name"
1284
+ done
1285
+
1286
+ say "everything's installed!"
1287
+
1288
+ # Avoid modifying the users PATH if they are managing their PATH manually
1289
+ case :$PATH:
1290
+ in *:$_install_dir:*) NO_MODIFY_PATH=1 ;;
1291
+ *) ;;
1292
+ esac
1293
+
1294
+ if [ "0" = "$NO_MODIFY_PATH" ]; then
1295
+ add_install_dir_to_ci_path "$_install_dir"
1296
+ add_install_dir_to_path "$_install_dir_expr" "$_env_script_path" "$_env_script_path_expr" ".profile" "sh"
1297
+ exit1=$?
1298
+ shotgun_install_dir_to_path "$_install_dir_expr" "$_env_script_path" "$_env_script_path_expr" ".profile .bashrc .bash_profile .bash_login" "sh"
1299
+ exit2=$?
1300
+ add_install_dir_to_path "$_install_dir_expr" "$_env_script_path" "$_env_script_path_expr" ".zshrc .zshenv" "sh"
1301
+ exit3=$?
1302
+ # This path may not exist by default
1303
+ ensure mkdir -p "$INFERRED_HOME/.config/fish/conf.d"
1304
+ exit4=$?
1305
+ add_install_dir_to_path "$_install_dir_expr" "$_fish_env_script_path" "$_fish_env_script_path_expr" ".config/fish/conf.d/$APP_NAME.env.fish" "fish"
1306
+ exit5=$?
1307
+
1308
+ if [ "${exit1:-0}" = 1 ] || [ "${exit2:-0}" = 1 ] || [ "${exit3:-0}" = 1 ] || [ "${exit4:-0}" = 1 ] || [ "${exit5:-0}" = 1 ]; then
1309
+ say ""
1310
+ say "To add $_install_dir_expr to your PATH, either restart your shell or run:"
1311
+ say ""
1312
+ say " source $_env_script_path_expr (sh, bash, zsh)"
1313
+ say " source $_fish_env_script_path_expr (fish)"
1314
+ fi
1315
+ fi
1316
+
1317
+ _shadowed_bins="$(check_for_shadowed_bins "$_install_dir" "$_bins")"
1318
+ if [ -n "$_shadowed_bins" ]; then
1319
+ warn "The following commands are shadowed by other commands in your PATH:$_shadowed_bins"
1320
+ fi
1321
+ }
1322
+
1323
+ check_for_shadowed_bins() {
1324
+ local _install_dir="$1"
1325
+ local _bins="$2"
1326
+ local _shadow
1327
+
1328
+ for _bin_name in $_bins; do
1329
+ _shadow="$(command -v "$_bin_name")"
1330
+ if [ -n "$_shadow" ] && [ "$_shadow" != "$_install_dir/$_bin_name" ]; then
1331
+ _shadowed_bins="$_shadowed_bins $_bin_name"
1332
+ fi
1333
+ done
1334
+
1335
+ echo "$_shadowed_bins"
1336
+ }
1337
+
1338
+ print_home_for_script() {
1339
+ local script="$1"
1340
+
1341
+ local _home
1342
+ case "$script" in
1343
+ # zsh has a special ZDOTDIR directory, which if set
1344
+ # should be considered instead of $HOME
1345
+ .zsh*)
1346
+ if [ -n "${ZDOTDIR:-}" ]; then
1347
+ _home="$ZDOTDIR"
1348
+ else
1349
+ _home="$INFERRED_HOME"
1350
+ fi
1351
+ ;;
1352
+ *)
1353
+ _home="$INFERRED_HOME"
1354
+ ;;
1355
+ esac
1356
+
1357
+ echo "$_home"
1358
+ }
1359
+
1360
+ add_install_dir_to_ci_path() {
1361
+ # Attempt to do CI-specific rituals to get the install-dir on PATH faster
1362
+ local _install_dir="$1"
1363
+
1364
+ # If GITHUB_PATH is present, then write install_dir to the file it refs.
1365
+ # After each GitHub Action, the contents will be added to PATH.
1366
+ # So if you put a curl | sh for this script in its own "run" step,
1367
+ # the next step will have this dir on PATH.
1368
+ #
1369
+ # Note that GITHUB_PATH will not resolve any variables, so we in fact
1370
+ # want to write install_dir and not install_dir_expr
1371
+ if [ -n "${GITHUB_PATH:-}" ]; then
1372
+ ensure echo "$_install_dir" >> "$GITHUB_PATH"
1373
+ fi
1374
+ }
1375
+
1376
+ add_install_dir_to_path() {
1377
+ # Edit rcfiles ($HOME/.profile) to add install_dir to $PATH
1378
+ #
1379
+ # We do this slightly indirectly by creating an "env" shell script which checks if install_dir
1380
+ # is on $PATH already, and prepends it if not. The actual line we then add to rcfiles
1381
+ # is to just source that script. This allows us to blast it into lots of different rcfiles and
1382
+ # have it run multiple times without causing problems. It's also specifically compatible
1383
+ # with the system rustup uses, so that we don't conflict with it.
1384
+ local _install_dir_expr="$1"
1385
+ local _env_script_path="$2"
1386
+ local _env_script_path_expr="$3"
1387
+ local _rcfiles="$4"
1388
+ local _shell="$5"
1389
+
1390
+ if [ -n "${INFERRED_HOME:-}" ]; then
1391
+ local _target
1392
+ local _home
1393
+
1394
+ # Find the first file in the array that exists and choose
1395
+ # that as our target to write to
1396
+ for _rcfile_relative in $_rcfiles; do
1397
+ _home="$(print_home_for_script "$_rcfile_relative")"
1398
+ local _rcfile="$_home/$_rcfile_relative"
1399
+
1400
+ if [ -f "$_rcfile" ]; then
1401
+ _target="$_rcfile"
1402
+ break
1403
+ fi
1404
+ done
1405
+
1406
+ # If we didn't find anything, pick the first entry in the
1407
+ # list as the default to create and write to
1408
+ if [ -z "${_target:-}" ]; then
1409
+ local _rcfile_relative
1410
+ _rcfile_relative="$(echo "$_rcfiles" | awk '{ print $1 }')"
1411
+ _home="$(print_home_for_script "$_rcfile_relative")"
1412
+ _target="$_home/$_rcfile_relative"
1413
+ fi
1414
+
1415
+ # `source x` is an alias for `. x`, and the latter is more portable/actually-posix.
1416
+ # This apparently comes up a lot on freebsd. It's easy enough to always add
1417
+ # the more robust line to rcfiles, but when telling the user to apply the change
1418
+ # to their current shell ". x" is pretty easy to misread/miscopy, so we use the
1419
+ # prettier "source x" line there. Hopefully people with Weird Shells are aware
1420
+ # this is a thing and know to tweak it (or just restart their shell).
1421
+ local _robust_line=". \"$_env_script_path_expr\""
1422
+ local _pretty_line="source \"$_env_script_path_expr\""
1423
+
1424
+ # Add the env script if it doesn't already exist
1425
+ if [ ! -f "$_env_script_path" ]; then
1426
+ say_verbose "creating $_env_script_path"
1427
+ if [ "$_shell" = "sh" ]; then
1428
+ write_env_script_sh "$_install_dir_expr" "$_env_script_path"
1429
+ else
1430
+ write_env_script_fish "$_install_dir_expr" "$_env_script_path"
1431
+ fi
1432
+ else
1433
+ say_verbose "$_env_script_path already exists"
1434
+ fi
1435
+
1436
+ # Check if the line is already in the rcfile
1437
+ # grep: 0 if matched, 1 if no match, and 2 if an error occurred
1438
+ #
1439
+ # Ideally we could use quiet grep (-q), but that makes "match" and "error"
1440
+ # have the same behaviour, when we want "no match" and "error" to be the same
1441
+ # (on error we want to create the file, which >> conveniently does)
1442
+ #
1443
+ # We search for both kinds of line here just to do the right thing in more cases.
1444
+ if ! grep -F "$_robust_line" "$_target" > /dev/null 2>/dev/null && \
1445
+ ! grep -F "$_pretty_line" "$_target" > /dev/null 2>/dev/null
1446
+ then
1447
+ # If the script now exists, add the line to source it to the rcfile
1448
+ # (This will also create the rcfile if it doesn't exist)
1449
+ if [ -f "$_env_script_path" ]; then
1450
+ local _line
1451
+ # Fish has deprecated `.` as an alias for `source` and
1452
+ # it will be removed in a later version.
1453
+ # https://fishshell.com/docs/current/cmds/source.html
1454
+ # By contrast, `.` is the traditional syntax in sh and
1455
+ # `source` isn't always supported in all circumstances.
1456
+ if [ "$_shell" = "fish" ]; then
1457
+ _line="$_pretty_line"
1458
+ else
1459
+ _line="$_robust_line"
1460
+ fi
1461
+ say_verbose "adding $_line to $_target"
1462
+ # prepend an extra newline in case the user's file is missing a trailing one
1463
+ ensure echo "" >> "$_target"
1464
+ ensure echo "$_line" >> "$_target"
1465
+ return 1
1466
+ fi
1467
+ else
1468
+ say_verbose "$_install_dir already on PATH"
1469
+ fi
1470
+ fi
1471
+ }
1472
+
1473
+ shotgun_install_dir_to_path() {
1474
+ # Edit rcfiles ($HOME/.profile) to add install_dir to $PATH
1475
+ # (Shotgun edition - write to all provided files that exist rather than just the first)
1476
+ local _install_dir_expr="$1"
1477
+ local _env_script_path="$2"
1478
+ local _env_script_path_expr="$3"
1479
+ local _rcfiles="$4"
1480
+ local _shell="$5"
1481
+
1482
+ if [ -n "${INFERRED_HOME:-}" ]; then
1483
+ local _found=false
1484
+ local _home
1485
+
1486
+ for _rcfile_relative in $_rcfiles; do
1487
+ _home="$(print_home_for_script "$_rcfile_relative")"
1488
+ local _rcfile_abs="$_home/$_rcfile_relative"
1489
+
1490
+ if [ -f "$_rcfile_abs" ]; then
1491
+ _found=true
1492
+ add_install_dir_to_path "$_install_dir_expr" "$_env_script_path" "$_env_script_path_expr" "$_rcfile_relative" "$_shell"
1493
+ fi
1494
+ done
1495
+
1496
+ # Fall through to previous "create + write to first file in list" behavior
1497
+ if [ "$_found" = false ]; then
1498
+ add_install_dir_to_path "$_install_dir_expr" "$_env_script_path" "$_env_script_path_expr" "$_rcfiles" "$_shell"
1499
+ fi
1500
+ fi
1501
+ }
1502
+
1503
+ write_env_script_sh() {
1504
+ # write this env script to the given path (this cat/EOF stuff is a "heredoc" string)
1505
+ local _install_dir_expr="$1"
1506
+ local _env_script_path="$2"
1507
+ ensure cat <<EOF > "$_env_script_path"
1508
+ #!/bin/sh
1509
+ # add binaries to PATH if they aren't added yet
1510
+ # affix colons on either side of \$PATH to simplify matching
1511
+ case ":\${PATH}:" in
1512
+ *:"$_install_dir_expr":*)
1513
+ ;;
1514
+ *)
1515
+ # Prepending path in case a system-installed binary needs to be overridden
1516
+ export PATH="$_install_dir_expr:\$PATH"
1517
+ ;;
1518
+ esac
1519
+ EOF
1520
+ }
1521
+
1522
+ write_env_script_fish() {
1523
+ # write this env script to the given path (this cat/EOF stuff is a "heredoc" string)
1524
+ local _install_dir_expr="$1"
1525
+ local _env_script_path="$2"
1526
+ ensure cat <<EOF > "$_env_script_path"
1527
+ if not contains "$_install_dir_expr" \$PATH
1528
+ # Prepending path in case a system-installed binary needs to be overridden
1529
+ set -x PATH "$_install_dir_expr" \$PATH
1530
+ end
1531
+ EOF
1532
+ }
1533
+
1534
+ get_current_exe() {
1535
+ # Returns the executable used for system architecture detection
1536
+ # This is only run on Linux
1537
+ local _current_exe
1538
+ if test -L /proc/self/exe ; then
1539
+ _current_exe=/proc/self/exe
1540
+ else
1541
+ warn "Unable to find /proc/self/exe. System architecture detection might be inaccurate."
1542
+ if test -n "$SHELL" ; then
1543
+ _current_exe=$SHELL
1544
+ else
1545
+ need_cmd /bin/sh
1546
+ _current_exe=/bin/sh
1547
+ fi
1548
+ warn "Falling back to $_current_exe."
1549
+ fi
1550
+ echo "$_current_exe"
1551
+ }
1552
+
1553
+ get_bitness() {
1554
+ need_cmd head
1555
+ # Architecture detection without dependencies beyond coreutils.
1556
+ # ELF files start out "\x7fELF", and the following byte is
1557
+ # 0x01 for 32-bit and
1558
+ # 0x02 for 64-bit.
1559
+ # The printf builtin on some shells like dash only supports octal
1560
+ # escape sequences, so we use those.
1561
+ local _current_exe=$1
1562
+ local _current_exe_head
1563
+ _current_exe_head=$(head -c 5 "$_current_exe")
1564
+ if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then
1565
+ echo 32
1566
+ elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then
1567
+ echo 64
1568
+ else
1569
+ err "unknown platform bitness"
1570
+ fi
1571
+ }
1572
+
1573
+ is_host_amd64_elf() {
1574
+ local _current_exe=$1
1575
+
1576
+ need_cmd head
1577
+ need_cmd tail
1578
+ # ELF e_machine detection without dependencies beyond coreutils.
1579
+ # Two-byte field at offset 0x12 indicates the CPU,
1580
+ # but we're interested in it being 0x3E to indicate amd64, or not that.
1581
+ local _current_exe_machine
1582
+ _current_exe_machine=$(head -c 19 "$_current_exe" | tail -c 1)
1583
+ [ "$_current_exe_machine" = "$(printf '\076')" ]
1584
+ }
1585
+
1586
+ get_endianness() {
1587
+ local _current_exe=$1
1588
+ local cputype=$2
1589
+ local suffix_eb=$3
1590
+ local suffix_el=$4
1591
+
1592
+ # detect endianness without od/hexdump, like get_bitness() does.
1593
+ need_cmd head
1594
+ need_cmd tail
1595
+
1596
+ local _current_exe_endianness
1597
+ _current_exe_endianness="$(head -c 6 "$_current_exe" | tail -c 1)"
1598
+ if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then
1599
+ echo "${cputype}${suffix_el}"
1600
+ elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then
1601
+ echo "${cputype}${suffix_eb}"
1602
+ else
1603
+ err "unknown platform endianness"
1604
+ fi
1605
+ }
1606
+
1607
+ # Detect the Linux/LoongArch UAPI flavor, with all errors being non-fatal.
1608
+ # Returns 0 or 234 in case of successful detection, 1 otherwise (/tmp being
1609
+ # noexec, or other causes).
1610
+ check_loongarch_uapi() {
1611
+ need_cmd base64
1612
+
1613
+ local _tmp
1614
+ if ! _tmp="$(ensure mktemp)"; then
1615
+ return 1
1616
+ fi
1617
+
1618
+ # Minimal Linux/LoongArch UAPI detection, exiting with 0 in case of
1619
+ # upstream ("new world") UAPI, and 234 (-EINVAL truncated) in case of
1620
+ # old-world (as deployed on several early commercial Linux distributions
1621
+ # for LoongArch).
1622
+ #
1623
+ # See https://gist.github.com/xen0n/5ee04aaa6cecc5c7794b9a0c3b65fc7f for
1624
+ # source to this helper binary.
1625
+ ignore base64 -d > "$_tmp" <<EOF
1626
+ f0VMRgIBAQAAAAAAAAAAAAIAAgEBAAAAeAAgAAAAAABAAAAAAAAAAAAAAAAAAAAAQQAAAEAAOAAB
1627
+ AAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAJAAAAAAAAAAkAAAAAAAAAAAA
1628
+ AQAAAAAABCiAAwUAFQAGABUAByCAAwsYggMAACsAC3iBAwAAKwAxen0n
1629
+ EOF
1630
+
1631
+ ignore chmod u+x "$_tmp"
1632
+ if [ ! -x "$_tmp" ]; then
1633
+ ignore rm "$_tmp"
1634
+ return 1
1635
+ fi
1636
+
1637
+ "$_tmp"
1638
+ local _retval=$?
1639
+
1640
+ ignore rm "$_tmp"
1641
+ return "$_retval"
1642
+ }
1643
+
1644
+ ensure_loongarch_uapi() {
1645
+ check_loongarch_uapi
1646
+ case $? in
1647
+ 0)
1648
+ return 0
1649
+ ;;
1650
+ 234)
1651
+ err 'Your Linux kernel does not provide the ABI required by this distribution.'
1652
+ ;;
1653
+ *)
1654
+ warn "Cannot determine current system's ABI flavor, continuing anyway."
1655
+ warn 'Note that the official distribution only works with the upstream kernel ABI.'
1656
+ warn 'Installation will fail if your running kernel happens to be incompatible.'
1657
+ ;;
1658
+ esac
1659
+ }
1660
+
1661
+ get_architecture() {
1662
+ local _ostype
1663
+ local _cputype
1664
+ _ostype="$(uname -s)"
1665
+ _cputype="$(uname -m)"
1666
+ local _clibtype="gnu"
1667
+ local _local_glibc
1668
+
1669
+ if [ "$_ostype" = Linux ]; then
1670
+ if [ "$(uname -o)" = Android ]; then
1671
+ _ostype=Android
1672
+ fi
1673
+ if ldd --version 2>&1 | grep -q 'musl'; then
1674
+ _clibtype="musl-dynamic"
1675
+ else
1676
+ # Assume all other linuxes are glibc (even if wrong, static libc fallback will apply)
1677
+ _clibtype="gnu"
1678
+ fi
1679
+ fi
1680
+
1681
+ if [ "$_ostype" = Darwin ]; then
1682
+ # Darwin `uname -m` can lie due to Rosetta shenanigans. If you manage to
1683
+ # invoke a native shell binary and then a native uname binary, you can
1684
+ # get the real answer, but that's hard to ensure, so instead we use
1685
+ # `sysctl` (which doesn't lie) to check for the actual architecture.
1686
+ if [ "$_cputype" = i386 ]; then
1687
+ # Handling i386 compatibility mode in older macOS versions (<10.15)
1688
+ # running on x86_64-based Macs.
1689
+ # Starting from 10.15, macOS explicitly bans all i386 binaries from running.
1690
+ # See: <https://support.apple.com/en-us/HT208436>
1691
+
1692
+ # Avoid `sysctl: unknown oid` stderr output and/or non-zero exit code.
1693
+ if sysctl hw.optional.x86_64 2> /dev/null || true | grep -q ': 1'; then
1694
+ _cputype=x86_64
1695
+ fi
1696
+ elif [ "$_cputype" = x86_64 ]; then
1697
+ # Handling x86-64 compatibility mode (a.k.a. Rosetta 2)
1698
+ # in newer macOS versions (>=11) running on arm64-based Macs.
1699
+ # Rosetta 2 is built exclusively for x86-64 and cannot run i386 binaries.
1700
+
1701
+ # Avoid `sysctl: unknown oid` stderr output and/or non-zero exit code.
1702
+ if sysctl hw.optional.arm64 2> /dev/null || true | grep -q ': 1'; then
1703
+ _cputype=arm64
1704
+ fi
1705
+ fi
1706
+ fi
1707
+
1708
+ if [ "$_ostype" = SunOS ]; then
1709
+ # Both Solaris and illumos presently announce as "SunOS" in "uname -s"
1710
+ # so use "uname -o" to disambiguate. We use the full path to the
1711
+ # system uname in case the user has coreutils uname first in PATH,
1712
+ # which has historically sometimes printed the wrong value here.
1713
+ if [ "$(/usr/bin/uname -o)" = illumos ]; then
1714
+ _ostype=illumos
1715
+ fi
1716
+
1717
+ # illumos systems have multi-arch userlands, and "uname -m" reports the
1718
+ # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86
1719
+ # systems. Check for the native (widest) instruction set on the
1720
+ # running kernel:
1721
+ if [ "$_cputype" = i86pc ]; then
1722
+ _cputype="$(isainfo -n)"
1723
+ fi
1724
+ fi
1725
+
1726
+ local _current_exe
1727
+ case "$_ostype" in
1728
+
1729
+ Android)
1730
+ _ostype=linux-android
1731
+ ;;
1732
+
1733
+ Linux)
1734
+ _current_exe=$(get_current_exe)
1735
+ _ostype=unknown-linux-$_clibtype
1736
+ _bitness=$(get_bitness "$_current_exe")
1737
+ ;;
1738
+
1739
+ FreeBSD)
1740
+ _ostype=unknown-freebsd
1741
+ ;;
1742
+
1743
+ NetBSD)
1744
+ _ostype=unknown-netbsd
1745
+ ;;
1746
+
1747
+ DragonFly)
1748
+ _ostype=unknown-dragonfly
1749
+ ;;
1750
+
1751
+ Darwin)
1752
+ _ostype=apple-darwin
1753
+ ;;
1754
+
1755
+ illumos)
1756
+ _ostype=unknown-illumos
1757
+ ;;
1758
+
1759
+ MINGW* | MSYS* | CYGWIN* | Windows_NT)
1760
+ _ostype=pc-windows-gnu
1761
+ ;;
1762
+
1763
+ *)
1764
+ err "unrecognized OS type: $_ostype"
1765
+ ;;
1766
+
1767
+ esac
1768
+
1769
+ case "$_cputype" in
1770
+
1771
+ i386 | i486 | i686 | i786 | x86)
1772
+ _cputype=i686
1773
+ ;;
1774
+
1775
+ xscale | arm)
1776
+ _cputype=arm
1777
+ if [ "$_ostype" = "linux-android" ]; then
1778
+ _ostype=linux-androideabi
1779
+ fi
1780
+ ;;
1781
+
1782
+ armv6l)
1783
+ _cputype=arm
1784
+ if [ "$_ostype" = "linux-android" ]; then
1785
+ _ostype=linux-androideabi
1786
+ else
1787
+ _ostype="${_ostype}eabihf"
1788
+ fi
1789
+ ;;
1790
+
1791
+ armv7l | armv8l)
1792
+ _cputype=armv7
1793
+ if [ "$_ostype" = "linux-android" ]; then
1794
+ _ostype=linux-androideabi
1795
+ else
1796
+ _ostype="${_ostype}eabihf"
1797
+ fi
1798
+ ;;
1799
+
1800
+ aarch64 | arm64)
1801
+ _cputype=aarch64
1802
+ ;;
1803
+
1804
+ x86_64 | x86-64 | x64 | amd64)
1805
+ _cputype=x86_64
1806
+ ;;
1807
+
1808
+ mips)
1809
+ _cputype=$(get_endianness "$_current_exe" mips '' el)
1810
+ ;;
1811
+
1812
+ mips64)
1813
+ if [ "$_bitness" -eq 64 ]; then
1814
+ # only n64 ABI is supported for now
1815
+ _ostype="${_ostype}abi64"
1816
+ _cputype=$(get_endianness "$_current_exe" mips64 '' el)
1817
+ fi
1818
+ ;;
1819
+
1820
+ ppc)
1821
+ _cputype=powerpc
1822
+ ;;
1823
+
1824
+ ppc64)
1825
+ _cputype=powerpc64
1826
+ ;;
1827
+
1828
+ ppc64le)
1829
+ _cputype=powerpc64le
1830
+ ;;
1831
+
1832
+ s390x)
1833
+ _cputype=s390x
1834
+ ;;
1835
+ riscv64)
1836
+ _cputype=riscv64gc
1837
+ ;;
1838
+ loongarch64)
1839
+ _cputype=loongarch64
1840
+ ensure_loongarch_uapi
1841
+ ;;
1842
+ *)
1843
+ err "unknown CPU type: $_cputype"
1844
+
1845
+ esac
1846
+
1847
+ # Detect 64-bit linux with 32-bit userland
1848
+ if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then
1849
+ case $_cputype in
1850
+ x86_64)
1851
+ # 32-bit executable for amd64 = x32
1852
+ if is_host_amd64_elf "$_current_exe"; then {
1853
+ err "x32 linux unsupported"
1854
+ }; else
1855
+ _cputype=i686
1856
+ fi
1857
+ ;;
1858
+ mips64)
1859
+ _cputype=$(get_endianness "$_current_exe" mips '' el)
1860
+ ;;
1861
+ powerpc64)
1862
+ _cputype=powerpc
1863
+ ;;
1864
+ aarch64)
1865
+ _cputype=armv7
1866
+ if [ "$_ostype" = "linux-android" ]; then
1867
+ _ostype=linux-androideabi
1868
+ else
1869
+ _ostype="${_ostype}eabihf"
1870
+ fi
1871
+ ;;
1872
+ riscv64gc)
1873
+ err "riscv64 with 32-bit userland unsupported"
1874
+ ;;
1875
+ esac
1876
+ fi
1877
+
1878
+ # Detect armv7 but without the CPU features Rust needs in that build,
1879
+ # and fall back to arm.
1880
+ if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then
1881
+ if ! (ensure grep '^Features' /proc/cpuinfo | grep -E -q 'neon|simd') ; then
1882
+ # Either `/proc/cpuinfo` is malformed or unavailable, or
1883
+ # at least one processor does not have NEON (which is asimd on armv8+).
1884
+ _cputype=arm
1885
+ fi
1886
+ fi
1887
+
1888
+ _arch="${_cputype}-${_ostype}"
1889
+
1890
+ RETVAL="$_arch"
1891
+ }
1892
+
1893
+ say() {
1894
+ if [ "0" = "$PRINT_QUIET" ]; then
1895
+ echo "$1"
1896
+ fi
1897
+ }
1898
+
1899
+ say_verbose() {
1900
+ if [ "1" = "$PRINT_VERBOSE" ]; then
1901
+ echo "$1"
1902
+ fi
1903
+ }
1904
+
1905
+ warn() {
1906
+ if [ "0" = "$PRINT_QUIET" ]; then
1907
+ local red
1908
+ local reset
1909
+ red=$(tput setaf 1 2>/dev/null || echo '')
1910
+ reset=$(tput sgr0 2>/dev/null || echo '')
1911
+ say "${red}WARN${reset}: $1" >&2
1912
+ fi
1913
+ }
1914
+
1915
+ err() {
1916
+ if [ "0" = "$PRINT_QUIET" ]; then
1917
+ local red
1918
+ local reset
1919
+ red=$(tput setaf 1 2>/dev/null || echo '')
1920
+ reset=$(tput sgr0 2>/dev/null || echo '')
1921
+ say "${red}ERROR${reset}: $1" >&2
1922
+ fi
1923
+ exit 1
1924
+ }
1925
+
1926
+ need_cmd() {
1927
+ if ! check_cmd "$1"
1928
+ then err "need '$1' (command not found)"
1929
+ fi
1930
+ }
1931
+
1932
+ check_cmd() {
1933
+ command -v "$1" > /dev/null 2>&1
1934
+ return $?
1935
+ }
1936
+
1937
+ assert_nz() {
1938
+ if [ -z "$1" ]; then err "assert_nz $2"; fi
1939
+ }
1940
+
1941
+ # Run a command that should never fail. If the command fails execution
1942
+ # will immediately terminate with an error showing the failing
1943
+ # command.
1944
+ ensure() {
1945
+ if ! "$@"; then err "command failed: $*"; fi
1946
+ }
1947
+
1948
+ # This is just for indicating that commands' results are being
1949
+ # intentionally ignored. Usually, because it's being executed
1950
+ # as part of error handling.
1951
+ ignore() {
1952
+ "$@"
1953
+ }
1954
+
1955
+ # This wraps curl or wget. Try curl first, if not installed,
1956
+ # use wget instead.
1957
+ downloader() {
1958
+ # Check if we have a broken snap curl
1959
+ # https://github.com/boukendesho/curl-snap/issues/1
1960
+ _snap_curl=0
1961
+ if command -v curl > /dev/null 2>&1; then
1962
+ _curl_path=$(command -v curl)
1963
+ if echo "$_curl_path" | grep "/snap/" > /dev/null 2>&1; then
1964
+ _snap_curl=1
1965
+ fi
1966
+ fi
1967
+
1968
+ # Check if we have a working (non-snap) curl
1969
+ if check_cmd curl && [ "$_snap_curl" = "0" ]
1970
+ then _dld=curl
1971
+ # Try wget for both no curl and the broken snap curl
1972
+ elif check_cmd wget
1973
+ then _dld=wget
1974
+ # If we can't fall back from broken snap curl to wget, report the broken snap curl
1975
+ elif [ "$_snap_curl" = "1" ]
1976
+ then
1977
+ say "curl installed with snap cannot be used to install $APP_NAME"
1978
+ say "due to missing permissions. Please uninstall it and"
1979
+ say "reinstall curl with a different package manager (e.g., apt)."
1980
+ say "See https://github.com/boukendesho/curl-snap/issues/1"
1981
+ exit 1
1982
+ else _dld='curl or wget' # to be used in error message of need_cmd
1983
+ fi
1984
+
1985
+ if [ "$1" = --check ]
1986
+ then need_cmd "$_dld"
1987
+ elif [ "$_dld" = curl ]; then
1988
+ if [ -n "${AUTH_TOKEN:-}" ]; then
1989
+ curl -sSfL --header "Authorization: Bearer ${AUTH_TOKEN}" "$1" -o "$2"
1990
+ else
1991
+ curl -sSfL "$1" -o "$2"
1992
+ fi
1993
+ elif [ "$_dld" = wget ]; then
1994
+ if [ -n "${AUTH_TOKEN:-}" ]; then
1995
+ wget --header "Authorization: Bearer ${AUTH_TOKEN}" "$1" -O "$2"
1996
+ else
1997
+ wget "$1" -O "$2"
1998
+ fi
1999
+ else err "Unknown downloader" # should not reach here
2000
+ fi
2001
+ }
2002
+
2003
+ verify_checksum() {
2004
+ local _file="$1"
2005
+ local _checksum_style="$2"
2006
+ local _checksum_value="$3"
2007
+ local _calculated_checksum
2008
+
2009
+ if [ -z "$_checksum_value" ]; then
2010
+ return 0
2011
+ fi
2012
+ case "$_checksum_style" in
2013
+ sha256)
2014
+ if ! check_cmd sha256sum; then
2015
+ say "skipping sha256 checksum verification (it requires the 'sha256sum' command)"
2016
+ return 0
2017
+ fi
2018
+ _calculated_checksum="$(sha256sum -b "$_file" | awk '{printf $1}')"
2019
+ ;;
2020
+ sha512)
2021
+ if ! check_cmd sha512sum; then
2022
+ say "skipping sha512 checksum verification (it requires the 'sha512sum' command)"
2023
+ return 0
2024
+ fi
2025
+ _calculated_checksum="$(sha512sum -b "$_file" | awk '{printf $1}')"
2026
+ ;;
2027
+ sha3-256)
2028
+ if ! check_cmd openssl; then
2029
+ say "skipping sha3-256 checksum verification (it requires the 'openssl' command)"
2030
+ return 0
2031
+ fi
2032
+ _calculated_checksum="$(openssl dgst -sha3-256 "$_file" | awk '{printf $NF}')"
2033
+ ;;
2034
+ sha3-512)
2035
+ if ! check_cmd openssl; then
2036
+ say "skipping sha3-512 checksum verification (it requires the 'openssl' command)"
2037
+ return 0
2038
+ fi
2039
+ _calculated_checksum="$(openssl dgst -sha3-512 "$_file" | awk '{printf $NF}')"
2040
+ ;;
2041
+ blake2s)
2042
+ if ! check_cmd b2sum; then
2043
+ say "skipping blake2s checksum verification (it requires the 'b2sum' command)"
2044
+ return 0
2045
+ fi
2046
+ # Test if we have official b2sum with blake2s support
2047
+ local _well_known_blake2s_checksum="93314a61f470985a40f8da62df10ba0546dc5216e1d45847bf1dbaa42a0e97af"
2048
+ local _test_blake2s
2049
+ _test_blake2s="$(printf "can do blake2s" | b2sum -a blake2s | awk '{printf $1}')" || _test_blake2s=""
2050
+
2051
+ if [ "X$_test_blake2s" = "X$_well_known_blake2s_checksum" ]; then
2052
+ _calculated_checksum="$(b2sum -a blake2s "$_file" | awk '{printf $1}')" || _calculated_checksum=""
2053
+ else
2054
+ say "skipping blake2s checksum verification (installed b2sum doesn't support blake2s)"
2055
+ return 0
2056
+ fi
2057
+ ;;
2058
+ blake2b)
2059
+ if ! check_cmd b2sum; then
2060
+ say "skipping blake2b checksum verification (it requires the 'b2sum' command)"
2061
+ return 0
2062
+ fi
2063
+ _calculated_checksum="$(b2sum "$_file" | awk '{printf $1}')"
2064
+ ;;
2065
+ false)
2066
+ ;;
2067
+ *)
2068
+ say "skipping unknown checksum style: $_checksum_style"
2069
+ return 0
2070
+ ;;
2071
+ esac
2072
+
2073
+ if [ "$_calculated_checksum" != "$_checksum_value" ]; then
2074
+ err "checksum mismatch
2075
+ want: $_checksum_value
2076
+ got: $_calculated_checksum"
2077
+ fi
2078
+ }
2079
+
2080
+ download_binary_and_run_installer "$@" || exit 1