Browse Source

feat(install): better install script visuals, custom progress bar and next steps (#4589)

Adam 4 months ago
parent
commit
08a366c4dc
1 changed files with 125 additions and 9 deletions
  1. 125 9
      install

+ 125 - 9
install

@@ -2,9 +2,8 @@
 set -euo pipefail
 APP=opencode
 
+MUTED='\033[0;2m'
 RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
 ORANGE='\033[38;2;255;140;0m'
 NC='\033[0m' # No Color
 
@@ -45,6 +44,11 @@ case "$filename" in
     ;;
 esac
 
+if ! command -v unzip >/dev/null 2>&1; then
+    echo -e "${RED}Error: 'unzip' is required but not installed.${NC}"
+    exit 1
+fi
+
 INSTALL_DIR=$HOME/.opencode/bin
 mkdir -p "$INSTALL_DIR"
 
@@ -67,8 +71,8 @@ print_message() {
     local color=""
 
     case $level in
-        info) color="${GREEN}" ;;
-        warning) color="${YELLOW}" ;;
+        info) color="${NC}" ;;
+        warning) color="${NC}" ;;
         error) color="${RED}" ;;
     esac
 
@@ -86,18 +90,113 @@ check_version() {
         installed_version=$(echo $installed_version | awk '{print $2}')
 
         if [[ "$installed_version" != "$specific_version" ]]; then
-            print_message info "Installed version: ${YELLOW}$installed_version."
+            print_message info "${MUTED}Installed version: ${NC}$installed_version."
         else
-            print_message info "Version ${YELLOW}$specific_version${GREEN} already installed"
+            print_message info "${MUTED}Version ${NC}$specific_version${MUTED} already installed"
             exit 0
         fi
     fi
 }
 
+unbuffered_sed() {
+    if echo | sed -u -e "" >/dev/null 2>&1; then
+        sed -nu "$@"
+    elif echo | sed -l -e "" >/dev/null 2>&1; then
+        sed -nl "$@"
+    else
+        local pad="$(printf "\n%512s" "")"
+        sed -ne "s/$/\\${pad}/" "$@"
+    fi
+}
+
+print_progress() {
+    local bytes="$1"
+    local length="$2"
+    [ "$length" -gt 0 ] || return 0
+
+    local width=50
+    local percent=$(( bytes * 100 / length ))
+    [ "$percent" -gt 100 ] && percent=100
+    local on=$(( percent * width / 100 ))
+    local off=$(( width - on ))
+
+    local filled=$(printf "%*s" "$on" "")
+    filled=${filled// /■}
+    local empty=$(printf "%*s" "$off" "")
+    empty=${empty// /・}
+
+    printf "\r${ORANGE}%s%s %3d%%${NC}" "$filled" "$empty" "$percent" >&4
+}
+
+download_with_progress() {
+    local url="$1"
+    local output="$2"
+
+    if [ -t 2 ]; then
+        exec 4>&2
+    else
+        exec 4>/dev/null
+    fi
+
+    local tmp_dir=${TMPDIR:-/tmp}
+    local basename="${tmp_dir}/opencode_install_$$"
+    local tracefile="${basename}.trace"
+
+    rm -f "$tracefile"
+    mkfifo "$tracefile"
+
+    # Hide cursor
+    printf "\033[?25l" >&4
+
+    trap "trap - RETURN; rm -f \"$tracefile\"; printf '\033[?25h' >&4; exec 4>&-" RETURN
+
+    (
+        curl --trace-ascii "$tracefile" -s -L -o "$output" "$url"
+    ) &
+    local curl_pid=$!
+
+    unbuffered_sed \
+        -e 'y/ACDEGHLNORTV/acdeghlnortv/' \
+        -e '/^0000: content-length:/p' \
+        -e '/^<= recv data/p' \
+        "$tracefile" | \
+    {
+        local length=0
+        local bytes=0
+        
+        while IFS=" " read -r -a line; do
+            [ "${#line[@]}" -lt 2 ] && continue
+            local tag="${line[0]} ${line[1]}"
+            
+            if [ "$tag" = "0000: content-length:" ]; then
+                length="${line[2]}"
+                length=$(echo "$length" | tr -d '\r')
+                bytes=0
+            elif [ "$tag" = "<= recv" ]; then
+                local size="${line[3]}"
+                bytes=$(( bytes + size ))
+                if [ "$length" -gt 0 ]; then
+                    print_progress "$bytes" "$length"
+                fi
+            fi
+        done
+    }
+
+    wait $curl_pid
+    local ret=$?
+    echo "" >&4
+    return $ret
+}
+
 download_and_install() {
-    print_message info "Downloading ${ORANGE}opencode ${GREEN}version: ${YELLOW}$specific_version ${GREEN}..."
+    print_message info "\n${MUTED}Installing ${NC}opencode ${MUTED}version: ${NC}$specific_version"
     mkdir -p opencodetmp && cd opencodetmp
-    curl -# -L -o "$filename" "$url"
+    
+    if [[ "$os" == "windows" ]] || ! download_with_progress "$url" "$filename"; then
+        # Fallback to standard curl on Windows or if custom progress fails
+        curl -# -L -o "$filename" "$url"
+    fi
+
     unzip -q "$filename"
     mv opencode "$INSTALL_DIR"
     chmod 755 "${INSTALL_DIR}/opencode"
@@ -117,7 +216,7 @@ add_to_path() {
     elif [[ -w $config_file ]]; then
         echo -e "\n# opencode" >> "$config_file"
         echo "$command" >> "$config_file"
-        print_message info "Successfully added ${ORANGE}opencode ${GREEN}to \$PATH in $config_file"
+        print_message info "${MUTED}Successfully added ${NC}opencode ${MUTED}to \$PATH in ${NC}$config_file"
     else
         print_message warning "Manually add the directory to $config_file (or similar):"
         print_message info "  $command"
@@ -191,3 +290,20 @@ if [ -n "${GITHUB_ACTIONS-}" ] && [ "${GITHUB_ACTIONS}" == "true" ]; then
     echo "$INSTALL_DIR" >> $GITHUB_PATH
     print_message info "Added $INSTALL_DIR to \$GITHUB_PATH"
 fi
+
+echo -e ""
+echo -e "${MUTED}                    ${NC}             ▄     "
+echo -e "${MUTED}█▀▀█ █▀▀█ █▀▀█ █▀▀▄ ${NC}█▀▀▀ █▀▀█ █▀▀█ █▀▀█"
+echo -e "${MUTED}█░░█ █░░█ █▀▀▀ █░░█ ${NC}█░░░ █░░█ █░░█ █▀▀▀"
+echo -e "${MUTED}▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀  ▀ ${NC}▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀"
+echo -e ""
+echo -e ""
+echo -e "${MUTED}To get started, navigate to a project and run:${NC}"
+echo -e "opencode                   ${MUTED}Use free models${NC}"
+echo -e "opencode auth login        ${MUTED}Add paid provider API keys${NC}"
+echo -e "opencode help              ${MUTED}List commands and options${NC}"
+echo -e ""
+echo -e "${MUTED}For more information visit ${NC}https://opencode.ai/docs"
+echo -e ""
+echo -e ""
+