From 1149dfaae4bc21441e9a9bb978f61137fff38ce3 Mon Sep 17 00:00:00 2001 From: soulis-1256 Date: Sun, 16 Aug 2026 14:36:25 +0300 Subject: [PATCH] Show elapsed seconds on wait lines instead of dots Radarr and the other polls now rewrite one line as 'Waiting for Radarr API (12s)' instead of a growing dot trail. --- bin/cli.sh | 20 +++++++------------- lib/api.sh | 6 ++---- lib/arr.sh | 3 +-- lib/bazarr.sh | 6 ++---- lib/core.sh | 16 +++++++++------- lib/jellyfin.sh | 12 ++++-------- lib/seerr.sh | 3 +-- lib/vpn.sh | 9 ++++----- tests/unit/test_core.sh | 5 +++++ 9 files changed, 35 insertions(+), 45 deletions(-) diff --git a/bin/cli.sh b/bin/cli.sh index 701aa15..3e954e5 100644 --- a/bin/cli.sh +++ b/bin/cli.sh @@ -186,8 +186,6 @@ wait_for_services() { local total=0 ready=0 local -a waiting=() - echo -n "Waiting for services to become ready" - while [ $wait_time -lt "$timeout" ]; do total=0 ready=0 @@ -207,25 +205,21 @@ wait_for_services() { done < <(_status_compose_rows) if [ "$total" -gt 0 ] && [ "$ready" -eq "$total" ]; then - echo + echo >&2 log_success "All $total services are ready." return 0 fi - echo -n "." + if [ "${#waiting[@]}" -gt 0 ] && [ "${#waiting[@]}" -le 6 ]; then + wait_inline "Waiting for services ($ready/$total ready: ${waiting[*]})" "$wait_time" + else + wait_inline "Waiting for services ($ready/$total ready)" "$wait_time" + fi sleep 1 wait_time=$((wait_time + 1)) - - if [ $((wait_time % 10)) -eq 0 ]; then - echo - echo -n "$ready/$total ready" - if [ "${#waiting[@]}" -gt 0 ] && [ "${#waiting[@]}" -le 6 ]; then - echo -n " (${waiting[*]})" - fi - fi done - echo + echo >&2 log_error "Not all services became ready within ${timeout}s ($ready/$total ready${waiting[*]:+: ${waiting[*]}})" } diff --git a/lib/api.sh b/lib/api.sh index 61bb419..43897d7 100644 --- a/lib/api.sh +++ b/lib/api.sh @@ -33,7 +33,6 @@ read_api_key() { local max_wait=120 local wait_time=0 - echo -n "Waiting for $service to initialize" >&2 while [ $wait_time -lt $max_wait ]; do if [ -f "$config_file" ]; then local key @@ -44,9 +43,9 @@ read_api_key() { return 0 fi fi + wait_inline "Waiting for $service to initialize" "$wait_time" sleep 3 wait_time=$((wait_time + 3)) - dot_inline done echo >&2 log_step_fail "$service: config.xml not found or ApiKey missing after ${max_wait}s" @@ -133,13 +132,12 @@ wait_for_api() { return 0 fi - echo -n "Waiting for $name API" >&2 while [ $wait_time -lt $max_wait ]; do if _api_ready "$port" "$apikey" "$api_path"; then echo >&2 return 0 fi - dot_inline + wait_inline "Waiting for $name API" "$wait_time" sleep 2 wait_time=$((wait_time + 2)) done diff --git a/lib/arr.sh b/lib/arr.sh index d1d5dd8..df3faab 100644 --- a/lib/arr.sh +++ b/lib/arr.sh @@ -120,7 +120,6 @@ qbit_set_credentials() { local wait_time=0 local max_wait=60 - echo -n "Waiting for qBittorrent to initialize" >&2 while [ $wait_time -lt $max_wait ]; do local qbit_temp_pass qbit_temp_pass=$(docker logs qbittorrent 2>&1 | awk -F': ' '/temporary password is provided for this session:/ { print $NF; exit }' || true) @@ -145,9 +144,9 @@ qbit_set_credentials() { return 0 fi fi + wait_inline "Waiting for qBittorrent to initialize" "$wait_time" sleep 3 wait_time=$((wait_time + 3)) - dot_inline done echo >&2 log_warning "Could not login to qBittorrent with temp password" diff --git a/lib/bazarr.sh b/lib/bazarr.sh index 648e94b..e31d0a4 100644 --- a/lib/bazarr.sh +++ b/lib/bazarr.sh @@ -62,7 +62,6 @@ read_bazarr_api_key() { local wait_time=0 local cfg key - echo -n "Waiting for Bazarr to initialize" >&2 while [ $wait_time -lt $max_wait ]; do if cfg=$(_bazarr_config_file 2>/dev/null); then key=$(_bazarr_extract_apikey "$cfg") @@ -72,9 +71,9 @@ read_bazarr_api_key() { return 0 fi fi + wait_inline "Waiting for Bazarr to initialize" "$wait_time" sleep 3 wait_time=$((wait_time + 3)) - dot_inline done echo >&2 log_step_fail "Bazarr: config.yaml/ini ApiKey missing after ${max_wait}s" @@ -87,7 +86,6 @@ wait_for_bazarr() { local wait_time=0 local code - echo -n "Waiting for Bazarr API" >&2 while [ $wait_time -lt $max_wait ]; do code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 3 \ "http://${API_HOST}:${BAZARR_PORT}/api/system/status?apikey=${apikey}" 2>/dev/null || echo "000") @@ -95,9 +93,9 @@ wait_for_bazarr() { echo >&2 return 0 fi + wait_inline "Waiting for Bazarr API" "$wait_time" sleep 3 wait_time=$((wait_time + 3)) - dot_inline done echo >&2 log_step_fail "Bazarr: API not ready after ${max_wait}s" diff --git a/lib/core.sh b/lib/core.sh index 825cfd4..d61b7db 100644 --- a/lib/core.sh +++ b/lib/core.sh @@ -1,7 +1,7 @@ #!/bin/bash # assemblrr core library — sourced by all other lib modules and entry points # Provides: color codes, logging, safe_source, find_install_directory, -# path utilities, directory helpers, dot_inline +# path utilities, directory helpers, wait_inline # Guard against double-sourcing (readonly arrays would fail on re-source) if [ -n "${_ASSEMBLRR_CORE_SOURCED:-}" ]; then @@ -30,8 +30,12 @@ log_info() { echo "$1"; _log_to_file "INFO: $1"; return 0; } log_debug() { _log_to_file "DEBUG: $1"; return 0; } # --- Progress indicators --- -# Inline dot for polling loops (simple, foreground, no process management) -dot_inline() { printf "." >&2; } +# Rewrite the current line as "Waiting for Radarr API (12s)". +wait_inline() { + local label="$1" + local secs="${2:-0}" + printf '\r%s (%ss) ' "$label" "$secs" >&2 +} # --- Safe source --- # Safely source a config file — validates that it contains only KEY=VALUE @@ -616,9 +620,8 @@ verify_docker() { if [ "$is_wsl" = true ] && [ -f "$docker_exe" ] && command -v cmd.exe &>/dev/null; then log_info "Docker Desktop integration is offline. Attempting to start Docker Desktop on Windows..." cmd.exe /c start "" "C:\\Program Files\\Docker\\Docker\\Docker Desktop.exe" < /dev/null > /dev/null 2>&1 & - log_info "Waiting for Docker Desktop integration to become ready (up to 45s)..." for i in {1..45}; do - dot_inline + wait_inline "Waiting for Docker Desktop integration" "$i" sleep 1 if command -v docker &>/dev/null && docker info &>/dev/null; then echo "" @@ -637,9 +640,8 @@ verify_docker() { if [ "$is_wsl" = true ] && [ -f "$docker_exe" ] && command -v cmd.exe &>/dev/null; then log_info "Docker daemon is not running. Attempting to start Docker Desktop on Windows..." cmd.exe /c start "" "C:\\Program Files\\Docker\\Docker\\Docker Desktop.exe" < /dev/null > /dev/null 2>&1 & - log_info "Waiting for Docker daemon to become ready (up to 45s)..." for i in {1..45}; do - dot_inline + wait_inline "Waiting for Docker daemon" "$i" sleep 1 if docker info &>/dev/null; then echo "" diff --git a/lib/jellyfin.sh b/lib/jellyfin.sh index 2944257..5757c49 100644 --- a/lib/jellyfin.sh +++ b/lib/jellyfin.sh @@ -16,7 +16,6 @@ configure_jellyfin() { # Step 1: Wait for Jellyfin to be responsive echo >&2 - echo -n "Waiting for Jellyfin to start" >&2 while [ $wait_time -lt $max_wait ]; do local http_code http_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 3 \ @@ -24,9 +23,9 @@ configure_jellyfin() { if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then break fi + wait_inline "Waiting for Jellyfin to start" "$wait_time" sleep 3 wait_time=$((wait_time + 3)) - dot_inline done echo >&2 @@ -59,7 +58,6 @@ configure_jellyfin() { # will return 500 if we hit it before the default user exists in the DB _cfg_log_info "Jellyfin: attempting startup wizard bypass via API..." echo >&2 - echo -n "Waiting for Jellyfin startup user to initialize" >&2 local first_user_wait=0 while [ $first_user_wait -lt 60 ]; do local first_user_resp @@ -72,9 +70,9 @@ configure_jellyfin() { break fi fi + wait_inline "Waiting for Jellyfin startup user to initialize" "$first_user_wait" sleep 3 first_user_wait=$((first_user_wait + 3)) - dot_inline done echo >&2 @@ -166,14 +164,13 @@ configure_jellyfin_xml_fallback() { # Wait for system.xml to appear echo >&2 - echo -n "Waiting for Jellyfin system.xml" >&2 while [ $wait_time -lt $max_wait ]; do if [ -f "$system_xml" ]; then break fi + wait_inline "Waiting for Jellyfin system.xml" "$wait_time" sleep 3 wait_time=$((wait_time + 3)) - dot_inline done echo >&2 @@ -201,15 +198,14 @@ configure_jellyfin_xml_fallback() { # Wait for Jellyfin to come back online echo >&2 - echo -n "Waiting for Jellyfin to come back online" >&2 local back_wait=0 while [ $back_wait -lt 60 ]; do if curl -sf --connect-timeout 3 "http://${API_HOST}:8096/health" >/dev/null 2>&1; then break fi + wait_inline "Waiting for Jellyfin to come back online" "$back_wait" sleep 3 back_wait=$((back_wait + 3)) - dot_inline done echo >&2 } diff --git a/lib/seerr.sh b/lib/seerr.sh index 4c5096e..20bab01 100644 --- a/lib/seerr.sh +++ b/lib/seerr.sh @@ -257,7 +257,6 @@ configure_seerr() { # Step 1: Wait for Seerr to be responsive echo >&2 - echo -n "Waiting for Seerr to start" >&2 while [ $wait_time -lt $max_wait ]; do local http_code http_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 3 \ @@ -265,9 +264,9 @@ configure_seerr() { if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then break fi + wait_inline "Waiting for Seerr to start" "$wait_time" sleep 3 wait_time=$((wait_time + 3)) - dot_inline done echo >&2 diff --git a/lib/vpn.sh b/lib/vpn.sh index 9c82a3b..7dfab69 100644 --- a/lib/vpn.sh +++ b/lib/vpn.sh @@ -24,17 +24,16 @@ test_vpn_connection_shared() { local wait_time=0 local max_wait=90 - echo -n "Waiting for VPN connection" while [ $wait_time -lt $max_wait ]; do local health health=$(docker inspect --format='{{.State.Health.Status}}' gluetun 2>/dev/null || echo "unknown") if [ "$health" = "healthy" ]; then - echo + echo >&2 log_success "VPN connection established successfully!" return 0 elif [ "$health" = "unhealthy" ]; then - echo + echo >&2 log_warning "VPN connection failed. Gluetun logs:" "${docker_cmd[@]}" logs gluetun --tail=20 2>/dev/null echo @@ -43,12 +42,12 @@ test_vpn_connection_shared() { return 1 fi + wait_inline "Waiting for VPN connection" "$wait_time" sleep 3 wait_time=$((wait_time + 3)) - echo -n "." done - echo + echo >&2 log_warning "VPN connection timed out after ${max_wait}s. Gluetun logs:" "${docker_cmd[@]}" logs gluetun --tail=20 2>/dev/null echo diff --git a/tests/unit/test_core.sh b/tests/unit/test_core.sh index af05606..edffaee 100755 --- a/tests/unit/test_core.sh +++ b/tests/unit/test_core.sh @@ -12,6 +12,11 @@ stub_log_error_no_exit tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT +# --- wait_inline --- +test_suite "wait_inline" +assert_contains "$(wait_inline "Waiting for Radarr API" 12 2>&1)" \ + "Waiting for Radarr API (12s)" "shows elapsed seconds" + # --- expand_path --- test_suite "expand_path" assert_eq "$HOME/foo" "$(expand_path "~/foo")" "expands leading tilde"