Sketch in skeleton of module from bzr-email
authorNeil <neil@dip.sun.ac.za>
Sun, 11 Nov 2012 09:44:28 +0000 (11:44 +0200)
committerNeil <neil@dip.sun.ac.za>
Sun, 11 Nov 2012 09:44:28 +0000 (11:44 +0200)
__init__.py [new file with mode: 0644]
irkerhook.py [new file with mode: 0644]

diff --git a/__init__.py b/__init__.py
new file mode 100644 (file)
index 0000000..31a2680
--- /dev/null
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+# vim:fileencoding=utf-8 ai ts=4 sts=4 et sw=4
+# Copyright 2012 Neil Muller
+# GPL 2+ - see COPYING for details
+"""Sending irker notifications for commits and branch changes.
+
+Details to follow
+"""
+
+from bzrlib.config import option_registry
+from bzrlib.lazy_import import lazy_import
+
+# lazy_import so that it doesn't get loaded if it isn't used
+# Approach borrowed from bzr-email
+lazy_import(globals(), """\
+from bzrlib.plugins.irkerhook import irkerhook as _irkerhook
+""")
+
+
+def post_commit(branch, revision_id):
+    """This is the post_commit hook that should get run after commit."""
+    _irkerhook.IrkerSender(branch, revision_id,
+            branch.get_config_stack()).send_maybe()
+
+
+def branch_commit_hook(local, master, old_revno, old_revid,
+        new_revno, new_revid):
+    """This is the post_commit hook that runs after commit."""
+    _irkerhook.IrkerSender(master, new_revid, master.get_config_stack(),
+                         local_branch=local).send_maybe()
+
+
+def branch_post_change_hook(params):
+    """This is the post_change_branch_tip hook."""
+    # (branch, old_revno, new_revno, old_revid, new_revid)
+    _irker.IrkerSender(params.branch, params.new_revid,
+        params.branch.get_config_stack(), local_branch=None,
+        op='change').send_maybe()
+
+
+def test_suite():
+    from unittest import TestSuite
+    import bzrlib.plugins.irkerhook.tests
+    result = TestSuite()
+    result.addTest(bzrlib.plugins.irkerhook.tests.test_suite())
+    return result
+
+
+option_registry.register_lazy("irker_channels",
+    "bzrlib.plugins.irkerhook.irkerhook", "opt_irker_channels")
+option_registry.register_lazy("irker_colours",
+    "bzrlib.plugins.irkerhook.irkerhook", "opt_irker_colours")
+option_registry.register_lazy("irker_url",
+    "bzrlib.plugins.irkerhook.irkerhook", "opt_irker_url")
+
+from bzrlib.hooks import install_lazy_named_hook
+install_lazy_named_hook("bzrlib.branch", "Branch.hooks", 'post_commit',
+        branch_commit_hook, 'bzr-irker')
+install_lazy_named_hook("bzrlib.branch", "Branch.hooks",
+        'post_change_branch_tip', branch_post_change_hook, 'bzr-irker')
diff --git a/irkerhook.py b/irkerhook.py
new file mode 100644 (file)
index 0000000..b2dd4fe
--- /dev/null
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+# vim:fileencoding=utf-8 ai ts=4 sts=4 et sw=4
+# Copyright 2012 Neil Muller
+# GPL 2+ - see COPYING for details
+
+from bzrlib import (
+    errors,
+    revision as _mod_revision,
+    )
+from bzrlib.config import (
+    ListOption,
+    Option,
+    bool_from_store,
+    int_from_store,
+    )
+
+
+class IrkerSender(object):
+    """An irker message sender."""
+
+    def __init__(self, branch, revision_id, config, local_branch=None,
+        op='commit'):
+        self.config = config
+        self.branch = branch
+        self.repository = branch.repository
+        if (local_branch is not None and
+            local_branch.repository.has_revision(revision_id)):
+            self.repository = local_branch.repository
+        self._revision_id = revision_id
+        self.revision = None
+        self.revno = None
+        self.op = op
+
+    def _setup_revision_and_revno(self):
+        self.revision = self.repository.get_revision(self._revision_id)
+        self.revno = self.branch.revision_id_to_revno(self._revision_id)
+
+    def _format(self):
+        fields = {
+            'committer': self.revision.committer,
+            'message': self.revision.get_summary(),
+            'revision': '%d' % self.revno,
+            'url': self.url()
+        }
+        text = ''
+        #for name, value in fields.items():
+        #    text = text.replace('$%s' % name, value)
+        return text
+
+    def body(self):
+        from bzrlib import log
+
+        rev1 = rev2 = self.revno
+        if rev1 == 0:
+            rev1 = None
+            rev2 = None
+
+        # use 'replace' so that we don't abort if trying to write out
+        # in e.g. the default C locale.
+
+        # Following bzr-email, we use StringIO.StringIO to minimise possible
+        # unicode issues.
+        from StringIO import StringIO
+        outf = StringIO()
+
+        lf = log.log_formatter('line',
+                               show_ids=True,
+                               to_file=outf
+                               )
+
+        if len(self.revision.parent_ids) <= 1:
+            # This is not a merge, so we can special case the display of one
+            # revision, and not have to encur the show_log overhead.
+            lr = log.LogRevision(self.revision, self.revno, 0, None)
+            lf.log_revision(lr)
+        else:
+            # let the show_log code figure out what revisions need to be
+            # displayed, as this is a merge
+            log.show_log(self.branch,
+                         lf,
+                         start_revision=rev1,
+                         end_revision=rev2,
+                         verbose=True
+                         )
+
+        return outf.getvalue()
+
+    def url(self):
+        """What URL to display in the subject of the mail"""
+        url = self.config.get('irker_url')
+        if url is None:
+            url = self.config.get('public_branch')
+        if url is None:
+            url = self.branch.base
+        return url
+
+    def send(self):
+        """Send the info to irkerd.
+        """
+        self.branch.lock_read()
+        self.repository.lock_read()
+        try:
+            # Do this after we have locked, to make things faster.
+            self._setup_revision_and_revno()
+        finally:
+            self.repository.unlock()
+            self.branch.unlock()
+
+opt_irker_url = Option('irker_url',
+    help='URL to mention for branch in messages.')
+opt_irker_channels = Option('irker_channels',
+    help='Channel(s) to post commit messages to.')
+opt_irker_colours = Option('irker_colours',
+    help='Colour option for irker.')