From 1c468948c6125d89ba9a5c094991fc7a316fca55 Mon Sep 17 00:00:00 2001 From: David Young Date: Wed, 11 Nov 2026 06:10:51 -0700 Subject: [PATCH] version: show a spinner while it checks for updates Checking for newer versions goes to the network and can take several seconds with nothing on screen. Show "Checking for updates..." with a spinner on the terminal until every check is done, then print the results all at once. The spinner goes to stderr and only to a terminal. Co-Authored-By: Claude Opus 5.5 --- tests/version.bats | 15 +++++++++++++++ version | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/tests/version.bats b/tests/version.bats index 3179e50..d5e483f 100644 --- a/tests/version.bats +++ b/tests/version.bats @@ -133,3 +133,18 @@ sibling_repo() { [[ "$output" == *"tools is at v1.1.0."* ]] [ "$(cat "$HOME/updated")" = "$HOME/.local/share/siblings/tools" ] } + +@test "version shows a spinner on a terminal while it checks, and clears it" { + run script -qec "bash '$CD/version'" /dev/null < /dev/null + [ "$status" -eq 0 ] + [[ "$output" == *"Checking for updates..."* ]] + # Cleared, and the cursor shown again, before the results are printed + [[ "$output" == *$'\r\e[K\e[?25hCoreDesktop 2026.10.31'* ]] +} + +@test "version shows no spinner when its output isn't a terminal" { + run bash "$CD/version" + [ "$status" -eq 0 ] + [[ "$output" != *"Checking"* ]] + [[ "$output" != *$'\e[?25l'* ]] +} diff --git a/version b/version index 744dd26..4881796 100755 --- a/version +++ b/version @@ -43,6 +43,35 @@ if [ "$1" = "--check" ]; then exit fi +# Checking for newer versions goes to the network and can take several +# seconds, so show a spinner on the terminal until the results are ready. It +# goes to stderr and only to a terminal, so output that's piped stays clean. +spinner_pid="" +start_spinner() { + [ -t 2 ] || return 0 + ( + frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏') + i=0 + printf '\e[?25l' >&2 + while :; do + printf '\r%s Checking for updates...' "${frames[i++ % ${#frames[@]}]}" >&2 + sleep 0.1 + done + ) & + spinner_pid=$! +} +stop_spinner() { + [ -n "$spinner_pid" ] || return 0 + kill "$spinner_pid" 2> /dev/null + wait "$spinner_pid" 2> /dev/null + spinner_pid="" + printf '\r\e[K\e[?25h' >&2 +} +trap stop_spinner EXIT +trap 'stop_spinner; exit 130' INT TERM + +start_spinner + version="$(describe HEAD)" # Local edits to the checkout mean this isn't exactly the version above @@ -123,13 +152,19 @@ else last_update="never" fi +# Sibling projects, as "nameinstalledavailable" lines (see sibling) +siblings="$(bash "$COREDESKTOP/sibling" check --porcelain 2> /dev/null)" + +# Hours since the package mirror last synced with Arch, empty if unknown +age="$(mirror_age_hours)" + +stop_spinner + echo "CoreDesktop $version" echo "Kernel $kernel" [ -n "$driver" ] && echo "Video driver $driver" echo "Last update $last_update" -# Sibling projects, as "nameinstalledavailable" lines (see sibling) -siblings="$(bash "$COREDESKTOP/sibling" check --porcelain 2> /dev/null)" newer_siblings=() if [ -n "$siblings" ]; then echo @@ -152,7 +187,7 @@ if [ -n "$siblings" ]; then fi # Packages newer than the mirror's last sync aren't shown above, or installed -if age="$(mirror_age_hours)" && (( age >= MIRROR_STALE_HOURS )); then +if [ -n "$age" ] && (( age >= MIRROR_STALE_HOURS )); then if (( age >= 48 )); then ago="$(( age / 24 )) days"; else ago="$age hours"; fi echo echo -e "\e[33mYour package mirror ($(first_mirror)) last synced with Arch $ago ago, so"