forked from strom/dotfiles
107 lines
2.3 KiB
Bash
Executable file
107 lines
2.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# shellcheck shell=bash disable=2155
|
|
|
|
# shellcheck source=../../lib/common.sh
|
|
source "${0%/*}/../share/dotfiles/lib/common.sh" || exit 1
|
|
|
|
lock_file="/tmp/update_git_repositories.lock"
|
|
|
|
acquire_lock() {
|
|
declare -gi lock_id=$RANDOM
|
|
exec 200>>"$lock_file"
|
|
if ! flock -n 200; then
|
|
_die "Another instance is running. Exiting."
|
|
fi
|
|
lock_id=$RANDOM
|
|
echo "$lock_id" >"$lock_file"
|
|
}
|
|
|
|
release_lock() {
|
|
local current_lock_id
|
|
if [[ ! -e $lock_file ]]; then
|
|
exit 0
|
|
fi
|
|
read -r current_lock_id <"$lock_file"
|
|
if [[ $current_lock_id == "$lock_id" ]]; then
|
|
flock -u 200
|
|
rm -f "$lock_file"
|
|
fi
|
|
}
|
|
|
|
trap 'release_lock' EXIT INT TERM
|
|
acquire_lock
|
|
|
|
if ! _has git; then
|
|
_die "git is required but not installed."
|
|
fi
|
|
|
|
if ! _has parallel; then
|
|
_die "GNU parallel is required but not installed."
|
|
fi
|
|
|
|
update_repo() {
|
|
declare -i max_retries=5
|
|
declare -i initial_delay=2
|
|
|
|
is_git_repo() {
|
|
local repo_path="$1"
|
|
git -C "$repo_path" symbolic-ref -q --short HEAD >/dev/null 2>&1
|
|
}
|
|
|
|
remote_branch_exists() {
|
|
local repo_path="$1"
|
|
git -C "$repo_path" ls-remote --exit-code --heads >/dev/null 2>&1
|
|
}
|
|
|
|
local repo_path="$1"
|
|
declare -i retries=0
|
|
declare -i delay="$initial_delay"
|
|
local repo_name="$(basename "$repo_path")"
|
|
|
|
if [[ ! -d $repo_path ]]; then
|
|
_msg "Directory does not exist. Skipping."
|
|
return
|
|
fi
|
|
|
|
if ! is_git_repo "$repo_path"; then
|
|
_msg "${repo_name} is not a Git repository. Skipping."
|
|
return
|
|
fi
|
|
|
|
if ! remote_branch_exists "$repo_path"; then
|
|
_msg "No remote branch configured for ${repo_name}. Skipping."
|
|
return
|
|
fi
|
|
|
|
while ((retries < max_retries)); do
|
|
if git -C "$repo_path" pull >/dev/null 2>&1; then
|
|
_msg "$repo_name" "updated successfully."
|
|
break
|
|
else
|
|
_msg "Network error or update failed for ${repo_name}. Retrying in ${delay} seconds."
|
|
((retries++))
|
|
sleep "$delay"
|
|
((delay *= 2))
|
|
fi
|
|
done
|
|
|
|
if ((retries == max_retries)); then
|
|
_msg "Max retries reached for ${repo_name}. Skipping."
|
|
fi
|
|
}
|
|
|
|
export -f _msg update_repo
|
|
|
|
if (($# != 1)); then
|
|
_die "Usage: $0 <repository_directory>"
|
|
fi
|
|
|
|
repo_dir="$1"
|
|
|
|
if [[ ! -d $repo_dir ]]; then
|
|
_die "Error: Repository directory '${repo_dir}' does not exist."
|
|
fi
|
|
|
|
find "$repo_dir" -mindepth 1 -maxdepth 1 -type d | parallel --group update_repo {}
|
|
|
|
# vi: set ft=sh ts=4 sw=0 sts=-1 sr noet nosi tw=0 fdm=manual:
|