Skip to content

Commit 321e4e6

Browse files
fix: install script (#1820)
* fix: install script make installer platform aware, shell profile safe * coderabbit comments fix * coderabbit comments fix * add separator newline when missing
1 parent acc9148 commit 321e4e6

1 file changed

Lines changed: 165 additions & 63 deletions

File tree

‎scripts/download.sh‎

Lines changed: 165 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,191 @@
1-
#!/bin/zsh
1+
#!/bin/sh
22

3-
# supported CPU architectures and operating systems
4-
SUPPORTED_ARCH=("x86_64" "arm64")
5-
SUPPORTED_OS=("linux" "darwin")
63
DOWNLOAD_BASE_URL="https://github.com/parseablehq/parseable/releases/download"
7-
ARM_APPLE_PREFIX="Parseable_OSS_aarch64-apple-darwin"
8-
ARM_LINUX_PREFIX="Parseable_OSS_aarch64-unknown-linux-gnu"
9-
INTEL_LINUX_PREFIX="Parseable_OSS_x86_64-unknown-linux-gnu"
10-
PARSEABLE_PREFIX=${ARM_APPLE_PREFIX}
4+
INSTALL_DIR="${HOME}/.parseable"
5+
BIN_DIR="${INSTALL_DIR}/bin"
6+
BIN_NAME="${BIN_DIR}/parseable"
117

12-
# Get the system's CPU architecture and operating system
8+
# Get the system's CPU architecture and operating system.
139
CPU_ARCH=$(uname -m)
1410
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
1511

16-
printf "\n=========================\n"
17-
printf "Detected CPU architecture: %s\n" "$CPU_ARCH"
18-
printf "Detected operating system: %s\n" "$OS"
12+
printf '\n=========================\n'
13+
printf 'Detected CPU architecture: %s\n' "$CPU_ARCH"
14+
printf 'Detected operating system: %s\n' "$OS"
1915

20-
SHELL_NAME=$(basename $SHELL)
21-
RC_FILE=".${SHELL_NAME}rc"
22-
RC_FILE_PATH="${HOME}/${RC_FILE}"
23-
INSTALL_DIR="${HOME}/.parseable"
24-
BIN_DIR="${INSTALL_DIR}/bin"
25-
BIN_NAME="${BIN_DIR}/parseable"
16+
# Select one downloader and use it for both the release lookup and the binary.
17+
if command -v curl >/dev/null 2>&1; then
18+
DOWNLOADER="curl"
19+
elif command -v wget >/dev/null 2>&1; then
20+
DOWNLOADER="wget"
21+
else
22+
printf 'Error: Neither curl nor wget was found. Please install either curl or wget.\n' >&2
23+
exit 1
24+
fi
25+
26+
# Match the platform names used by the release assets. Linux commonly reports
27+
# ARM64 as "aarch64", while macOS reports it as "arm64".
28+
case "${OS}_${CPU_ARCH}" in
29+
darwin_arm64)
30+
PARSEABLE_PREFIX="Parseable_OSS_aarch64-apple-darwin"
31+
;;
32+
linux_arm64|linux_aarch64)
33+
PARSEABLE_PREFIX="Parseable_OSS_aarch64-unknown-linux-gnu"
34+
;;
35+
linux_x86_64|linux_amd64)
36+
PARSEABLE_PREFIX="Parseable_OSS_x86_64-unknown-linux-gnu"
37+
;;
38+
*)
39+
printf 'Error: unsupported platform %s/%s.\n' "$OS" "$CPU_ARCH" >&2
40+
exit 1
41+
;;
42+
esac
43+
44+
# Parseable's Linux release binaries require glibc.
45+
if [ "$OS" = "linux" ]; then
46+
MUSL_FOUND="false"
47+
if command -v ldd >/dev/null 2>&1 && ldd --version 2>&1 | grep -qi musl; then
48+
MUSL_FOUND="true"
49+
else
50+
for MUSL_LOADER in /lib/ld-musl-*.so.1; do
51+
if [ -e "$MUSL_LOADER" ]; then
52+
MUSL_FOUND="true"
53+
break
54+
fi
55+
done
56+
fi
57+
if [ "$MUSL_FOUND" = "true" ]; then
58+
printf 'Error: Alpine Linux and other musl-based systems are not supported by the available release binaries.\n' >&2
59+
exit 1
60+
fi
61+
fi
2662

27-
# Check if the CPU architecture is supported
28-
if ! echo "${SUPPORTED_ARCH[@]}" | grep -q "\\b${CPU_ARCH}\\b"; then
29-
echo "Error: Unsupported CPU architecture (${CPU_ARCH})."
63+
# Get the latest release tag from the GitHub API.
64+
fetch_release() {
65+
case "$DOWNLOADER" in
66+
curl)
67+
curl -fsSL "https://api.github.com/repos/parseablehq/parseable/releases/latest"
68+
;;
69+
wget)
70+
wget -q -O - "https://api.github.com/repos/parseablehq/parseable/releases/latest"
71+
;;
72+
esac
73+
}
74+
if ! release=$(fetch_release); then
75+
printf 'Error: Could not fetch the latest release information.\n' >&2
3076
exit 1
3177
fi
32-
# Check if the OS is supported
33-
if ! echo "${SUPPORTED_OS[@]}" | grep -q "\\b${OS}\\b"; then
34-
echo "Error: Unsupported operating system (${OS})."
78+
release_tag=$(printf '%s\n' "$release" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n 1)
79+
if [ -z "$release_tag" ]; then
80+
printf 'Error: Could not determine the latest release version.\n' >&2
3581
exit 1
3682
fi
3783

38-
# Get the latest release information using GitHub API
39-
release=$(curl -s "https://api.github.com/repos/parseablehq/parseable/releases/latest")
40-
# find the release tag
41-
release_tag=$(echo "$release" | grep -o "\"tag_name\":\s*\"[^\"]*\"" | cut -d '"' -f 4)
42-
if [[ -z "$release_tag" ]]; then
43-
echo "Error: Could not determine the latest release version."
84+
printf 'Latest Parseable version: %s\n' "$release_tag"
85+
86+
download_url="${DOWNLOAD_BASE_URL}/${release_tag}/${PARSEABLE_PREFIX}"
87+
88+
if [ -d "$INSTALL_DIR" ]; then
89+
printf "A previous version of Parseable already exists. Run 'parseable --version' to check the version,\n"
90+
printf 'or remove %s before installing a new version.\n' "$INSTALL_DIR"
4491
exit 1
4592
fi
93+
mkdir -p "$BIN_DIR" || {
94+
printf 'Error: Could not create installation directory %s.\n' "$BIN_DIR" >&2
95+
rmdir "$BIN_DIR" "$INSTALL_DIR" 2>/dev/null || :
96+
exit 1
97+
}
4698

47-
printf "Latest Parseable version: $release_tag\n"
48-
49-
# Determine the appropriate binary prefix based on OS and CPU architecture
50-
declare -A PREFIX_MAP=(
51-
["darwin_arm64"]=$ARM_APPLE_PREFIX
52-
["linux_arm64"]=$ARM_LINUX_PREFIX
53-
["linux_x86_64"]=$INTEL_LINUX_PREFIX
54-
)
55-
key="${OS}_${CPU_ARCH}"
56-
PARSEABLE_PREFIX=${PREFIX_MAP[$key]:-""} || {
57-
echo "Error: unsupported platform $OS/$CPU_ARCH"; exit 1;
99+
TEMP_BIN="${BIN_NAME}.tmp"
100+
# Remove files and empty directories created by an incomplete installation.
101+
cleanup_install() {
102+
rm -f "$TEMP_BIN" "$BIN_NAME"
103+
rmdir "$BIN_DIR" "$INSTALL_DIR" 2>/dev/null || :
58104
}
105+
trap 'cleanup_install' 0
106+
trap 'cleanup_install; exit 1' 1 2 15
59107

60-
download_url=${DOWNLOAD_BASE_URL}/${release_tag}/${PARSEABLE_PREFIX}
108+
printf 'Downloading Parseable version %s, for OS: %s, CPU architecture: %s\n' "$release_tag" "$OS" "$CPU_ARCH"
109+
printf 'Download URL: %s\n\n' "$download_url"
61110

62-
if [[ -d ${INSTALL_DIR} ]]; then
63-
printf "A Previous version of parseable already exists. Run 'parseable --version' to check the version."
64-
printf "or consider removing that before new installation\n"
111+
# Download the selected release asset to the temporary installation path.
112+
download_binary() {
113+
case "$DOWNLOADER" in
114+
curl)
115+
curl -fL -o "$TEMP_BIN" "$download_url"
116+
;;
117+
wget)
118+
wget -q -O "$TEMP_BIN" "$download_url"
119+
;;
120+
esac
121+
}
122+
if ! download_binary; then
123+
printf 'Error: download failed.\n' >&2
65124
exit 1
66-
else
67-
mkdir -p ${BIN_DIR}
68125
fi
69126

70-
# Download the binary using curl or wget
71-
printf "Downloading Parseable version $release_tag, for OS: $OS, CPU architecture: $CPU_ARCH\n"
72-
printf "Download URL: $download_url\n\n"
73-
74-
if command -v curl &>/dev/null; then
75-
curl -fL -o "${BIN_NAME}" "$download_url" || { echo "Error: download failed"; exit 1; }
76-
elif command -v wget &>/dev/null; then
77-
wget -q -O "${BIN_NAME}" "$download_url" || { echo "Error: download failed"; exit 1; }
78-
else
79-
echo "Error: Neither curl nor wget found. Please install either curl or wget."
127+
chmod +x "$TEMP_BIN" || {
128+
printf 'Error: Could not make the downloaded binary executable.\n' >&2
80129
exit 1
81-
fi
130+
}
131+
mv "$TEMP_BIN" "$BIN_NAME" || {
132+
printf 'Error: Could not finish installing %s.\n' "$BIN_NAME" >&2
133+
exit 1
134+
}
135+
trap - 0 1 2 15
82136

83-
printf "Parseable Server was successfully installed at: ${BIN_NAME}\n"
137+
printf 'Parseable Server was successfully installed at: %s\n' "$BIN_NAME"
84138

85-
chmod +x "${BIN_NAME}"
139+
# Use the user's login shell to select its startup file. Do not source that file
140+
# here: this installer may be running under a different shell via `... | sh`.
141+
SHELL_NAME=${SHELL##*/}
142+
case "$SHELL_NAME" in
143+
zsh)
144+
RC_FILE_PATH="${ZDOTDIR:-$HOME}/.zshrc"
145+
;;
146+
bash)
147+
RC_FILE_PATH="${HOME}/.bash_profile"
148+
for BASH_PROFILE in .bash_profile .bash_login .profile; do
149+
if [ -f "${HOME}/${BASH_PROFILE}" ]; then
150+
RC_FILE_PATH="${HOME}/${BASH_PROFILE}"
151+
break
152+
fi
153+
done
154+
;;
155+
sh|dash|ksh)
156+
RC_FILE_PATH="${HOME}/.profile"
157+
;;
158+
*)
159+
RC_FILE_PATH=""
160+
;;
161+
esac
86162

87-
PATH_STR="export PATH=${BIN_DIR}"':$PATH'
88-
echo ${PATH_STR} >> ${RC_FILE_PATH}
89-
source ${RC_FILE_PATH}
163+
PATH_STR="export PATH=\"${BIN_DIR}:\$PATH\""
164+
# Add the PATH export to a shell profile unless it is already present.
165+
append_path() {
166+
PROFILE_PATH=$1
167+
if grep -Fqx "$PATH_STR" "$PROFILE_PATH" 2>/dev/null; then
168+
printf 'Parseable is already configured in %s.\n' "$PROFILE_PATH"
169+
elif {
170+
if [ -s "$PROFILE_PATH" ] && ! tail -c 1 "$PROFILE_PATH" | grep -q '^$'; then
171+
printf '\n'
172+
fi
173+
printf '%s\n' "$PATH_STR"
174+
} >> "$PROFILE_PATH"; then
175+
printf 'Added Parseable to PATH in %s.\n' "$PROFILE_PATH"
176+
else
177+
printf 'Warning: Could not update %s.\n' "$PROFILE_PATH" >&2
178+
fi
179+
}
180+
181+
if [ "$SHELL_NAME" = "bash" ]; then
182+
append_path "${HOME}/.bashrc"
183+
if [ "$RC_FILE_PATH" != "${HOME}/.bashrc" ]; then
184+
append_path "$RC_FILE_PATH"
185+
fi
186+
elif [ -n "$RC_FILE_PATH" ]; then
187+
append_path "$RC_FILE_PATH"
188+
else
189+
printf 'No supported shell profile was detected.\n'
190+
fi
191+
printf 'To use Parseable in the current shell, run:\n %s\n' "$PATH_STR"

0 commit comments

Comments
 (0)