129 lines
3.1 KiB
Bash
129 lines
3.1 KiB
Bash
#!/usr/bin/env bash
|
|
# ...
|
|
# shellcheck disable=2317,2059
|
|
# created: 20240515
|
|
# purpose: automatic git pull of repos
|
|
# author: afinet
|
|
#
|
|
# update: 20240620
|
|
# purpose: progress bar
|
|
|
|
local_repository_folder=$HOME"/GIT-LAB/"
|
|
|
|
# Array of git repositories
|
|
REPOS=($(find $local_repository_folder -name ".git" -type d))
|
|
# Lenght of the array
|
|
PULL_ITER=${#REPOS[@]}
|
|
|
|
# Progress bar dedicated variables
|
|
# We can control how progress bar work
|
|
PROGRESS_BAR_CHAR=(█ ▒)
|
|
|
|
# Display template
|
|
# We can control how informations is displayed
|
|
PROGRESS_BAR_INFO_TEMPLATE=' %s [%2d/%2d] '
|
|
PROGRESS_BAR_COMPL_TEMPLATE=' %2d%% '
|
|
PROGRESS_BAR_TEMPLATE='\033[1m%s%s\033[0m%s%s\r'
|
|
|
|
# control which information is displayed"
|
|
PROGRESS_BAR_DISPLAY_INFO=1
|
|
PROGRESS_BAR_DISPLAY_COMPL=1
|
|
|
|
puller() {
|
|
SECONDS=0
|
|
i=1
|
|
reporting=false
|
|
report=$'============================\nPulling generated messages :\n============================\n'
|
|
|
|
for repo in ${REPOS[@]}; do
|
|
run_error=""
|
|
echo $repo $i
|
|
run_error=$(git -C $repo/.. pull 2>&1 > /dev/null)
|
|
if [[ $run_error ]]; then
|
|
reporting=true
|
|
report=$report$"* On $repo :"$'\n'"$run_error"$'\n'
|
|
fi
|
|
((i++))
|
|
done
|
|
duration=$SECONDS
|
|
((i--))
|
|
echo "[Finished] - Pulled $i/$PULL_ITER repositories in $((duration / 60)):$((duration % 60))"
|
|
|
|
if [ "$reporting" = true ]; then
|
|
echo "$report"
|
|
fi
|
|
}
|
|
|
|
draw_progressbar() {
|
|
# function parameters
|
|
local -r progress=${1?"progress is mandatory"}
|
|
local -r total=${2?"total elements is mandatory"}
|
|
local -r info=${3:-"In progress"}
|
|
|
|
# function local variables
|
|
local progress_segment
|
|
local todo_segment
|
|
local info_segment=""
|
|
local compl_segment=""
|
|
|
|
if [[ ${PROGRESS_BAR_DISPLAY_INFO:-1} -eq 1 ]]; then
|
|
printf -v info_segment "${PROGRESS_BAR_INFO_TEMPLATE}" \
|
|
"$info" "$progress" "$total"
|
|
fi
|
|
|
|
local -r progress_ratio=$((progress * 100 / total))
|
|
if [[ ${PROGRESS_BAR_DISPLAY_COMPL:-0} -eq 1 ]]; then
|
|
printf -v compl_segment "${PROGRESS_BAR_COMPL_TEMPLATE}" \
|
|
"$progress_ratio"
|
|
fi
|
|
|
|
# progress bar construction
|
|
# calculate each element sizes, bar must fit in ou screen
|
|
local -r bar_size=$((COLUMNS - ${#info_segment} - ${#compl_segment}))
|
|
local -r progress_segment_size=$((bar_size * progress_ratio / 100))
|
|
local -r todo_segment_size=$((bar_size - progress_segment_size))
|
|
printf -v progress_segment "%${progress_segment_size}s" ""
|
|
printf -v todo_segment "%${todo_segment_size}s" ""
|
|
|
|
printf >&2 "$PROGRESS_BAR_TEMPLATE" \
|
|
"$info_segment" \
|
|
"${progress_segment// /${PROGRESS_BAR_CHAR[0]}}" \
|
|
"${todo_segment// /${PROGRESS_BAR_CHAR[1]}}" \
|
|
"$compl_segment"
|
|
|
|
}
|
|
|
|
parse_output() {
|
|
# trap if shell column count change
|
|
trap change_column_size WINCH
|
|
# while puller() echoes
|
|
while read -r line; do
|
|
if [[ "$line" =~ ^/ ]];then
|
|
current_repo=$(echo $line | cut -d " " -f 1 | cut -d "/" -f 5-7 | sed 's/\//::/g')
|
|
iteration=$(echo $line | cut -d " " -f 2)
|
|
printf -v info "Pulling %-35s %s" $current_repo
|
|
draw_progressbar \
|
|
"$iteration" \
|
|
"$PULL_ITER" \
|
|
"$info"
|
|
else
|
|
printf >&2 "\033[0K\r"
|
|
printf "%s\n" "$line"
|
|
fi
|
|
done
|
|
}
|
|
|
|
change_column_size() {
|
|
printf >&2 "%${COLUMNS}s" ""
|
|
printf >&2 "\033[0K\r"
|
|
COLUMNS=$(tput cols)
|
|
}
|
|
|
|
main() {
|
|
COLUMNS=$(tput cols)
|
|
puller > >(parse_output)
|
|
}
|
|
|
|
main
|
|
exit 0
|