From 3da799a5261273b852f0a288e58af4cc555356dd Mon Sep 17 00:00:00 2001 From: lingkai5wu Date: Sat, 10 Oct 2026 17:13:25 +0800 Subject: [PATCH] feat: show live grouped stack states --- manage.sh | 98 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 40 deletions(-) diff --git a/manage.sh b/manage.sh index 4efef56..7a1a896 100755 --- a/manage.sh +++ b/manage.sh @@ -290,11 +290,12 @@ run_group() { local action="$2" local group_name="${GROUP_NAMES[group_index]}" local limit="${GROUP_LIMITS[group_index]}" - local stack pid finished_pid status result result_color marker success_result details - local next=0 running=0 completed=0 failed=0 stack_width=0 interactive=0 + local stack pid finished_pid status success_result working_result details + local index finished_index total + local next=0 running=0 completed=0 failed=0 stack_width=0 interactive=0 rendered=0 local success_color="" failure_color="" color_reset="" - local -a stacks=() - local -A pid_stacks=() + local -a stacks=() states=() markers=() state_colors=() + local -A pid_indexes=() if [[ -t 1 ]]; then interactive=1 @@ -306,81 +307,98 @@ run_group() { fi read -r -a stacks <<<"${GROUP_STACKS[group_index]}" - ((${#stacks[@]} > 0)) || return 0 - for stack in "${stacks[@]}"; do + total="${#stacks[@]}" + ((total > 0)) || return 0 + for ((index = 0; index < total; index++)); do + stack="${stacks[index]}" ((${#stack} > stack_width)) && stack_width="${#stack}" + states+=("Waiting") + markers+=(" ") + state_colors+=("") done - if ((limit == 0 || limit > ${#stacks[@]})); then - limit="${#stacks[@]}" + if ((limit == 0 || limit > total)); then + limit="$total" fi - if ((${#stacks[@]} == 1)); then + if ((total == 1)); then details="1 stack" - elif ((limit == ${#stacks[@]})); then - details="${#stacks[@]} stacks in parallel" + elif ((limit == total)); then + details="$total stacks in parallel" else - details="${#stacks[@]} stacks, max $limit in parallel" + details="$total stacks, max $limit in parallel" fi echo - if ((interactive)); then - printf '[+] %s: %s 0/%d\n' "$group_name" "$action" "${#stacks[@]}" - else + if ((!interactive)); then echo "==> Group $group_name: $action ($details)" fi case "$action" in - up | start) success_result="Started" ;; - restart) success_result="Restarted" ;; - stop) success_result="Stopped" ;; - down) success_result="Removed" ;; - pull) success_result="Pulled" ;; - update) success_result="Updated" ;; + up | start) working_result="Starting"; success_result="Started" ;; + restart) working_result="Restarting"; success_result="Restarted" ;; + stop) working_result="Stopping"; success_result="Stopped" ;; + down) working_result="Removing"; success_result="Removed" ;; + pull) working_result="Pulling"; success_result="Pulled" ;; + update) working_result="Updating"; success_result="Updated" ;; esac - while ((next < ${#stacks[@]} || running > 0)); do - while ((next < ${#stacks[@]} && running < limit)); do + while :; do + while ((next < total && running < limit)); do stack="${stacks[next]}" + states[next]="$working_result" STACKS_QUIET_PROGRESS=1 run_stack "$stack" "$action" 0 & pid="$!" - pid_stacks["$pid"]="$stack" + pid_indexes["$pid"]="$next" ((next += 1, running += 1)) done + if ((interactive)); then + ((rendered)) && printf '\033[%dA' "$((total + 1))" + printf '\r\033[2K[+] %s: %s %d/%d\n' \ + "$group_name" "$action" "$completed" "$total" + for ((index = 0; index < total; index++)); do + printf '\r\033[2K %s%s%s Stack %-*s %s%s%s\n' \ + "${state_colors[index]}" "${markers[index]}" "$color_reset" \ + "$stack_width" "${stacks[index]}" \ + "${state_colors[index]}" "${states[index]}" "$color_reset" + done + rendered=1 + fi + + ((running > 0)) || break + finished_pid="" status=0 wait -n -p finished_pid || status=$? [[ -n "$finished_pid" ]] || die "cannot identify completed stack" - stack="${pid_stacks[$finished_pid]}" - unset 'pid_stacks[$finished_pid]' + finished_index="${pid_indexes[$finished_pid]}" + unset 'pid_indexes[$finished_pid]' + stack="${stacks[finished_index]}" ((running -= 1)) if ((status == 0)); then - marker="✔" - result="$success_result" - result_color="$success_color" + markers[finished_index]="✔" + states[finished_index]="$success_result" + state_colors[finished_index]="$success_color" ((RUN_SUCCESS += 1)) else - marker="✘" - result="Failed" - result_color="$failure_color" + markers[finished_index]="✘" + states[finished_index]="Failed" + state_colors[finished_index]="$failure_color" ((RUN_FAILED += 1)) RUN_FAILED_STACKS+=("$stack") ((failed += 1)) fi ((completed += 1)) - if ((interactive)); then - printf '\033[%dA\r\033[2K[+] %s: %s %d/%d\n' \ - "$completed" "$group_name" "$action" "$completed" "${#stacks[@]}" - ((completed > 1)) && printf '\033[%dB\r' "$((completed - 1))" + if ((!interactive)); then + printf ' %s%s%s Stack %-*s %s%s%s\n' \ + "${state_colors[finished_index]}" "${markers[finished_index]}" "$color_reset" \ + "$stack_width" "$stack" \ + "${state_colors[finished_index]}" "${states[finished_index]}" "$color_reset" fi - - printf ' %s%s%s Stack %-*s %s%s%s\n' \ - "$result_color" "$marker" "$color_reset" "$stack_width" "$stack" \ - "$result_color" "$result" "$color_reset" done ((failed == 0))