fix(deploy): single-line progress bar (no fragile cursor moves)

- previous 2-line render with \033[1A broke when xcodebuild crashed
  early — left mangled output and lost stderr
- new render_progress: ONE line, truncated to $COLUMNS, no cursor moves
- indeterminate mode (no baseline) shows ping-pong bar instead of spinner
- removes 2-line reserve + clear logic in run_quiet
This commit is contained in:
chahinebrini 2026-05-30 09:51:49 +02:00
parent 32d270ccad
commit e6e1bab35a

View File

@ -112,42 +112,39 @@ runtime_save() {
echo "$label|$duration" >> "$RUNTIME_CACHE"
}
# Render brew-style progress bar: ████████░░░░░░░░ 42% (1m23s / ~3m18s)
# Render brew-style SINGLE-LINE progress bar:
# ==> Building xcarchive ████████░░░░░░░░ 42% (1m23s/~3m18s) ↳ CompileSwift Foo
render_progress() {
local elapsed="$1" expected="$2" label="$3" subtitle="$4"
local width=30 pct filled empty bar elapsed_h expected_h
local width=20 pct filled empty bar elapsed_h expected_h line
if (( expected > 0 )); then
pct=$(( elapsed * 100 / expected ))
(( pct > 99 )) && pct=99 # never show 100% while still running
(( pct > 99 )) && pct=99
filled=$(( elapsed * width / expected ))
(( filled > width )) && filled=$width
else
pct=0; filled=0
# No baseline — animated indeterminate bar position
pct=0
filled=$(( RUN_QUIET_I % (width * 2) ))
(( filled > width )) && filled=$(( width * 2 - filled ))
fi
empty=$(( width - filled ))
bar=$(printf '%*s' "$filled" '' | tr ' ' '█')$(printf '%*s' "$empty" '' | tr ' ' '░')
elapsed_h=$(format_duration "$elapsed")
if (( expected > 0 )); then
expected_h=$(format_duration "$expected")
if [[ -n "$subtitle" ]]; then
printf '\r\033[K%s==>%s %s\n %s %s%3d%%%s (%s / ~%s) %s%s↳ %s%s\033[1A' \
"$BLUE" "$RESET" "$label" "$bar" "$YELLOW" "$pct" "$RESET" "$elapsed_h" "$expected_h" "$BLUE" "$BOLD" "$subtitle" "$RESET" >&2
else
printf '\r\033[K%s==>%s %s\n %s %s%3d%%%s (%s / ~%s)\033[1A' \
"$BLUE" "$RESET" "$label" "$bar" "$YELLOW" "$pct" "$RESET" "$elapsed_h" "$expected_h" >&2
fi
line=$(printf '%s==>%s %s %s %s%3d%%%s (%s/~%s)' \
"$BLUE" "$RESET" "$label" "$bar" "$YELLOW" "$pct" "$RESET" "$elapsed_h" "$expected_h")
else
# No baseline yet — spinner mode
local spin='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
local frame="${spin:RUN_QUIET_I%10:1}"
if [[ -n "$subtitle" ]]; then
printf '\r\033[K%s %s==>%s %s %s(%s)%s ↳ %s' \
"$frame" "$BLUE" "$RESET" "$label" "$YELLOW" "$elapsed_h" "$RESET" "$subtitle" >&2
else
printf '\r\033[K%s %s==>%s %s %s(%s)%s' \
"$frame" "$BLUE" "$RESET" "$label" "$YELLOW" "$elapsed_h" "$RESET" >&2
fi
line=$(printf '%s==>%s %s %s %s(%s)%s' \
"$BLUE" "$RESET" "$label" "$bar" "$YELLOW" "$elapsed_h" "$RESET")
fi
if [[ -n "$subtitle" ]]; then
line="$line$subtitle"
fi
# Truncate to terminal width to avoid line-wrap garbling the redraw
local cols=${COLUMNS:-$(tput cols 2>/dev/null || echo 120)}
printf '\r\033[K%s' "${line:0:cols}" >&2
}
format_duration() {
@ -182,10 +179,6 @@ run_quiet() {
RUN_QUIET_I=0
( "$@" >"$logfile" 2>&1 ) &
pid=$!
# If we have a baseline, render 2-line bar (label + bar); else 1-line spinner.
if (( expected > 0 )); then
printf '\n\033[1A' >&2 # Reserve second line, then move up
fi
while kill -0 "$pid" 2>/dev/null; do
elapsed=$((SECONDS - start))
RUN_QUIET_I=$((RUN_QUIET_I + 1))
@ -203,12 +196,8 @@ run_quiet() {
wait "$pid"
local rc=$?
elapsed=$((SECONDS - start))
# Clear both lines if we used 2-line mode, else 1 line
if (( expected > 0 )); then
printf '\r\033[K\n\033[K\033[1A' >&2
else
printf '\r\033[K' >&2
fi
# Clear progress line
printf '\r\033[K' >&2
if [[ $rc -eq 0 ]]; then
ok "$label ${YELLOW}($(format_duration "$elapsed"))${RESET}"
runtime_save "$label" "$elapsed"