#!/usr/bin/env bash set -euo pipefail BAR_WIDTH=40 SLEEP_INTERVAL=0.05 CLEAR_LINE="\033[K" GREEN="\033[32m" RESET="\033[0m" STAGES=( "Stage changes" "Commit changes" "Push to remote" ) COMMANDS=( "git add ." "git commit -m \"Manual Push\"" "git push" ) draw_bar() { local percent=$1 local width=$2 local text="$3" local clean_text=$(echo -ne "$text" | sed 's/\x1b\[[0-9;]*m//g') [ ${#clean_text} -gt $width ] && clean_text="${clean_text:0:$width}" local filled=$(( percent * width / 100 )) [ $filled -gt $width ] && filled=$width local text_start=$(( (width - ${#clean_text}) / 2 )) local text_end=$(( text_start + ${#clean_text} )) local bar="" for ((i=0;i= text_start && i < text_end )); then bar+="${clean_text:i-text_start:1}" else if (( i < filled )); then bar+="#" else bar+="-" fi fi done printf "[%s] %3d%%" "$bar" "$percent" } run_stage() { local name=$1 local cmd=$2 local start=$3 local end=$4 bash -c "$cmd" > /dev/null 2>&1 & local pid=$! local percent=$start while kill -0 "$pid" 2>/dev/null; do [ "$percent" -lt "$end" ] && percent=$((percent + 1)) echo -ne "\r$(draw_bar $percent $BAR_WIDTH "$name")$CLEAR_LINE" sleep "$SLEEP_INTERVAL" done wait "$pid" echo -ne "\r$(draw_bar $end $BAR_WIDTH "$name")$CLEAR_LINE" echo } main() { local total=${#STAGES[@]} for i in "${!STAGES[@]}"; do start=$(( i * 100 / total )) end=$(( (i + 1) * 100 / total )) run_stage "${STAGES[$i]}" "${COMMANDS[$i]}" "$start" "$end" done echo -e "${GREEN}Push complete!${RESET}" } main