Rev 2246: New Branch hooks facility, with one initial hook 'set_rh' which triggers in file:///home/robertc/source/baz/branch-hook/
Robert Collins
robertc at robertcollins.net
Mon Jan 29 16:58:52 GMT 2007
------------------------------------------------------------
revno: 2246
revision-id: robertc at robertcollins.net-20070129165849-409f5714fa7ebe48
parent: pqm at pqm.ubuntu.com-20070125194626-4ded330415b7276d
committer: Robert Collins <robertc at robertcollins.net>
branch nick: branch-hook
timestamp: Tue 2007-01-30 03:58:49 +1100
message:
New Branch hooks facility, with one initial hook 'set_rh' which triggers
whenever the revision history is set. This allows triggering on e.g.
push, pull, commit, and so on. Developed for use with the branchrss
plugin. See bzrlib/tests/branch_implementations/test_hooks for more
details. (Robert Collins)
added:
bzrlib/tests/branch_implementations/test_hooks.py test_hooks.py-20070129154855-blhpwxmvjs07waei-1
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
bzrlib/tests/test_branch.py test_branch.py-20060116013032-97819aa07b8ab3b5
bzrlib/tests/test_selftest.py test_selftest.py-20051202044319-c110a115d8c0456a
=== added file 'bzrlib/tests/branch_implementations/test_hooks.py'
--- a/bzrlib/tests/branch_implementations/test_hooks.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/branch_implementations/test_hooks.py 2007-01-29 16:58:49 +0000
@@ -0,0 +1,67 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Tests for branch hooking operations."""
+
+from bzrlib.branch import Branch
+from bzrlib.tests import TestCaseWithMemoryTransport
+
+
+class TestPushHook(TestCaseWithMemoryTransport):
+
+ def setUp(self):
+ self.hook_calls = []
+ TestCaseWithMemoryTransport.setUp(self)
+
+ def capture_set_rh_hook(self, branch, rev_history):
+ """Capture post push hook calls to self.hook_calls.
+
+ The call is logged, as is some state of the two branches.
+ """
+ self.hook_calls.append(
+ ('set_rh', branch, rev_history, branch.is_locked()))
+
+ def test_set_rh_empty_history(self):
+ branch = self.make_branch('source')
+ Branch.hooks['set_rh'].append(self.capture_set_rh_hook)
+ branch.set_revision_history([])
+ self.assertEqual(self.hook_calls,
+ [('set_rh', branch, [], True)])
+
+ def test_set_rh_nonempty_history(self):
+ branch = self.make_branch('source')
+ Branch.hooks['set_rh'].append(self.capture_set_rh_hook)
+ branch.set_revision_history([u'foo'])
+ self.assertEqual(self.hook_calls,
+ [('set_rh', branch, [u'foo'], True)])
+
+ def test_set_rh_branch_is_locked(self):
+ branch = self.make_branch('source')
+ Branch.hooks['set_rh'].append(self.capture_set_rh_hook)
+ branch.set_revision_history([])
+ self.assertEqual(self.hook_calls,
+ [('set_rh', branch, [], True)])
+
+ def test_set_rh_calls_all_hooks_no_errors(self):
+ branch = self.make_branch('source')
+ Branch.hooks['set_rh'].append(self.capture_set_rh_hook)
+ Branch.hooks['set_rh'].append(self.capture_set_rh_hook)
+ branch.set_revision_history([])
+ self.assertEqual(self.hook_calls,
+ [('set_rh', branch, [], True),
+ ('set_rh', branch, [], True),
+ ])
+
=== modified file 'NEWS'
--- a/NEWS 2007-01-24 19:42:26 +0000
+++ b/NEWS 2007-01-29 16:58:49 +0000
@@ -25,6 +25,12 @@
versionedfiles, repositories, branches, and working trees
(Aaron Bentley)
+ * New Branch hooks facility, with one initial hook 'set_rh' which triggers
+ whenever the revision history is set. This allows triggering on e.g.
+ push, pull, commit, and so on. Developed for use with the branchrss
+ plugin. See bzrlib/tests/branch_implementations/test_hooks for more
+ details. (Robert Collins)
+
BUGFIXES:
TESTING:
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py 2007-01-17 15:37:08 +0000
+++ b/bzrlib/branch.py 2007-01-29 16:58:49 +0000
@@ -81,6 +81,10 @@
base
Base directory/url of the branch.
+
+ hooks: A dictionary mapping hook actions to callables to invoke.
+ e.g. 'set_rh':[] is the set_rh hook list. See DefaultHooks for
+ full details.
"""
# this is really an instance variable - FIXME move it there
# - RBC 20060112
@@ -104,6 +108,16 @@
master.break_lock()
@staticmethod
+ def DefaultHooks():
+ """Return a dict of the default branch hook settings."""
+ return {
+ 'set_rh':[], # invoked whenever the revision history has been set
+ # with set_revision_history. The api signature is
+ # (branch, revision_history), and the branch will
+ # be write-locked.
+ }
+
+ @staticmethod
@deprecated_method(zero_eight)
def open_downlevel(base):
"""Open a branch which may be of an old format."""
@@ -629,6 +643,10 @@
return checkout.create_workingtree(revision_id)
+# install the default hooks into the class.
+Branch.hooks = Branch.DefaultHooks()
+
+
class BranchFormat(object):
"""An encapsulation of the initialization and open routines for a format.
@@ -1101,6 +1119,8 @@
# this call is disabled because revision_history is
# not really an object yet, and the transaction is for objects.
# transaction.register_clean(history)
+ for hook in Branch.hooks['set_rh']:
+ hook(self, rev_history)
@needs_read_lock
def revision_history(self):
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2007-01-19 19:42:19 +0000
+++ b/bzrlib/tests/__init__.py 2007-01-29 16:58:49 +0000
@@ -569,6 +569,12 @@
self._startLogFile()
self._benchcalls = []
self._benchtime = None
+ # prevent hooks affecting tests
+ self._preserved_hooks = bzrlib.branch.Branch.hooks
+ self.addCleanup(self._restoreHooks)
+ # this list of hooks must be kept in sync with the defaults
+ # in branch.py
+ bzrlib.branch.Branch.hooks = bzrlib.branch.Branch.DefaultHooks()
def _silenceUI(self):
"""Turn off UI for duration of test"""
@@ -835,6 +841,9 @@
for name, value in self.__old_env.iteritems():
osutils.set_or_unset_env(name, value)
+ def _restoreHooks(self):
+ bzrlib.branch.Branch.hooks = self._preserved_hooks
+
def tearDown(self):
self._runCleanups()
unittest.TestCase.tearDown(self)
=== modified file 'bzrlib/tests/branch_implementations/__init__.py'
--- a/bzrlib/tests/branch_implementations/__init__.py 2006-10-11 23:08:27 +0000
+++ b/bzrlib/tests/branch_implementations/__init__.py 2007-01-29 16:58:49 +0000
@@ -42,6 +42,7 @@
'bzrlib.tests.branch_implementations.test_bound_sftp',
'bzrlib.tests.branch_implementations.test_branch',
'bzrlib.tests.branch_implementations.test_break_lock',
+ 'bzrlib.tests.branch_implementations.test_hooks',
'bzrlib.tests.branch_implementations.test_http',
'bzrlib.tests.branch_implementations.test_locking',
'bzrlib.tests.branch_implementations.test_parent',
=== modified file 'bzrlib/tests/test_branch.py'
--- a/bzrlib/tests/test_branch.py 2006-09-07 23:31:28 +0000
+++ b/bzrlib/tests/test_branch.py 2007-01-29 16:58:49 +0000
@@ -162,3 +162,17 @@
self.assertEqual(made_branch.base, target_branch.base)
opened_branch = branch_dir.open_branch()
self.assertEqual(opened_branch.base, target_branch.base)
+
+
+class TestHooks(TestCase):
+
+ def test_set_rh_in_defaults(self):
+ """Check that the set_rh hook exists in the defaults."""
+ default_hooks = bzrlib.branch.Branch.DefaultHooks()
+ self.assertTrue("set_rh" in default_hooks,
+ "set_rh not in %s" % default_hooks)
+
+ def test_set_rh_in_actual_hooks(self):
+ """Check that the set_rh hook exists in the saved hook set."""
+ self.assertTrue("set_rh" in self._preserved_hooks,
+ "set_rh not in %s" % self._preserved_hooks)
=== modified file 'bzrlib/tests/test_selftest.py'
--- a/bzrlib/tests/test_selftest.py 2007-01-11 08:45:51 +0000
+++ b/bzrlib/tests/test_selftest.py 2007-01-29 16:58:49 +0000
@@ -852,7 +852,12 @@
self.assertContainsRe(
output_stream.getvalue(),
r"\d+ms/ +\d+ms\n$")
-
+
+ def test_hooks_sanitised(self):
+ """The bzrlib hooks should be sanitised by setUp."""
+ self.assertEqual(bzrlib.branch.Branch.DefaultHooks(),
+ bzrlib.branch.Branch.hooks)
+
def test__gather_lsprof_in_benchmarks(self):
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
More information about the bazaar-commits
mailing list