Skip to content

Commit 08a366c

Browse files
authored
feat(install): better install script visuals, custom progress bar and next steps (anomalyco#4589)
1 parent 670e152 commit 08a366c

1 file changed

Lines changed: 125 additions & 9 deletions

File tree

install

Lines changed: 125 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
set -euo pipefail
33
APP=opencode
44

5+
MUTED='\033[0;2m'
56
RED='\033[0;31m'
6-
GREEN='\033[0;32m'
7-
YELLOW='\033[1;33m'
87
ORANGE='\033[38;2;255;140;0m'
98
NC='\033[0m' # No Color
109

@@ -45,6 +44,11 @@ case "$filename" in
4544
;;
4645
esac
4746

47+
if ! command -v unzip >/dev/null 2>&1; then
48+
echo -e "${RED}Error: 'unzip' is required but not installed.${NC}"
49+
exit 1
50+
fi
51+
4852
INSTALL_DIR=$HOME/.opencode/bin
4953
mkdir -p "$INSTALL_DIR"
5054

@@ -67,8 +71,8 @@ print_message() {
6771
local color=""
6872

6973
case $level in
70-
info) color="${GREEN}" ;;
71-
warning) color="${YELLOW}" ;;
74+
info) color="${NC}" ;;
75+
warning) color="${NC}" ;;
7276
error) color="${RED}" ;;
7377
esac
7478

@@ -86,18 +90,113 @@ check_version() {
8690
installed_version=$(echo $installed_version | awk '{print $2}')
8791

8892
if [[ "$installed_version" != "$specific_version" ]]; then
89-
print_message info "Installed version: ${YELLOW}$installed_version."
93+
print_message info "${MUTED}Installed version: ${NC}$installed_version."
9094
else
91-
print_message info "Version ${YELLOW}$specific_version${GREEN} already installed"
95+
print_message info "${MUTED}Version ${NC}$specific_version${MUTED} already installed"
9296
exit 0
9397
fi
9498
fi
9599
}
96100

101+
unbuffered_sed() {
102+
if echo | sed -u -e "" >/dev/null 2>&1; then
103+
sed -nu "$@"
104+
elif echo | sed -l -e "" >/dev/null 2>&1; then
105+
sed -nl "$@"
106+
else
107+
local pad="$(printf "\n%512s" "")"
108+
sed -ne "s/$/\\${pad}/" "$@"
109+
fi
110+
}
111+
112+
print_progress() {
113+
local bytes="$1"
114+
local length="$2"
115+
[ "$length" -gt 0 ] || return 0
116+
117+
local width=50
118+
local percent=$(( bytes * 100 / length ))
119+
[ "$percent" -gt 100 ] && percent=100
120+
local on=$(( percent * width / 100 ))
121+
local off=$(( width - on ))
122+
123+
local filled=$(printf "%*s" "$on" "")
124+
filled=${filled// /■}
125+
local empty=$(printf "%*s" "$off" "")
126+
empty=${empty// /・}
127+
128+
printf "\r${ORANGE}%s%s %3d%%${NC}" "$filled" "$empty" "$percent" >&4
129+
}
130+
131+
download_with_progress() {
132+
local url="$1"
133+
local output="$2"
134+
135+
if [ -t 2 ]; then
136+
exec 4>&2
137+
else
138+
exec 4>/dev/null
139+
fi
140+
141+
local tmp_dir=${TMPDIR:-/tmp}
142+
local basename="${tmp_dir}/opencode_install_$$"
143+
local tracefile="${basename}.trace"
144+
145+
rm -f "$tracefile"
146+
mkfifo "$tracefile"
147+
148+
# Hide cursor
149+
printf "\033[?25l" >&4
150+
151+
trap "trap - RETURN; rm -f \"$tracefile\"; printf '\033[?25h' >&4; exec 4>&-" RETURN
152+
153+
(
154+
curl --trace-ascii "$tracefile" -s -L -o "$output" "$url"
155+
) &
156+
local curl_pid=$!
157+
158+
unbuffered_sed \
159+
-e 'y/ACDEGHLNORTV/acdeghlnortv/' \
160+
-e '/^0000: content-length:/p' \
161+
-e '/^<= recv data/p' \
162+
"$tracefile" | \
163+
{
164+
local length=0
165+
local bytes=0
166+
167+
while IFS=" " read -r -a line; do
168+
[ "${#line[@]}" -lt 2 ] && continue
169+
local tag="${line[0]} ${line[1]}"
170+
171+
if [ "$tag" = "0000: content-length:" ]; then
172+
length="${line[2]}"
173+
length=$(echo "$length" | tr -d '\r')
174+
bytes=0
175+
elif [ "$tag" = "<= recv" ]; then
176+
local size="${line[3]}"
177+
bytes=$(( bytes + size ))
178+
if [ "$length" -gt 0 ]; then
179+
print_progress "$bytes" "$length"
180+
fi
181+
fi
182+
done
183+
}
184+
185+
wait $curl_pid
186+
local ret=$?
187+
echo "" >&4
188+
return $ret
189+
}
190+
97191
download_and_install() {
98-
print_message info "Downloading ${ORANGE}opencode ${GREEN}version: ${YELLOW}$specific_version ${GREEN}..."
192+
print_message info "\n${MUTED}Installing ${NC}opencode ${MUTED}version: ${NC}$specific_version"
99193
mkdir -p opencodetmp && cd opencodetmp
100-
curl -# -L -o "$filename" "$url"
194+
195+
if [[ "$os" == "windows" ]] || ! download_with_progress "$url" "$filename"; then
196+
# Fallback to standard curl on Windows or if custom progress fails
197+
curl -# -L -o "$filename" "$url"
198+
fi
199+
101200
unzip -q "$filename"
102201
mv opencode "$INSTALL_DIR"
103202
chmod 755 "${INSTALL_DIR}/opencode"
@@ -117,7 +216,7 @@ add_to_path() {
117216
elif [[ -w $config_file ]]; then
118217
echo -e "\n# opencode" >> "$config_file"
119218
echo "$command" >> "$config_file"
120-
print_message info "Successfully added ${ORANGE}opencode ${GREEN}to \$PATH in $config_file"
219+
print_message info "${MUTED}Successfully added ${NC}opencode ${MUTED}to \$PATH in ${NC}$config_file"
121220
else
122221
print_message warning "Manually add the directory to $config_file (or similar):"
123222
print_message info " $command"
@@ -191,3 +290,20 @@ if [ -n "${GITHUB_ACTIONS-}" ] && [ "${GITHUB_ACTIONS}" == "true" ]; then
191290
echo "$INSTALL_DIR" >> $GITHUB_PATH
192291
print_message info "Added $INSTALL_DIR to \$GITHUB_PATH"
193292
fi
293+
294+
echo -e ""
295+
echo -e "${MUTED}  ${NC}"
296+
echo -e "${MUTED}█▀▀█ █▀▀█ █▀▀█ █▀▀▄ ${NC}█▀▀▀ █▀▀█ █▀▀█ █▀▀█"
297+
echo -e "${MUTED}█░░█ █░░█ █▀▀▀ █░░█ ${NC}█░░░ █░░█ █░░█ █▀▀▀"
298+
echo -e "${MUTED}▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀ ▀ ${NC}▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀"
299+
echo -e ""
300+
echo -e ""
301+
echo -e "${MUTED}To get started, navigate to a project and run:${NC}"
302+
echo -e "opencode ${MUTED}Use free models${NC}"
303+
echo -e "opencode auth login ${MUTED}Add paid provider API keys${NC}"
304+
echo -e "opencode help ${MUTED}List commands and options${NC}"
305+
echo -e ""
306+
echo -e "${MUTED}For more information visit ${NC}https://opencode.ai/docs"
307+
echo -e ""
308+
echo -e ""
309+

0 commit comments

Comments
 (0)