]> git.ozlabs.org Git - patchwork/commitdiff
tools: Add a simple sample Git post-receive hook
authorMartin Krafft <madduck@madduck.net>
Thu, 4 Feb 2010 17:33:14 +0000 (17:33 +0000)
committerJeremy Kerr <jk@ozlabs.org>
Tue, 10 Aug 2010 03:49:35 +0000 (11:49 +0800)
This patch adds a post-receive hook to lib/git, which can be used to
update Patchwork following a push to the Git repository.

Surely, it can be improved. One thing to do would be to export the state
map to git-config somehow.

Signed-off-by: martin f. krafft <madduck@madduck.net>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
tools/post-receive.hook [new file with mode: 0755]

diff --git a/tools/post-receive.hook b/tools/post-receive.hook
new file mode 100755 (executable)
index 0000000..004422f
--- /dev/null
@@ -0,0 +1,73 @@
+#!/bin/bash
+#
+# Git post-receive hook to update Patchwork patches after Git pushes
+#
+# Copyright © 2010 martin f. krafft <madduck@madduck.net>
+# Released under the terms of the Artistic Licence 2.0
+#
+set -eu
+
+#TODO: the state map should really live in the repo's git-config
+STATE_MAP="refs/heads/master:Accepted"
+
+PWDIR=/srv/patchwork/apps/patchwork
+
+do_exit=0
+trap "do_exit=1" INT
+
+get_patchwork_hash()
+{
+  local hash
+  hash=$(git show $1 | python $PWDIR/parser.py --hash)
+  echo $hash
+  test -n "$hash"
+}
+
+get_patch_id()
+{
+  local id
+  id=$($PWDIR/bin/pwclient view -h $1 2>/dev/null \
+    | sed -rne 's,X-Patchwork-Id: ,,p')
+  echo $id
+  test -n "$id"
+}
+
+set_patch_state()
+{
+  $PWDIR/bin/pwclient update -s $2 -c $3 $1 2>&1
+}
+
+update_patches()
+{
+  local cnt; cnt=0
+  for rev in $(git rev-list --no-merges --reverse ${1}^..${2}); do
+    if [ "$do_exit" = 1 ]; then
+      echo "I: exiting..." >&2
+      break
+    fi
+    hash=$(get_patchwork_hash $rev) \
+      || { echo "E: failed to hash rev $rev." >&2; continue; }
+    id=$(get_patch_id $hash) \
+      || { echo "E: failed to find patch for rev $rev." >&2; continue; }
+    reason="$(set_patch_state $id $3 $rev)" \
+      || { echo "E: failed to update patch #$id${reason:+: $reason}." >&2; continue; }
+    echo "I: patch #$id updated using rev $rev." >&2
+    cnt=$(($cnt + 1))
+  done
+  echo "I: $cnt patch(es) updated to state $3." >&2
+}
+
+while read oldrev newrev refname; do
+  found=0
+  for i in $STATE_MAP; do
+    key="${i%:*}"
+    if [ "$key" = "$refname" ]; then
+      update_patches $oldrev $newrev ${i#*:}
+      found=1
+      break
+    fi
+  done
+  if [ $found -eq 0 ]; then
+    echo "E: no mapping for refname $key" >&2
+  fi
+done