multithreaded version_check

This commit is contained in:
Megamouse 2025-05-28 23:37:53 +02:00
parent c0bfc34a75
commit ae35430c96

View file

@ -1,7 +1,11 @@
#!/bin/sh -ex #!/bin/bash -ex
verbose=0 verbose=0
git_verbose=0 git_verbose=0
max_jobs=16
lockfile="$(pwd)/version_check.lock"
resultfile="$(pwd)/version_check_results.txt"
if [ "$1" = "-v" ]; then if [ "$1" = "-v" ]; then
verbose=1 verbose=1
@ -10,9 +14,13 @@ elif [ "$1" = "-vv" ]; then
git_verbose=1 git_verbose=1
fi fi
max_dir_length=0 # Limit concurrent jobs
result_dirs=() job_control()
result_msgs=() {
while [ "$(jobs | wc -l)" -ge "$max_jobs" ]; do
sleep 0.1
done
}
git_call() git_call()
{ {
@ -27,20 +35,20 @@ git_call()
check_tags() check_tags()
{ {
path=$(echo "$1" | sed 's:/*$::') local path=$(echo "$1" | sed 's:/*$::')
echo "Checking $path" echo "Checking $path"
git_call fetch --prune --all # git_call fetch --prune --all
# Get the latest tag (by commit date, not tag name) # Get the latest tag (by commit date, not tag name)
tag_list=$(git_call rev-list --tags --max-count=1) local tag_list=$(git_call rev-list --tags --max-count=1)
latest_tag=$(git_call describe --tags "$tag_list") local latest_tag=$(git_call describe --tags "$tag_list")
if [ -n "$latest_tag" ]; then if [ -n "$latest_tag" ]; then
# Get the current tag # Get the current tag
current_tag=$(git_call describe --tags --abbrev=0) local current_tag=$(git_call describe --tags --abbrev=0)
if [ -n "$current_tag" ]; then if [ -n "$current_tag" ]; then
@ -48,8 +56,8 @@ check_tags()
echo "$path -> latest: $latest_tag, current: $current_tag" echo "$path -> latest: $latest_tag, current: $current_tag"
fi fi
ts1=$(git_call log -1 --format=%ct $latest_tag) local ts1=$(git_call log -1 --format=%ct $latest_tag)
ts2=$(git_call log -1 --format=%ct $current_tag) local ts2=$(git_call log -1 --format=%ct $current_tag)
if (( ts1 > ts2 )); then if (( ts1 > ts2 )); then
if [ "$verbose" -eq 1 ]; then if [ "$verbose" -eq 1 ]; then
@ -58,12 +66,11 @@ check_tags()
echo "$path -> latest: $latest_tag, current: $current_tag" echo "$path -> latest: $latest_tag, current: $current_tag"
fi fi
path_length=${#path} # Critical section guarded by flock
if (( $path_length > $max_dir_length )); then (
max_dir_length=$path_length flock 200
fi echo "$path -> latest: $latest_tag, current: $current_tag" >> "$resultfile"
result_dirs+=("$path") ) 200>"$lockfile"
result_msgs+=("latest: $latest_tag, current: $current_tag")
fi fi
elif [ "$verbose" -eq 1 ]; then elif [ "$verbose" -eq 1 ]; then
@ -79,19 +86,21 @@ check_tags()
fi fi
} }
# Fetch and check repositories multi threaded
for submoduledir in */ ; for submoduledir in */ ;
do do
cd "$submoduledir" || continue cd "$submoduledir" || continue
if [ -e ".git" ]; then if [ -e ".git" ]; then
check_tags "$submoduledir" job_control
check_tags "$submoduledir" &
else else
# find */ -mindepth 1 -maxdepth 1 -type d | while read -r sub;
for sub in */ ; for sub in */ ;
do do
if [ -e "$sub/.git" ]; then if [ -e "$sub/.git" ]; then
cd "$sub" || continue cd "$sub" || continue
check_tags "$submoduledir$sub" job_control
check_tags "$submoduledir$sub" &
cd .. || exit cd .. || exit
fi fi
done done
@ -100,16 +109,27 @@ do
cd .. || exit cd .. || exit
done done
# Wait for all background jobs to finish
wait
# Print results
echo -e "\n\nResult:\n" echo -e "\n\nResult:\n"
i=0
for result_dir in "${result_dirs[@]}"; do # Find the max length of the paths (before '->')
msg="" max_len=0
diff=$(($max_dir_length - ${#result_dir})) while IFS='->' read -r left _; do
if (( $diff > 0 )); then len=$(echo -n "$left" | wc -c)
msg+=$(printf "%${diff}s" "") if (( len > max_len )); then
max_len=$len
fi fi
msg+="$result_dir" done < "$resultfile"
echo "$msg -> ${result_msgs[$i]}"
((i++)) # Print with padding so '->' lines up
done while IFS='->' read -r left right; do
echo "" right=$(echo "$right" | sed 's/^[[:space:]]*>*[[:space:]]*//')
printf "%-${max_len}s -> %s\n" "$left" "$right"
done < "$resultfile"
# Remove tmp files
rm -f "$resultfile"
rm -f "$lockfile"