-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathinstall.sh
More file actions
222 lines (194 loc) · 7.19 KB
/
install.sh
File metadata and controls
222 lines (194 loc) · 7.19 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
#!/bin/sh
# Rendobar CLI installer for macOS and Linux
# Usage: curl -fsSL https://rendobar.com/install.sh | sh
# Env:
# RENDOBAR_INSTALL_DIR override binary dir (default: $HOME/.rendobar/bin)
# RENDOBAR_VERSION pin a specific tag (e.g. "v1.0.0"); default = latest stable
# RENDOBAR_GITHUB_TOKEN optional GH token to lift the 60/hr unauth rate limit
# (falls back to GITHUB_TOKEN for CI environments)
# RENDOBAR_NO_MODIFY_PATH=1 install binary but do not touch shell rc files
# (use for Docker, provisioning, or when rc is managed elsewhere)
set -eu
# Note: we do NOT set -o pipefail here. `set` is a POSIX special-builtin,
# so in dash the unknown option kills the shell before `|| true` can fire.
# Instead, the two pipelines that matter (tag parsing and checksum verify)
# each check their output explicitly below.
REPO="rendobar/cli"
INSTALL_DIR="${RENDOBAR_INSTALL_DIR:-$HOME/.rendobar/bin}"
BIN_NAME="rb"
PINNED_VERSION="${RENDOBAR_VERSION:-}"
GH_TOKEN_VALUE="${RENDOBAR_GITHUB_TOKEN:-${GITHUB_TOKEN:-}}"
NO_MODIFY_PATH="${RENDOBAR_NO_MODIFY_PATH:-0}"
# --- downloader detection -------------------------------------------------
# Detect downloader once; all subsequent fetches go through this.
# Headers (with potentially spaced values like "Bearer TOKEN") require
# tool-specific syntax, so we pick curl/wget up front and keep call sites
# explicit rather than papering over with string args.
if command -v curl >/dev/null 2>&1; then
DOWNLOADER=curl
elif command -v wget >/dev/null 2>&1; then
DOWNLOADER=wget
else
echo "Error: need curl or wget to install Rendobar CLI." >&2
exit 1
fi
# Download $1 (URL) to $2 (path). Follows redirects, 3 retries.
download_to_file() {
if [ "$DOWNLOADER" = curl ]; then
curl -fsSL --retry 3 --retry-delay 2 --retry-connrefused -o "$2" "$1"
else
wget --quiet --tries=3 --retry-connrefused -O "$2" "$1"
fi
}
# Fetch $1 with optional bearer token in $2; print response to stdout.
fetch_api() {
_url="$1"
_token="${2:-}"
if [ "$DOWNLOADER" = curl ]; then
if [ -n "$_token" ]; then
curl -fsSL --retry 3 --retry-delay 2 --retry-connrefused \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $_token" \
"$_url"
else
curl -fsSL --retry 3 --retry-delay 2 --retry-connrefused \
-H "Accept: application/vnd.github+json" \
"$_url"
fi
else
if [ -n "$_token" ]; then
wget --quiet --tries=3 --retry-connrefused \
--header="Accept: application/vnd.github+json" \
--header="Authorization: Bearer $_token" \
-O - "$_url"
else
wget --quiet --tries=3 --retry-connrefused \
--header="Accept: application/vnd.github+json" \
-O - "$_url"
fi
fi
}
# --- OS/arch detection ----------------------------------------------------
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
ARCH="$(uname -m)"
case "$OS" in
linux*) OS="linux" ;;
darwin*) OS="darwin" ;;
*)
echo "Unsupported OS: $OS"
echo "Rendobar CLI supports: Linux (x64/arm64), macOS (x64/arm64), Windows (x64 -- use install.ps1)"
exit 1
;;
esac
case "$ARCH" in
x86_64|amd64) ARCH="x64" ;;
arm64|aarch64) ARCH="arm64" ;;
*)
echo "Unsupported arch: $ARCH"
exit 1
;;
esac
ASSET="rb-${OS}-${ARCH}"
ARCHIVE="${ASSET}.tar.gz"
# --- resolve release tag --------------------------------------------------
if [ -n "$PINNED_VERSION" ]; then
case "$PINNED_VERSION" in
v*) LATEST_TAG="$PINNED_VERSION" ;;
*) LATEST_TAG="v$PINNED_VERSION" ;;
esac
echo "Using pinned version: $LATEST_TAG"
else
# Fetch latest non-draft, non-prerelease tag. The GitHub /releases/latest
# endpoint already filters both.
echo "Fetching latest release tag..."
RESP=$(fetch_api "https://api.github.com/repos/${REPO}/releases/latest" "$GH_TOKEN_VALUE")
LATEST_TAG=$(printf '%s\n' "$RESP" | \
sed -n 's/.*"tag_name":[[:space:]]*"\(v[^"]*\)".*/\1/p' | \
head -n1)
if [ -z "$LATEST_TAG" ]; then
echo "Failed to find a stable CLI release (looking for v*)."
echo "If no releases exist yet, install.sh cannot proceed. Try again later."
exit 1
fi
echo "Latest: $LATEST_TAG"
fi
VERSION="${LATEST_TAG#v}"
# --- download + verify ----------------------------------------------------
TMP=$(mktemp -d)
# Trap all common termination signals to guarantee tmp cleanup.
trap 'rm -rf "$TMP"' EXIT
trap 'rm -rf "$TMP"; exit 130' INT
trap 'rm -rf "$TMP"; exit 143' TERM HUP
ARCHIVE_URL="https://github.com/${REPO}/releases/download/${LATEST_TAG}/${ARCHIVE}"
CHECKSUMS_URL="https://github.com/${REPO}/releases/download/${LATEST_TAG}/checksums.txt"
echo "Downloading $ARCHIVE..."
download_to_file "$ARCHIVE_URL" "$TMP/$ARCHIVE"
echo "Downloading checksums.txt..."
download_to_file "$CHECKSUMS_URL" "$TMP/checksums.txt"
echo "Verifying checksum..."
cd "$TMP"
# Guard against an empty grep result: `sha256sum -c` with empty stdin prints
# a warning and exits 0, which would silently skip verification. Check first.
EXPECTED_LINE=$(grep " ${ARCHIVE}\$" checksums.txt || true)
if [ -z "$EXPECTED_LINE" ]; then
echo "No checksum entry for $ARCHIVE in checksums.txt" >&2
exit 1
fi
if command -v sha256sum >/dev/null 2>&1; then
printf '%s\n' "$EXPECTED_LINE" | sha256sum -c -
elif command -v shasum >/dev/null 2>&1; then
EXPECTED=$(printf '%s\n' "$EXPECTED_LINE" | awk '{print $1}')
ACTUAL=$(shasum -a 256 "$ARCHIVE" | awk '{print $1}')
if [ "$EXPECTED" != "$ACTUAL" ]; then
echo "Checksum mismatch: expected $EXPECTED, got $ACTUAL" >&2
exit 1
fi
else
echo "No SHA256 tool found (need sha256sum or shasum)" >&2
exit 1
fi
echo "Checksum verified."
# --- extract + install ----------------------------------------------------
echo "Extracting..."
tar xzf "$ARCHIVE"
mkdir -p "$INSTALL_DIR"
mv "$BIN_NAME" "$INSTALL_DIR/$BIN_NAME"
chmod +x "$INSTALL_DIR/$BIN_NAME"
if [ "$OS" = "darwin" ]; then
xattr -d com.apple.quarantine "$INSTALL_DIR/$BIN_NAME" 2>/dev/null || true
fi
echo ""
echo "Installed rb $VERSION to $INSTALL_DIR/$BIN_NAME"
echo ""
# --- PATH handling --------------------------------------------------------
if [ "$NO_MODIFY_PATH" = "1" ]; then
echo "Skipping PATH modification (RENDOBAR_NO_MODIFY_PATH=1)."
echo "Add this directory to PATH manually: $INSTALL_DIR"
else
case ":$PATH:" in
*":$INSTALL_DIR:"*)
echo "PATH already contains $INSTALL_DIR -- ready to use."
;;
*)
SHELL_NAME="$(basename "${SHELL:-sh}")"
case "$SHELL_NAME" in
bash) RC="$HOME/.bashrc" ;;
zsh) RC="$HOME/.zshrc" ;;
fish) RC="$HOME/.config/fish/config.fish" ;;
*) RC="$HOME/.profile" ;;
esac
if [ "$SHELL_NAME" = "fish" ]; then
mkdir -p "$(dirname "$RC")"
printf "\n# Added by Rendobar installer\nset -x PATH %s \$PATH\n" "$INSTALL_DIR" >> "$RC"
else
printf "\n# Added by Rendobar installer\nexport PATH=\"%s:\$PATH\"\n" "$INSTALL_DIR" >> "$RC"
fi
echo "Added $INSTALL_DIR to PATH in $RC"
echo ""
echo "To use rb in THIS terminal without reopening, run:"
echo " export PATH=\"$INSTALL_DIR:\$PATH\""
;;
esac
fi
echo ""
echo "Next: run 'rb login' to authenticate, then 'rb --help' to see commands."