-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·163 lines (150 loc) · 7.99 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·163 lines (150 loc) · 7.99 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
#!/bin/bash
set -e
INSTALL_DIR="$HOME/.polkadot"
REPO="paritytech/playground-cli"
# The command users invoke, plus a short alias. Both resolve to the same binary.
CMD="playground"
ALIAS="pg"
# Release artifacts are still published as `dot-<os>-<arch>` — keep the asset
# prefix in sync with .github/workflows/release.yml. The downloaded file is
# saved locally under $CMD, so the old `dot` command name is gone.
ASSET_PREFIX="dot"
# Record whether the command ALREADY resolves on the caller's PATH (re-install /
# upgrade) before we touch anything. We install into BOTH $INSTALL_DIR/bin and
# ~/.local/bin (the symlinks below); ~/.local/bin is already on PATH by default
# on Debian/Ubuntu, so a "fresh" install there resolves immediately. Check both
# dirs so the reload hint is suppressed whenever the command already works.
case ":$PATH:" in
*":$INSTALL_DIR/bin:"*|*":$HOME/.local/bin:"*) ALREADY_ON_PATH=1 ;;
*) ALREADY_ON_PATH=0 ;;
esac
# 1) Detect platform. Git Bash / MSYS / Cygwin report MINGW*/MSYS*/CYGWIN* —
# point Windows users at WSL instead of a bare "Unsupported OS".
OS=$(uname -s); case "$OS" in Linux) OS=linux;; Darwin) OS=darwin;; MINGW*|MSYS*|CYGWIN*) echo "Windows is not supported natively. Install WSL (https://learn.microsoft.com/windows/wsl/install) and re-run this command inside it."; exit 1;; *) echo "Unsupported OS: $OS"; exit 1;; esac
ARCH=$(uname -m); case "$ARCH" in x86_64|amd64) ARCH=x64;; arm64|aarch64) ARCH=arm64;; *) echo "Unsupported arch: $ARCH"; exit 1;; esac
ASSET="$ASSET_PREFIX-$OS-$ARCH"
# 1b) Prerequisite guard (#248). Everything below fetches via curl. Reaching
# this point without curl means the script was fetched some other way (wget,
# copy-paste), so fail fast with the exact remedy instead of a cryptic error.
if ! command -v curl >/dev/null 2>&1; then
echo "Error: curl is required but not installed." >&2
if [ "$OS" = "linux" ]; then
echo "Install prerequisites first: sudo apt update && sudo apt install -y build-essential curl" >&2
else
echo "Install the Xcode Command Line Tools first: xcode-select --install" >&2
fi
exit 1
fi
# 2) Resolve release tag
#
# Use VERSION to install a specific tag. Otherwise, prefer GitHub's no-body
# `releases/latest` redirect. This avoids api.github.com quota while keeping
# "latest" tied to the same GitHub release source used for the binary
# download. jsDelivr is CDN-backed and can lag a freshly published release,
# so keep it as fallback only.
if [ -n "$VERSION" ]; then
TAG="$VERSION"
else
TAG=$(curl -fsSI -H "Cache-Control: no-cache" -H "Pragma: no-cache" "https://github.com/$REPO/releases/latest" \
| sed -n 's|^[Ll][Oo][Cc][Aa][Tt][Ii][Oo][Nn]:[[:space:]]*.*/tag/\(.*\)$|\1|p' \
| tr -d '\r' | head -n1) || true
if [ -z "$TAG" ]; then
TAG=$(curl -fsSL "https://data.jsdelivr.com/v1/packages/gh/$REPO/resolved" \
| sed -n 's/.*"version": *"\([^"]*\)".*/\1/p' | head -n1) || true
fi
case "$TAG" in v*|'') ;; *) TAG="v$TAG" ;; esac
fi
[ -z "$TAG" ] && echo "Could not determine latest release" && exit 1
# 3) Install binary
spin() { while true; do for c in '|' '/' '-' '\'; do printf "\r%s %s" "$1" "$c"; sleep 0.1; done; done; }
spin "Installing $CMD ($OS/$ARCH) $TAG" &
SPIN_PID=$!
trap "kill $SPIN_PID 2>/dev/null" EXIT
mkdir -p "$INSTALL_DIR/bin" "$HOME/.local/bin"
curl -fsSL "https://github.com/$REPO/releases/download/$TAG/$ASSET" -o "$INSTALL_DIR/bin/$CMD"
chmod +x "$INSTALL_DIR/bin/$CMD"
if [ "$OS" = "darwin" ]; then
codesign --sign - --force "$INSTALL_DIR/bin/$CMD" 2>/dev/null || true
xattr -c "$INSTALL_DIR/bin/$CMD" 2>/dev/null || true
fi
# Expose both the full command and its short alias from both bin dirs on PATH.
ln -sf "$INSTALL_DIR/bin/$CMD" "$INSTALL_DIR/bin/$ALIAS"
ln -sf "$INSTALL_DIR/bin/$CMD" "$HOME/.local/bin/$CMD"
ln -sf "$INSTALL_DIR/bin/$CMD" "$HOME/.local/bin/$ALIAS"
# Remove the legacy `dot` binary/symlink from earlier installs so it stops
# resolving on PATH — the command is now `playground` (or `pg`).
rm -f "$INSTALL_DIR/bin/dot" "$HOME/.local/bin/dot"
kill $SPIN_PID 2>/dev/null; wait $SPIN_PID 2>/dev/null || true; trap - EXIT
printf "\rInstalled %s (%s/%s) %s \n" "$CMD" "$OS" "$ARCH" "$TAG"
# 4) Add to PATH
append_once() {
local file="$1" line="$2"
grep -Fqx "$line" "$file" 2>/dev/null || printf "\n%s\n" "$line" >> "$file"
}
if command -v bash >/dev/null 2>&1; then
append_once "$HOME/.bashrc" 'export PATH="$HOME/.polkadot/bin:$HOME/.local/bin:$PATH"'
# Login bash shells (every macOS terminal tab) read only the FIRST existing of
# ~/.bash_profile, ~/.bash_login, ~/.profile and never auto-source ~/.bashrc.
# We need a ~/.bash_profile bridge so the PATH line above is loaded. But
# CREATING ~/.bash_profile from scratch would shadow a pre-existing
# ~/.bash_login / ~/.profile and silently drop the user's login-shell config.
# So when we have to create the bridge, carry the file bash would otherwise
# have read forward first. (If ~/.bash_profile already exists we leave its
# precedence untouched and only append the bashrc source below.)
if [ ! -e "$HOME/.bash_profile" ]; then
for legacy in .bash_login .profile; do
if [ -f "$HOME/$legacy" ]; then
printf '[ -f "$HOME/%s" ] && . "$HOME/%s"\n' "$legacy" "$legacy" >> "$HOME/.bash_profile"
break
fi
done
fi
# NB: if the carried-forward file itself sources ~/.bashrc (e.g. Debian's
# default ~/.profile does), a login shell sources ~/.bashrc twice. That is
# harmless for the idempotent PATH export above and not worth a runtime guard;
# sourcing ~/.bashrc exactly once across both that case and a macOS ~/.profile
# (which does NOT source it, so this line is required) would need a marker var
# coupling the two files. Double-sourcing beats silently dropping the config.
append_once "$HOME/.bash_profile" '[ -f "$HOME/.bashrc" ] && . "$HOME/.bashrc"'
fi
if command -v zsh >/dev/null 2>&1; then
append_once "$HOME/.zshrc" 'export PATH="$HOME/.polkadot/bin:$HOME/.local/bin:$PATH"'
fi
if command -v fish >/dev/null 2>&1; then
mkdir -p "$HOME/.config/fish"
append_once "$HOME/.config/fish/config.fish" 'fish_add_path $HOME/.polkadot/bin $HOME/.local/bin'
fi
export PATH="$INSTALL_DIR/bin:$HOME/.local/bin:$PATH"
echo ""
echo -e "$CMD is ready! Setting up dependencies…"
echo ""
if ! "$INSTALL_DIR/bin/$CMD" login --yes; then
LOGIN_EXIT=$?
echo -e "\n\033[33mDependency setup failed. Run \033[1m$CMD login\033[0;33m when ready.\033[0m" >&2
exit "$LOGIN_EXIT"
fi
# Final "what to run next" prompt, styled to match the yellow rounded-border
# Callout the TUI uses for phone-signing notifications (see
# src/utils/ui/theme/Callout.tsx). Mirrored in bash so it shows the moment the
# curl install finishes. Like npm/gh/cargo, we surface a single canonical
# command and note the alias once, dimmed — not two commands billed as equals.
Y='\033[33m'; B='\033[1m'; D='\033[2m'; R='\033[0m'
echo ""
echo -e "${Y}╭─ ${B}Next step${R}${Y} ────────────────────────────╮${R}"
echo -e "${Y}│${R} Log in with the Polkadot mobile app: ${Y}│${R}"
echo -e "${Y}│${R} ${Y}│${R}"
echo -e "${Y}│${R} ${B}$CMD login${R} ${Y}│${R}"
echo -e "${Y}╰────────────────────────────────────────╯${R}"
echo -e "${D} Tip: ${ALIAS} is a short alias for ${CMD}.${R}"
# This script runs in a child process, so it CANNOT add $CMD to the caller's
# live PATH — sourcing an rc file here would only touch this dying process, not
# the parent shell. On a fresh install the command therefore won't resolve until
# the caller's shell reloads, so print the exact reload command for their shell.
if [ "$ALREADY_ON_PATH" = "0" ]; then
case "$(basename "${SHELL:-bash}")" in
zsh) RC="$HOME/.zshrc" ;;
fish) RC="$HOME/.config/fish/config.fish" ;;
*) RC="$HOME/.bashrc" ;;
esac
echo -e "${D} First run \033[1msource ${RC/#$HOME/\$HOME}${R}${D} (or open a new terminal) to use ${CMD}.${R}"
fi