In my setup I do not want to hook patchwork directly in the upstream
master tree as I do not have access to it.
So I created this patch that will update the status of patches after a pull.
It adds some code in utils.py to performthe actual update and a
post-merge hook that is called when my cron job does a git pull from master.
I have briefly tested this in a staging server, and will deploy on my
site shortly.
HTH,
Simo.
>From 8767da729516725120027f37f65436e26137e45f Mon Sep 17 00:00:00 2001
From: Simo Sorce <[email protected]>
Date: Sat, 23 Mar 2013 14:40:00 -0400
Subject: [PATCH] Add post-merge tool to update git tree
In some cases it is not possible to add hooks to the master
tree however it is possible to easily pull from it into the
patchwork server.
This post-merge hook allows to mark patch status on pull with
a merge hook instead of on a push with post update hook.
Extends utils.py so it is callable from the hook and exposes
an utility to set the patch status by patch hash
---
apps/patchwork/utils.py | 52 +++++++++++++++++++++++++++++++++-
tools/post-merge.hook | 75 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 126 insertions(+), 1 deletion(-)
create mode 100755 tools/post-merge.hook
diff --git a/apps/patchwork/utils.py b/apps/patchwork/utils.py
index 1771167..3b48613 100644
--- a/apps/patchwork/utils.py
+++ b/apps/patchwork/utils.py
@@ -29,7 +29,7 @@ from django.db.models import Max
from django.db.utils import IntegrityError
from patchwork.forms import MultiplePatchForm
from patchwork.models import Bundle, Project, BundlePatch, UserProfile, \
- PatchChangeNotification, EmailOptout
+ PatchChangeNotification, EmailOptout, Patch, State
def get_patch_ids(d, prefix = 'patch_id'):
ids = []
@@ -206,3 +206,53 @@ def send_notifications():
delete_notifications()
return errors
+
+def patch_set_state(patch_hash, state_name):
+ """Update patch state: Inputs are patch hash and state name"""
+ try:
+ patch = Patch.objects.get(hash = patch_hash)
+ patch.state = State.objects.get(name = state_name)
+ patch.save()
+ return True
+ except:
+ raise
+
+def main(args):
+ from optparse import OptionParser
+
+ usage = "usage: %prog [options] command"
+ parser = OptionParser(usage=usage)
+ parser.add_option('-#', '--hash',
+ dest = 'patch_hash', help = 'Patch Hash')
+ parser.add_option('-s', '--state',
+ dest = 'state_name', help = 'State Name')
+
+ (options, args) = parser.parse_args()
+
+ if len(args) != 1:
+ parser.print_help()
+ sys.exit(-1)
+
+ if args[0] == "set":
+ if not options.patch_hash:
+ print "Missing Patch Hash\n"
+ parser.print_help()
+ sys.exit(-1)
+
+ if not options.state_name:
+ print "Missing State Name\n"
+ parser.print_help()
+ sys.exit(-1)
+
+ try:
+ patch_set_state(options.patch_hash, options.state_name)
+ except:
+ print "E: Failed to update patch!\n"
+
+ else:
+ parser.print_help()
+ sys.exit(-1)
+
+if __name__ == '__main__':
+ import sys
+ sys.exit(main(sys.argv))
diff --git a/tools/post-merge.hook b/tools/post-merge.hook
new file mode 100755
index 0000000..7cba308
--- /dev/null
+++ b/tools/post-merge.hook
@@ -0,0 +1,75 @@
+#!/bin/bash
+#
+# Git post-merge hook to update Patchwork patches after Git pulls
+#
+# Copyright © 203 Simo Sorce <[email protected]>
+#
+# Based on code from the post-receive hoof from:
+# Copyright © 2010 martin f. krafft <[email protected]>
+# Released under the GNU General Public License v2 or later.
+set -eu
+
+STATE_MAP="refs/heads/master:Accepted"
+PWDIR=/home/patchwork/patchwork/apps
+
+BASE_DIR=$(git rev-parse --show-toplevel)
+STATE_DIR=${BASE_DIR}/.git/patchwork
+
+do_exit=0
+trap "do_exit=1" INT
+
+get_patchwork_hash()
+{
+ local hash
+ hash=$(git show $1 | python $PWDIR/patchwork/parser.py --hash)
+ echo $hash
+ test -n "$hash"
+}
+
+set_patch_state()
+{
+ PYTHONPATH=${PWDIR} DJANGO_SETTINGS_MODULE=settings python ${PWDIR}/patchwork/utils.py -# ${1} -s ${2} set
+}
+
+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; }
+ reason="$(set_patch_state $hash $3)" \
+ || { echo "E: failed to update patch ${reason:+: $reason}." >&2; continue; }
+ echo "I: patch $hash updated using rev $rev." >&2
+ cnt=$(($cnt + 1))
+ done
+ echo "I: $cnt patch(es) updated to state $3." >&2
+}
+
+if [ ! -d ${STATE_DIR} ]; then
+ mkdir -p ${STATE_DIR}
+fi
+
+CUR_REFS=$(git show-ref --heads |cut -d ' ' -f 2)
+
+for refname in $CUR_REFS; do
+ BRANCH=$(echo ${refname} | cut -d '/' -f 3)
+ newrev=$(git rev-parse ${refname})
+ if [ ! -f ${STATE_DIR}/${BRANCH} ]; then
+ echo ${newrev} > ${STATE_DIR}/${BRANCH}
+ continue
+ fi
+ oldrev=$(cat ${STATE_DIR}/${BRANCH})
+ echo ${newrev} > ${STATE_DIR}/${BRANCH}
+
+ for i in $STATE_MAP; do
+ key="${i%:*}"
+ if [ "${key}" = "${refname}" ]; then
+ update_patches ${oldrev} ${newrev} ${i#*:}
+ break
+ fi
+ done
+done
--
1.7.12.1
_______________________________________________
Patchwork mailing list
[email protected]
https://lists.ozlabs.org/listinfo/patchwork