aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2017-08-04 17:32:36 +1200
committerTom Ryder <tom@sanctum.geek.nz>2017-08-04 17:32:36 +1200
commit50aaa96b078e6dbc47c21355d34ef1da83ab20a8 (patch)
tree00b6eb4e1ea499b499f314ab0cc28ebd80746e74
downloadwatch-vcs-tags-50aaa96b078e6dbc47c21355d34ef1da83ab20a8.tar.gz
watch-vcs-tags-50aaa96b078e6dbc47c21355d34ef1da83ab20a8.zip
Initial version with Makefile and README
-rw-r--r--Makefile9
-rw-r--r--README.markdown27
-rwxr-xr-xwatch-git-tags72
3 files changed, 108 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..90bfa3b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+.POSIX:
+.SUFFIXES:
+.PHONY: all install clean
+PREFIX = /usr/local
+all:
+install:
+ mkdir -p -- $(PREFIX)/bin
+ cp -- watch-git-tags $(PREFIX)/bin
+clean:
diff --git a/README.markdown b/README.markdown
new file mode 100644
index 0000000..fb49318
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,27 @@
+`watch-vcs-tags`
+================
+
+Scripts that given a list of repository roots as arguments look for new tags
+available on remote systems, and report the repository name and a tab-indented
+list of new tags, if any:
+
+Presently only `git` is implemented (well, published). This is all implemented
+in POSIX `sh`, but does require a `mktemp(1)` implementation that supports the
+`-d` option to create temporary directories.
+
+ $ watch-git-tags ~/.local/src/ed/vim
+ /home/tom/.local/src/ed/vim
+ v8.0.0858
+
+If you keep a list of your repository paths in a file like ~/.watch-git-tags,
+you could put this in a `crontab(5)` task to email you new tags:
+
+ xargs watch-git-tags < /home/tom/.watch-git-tags-repos
+
+License
+-------
+
+Copyright (c) [Tom Ryder][1]. Distributed under an [MIT License][2].
+
+[1]: https://sanctum.geek.nz/
+[2]: https://www.opensource.org/licenses/MIT
diff --git a/watch-git-tags b/watch-git-tags
new file mode 100755
index 0000000..ccccd00
--- /dev/null
+++ b/watch-git-tags
@@ -0,0 +1,72 @@
+#!/bin/sh
+self=watch-git-tags
+
+# List sorted local tags
+lt() {
+ git tag -l |
+ LC_COLLATE=C sort
+}
+
+# List sorted remote tags
+rt() {
+ git ls-remote -qt |
+ awk '!/\^\{\}$/{print substr($2,11)}' |
+ LC_COLLATE=C sort
+}
+
+# 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
+[ "$#" -gt 0 ] || set -- .
+
+# Iterate through each repo in a subshell in parallel
+for repo ; do (
+
+ # Make a temporary directory with a hash in its name for uniqueness
+ df=$(printf %s "$repo" | sed s:/:_:g)
+ cs=$(printf %s "$repo" | cksum)
+ sd=$td/$df.${cs%% *}
+ mkdir -- "$sd" || 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
+ (
+ cd -- "$repo" || exit
+ lt "$repo" > "$sd"/a || exit
+ rt "$repo" > "$sd"/b
+ ) ||
+ exit
+
+ # Write new tags to file
+ LC_COLLATE=C comm -13 -- [ab] > new
+
+) & done
+
+# Wait for each of those to finish
+wait
+
+# Iterate through the temp dirs in order
+for dir in "$td"/* ; do (
+ cd -- "$dir" || exit 0
+
+ # Look for non-zero "new" files (at least one new tag)
+ [ -s new ] || exit 0
+
+ # Print repository path and new tags
+ sed '1!s/^/\t/' -- path new
+ exit 1
+
+) ; done