This repository was archived by the owner on Apr 25, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 299
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·369 lines (342 loc) · 11.3 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·369 lines (342 loc) · 11.3 KB
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
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
#!/usr/bin/env bash
# -e is not set so that we can check for errors ourselves
set -uo pipefail
# Anonymous telemetry
TELEMETRY="1"
PLATFORM=""
NEW_INSTALL="true"
INSTALL_METHOD=""
OUTCOME=""
STEP_FAILED="N/A"
STARTED_AT=""
if command -v date &>/dev/null; then
STARTED_AT="$(date -u -Iseconds)"
fi
case "$OSTYPE" in
linux*) PLATFORM="linux" ;;
darwin*) PLATFORM="macos" ;;
*) PLATFORM="unknown" ;;
esac
# disable telemetry if any opt-out vars are set
if [[ \
"${DO_NOT_TRACK:-}" == "1" || "${DO_NOT_TRACK:-}" == "true" || \
"${DISABLE_TELEMETRY:-}" == "1" || "${DISABLE_TELEMETRY:-}" == "true" || \
"${SHUTTLE_DISABLE_TELEMETRY:-}" == "1" || "${SHUTTLE_DISABLE_TELEMETRY:-}" == "true" || \
"${CI:-}" == "1" || "${CI:-}" == "true"
]]; then
TELEMETRY=0
fi
# default terminal on mac gives xterm-256color but still doesn't show colors
if [[ "${TERM:-}" = "xterm-256color" && "$PLATFORM" != "macos" ]]; then
SUPPORTS_COLOR="1"
echo -e "\
\e[40;38;5;208m ___ \e[0m
\e[40;38;5;208m / \\ \e[37m _ _ _ _ \e[0m
\e[40;38;5;208m __/ /\e[37m___| |__ _ _| |_| |_| | ___ \e[0m
\e[40;38;5;208m /_ /\e[37m/ __| '_ \\| | | | __| __| |/ _ \\ \e[0m
\e[40;38;5;208m _|_ | \e[37m\__ \\ | | | |_| | |_| |_| | __/ \e[0m
\e[40;38;5;208m |_| |/ \e[37m|___/_| |_|\\__,_|\\__|\\__|_|\\___| \e[0m
\e[40m \e[0m
"
else
SUPPORTS_COLOR="0"
echo "\
___
/ \\ _ _ _ _
__/ /___| |__ _ _| |_| |_| | ___
/_ // __| '_ \\| | | | __| __| |/ _ \\
_|_ | \__ \\ | | | |_| | |_| |_| | __/
|_| |/ |___/_| |_|\\__,_|\\__|\\__|_|\\___|
"
fi
echo "\
https://docs.shuttle.dev
https://discord.gg/shuttle
https://github.com/shuttle-hq/shuttle
Please open an issue if you encounter any problems!"
if [[ "$TELEMETRY" = "1" ]]; then
[[ "$SUPPORTS_COLOR" = "1" ]] && echo -en "\e[2m"
echo "Anonymous telemetry enabled. More info and opt-out:"
echo "https://docs.shuttle.dev/install-script"
[[ "$SUPPORTS_COLOR" = "1" ]] && echo -en "\e[0m"
fi
echo "==================================================="
echo
INSTALLED_RUST=""
CARGO_DIR="${CARGO_HOME:-$HOME/.cargo}"
CARGO_INSTALL_DIR="${CARGO_INSTALL_ROOT:-$CARGO_DIR}"
CARGO_INSTALL_BIN_DIR="$CARGO_INSTALL_DIR/bin"
_send_telemetry() {
if [[ "$TELEMETRY" = "1" ]]; then
ENDED_AT=""
if command -v date &>/dev/null; then
ENDED_AT="$(date -u -Iseconds)"
fi
telemetry_data="{
\"api_key\":\"phc_cQMQqF5QmcEzXEaVlrhv3yBSNRyaabXYAyiCV7xKHUH\",
\"distinct_id\":\"install_script\",
\"event\":\"install_script_completion\",
\"properties\":{
\"platform\":\"$PLATFORM\",
\"new_install\":\"$NEW_INSTALL\",
\"install_method\":\"$INSTALL_METHOD\",
\"started_at\":\"$STARTED_AT\",
\"ended_at\":\"$ENDED_AT\",
\"outcome\":\"$OUTCOME\",
\"step_failed\":\"$STEP_FAILED\",
\"dont_track_ip\":true
}
}"
[ -n "${SHUTTLE_DEBUG:-}" ] && echo -e "DEBUG: Sending telemetry data:\n$telemetry_data"
curl -sL -H 'Content-Type: application/json' -d "$telemetry_data" https://console.shuttle.dev/ingest/i/v0/e > /dev/null
fi
}
_exit_success() {
OUTCOME="success"
_send_telemetry
echo
[[ "$SUPPORTS_COLOR" = "1" ]] && echo -en "\e[32m" # green
echo "Thanks for installing Shuttle CLI! 🚀"
[[ "$SUPPORTS_COLOR" = "1" ]] && echo -en "\e[0m"
if [[ "$INSTALLED_RUST" = "yes" ]]; then
echo
[[ "$SUPPORTS_COLOR" = "1" ]] && echo -en "\e[33m" # yellow
echo "Remember to 'source \"$CARGO_DIR/env\"' or restart your shell to run cargo and shuttle commands!"
[[ "$SUPPORTS_COLOR" = "1" ]] && echo -en "\e[0m"
fi
exit 0
}
_exit_neutral() {
OUTCOME="neutral"
echo
echo "If you have any problems, please open an issue on GitHub or visit our Discord!"
_send_telemetry
exit 0
}
_exit_failure() {
STEP_FAILED="$1"
OUTCOME="failure"
echo
[[ "$SUPPORTS_COLOR" = "1" ]] && echo -en "\e[31m" # red
echo "Shuttle installation script failed with reason: $STEP_FAILED"
[[ "$SUPPORTS_COLOR" = "1" ]] && echo -en "\e[0m"
echo "If you have any problems, please open an issue on GitHub or visit our Discord!"
_send_telemetry
exit 1
}
if ! command -v curl &>/dev/null; then
echo "curl not installed. Please install curl or use a different install method."
_exit_failure "curl-not-found"
elif ! command -v sed &>/dev/null; then
echo "sed not installed. Please install sed or use a different install method."
_exit_failure "sed-not-found"
fi
REPO_URL="https://github.com/shuttle-hq/shuttle"
LATEST_RELEASE=$(curl -fsL -H 'Accept: application/json' "$REPO_URL/releases/latest")
[ $? -ne 0 ] && _exit_failure "check-latest-release"
# shellcheck disable=SC2001
LATEST_VERSION=$(echo "$LATEST_RELEASE" | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
[ $? -ne 0 ] && _exit_failure "parse-latest-version"
if command -v cargo-shuttle &>/dev/null; then
NEW_INSTALL="false"
if [[ "$(cargo-shuttle -V)" = *"${LATEST_VERSION#v}" ]]; then
[[ "$SUPPORTS_COLOR" = "1" ]] && echo -en "\e[32m" # green
echo "Shuttle CLI is already at the latest version!"
[[ "$SUPPORTS_COLOR" = "1" ]] && echo -en "\e[0m"
exit 0 # skip telemetry and instantly exit
else
echo "Updating Shuttle CLI to $LATEST_VERSION"
fi
fi
_install_linux() {
echo "Detected Linux!"
echo "Checking distro..."
if (uname -a | grep -qi "Microsoft"); then
OS="ubuntuwsl"
elif ! command -v lsb_release &>/dev/null; then
[ -n "${SHUTTLE_DEBUG:-}" ] && echo "DEBUG: lsb_release could not be found. Falling back to /etc/os-release"
OS="$(grep -Eo '^ID=.*$' /etc/os-release | cut -d '=' -f 2 | tr '[:upper:]' '[:lower:]')" 2>/dev/null
else
OS=$(lsb_release -i | awk '{ print $3 }' | tr '[:upper:]' '[:lower:]')
fi
case "$OS" in
"arch" | "manjarolinux" | "endeavouros")
_install_arch_linux
;;
"alpine")
_install_alpine_linux
;;
"ubuntu" | "ubuntuwsl" | "debian" | "linuxmint" | "parrot" | "kali" | "elementary" | "pop")
# TODO: distribute .deb packages via `cargo-deb` and install them here
_install_default
;;
*)
_install_default
;;
esac
}
_install_arch_linux() {
echo "Arch Linux detected!"
if command -v pacman &>/dev/null; then
pacman_version=$(sudo pacman -Si cargo-shuttle | sed -n 's/^Version *: \(.*\)/\1/p')
if [[ "${pacman_version}" != "${LATEST_VERSION#v}"* ]]; then
echo "cargo-shuttle is not updated in the repos, ping @orhun!!!"
_install_default
else
echo "Installing with pacman"
INSTALL_METHOD="pacman"
sudo pacman -S --noconfirm cargo-shuttle || _exit_failure "pacman-install"
fi
else
echo "Pacman not found"
_install_default
fi
}
_install_alpine_linux() {
echo "Alpine Linux detected!"
if command -v apk &>/dev/null; then
if [ -z "$(apk search -q cargo-shuttle)" ]; then
while true; do
read -r -p "cargo-shuttle apk package not found. Do you want to enable the testing repository? [Y/n] " yn </dev/tty
case $yn in
[Yy]*|"")
echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories
apk update || _exit_failure "apk-update"
break
;;
[Nn]*)
_install_default
return 0
;;
*) echo "Please answer yes or no." ;;
esac
done
fi
if ! apk info -q --installed cargo-shuttle; then
echo "Installing with apk"
INSTALL_METHOD="apk"
apk add cargo-shuttle@testing || _exit_failure "apk-add"
else
apk_version=$(apk version cargo-shuttle | awk 'NR==2{print $3}')
if [[ "${apk_version}" != "${LATEST_VERSION#v}"* ]]; then
echo "cargo-shuttle is not updated in the testing repository, ping @orhun!!!"
_install_default
else
echo "Installing with apk"
INSTALL_METHOD="apk"
apk upgrade cargo-shuttle || _exit_failure "apk-upgrade"
fi
fi
else
echo "APK (Alpine Package Keeper) not found"
_install_default
fi
}
# TODO: package cargo-shuttle for Homebrew
_install_mac() {
_install_default
}
_install_binary() {
INSTALL_METHOD="binary-download"
case "$OSTYPE" in
linux*) target="x86_64-unknown-linux-musl" ;;
darwin*) target="x86_64-apple-darwin" ;;
*)
echo "Cannot determine the target to install"
_exit_failure "cannot-determine-target"
;;
esac
temp_dir=$(mktemp -d)
[ $? -ne 0 ] && _exit_failure "mktemp"
pushd "$temp_dir" >/dev/null || _exit_failure "pushd"
curl -LO "$REPO_URL/releases/download/$LATEST_VERSION/cargo-shuttle-$LATEST_VERSION-$target.tar.gz" || _exit_failure "download-binary"
if ! command -v tar &>/dev/null; then
_exit_failure "tar-not-found"
fi
tar -xzf "cargo-shuttle-$LATEST_VERSION-$target.tar.gz" || _exit_failure "tar-extract-binary"
mkdir -p "$CARGO_INSTALL_BIN_DIR"
echo "Installing to $CARGO_INSTALL_BIN_DIR/cargo-shuttle"
mv "cargo-shuttle-$target-$LATEST_VERSION/cargo-shuttle" "$CARGO_INSTALL_BIN_DIR/" || _exit_failure "move-binary"
echo "Installing to $CARGO_INSTALL_BIN_DIR/shuttle"
mv "cargo-shuttle-$target-$LATEST_VERSION/shuttle" "$CARGO_INSTALL_BIN_DIR/" || _exit_failure "move-binary"
popd >/dev/null || _exit_failure "popd"
if [[ ":$PATH:" != *":$CARGO_INSTALL_BIN_DIR:"* ]]; then
echo "Add $CARGO_INSTALL_BIN_DIR to PATH to access the 'shuttle' command"
fi
}
_install_rust_and_cargo() {
echo "Rust installation not found!"
while true; do
read -r -p "Install Rust and Cargo via rustup? [Y/n] " yn </dev/tty
case $yn in
[Yy]*|"")
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y || _exit_failure "install-rust"
# this only affects this script's env,
# user has to source or restart shell to apply to their shell
source "$CARGO_DIR/env"
break
;;
[Nn]*)
_exit_neutral
;;
*) echo "Please answer yes or no." ;;
esac
done
}
_install_with_cargo() {
echo "Installing with cargo..."
INSTALL_METHOD="cargo"
cargo install --locked cargo-shuttle || _exit_failure "cargo-install"
}
_install_default() {
echo "Installing with package manager is not supported"
if command -v cargo-binstall &>/dev/null; then
echo "Installing with cargo-binstall"
INSTALL_METHOD="cargo-binstall"
cargo-binstall -y --force --locked cargo-shuttle || _exit_failure "cargo-binstall"
return 0
fi
while true; do
read -r -p "Install the pre-built binary? [Y/n] " yn </dev/tty
case $yn in
[Yy]*|"")
_install_binary
break
;;
[Nn]*)
while true; do
read -r -p "Install from source with cargo? [Y/n] " yn </dev/tty
case $yn in
[Yy]*|"")
_install_with_cargo
break
;;
[Nn]*)
_exit_neutral
;;
*) echo "Please answer yes or no." ;;
esac
done
;;
*) echo "Please answer yes or no." ;;
esac
done
}
# Check Rust installation since it is a required dependency
if ! command -v cargo &>/dev/null; then
if ! command -v rustup &>/dev/null; then
_install_rust_and_cargo
INSTALLED_RUST="yes"
echo
else
echo "rustup was found, but cargo wasn't. Something is up with your Rust installation."
_exit_failure "rustup-found-cargo-not-found"
fi
fi
case "$OSTYPE" in
linux*) _install_linux ;;
darwin*) _install_mac ;;
*) _install_default ;;
esac
_exit_success
# vim: ts=2 sw=2 et: