feat: report grouped task progress

This commit is contained in:
lingkai5wu committed 2026-10-10 16:56:14 +08:00
1 parent 5895d8f3a3
commit 475434042c
1 file changed
+50 -34
+50 -34
View File
@@ -247,10 +247,15 @@ stack_group() {
compose() {
local stack="$1"
shift
local -a docker_args=(compose)
if [[ "${STACKS_QUIET_PROGRESS:-0}" == "1" ]]; then
docker_args+=(--progress quiet)
fi
(
cd -- "$STACKS_DIR/$stack" || exit 1
docker compose "$@"
docker "${docker_args[@]}" "$@"
)
}
@@ -285,10 +290,17 @@ run_group() {
local action="$2"
local group_name="${GROUP_NAMES[group_index]}"
local limit="${GROUP_LIMITS[group_index]}"
local semaphore_dir semaphore_fifo semaphore_fd
local stack pid i status details
local failed=0
local -a stacks=() pids=() pid_stacks=()
local stack pid finished_pid status result result_color success_result details
local next=0 running=0 completed=0 failed=0
local success_color="" failure_color="" color_reset=""
local -a stacks=()
local -A pid_stacks=()
if [[ -t 1 && -z "${NO_COLOR:-}" ]]; then
success_color=$'\033[32m'
failure_color=$'\033[31m'
color_reset=$'\033[0m'
fi
read -r -a stacks <<<"${GROUP_STACKS[group_index]}"
((${#stacks[@]} > 0)) || return 0
@@ -308,46 +320,50 @@ run_group() {
echo
echo "==> Group $group_name: $action ($details)"
semaphore_dir="$(mktemp -d "${TMPDIR:-/tmp}/stacks-manage.XXXXXX")" ||
die "cannot create semaphore directory"
semaphore_fifo="$semaphore_dir/tokens"
mkfifo "$semaphore_fifo" || die "cannot create semaphore"
exec {semaphore_fd}<>"$semaphore_fifo" || die "cannot open semaphore"
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" ;;
esac
for ((i = 0; i < limit; i++)); do
printf '\n' >&"$semaphore_fd"
done
while ((next < ${#stacks[@]} || running > 0)); do
while ((next < ${#stacks[@]} && running < limit)); do
stack="${stacks[next]}"
STACKS_QUIET_PROGRESS=1 run_stack "$stack" "$action" 0 &
pid="$!"
pid_stacks["$pid"]="$stack"
((next += 1, running += 1))
done
for stack in "${stacks[@]}"; do
IFS= read -r -u "$semaphore_fd"
finished_pid=""
status=0
wait -n -p finished_pid || status=$?
[[ -n "$finished_pid" ]] || die "cannot identify completed stack"
(
status=0
run_stack "$stack" "$action" 0 || status=$?
printf '\n' >&"$semaphore_fd"
exit "$status"
) &
stack="${pid_stacks[$finished_pid]}"
unset 'pid_stacks[$finished_pid]'
((running -= 1))
pids+=("$!")
pid_stacks+=("$stack")
done
for ((i = 0; i < ${#pids[@]}; i++)); do
pid="${pids[i]}"
stack="${pid_stacks[i]}"
if wait "$pid"; then
if ((status == 0)); then
result="$success_result"
result_color="$success_color"
((RUN_SUCCESS += 1))
else
result="Failed"
result_color="$failure_color"
((RUN_FAILED += 1))
RUN_FAILED_STACKS+=("$stack")
((failed += 1))
fi
done
exec {semaphore_fd}>&-
rm -f -- "$semaphore_fifo"
rmdir -- "$semaphore_dir"
((completed += 1))
printf '[%d/%d] %s: %s%s%s\n' \
"$completed" "${#stacks[@]}" "$stack" \
"$result_color" "$result" "$color_reset"
done
((failed == 0))
}