feat: show live grouped stack states

This commit is contained in:
lingkai5wu committed 2026-10-10 17:13:25 +08:00
1 parent ae5a980cac
commit 3da799a526
1 file changed
+58 -40
+58 -40
View File
@@ -290,11 +290,12 @@ run_group() {
local action="$2" local action="$2"
local group_name="${GROUP_NAMES[group_index]}" local group_name="${GROUP_NAMES[group_index]}"
local limit="${GROUP_LIMITS[group_index]}" local limit="${GROUP_LIMITS[group_index]}"
local stack pid finished_pid status result result_color marker success_result details local stack pid finished_pid status success_result working_result details
local next=0 running=0 completed=0 failed=0 stack_width=0 interactive=0 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 success_color="" failure_color="" color_reset=""
local -a stacks=() local -a stacks=() states=() markers=() state_colors=()
local -A pid_stacks=() local -A pid_indexes=()
if [[ -t 1 ]]; then if [[ -t 1 ]]; then
interactive=1 interactive=1
@@ -306,81 +307,98 @@ run_group() {
fi fi
read -r -a stacks <<<"${GROUP_STACKS[group_index]}" read -r -a stacks <<<"${GROUP_STACKS[group_index]}"
((${#stacks[@]} > 0)) || return 0 total="${#stacks[@]}"
for stack in "${stacks[@]}"; do ((total > 0)) || return 0
for ((index = 0; index < total; index++)); do
stack="${stacks[index]}"
((${#stack} > stack_width)) && stack_width="${#stack}" ((${#stack} > stack_width)) && stack_width="${#stack}"
states+=("Waiting")
markers+=(" ")
state_colors+=("")
done done
if ((limit == 0 || limit > ${#stacks[@]})); then if ((limit == 0 || limit > total)); then
limit="${#stacks[@]}" limit="$total"
fi fi
if ((${#stacks[@]} == 1)); then if ((total == 1)); then
details="1 stack" details="1 stack"
elif ((limit == ${#stacks[@]})); then elif ((limit == total)); then
details="${#stacks[@]} stacks in parallel" details="$total stacks in parallel"
else else
details="${#stacks[@]} stacks, max $limit in parallel" details="$total stacks, max $limit in parallel"
fi fi
echo echo
if ((interactive)); then if ((!interactive)); then
printf '[+] %s: %s 0/%d\n' "$group_name" "$action" "${#stacks[@]}"
else
echo "==> Group $group_name: $action ($details)" echo "==> Group $group_name: $action ($details)"
fi fi
case "$action" in case "$action" in
up | start) success_result="Started" ;; up | start) working_result="Starting"; success_result="Started" ;;
restart) success_result="Restarted" ;; restart) working_result="Restarting"; success_result="Restarted" ;;
stop) success_result="Stopped" ;; stop) working_result="Stopping"; success_result="Stopped" ;;
down) success_result="Removed" ;; down) working_result="Removing"; success_result="Removed" ;;
pull) success_result="Pulled" ;; pull) working_result="Pulling"; success_result="Pulled" ;;
update) success_result="Updated" ;; update) working_result="Updating"; success_result="Updated" ;;
esac esac
while ((next < ${#stacks[@]} || running > 0)); do while :; do
while ((next < ${#stacks[@]} && running < limit)); do while ((next < total && running < limit)); do
stack="${stacks[next]}" stack="${stacks[next]}"
states[next]="$working_result"
STACKS_QUIET_PROGRESS=1 run_stack "$stack" "$action" 0 & STACKS_QUIET_PROGRESS=1 run_stack "$stack" "$action" 0 &
pid="$!" pid="$!"
pid_stacks["$pid"]="$stack" pid_indexes["$pid"]="$next"
((next += 1, running += 1)) ((next += 1, running += 1))
done 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="" finished_pid=""
status=0 status=0
wait -n -p finished_pid || status=$? wait -n -p finished_pid || status=$?
[[ -n "$finished_pid" ]] || die "cannot identify completed stack" [[ -n "$finished_pid" ]] || die "cannot identify completed stack"
stack="${pid_stacks[$finished_pid]}" finished_index="${pid_indexes[$finished_pid]}"
unset 'pid_stacks[$finished_pid]' unset 'pid_indexes[$finished_pid]'
stack="${stacks[finished_index]}"
((running -= 1)) ((running -= 1))
if ((status == 0)); then if ((status == 0)); then
marker="✔" markers[finished_index]="✔"
result="$success_result" states[finished_index]="$success_result"
result_color="$success_color" state_colors[finished_index]="$success_color"
((RUN_SUCCESS += 1)) ((RUN_SUCCESS += 1))
else else
marker="✘" markers[finished_index]="✘"
result="Failed" states[finished_index]="Failed"
result_color="$failure_color" state_colors[finished_index]="$failure_color"
((RUN_FAILED += 1)) ((RUN_FAILED += 1))
RUN_FAILED_STACKS+=("$stack") RUN_FAILED_STACKS+=("$stack")
((failed += 1)) ((failed += 1))
fi fi
((completed += 1)) ((completed += 1))
if ((interactive)); then if ((!interactive)); then
printf '\033[%dA\r\033[2K[+] %s: %s %d/%d\n' \ printf ' %s%s%s Stack %-*s %s%s%s\n' \
"$completed" "$group_name" "$action" "$completed" "${#stacks[@]}" "${state_colors[finished_index]}" "${markers[finished_index]}" "$color_reset" \
((completed > 1)) && printf '\033[%dB\r' "$((completed - 1))" "$stack_width" "$stack" \
"${state_colors[finished_index]}" "${states[finished_index]}" "$color_reset"
fi 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 done
((failed == 0)) ((failed == 0))