[MERGE REQUEST] Couple of small fixes

Jelmer Vernooij jelmer at samba.org
Fri Dec 9 01:21:30 GMT 2005


Hi Martin,

Please consider merging the following changes from my integration branch at 
http://samba.org/~jelmer/bzr/foreignbranch.

 1428 Jelmer Vernooij	2005-11-20
      Use other registered branch types and add tests for foreign branches.

 1427 Jelmer Vernooij	2005-11-20
      Move use of Transport to BzrBranch 

These changes are required for foreign Branch support and allow
viewing the history of foreign branches.

I am currently working on support for real checkouts in a branch that
contains this branch joined with Aaron's storage branch.

A diff of the changes in these revisions is attached.

Cheers, Jelmer

-- 
-------------- next part --------------
=== modified file 'bzrlib/branch.py'
--- bzrlib/branch.py	
+++ bzrlib/branch.py	
@@ -92,6 +92,15 @@
             self.unlock()
     return decorated
 
+branch_types = []
+
+def register_branch_type(bt):
+    """Utility function to help register a branch type"""
+
+    branch_types.append(bt)
+
+    mutter('registered foreign branch type %s', bt.__name__)
+
 ######################################################################
 # branch objects
 
@@ -114,14 +123,27 @@
         return BzrBranch(get_transport(base), relax_version_check=True)
         
     @staticmethod
-    def open(base):
-        """Open an existing branch, rooted at 'base' (url)"""
-        t = get_transport(base)
-        mutter("trying to open %r with transport %r", base, t)
-        return BzrBranch(t)
+    def open(base,allowed_types=None):
+        """Open an existing branch, rooted at 'base' (url)
+        
+        allowed_types
+            Branch types to allow (defaults to all branch types available)
+        """
+        if not allowed_types:
+            allowed_types = branch_types
+
+        for bt in allowed_types:
+            assert issubclass(bt, Branch)
+
+            try:
+                return bt.open(base)
+            except NotBranchError:
+                pass
+        
+        raise NotBranchError(path=base)
 
     @staticmethod
-    def open_containing(url):
+    def open_containing(url,allowed_types=None):
         """Open an existing branch which contains url.
         
         This probes for a branch at url, and searches upwards from there.
@@ -129,24 +151,28 @@
         Basically we keep looking up until we find the control directory or
         run into the root.  If there isn't one, raises NotBranchError.
         If there is one, it is returned, along with the unused portion of url.
-        """
-        t = get_transport(url)
-        while True:
+
+        allowed_types
+            Branch types to allow (defaults to all branch types available)
+        """
+
+        if not allowed_types:
+            allowed_types = branch_types
+
+        for bt in allowed_types:
+            assert issubclass(bt, Branch)
+
             try:
-                return BzrBranch(t), t.relpath(url)
+                return bt.open_containing(url)
             except NotBranchError:
                 pass
-            new_t = t.clone('..')
-            if new_t.base == t.base:
-                # reached the root, whatever that may be
-                raise NotBranchError(path=url)
-            t = new_t
+        
+        raise NotBranchError(path=url)
 
     @staticmethod
     def initialize(base):
         """Create a new branch, rooted at 'base' (url)"""
-        t = get_transport(base)
-        return BzrBranch(t, init=True)
+        return BzrBranch.initialize(base)
 
     def setup_caching(self, cache_root):
         """Subclasses that care about caching should override this, and set
@@ -611,6 +637,35 @@
         except UnlistableStore:
             raise UnlistableBranch(from_store)
 
+    @staticmethod
+    def open(base):
+        """See Branch.open."""
+        t = get_transport(base)
+        mutter("trying to open %r with transport %r", base, t)
+        return BzrBranch(t)
+
+    @staticmethod
+    def open_containing(url):
+        """See Branch.open_containing."""
+        t = get_transport(url)
+        while True:
+            try:
+                return BzrBranch(t), t.relpath(url)
+            except NotBranchError:
+                pass
+            new_t = t.clone('..')
+            if new_t.base == t.base:
+                # reached the root, whatever that may be
+                raise NotBranchError(path=url)
+            t = new_t
+
+    
+    @staticmethod
+    def initialize(base):
+        """See Branch.initialize."""
+        t = get_transport(base)
+        return BzrBranch(t,init=True)
+
     def __init__(self, transport, init=False,
                  relax_version_check=False):
         """Create new branch object at a particular location.
@@ -1339,6 +1394,7 @@
         self.revision_store.add(StringIO(gpg_strategy.sign(plaintext)), 
                                 revision_id, "sig")
 
+register_branch_type(BzrBranch)
 
 class ScratchBranch(BzrBranch):
     """Special test class: a branch that cleans up after itself.

=== modified file 'bzrlib/selftest/testbranch.py'
--- bzrlib/selftest/testbranch.py	
+++ bzrlib/selftest/testbranch.py	
@@ -388,3 +388,64 @@
 
     # TODO RBC 20051029 test getting a push location from a branch in a 
     # recursive section - that is, it appends the branch name.
+
+class TestForeignBranch(TestCaseInTempDir):
+    class FooError(Exception): pass
+    class FooBranch(Branch):
+        def __init__(self):
+            pass
+                
+        @staticmethod
+        def open(url):
+            if url == 'foo':
+                return TestForeignBranch.FooBranch()
+
+            if url == 'invalid':
+                raise TestForeignBranch.FooError
+                
+            raise NotBranchError(path=url)
+
+        @staticmethod
+        def open_containing(base):
+            raise NotBranchError(path=base)
+
+    class BarBranch(Branch):
+        def __init__(self):
+            pass
+         
+        @staticmethod
+        def open(url):
+            if url == 'foo' or url == 'bar':
+                return TestForeignBranch.BarBranch()
+            raise NotBranchError(path=url)
+
+        @staticmethod
+        def open_containing(base):
+            raise NotBranchError(path=base)
+
+    def setUp(self):
+        super(TestForeignBranch, self).setUp()
+
+        from bzrlib.branch import register_branch_type
+        register_branch_type(self.FooBranch)
+        register_branch_type(self.BarBranch)
+
+    def test_open_allowed_types(self):
+        """test that the allowed_types argument to open() is honored"""
+        from bzrlib.branch import BzrBranch
+        self.assertRaises(NotBranchError, Branch.open, 'invalid', [BzrBranch])
+        self.assertRaises(NotBranchError, Branch.open, 'foo', [BzrBranch])
+        self.failUnless(isinstance(Branch.open('foo', [self.BarBranch]), self.BarBranch))
+       
+    def test_non_exception_passthru(self):
+        """test that any non-NotBranchError exception gets thru"""
+        self.assertRaises(self.FooError, Branch.open, 'invalid', [self.FooBranch])
+        self.assertRaises(self.FooError, Branch.open, 'invalid')
+        self.assertRaises(NotBranchError, Branch.open, 'nonexisting')
+
+    def test_passthru(self):
+        """test that any successful branch url gets through
+        test that foreign branches get checked in the order they are registered"""
+        self.failUnless(isinstance(Branch.open('foo'), self.FooBranch))
+        self.failUnless(isinstance(Branch.open('bar'), self.BarBranch))
+

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20051209/9c520e95/attachment.pgp 


More information about the bazaar mailing list