diff options
Diffstat (limited to 'watch-git-tags.sh')
-rw-r--r-- | watch-git-tags.sh | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/watch-git-tags.sh b/watch-git-tags.sh new file mode 100644 index 0000000..f8d4265 --- /dev/null +++ b/watch-git-tags.sh @@ -0,0 +1,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 |