From 60bfedc2021c8b8c910de107e8b9658914e7d4a3 Mon Sep 17 00:00:00 2001 From: karlicoss Date: Fri, 17 Apr 2026 03:19:48 +0100 Subject: [PATCH] fix: speed up installer script in interactive mode by using builtin curl progress functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/anomalyco/opencode/issues/22998 Before the changes the installation was taking ~50 seconds for me. The actual opencode binary is just 50MB, and manual curl download from github is instantaneous. The reason is `--trace-ascii` flag is producing _a lot_ of stderr output which is later parsed with sed to recover the progress. This is also eating a lot of CPU in process. Running this `bash install.sh --no-modify-path 2>/dev/null` confirms it -- completes in a second since it's not doing `--trace-ascii` anymore. Switching to builtin curl `--progress-bar` resolves the issue. Testing: tested on Ubuntu 24.04 - `bash install.sh 2>/dev/null` -- works as before; no progress - `bash install.sh`: works and results in the following output ``` Installing opencode version: 1.4.7 ######################################################################################################### 100.0%   ▄ █▀▀█ █▀▀█ █▀▀█ █▀▀▄ █▀▀▀ █▀▀█ █▀▀█ █▀▀█ █░░█ █░░█ █▀▀▀ █░░█ █░░░ █░░█ █░░█ █▀▀▀ ▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀ ▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ OpenCode includes free models, to start: cd # Open directory opencode # Run command For more information visit https://opencode.ai/docs ``` Not as fancy, but it hardly matters when setup takes 1 second! --- install | 90 +++------------------------------------------------------ 1 file changed, 4 insertions(+), 86 deletions(-) diff --git a/install b/install index b0716d532082..87980d343ff4 100755 --- a/install +++ b/install @@ -234,94 +234,15 @@ check_version() { 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() { +download_file() { local url="$1" local output="$2" if [ -t 2 ]; then - exec 4>&2 + curl --fail --location --progress-bar --output "$output" "$url" else - exec 4>/dev/null + curl --fail --location --silent --show-error --output "$output" "$url" 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() { @@ -329,10 +250,7 @@ download_and_install() { local tmp_dir="${TMPDIR:-/tmp}/opencode_install_$$" mkdir -p "$tmp_dir" - if [[ "$os" == "windows" ]] || ! [ -t 2 ] || ! download_with_progress "$url" "$tmp_dir/$filename"; then - # Fallback to standard curl on Windows, non-TTY environments, or if custom progress fails - curl -# -L -o "$tmp_dir/$filename" "$url" - fi + download_file "$url" "$tmp_dir/$filename" if [ "$os" = "linux" ]; then tar -xzf "$tmp_dir/$filename" -C "$tmp_dir"