blob: f8d42658e547a50381c7d9a62b0acbc2e863d40f (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
# Function to retrieve and filter tag names
tags() {
case $1 in
local) git -C "${2:-.}" show-ref --tags ;;
remote) git -C "${2:-.}" ls-remote --quiet --refs --tags ;;
*) return 2 ;;
esac |
while read -r _ tag ; do
tag=${tag#refs/tags/}
printf '%s\n' "$tag"
done
}
# Create a temporary directory with name in $td, and handle POSIX-ish traps to
# remove it when the script exits; requires mktemp(1) (not POSIX)
td=$(mktemp -d) || exit
cleanup() {
[ -n "$td" ] || return
rm -fr -- "$td"
}
for sig in EXIT HUP INT TERM ; do
# shellcheck disable=SC2064
trap "cleanup $sig" "$sig"
done
# Use current directory if no other arguments
if [ "$#" -eq 0 ] ; then
set -- "$PWD"
fi
# Iterate through each repo in a subshell in parallel
for repo do (
# Make a temporary directory with a hash in its name for uniqueness
name=$(printf '%s' "$repo" | sed 's:/:_:g')
cksum=$(printf '%s' "$repo" | cksum | sed 's:[^0-9].*::')
sd=$td/$name.$cksum
mkdir -- "$sd" "$sd"/tags || exit
# Step in and write repo path to file
cd -- "$sd" || exit
printf '%s\n' "$repo" > path || exit
# Write local and remote tags to files
tags local "$repo" > tags/local || exit
tags remote "$repo" > tags/remote || exit
# Write new tags to file
LC_COLLATE=C comm -13 -- tags/local tags/remote > tags/new
# Attempt to quietly fetch new tags so that we don't notify about the same
# ones next time
[ -s tags/new ] || exit
git -C "$repo" fetch --quiet --tags
) & done
# Wait for all of those to finish
wait
# Iterate through the temp dirs in order
for dir in "$td"/* ; do (
cd -- "$dir" || exit
# Look for non-zero "new" files (at least one new tag)
[ -s tags/new ] || exit
# Print repository path and new tags
cat path
while read -r tag ; do
printf '* %s\n' "$tag"
done < tags/new
) ; done
# Haven't yet decided on exit value semantics; for the moment, if it completes,
# exit success
exit 0
|