Rev 4161: Add a BzrDir.pre_open hook for use by the smart server gaol. in http://people.ubuntu.com/~robertc/baz2.0/pending/BzrDir.pre_open

Robert Collins robertc at robertcollins.net
Wed Mar 18 03:47:34 GMT 2009


At http://people.ubuntu.com/~robertc/baz2.0/pending/BzrDir.pre_open

------------------------------------------------------------
revno: 4161
revision-id: robertc at robertcollins.net-20090318034730-xex5ks3t5ct7gin6
parent: pqm at pqm.ubuntu.com-20090318021431-md1n8o3542wwsvai
committer: Robert Collins <robertc at robertcollins.net>
branch nick: BzrDir.pre_open
timestamp: Wed 2009-03-18 14:47:30 +1100
message:
  Add a BzrDir.pre_open hook for use by the smart server gaol.
=== modified file 'NEWS'
--- a/NEWS	2009-03-18 02:14:31 +0000
+++ b/NEWS	2009-03-18 03:47:30 +0000
@@ -114,6 +114,10 @@
     * New ``assertLength`` method based on one Martin has squirreled away
       somewhere. (Robert Collins, Martin Pool)
 
+    * New hook ``BzrDir.pre_open`` which runs before opening ``BzrDir``
+      objects, allowing better enforcement of the smart server jail when
+      dealing with stacked branches. (Robert Collins, Andrew Bennetts)
+
     * New repository method ``refresh_data`` to cause any repository to
       make visible data inserted into the repository by a smart server
       fetch operation. (Robert Collins, Andrew Bennetts)

=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2009-03-18 01:27:58 +0000
+++ b/bzrlib/bzrdir.py	2009-03-18 03:47:30 +0000
@@ -75,6 +75,7 @@
     )
 
 from bzrlib import (
+    hooks,
     registry,
     symbol_versioning,
     )
@@ -93,6 +94,8 @@
         (i.e. the parent directory holding the .bzr directory).
 
     Everything in the bzrdir should have the same file permissions.
+
+    :cvar hooks: An instance of BzrDirHooks.
     """
 
     def break_lock(self):
@@ -806,6 +809,8 @@
         :param transport: Transport containing the bzrdir.
         :param _unsupported: private.
         """
+        for hook in BzrDir.hooks['pre_open']:
+            hook(transport)
         # Keep initial base since 'transport' may be modified while following
         # the redirections.
         base = transport.base
@@ -1190,6 +1195,20 @@
         return result
 
 
+class BzrDirHooks(hooks.Hooks):
+    """Hooks for BzrDir operations."""
+
+    def __init__(self):
+        """Create the default hooks."""
+        hooks.Hooks.__init__(self)
+        self.create_hook(hooks.HookPoint('pre_open',
+            "Invoked before attempting to open a BzrDir with the transport "
+            "that the open will use.", (1, 14), None))
+
+# install the default hooks
+BzrDir.hooks = BzrDirHooks()
+
+
 class BzrDirPreSplitOut(BzrDir):
     """A common class for the all-in-one formats."""
 

=== modified file 'bzrlib/hooks.py'
--- a/bzrlib/hooks.py	2009-03-12 08:34:53 +0000
+++ b/bzrlib/hooks.py	2009-03-18 03:47:30 +0000
@@ -33,6 +33,8 @@
 known_hooks = registry.Registry()
 known_hooks.register_lazy(('bzrlib.branch', 'Branch.hooks'), 'bzrlib.branch',
     'BranchHooks')
+known_hooks.register_lazy(('bzrlib.bzrdir', 'BzrDir.hooks'), 'bzrlib.bzrdir',
+    'BzrDirHooks')
 known_hooks.register_lazy(('bzrlib.commands', 'Command.hooks'),
     'bzrlib.commands', 'CommandHooks')
 known_hooks.register_lazy(('bzrlib.lock', 'Lock.hooks'), 'bzrlib.lock',

=== modified file 'bzrlib/tests/test_bzrdir.py'
--- a/bzrlib/tests/test_bzrdir.py	2009-03-18 01:27:58 +0000
+++ b/bzrlib/tests/test_bzrdir.py	2009-03-18 03:47:30 +0000
@@ -1306,3 +1306,26 @@
         parent = grandparent_tree.bzrdir.sprout('parent').open_branch()
         branch_tree = parent.bzrdir.sprout('branch').open_branch()
         self.assertContainsRe(branch_tree.get_parent(), '/parent/$')
+
+
+class TestBzrDirHooks(TestCaseWithMemoryTransport):
+
+    def test_pre_open_called(self):
+        calls = []
+        bzrdir.BzrDir.hooks.install_named_hook('pre_open', calls.append, None)
+        transport = self.get_transport('foo')
+        url = transport.base
+        self.assertRaises(errors.NotBranchError, bzrdir.BzrDir.open, url)
+        self.assertEqual([transport.base], [t.base for t in calls])
+
+    def test_pre_open_actual_exceptions_raised(self):
+        count = [0]
+        def fail_once(transport):
+            count[0] += 1
+            if count[0] == 1:
+                raise errors.BzrError("fail")
+        bzrdir.BzrDir.hooks.install_named_hook('pre_open', fail_once, None)
+        transport = self.get_transport('foo')
+        url = transport.base
+        err = self.assertRaises(errors.BzrError, bzrdir.BzrDir.open, url)
+        self.assertEqual('fail', err._preformatted_string)




More information about the bazaar-commits mailing list