Skip to content

Commit eed085e

Browse files
add install script (#18)
* add install script * . * . * Apply suggestions from code review --------- Co-authored-by: Matt Johnson-Pint <[email protected]>
1 parent 203de59 commit eed085e

File tree

1 file changed

+291
-0
lines changed

1 file changed

+291
-0
lines changed

install.sh

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2024 Hypermode Inc.
4+
# Licensed under the terms of the Apache License, Version 2.0
5+
# See the LICENSE file that accompanied this code for further details.
6+
#
7+
# SPDX-FileCopyrightText: 2024 Hypermode Inc. <[email protected]>
8+
# SPDX-License-Identifier: Apache-2.0
9+
10+
# Run with: curl install.hypermode.com/hyp.sh -sSfL | bash
11+
12+
# Config
13+
CLI_NAME="Hyp CLI"
14+
PACKAGE_ORG="@hypermode"
15+
PACKAGE_NAME="hyp-cli"
16+
INSTALL_DIR="${HYP_CLI:-"$HOME/.hypermode/cli"}"
17+
VERSION="latest"
18+
INSTALLER_VERSION="0.1.1"
19+
20+
NODE_MIN=22
21+
NODE_PATH="$(which node)"
22+
NPM_PATH="$(which npm)"
23+
24+
# Properties
25+
ARCH="$(uname -m)"
26+
OS="$(uname -s)"
27+
28+
# ANSI escape codes
29+
if [[ -t 1 ]]; then
30+
CLEAR_LINE="\e[1A\e[2K\e[2K"
31+
BOLD="\e[1m"
32+
BLUE="\e[34;1m"
33+
YELLOW="\e[33m"
34+
RED="\e[31m"
35+
DIM="\e[2m"
36+
RESET="\e[0m"
37+
else
38+
CLEAR_LINE=""
39+
BOLD=""
40+
BLUE=""
41+
YELLOW=""
42+
RED=""
43+
DIM=""
44+
RESET=""
45+
fi
46+
47+
get_latest_version() {
48+
local url="https://registry.npmjs.org/${PACKAGE_ORG:+$PACKAGE_ORG/}$PACKAGE_NAME"
49+
50+
curl --silent "$url" | jq -r '.["dist-tags"].latest'
51+
}
52+
53+
ARCHIVE_URL=""
54+
download_from_npm() {
55+
local tmpdir="$1"
56+
local url="$2"
57+
local filename="${PACKAGE_NAME}-${VERSION}.tgz"
58+
local download_file="$tmpdir/$filename"
59+
60+
mkdir -p "$tmpdir"
61+
62+
curl --progress-bar --show-error --location --fail "$url" --output "$download_file"
63+
if [ "$?" != 0 ]; then
64+
return 1
65+
fi
66+
67+
printf "$CLEAR_LINE" >&2
68+
echo "$download_file"
69+
}
70+
71+
echo_fexists() {
72+
[ -f "$1" ] && echo "$1"
73+
}
74+
75+
detect_profile() {
76+
local shellname="$1"
77+
local uname="$2"
78+
79+
if [ -f "$PROFILE" ]; then
80+
echo "$PROFILE"
81+
return
82+
fi
83+
84+
case "$shellname" in
85+
bash)
86+
case $uname in
87+
Darwin)
88+
echo_fexists "$HOME/.bash_profile" || echo_fexists "$HOME/.bashrc"
89+
;;
90+
*)
91+
echo_fexists "$HOME/.bashrc" || echo_fexists "$HOME/.bash_profile"
92+
;;
93+
esac
94+
;;
95+
zsh)
96+
echo "$HOME/.zshrc"
97+
;;
98+
fish)
99+
echo "$HOME/.config/fish/config.fish"
100+
;;
101+
*)
102+
local profiles
103+
case $uname in
104+
Darwin)
105+
profiles=(.profile .bash_profile .bashrc .zshrc .config/fish/config.fish)
106+
;;
107+
*)
108+
profiles=(.profile .bashrc .bash_profile .zshrc .config/fish/config.fish)
109+
;;
110+
esac
111+
112+
for profile in "${profiles[@]}"; do
113+
echo_fexists "$HOME/$profile" && break
114+
done
115+
;;
116+
esac
117+
}
118+
119+
build_path_str() {
120+
local profile="$1" install_dir="$2"
121+
if [[ $profile == *.fish ]]; then
122+
echo -e "set -gx HYP_CLI \"$install_dir\"\nstring match -r \".hypermode\" \"\$PATH\" > /dev/null; or set -gx PATH \"\$HYP_CLI/bin\" \$PATH"
123+
else
124+
install_dir="${install_dir/#$HOME/\$HOME}"
125+
echo -e "\n# ${CLI_NAME}\nexport HYP_CLI=\"$install_dir\"\nexport PATH=\"\$HYP_CLI/bin:\$PATH\""
126+
fi
127+
}
128+
129+
cli_dir_valid() {
130+
if [ -n "${HYP_CLI-}" ] && [ -e "$HYP_CLI" ] && ! [ -d "$HYP_CLI" ]; then
131+
printf "\$HYP_CLI is set but is not a directory ($HYP_CLI).\n" >&2
132+
printf "Please check your profile scripts and environment.\n" >&2
133+
exit 1
134+
fi
135+
return 0
136+
}
137+
138+
update_profile() {
139+
local install_dir="$1"
140+
if [[ ":$PATH:" == *":$install_dir:"* ]]; then
141+
printf "[3/4] ${DIM}The ${CLI_NAME} is already in \$PATH${RESET}\n" >&2
142+
return 0
143+
fi
144+
145+
local profile="$(detect_profile $(basename "$SHELL") $(uname -s))"
146+
if [ -z "$profile" ]; then
147+
printf "No user shell profile found.\n" >&2
148+
return 1
149+
fi
150+
151+
export SHOW_RESET_PROFILE=1
152+
export PROFILE="~/$(basename "$profile")"
153+
154+
if grep -q 'HYP_CLI' "$profile"; then
155+
printf "[3/4] ${DIM}The ${CLI_NAME} has already been configured in ${PROFILE}${RESET}\n" >&2
156+
return 0
157+
fi
158+
159+
local path_str="$(build_path_str "$profile" "$install_dir")"
160+
echo "$path_str" >>"$profile"
161+
162+
printf "[3/4] ${DIM}Added the ${CLI_NAME} to the PATH in ${PROFILE}${RESET}\n" >&2
163+
}
164+
165+
install_version() {
166+
if ! cli_dir_valid; then
167+
exit 1
168+
fi
169+
170+
case "$VERSION" in
171+
latest)
172+
VERSION="$(get_latest_version)"
173+
;;
174+
*) ;;
175+
esac
176+
177+
install_release
178+
if [ "$?" == 0 ]; then
179+
update_profile "$INSTALL_DIR" && printf "[4/4] ${DIM}Installed the ${CLI_NAME}${RESET}\n" >&2
180+
fi
181+
}
182+
183+
install_release() {
184+
printf "[1/4] ${DIM}Downloading the ${CLI_NAME} from NPM${RESET}\n"
185+
186+
local url="https://registry.npmjs.org/${PACKAGE_ORG:+$PACKAGE_ORG/}${PACKAGE_NAME}/-/${PACKAGE_NAME}-${VERSION}.tgz"
187+
188+
download_archive="$(
189+
download_release "$url"
190+
exit "$?"
191+
)"
192+
exit_status="$?"
193+
if [ "$exit_status" != 0 ]; then
194+
printf "Could not download the ${CLI_NAME} version '$VERSION' from\n$url\n" >&2
195+
exit 1
196+
fi
197+
198+
printf "$CLEAR_LINE" >&2
199+
printf "[1/4] ${DIM}Downloaded latest ${CLI_NAME} v${VERSION}${RESET}\n" >&2
200+
201+
install_from_file "$download_archive"
202+
}
203+
204+
download_release() {
205+
local url="$1"
206+
local download_dir="$(mktemp -d)"
207+
download_from_npm "$download_dir" "$url"
208+
}
209+
210+
install_from_file() {
211+
local archive="$1"
212+
local extract_to="$(dirname "$archive")"
213+
214+
printf "[2/4] ${DIM}Unpacking archive${RESET}\n" >&2
215+
216+
tar -xf "$archive" -C "$extract_to"
217+
218+
rm -rf "$INSTALL_DIR"
219+
mkdir -p "$INSTALL_DIR"
220+
rm -f "$archive"
221+
mv "$extract_to/package/"* "$INSTALL_DIR"
222+
rm -rf "$extract_to"
223+
224+
ln -s "$INSTALL_DIR/bin/run.js" "$INSTALL_DIR/bin/hyp"
225+
226+
printf "$CLEAR_LINE" >&2
227+
printf "[2/4] ${DIM}Installing dependencies${RESET}\n" >&2
228+
(cd "$INSTALL_DIR" && "$NPM_PATH" install --omit=dev --silent && find . -type d -empty -delete)
229+
230+
printf "$CLEAR_LINE" >&2
231+
printf "[2/4] ${DIM}Unpacked archive${RESET}\n" >&2
232+
}
233+
234+
check_platform() {
235+
case $ARCH in
236+
arm64) ARCH="arm64" ;;
237+
x86_64) ARCH="x64" ;;
238+
*) ;;
239+
esac
240+
241+
case "$ARCH/$OS" in
242+
x64/Linux | arm64/Linux | x64/Darwin | arm64/Darwin) return 0 ;;
243+
*)
244+
printf "Unsupported os $OS $ARCH\n" >&2
245+
exit 1
246+
;;
247+
esac
248+
}
249+
250+
check_node() {
251+
if [ -z "$NODE_PATH" ]; then
252+
printf "${RED}Node.js is not installed.${RESET}\n" >&2
253+
printf "${RED}Please install Node.js $NODE_WANTED or later and try again.${RESET}\n" >&2
254+
exit 1
255+
fi
256+
257+
# check node version
258+
local node_version="$("$NODE_PATH" --version)"
259+
local node_major="${node_version%%.*}"
260+
node_major="${node_major#v}"
261+
if [ "$node_major" -lt "$NODE_MIN" ]; then
262+
printf "${RED}Node.js $NODE_MIN or later is required. You have $node_version.${RESET}\n" >&2
263+
printf "${RED}Please update and try again${RESET}\n" >&2
264+
exit 1
265+
fi
266+
267+
# make sure npm can be found too
268+
if [ -z "$NPM_PATH" ]; then
269+
printf "${RED}npm is not installed. Please install npm and try again.${RESET}\n" >&2
270+
exit 1
271+
fi
272+
}
273+
274+
# This is the entry point
275+
printf "\n${BOLD}${BLUE}${CLI_NAME}${RESET} Installer ${DIM}v${INSTALLER_VERSION}${RESET}\n\n" >&2
276+
277+
check_platform
278+
check_node
279+
install_version
280+
281+
printf "\nThe ${CLI_NAME} has been installed! 🎉\n" >&2
282+
283+
if [ -n "${SHOW_RESET_PROFILE-}" ]; then
284+
printf "\n${YELLOW}Please restart your terminal or run:${RESET}\n" >&2
285+
printf " ${DIM}source ${PROFILE}${RESET}\n" >&2
286+
printf "\nThen, run ${DIM}hyp${RESET} to get started${RESET}\n" >&2
287+
else
288+
printf "\nRun ${DIM}hyp${RESET} to get started${RESET}\n" >&2
289+
fi
290+
291+
printf "\n" >&2

0 commit comments

Comments
 (0)