~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-07-22 18:09:04 UTC
  • mfrom: (2485.8.63 bzr.connection.sharing)
  • Revision ID: pqm@pqm.ubuntu.com-20070722180904-wy7y7oyi32wbghgf
Transport connection sharing

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
directories.
21
21
"""
22
22
 
23
 
# TODO: remove unittest dependency; put that stuff inside the test suite
24
 
 
25
23
# TODO: Can we move specific formats into separate modules to make this file
26
24
# smaller?
27
25
 
31
29
 
32
30
from bzrlib.lazy_import import lazy_import
33
31
lazy_import(globals(), """
34
 
from copy import deepcopy
35
32
from stat import S_ISDIR
36
 
import unittest
37
33
 
38
34
import bzrlib
39
35
from bzrlib import (
52
48
    workingtree_4,
53
49
    )
54
50
from bzrlib.osutils import (
55
 
    safe_unicode,
56
51
    sha_strings,
57
52
    sha_string,
58
53
    )
213
208
        t = get_transport(url)
214
209
        t.ensure_base()
215
210
 
216
 
    # TODO: Should take a Transport
217
211
    @classmethod
218
 
    def create(cls, base, format=None):
 
212
    def create(cls, base, format=None, possible_transports=None):
219
213
        """Create a new BzrDir at the url 'base'.
220
214
        
221
215
        This will call the current default formats initialize with base
223
217
 
224
218
        :param format: If supplied, the format of branch to create.  If not
225
219
            supplied, the default is used.
 
220
        :param possible_transports: If supplied, a list of transports that 
 
221
            can be reused to share a remote connection.
226
222
        """
227
223
        if cls is not BzrDir:
228
224
            raise AssertionError("BzrDir.create always creates the default"
229
225
                " format, not one of %r" % cls)
230
 
        t = get_transport(base)
 
226
        t = get_transport(base, possible_transports)
231
227
        t.ensure_base()
232
228
        if format is None:
233
229
            format = BzrDirFormat.get_default_format()
234
 
        return format.initialize(safe_unicode(base))
 
230
        return format.initialize(base, possible_transports)
235
231
 
236
232
    def create_branch(self):
237
233
        """Create a branch in this BzrDir.
270
266
        
271
267
    @staticmethod
272
268
    def create_branch_convenience(base, force_new_repo=False,
273
 
                                  force_new_tree=None, format=None):
 
269
                                  force_new_tree=None, format=None,
 
270
                                  possible_transports=None):
274
271
        """Create a new BzrDir, Branch and Repository at the url 'base'.
275
272
 
276
273
        This is a convenience function - it will use an existing repository
292
289
        :param force_new_repo: If True a new repository is always created.
293
290
        :param force_new_tree: If True or False force creation of a tree or 
294
291
                               prevent such creation respectively.
295
 
        :param format: Override for the for the bzrdir format to create
 
292
        :param format: Override for the for the bzrdir format to create.
 
293
        :param possible_transports: An optional reusable transports list.
296
294
        """
297
295
        if force_new_tree:
298
296
            # check for non local urls
299
 
            t = get_transport(safe_unicode(base))
 
297
            t = get_transport(base, possible_transports)
300
298
            if not isinstance(t, LocalTransport):
301
299
                raise errors.NotLocalUrl(base)
302
 
        bzrdir = BzrDir.create(base, format)
 
300
        bzrdir = BzrDir.create(base, format, possible_transports)
303
301
        repo = bzrdir._find_or_create_repository(force_new_repo)
304
302
        result = bzrdir.create_branch()
305
 
        if force_new_tree or (repo.make_working_trees() and 
 
303
        if force_new_tree or (repo.make_working_trees() and
306
304
                              force_new_tree is None):
307
305
            try:
308
306
                bzrdir.create_workingtree()
309
307
            except errors.NotLocalUrl:
310
308
                pass
311
309
        return result
312
 
        
 
310
 
313
311
    @staticmethod
314
312
    def create_repository(base, shared=False, format=None):
315
313
        """Create a new BzrDir and Repository at the url 'base'.
341
339
 
342
340
        :return: The WorkingTree object.
343
341
        """
344
 
        t = get_transport(safe_unicode(base))
 
342
        t = get_transport(base)
345
343
        if not isinstance(t, LocalTransport):
346
344
            raise errors.NotLocalUrl(base)
347
 
        bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base),
 
345
        bzrdir = BzrDir.create_branch_and_repo(base,
348
346
                                               force_new_repo=True,
349
347
                                               format=format).bzrdir
350
348
        return bzrdir.create_workingtree()
585
583
        raise NotImplementedError(self.open_branch)
586
584
 
587
585
    @staticmethod
588
 
    def open_containing(url):
 
586
    def open_containing(url, possible_transports=None):
589
587
        """Open an existing branch which contains url.
590
588
        
591
589
        :param url: url to search from.
592
590
        See open_containing_from_transport for more detail.
593
591
        """
594
 
        return BzrDir.open_containing_from_transport(get_transport(url))
 
592
        transport = get_transport(url, possible_transports)
 
593
        return BzrDir.open_containing_from_transport(transport)
595
594
    
596
595
    @staticmethod
597
596
    def open_containing_from_transport(a_transport):
747
746
        return self.cloning_metadir()
748
747
 
749
748
    def sprout(self, url, revision_id=None, force_new_repo=False,
750
 
               recurse='down'):
 
749
               recurse='down', possible_transports=None):
751
750
        """Create a copy of this bzrdir prepared for use as a new line of
752
751
        development.
753
752
 
761
760
        if revision_id is not None, then the clone operation may tune
762
761
            itself to download less data.
763
762
        """
764
 
        target_transport = get_transport(url)
 
763
        target_transport = get_transport(url, possible_transports)
765
764
        target_transport.ensure_base()
766
765
        cloning_format = self.cloning_metadir()
767
766
        result = cloning_format.initialize_on_transport(target_transport)
788
787
            result.create_repository()
789
788
        elif source_repository is not None and result_repo is None:
790
789
            # have source, and want to make a new target repo
791
 
            result_repo = source_repository.sprout(result, revision_id=revision_id)
 
790
            result_repo = source_repository.sprout(result,
 
791
                                                   revision_id=revision_id)
792
792
        else:
793
793
            # fetch needed content into target.
794
794
            if source_repository is not None:
795
795
                # would rather do 
796
 
                # source_repository.copy_content_into(result_repo, revision_id=revision_id)
 
796
                # source_repository.copy_content_into(result_repo,
 
797
                #                                     revision_id=revision_id)
797
798
                # so we can override the copy method
798
799
                result_repo.fetch(source_repository, revision_id=revision_id)
799
800
        if source_branch is not None:
800
801
            source_branch.sprout(result, revision_id=revision_id)
801
802
        else:
802
803
            result.create_branch()
803
 
        # TODO: jam 20060426 we probably need a test in here in the
804
 
        #       case that the newly sprouted branch is a remote one
805
 
        if result_repo is None or result_repo.make_working_trees():
 
804
        if isinstance(target_transport, LocalTransport) and (
 
805
            result_repo is None or result_repo.make_working_trees()):
806
806
            wt = result.create_workingtree()
807
807
            wt.lock_write()
808
808
            try:
962
962
        self._check_supported(format, unsupported)
963
963
        return format.open(self, _found=True)
964
964
 
965
 
    def sprout(self, url, revision_id=None, force_new_repo=False):
 
965
    def sprout(self, url, revision_id=None, force_new_repo=False,
 
966
               possible_transports=None):
966
967
        """See BzrDir.sprout()."""
967
968
        from bzrlib.workingtree import WorkingTreeFormat2
968
969
        self._make_tail(url)
1291
1292
        """
1292
1293
        raise NotImplementedError(self.get_converter)
1293
1294
 
1294
 
    def initialize(self, url):
 
1295
    def initialize(self, url, possible_transports=None):
1295
1296
        """Create a bzr control dir at this url and return an opened copy.
1296
1297
        
1297
1298
        Subclasses should typically override initialize_on_transport
1298
1299
        instead of this method.
1299
1300
        """
1300
 
        return self.initialize_on_transport(get_transport(url))
 
1301
        return self.initialize_on_transport(get_transport(url,
 
1302
                                                          possible_transports))
1301
1303
 
1302
1304
    def initialize_on_transport(self, transport):
1303
1305
        """Initialize a new bzrdir in the base directory of a Transport."""
1700
1702
BzrDirFormat._default_format = __default_format
1701
1703
 
1702
1704
 
1703
 
class BzrDirTestProviderAdapter(object):
1704
 
    """A tool to generate a suite testing multiple bzrdir formats at once.
1705
 
 
1706
 
    This is done by copying the test once for each transport and injecting
1707
 
    the transport_server, transport_readonly_server, and bzrdir_format
1708
 
    classes into each copy. Each copy is also given a new id() to make it
1709
 
    easy to identify.
1710
 
    """
1711
 
 
1712
 
    def __init__(self, vfs_factory, transport_server, transport_readonly_server,
1713
 
        formats):
1714
 
        """Create an object to adapt tests.
1715
 
 
1716
 
        :param vfs_server: A factory to create a Transport Server which has
1717
 
            all the VFS methods working, and is writable.
1718
 
        """
1719
 
        self._vfs_factory = vfs_factory
1720
 
        self._transport_server = transport_server
1721
 
        self._transport_readonly_server = transport_readonly_server
1722
 
        self._formats = formats
1723
 
    
1724
 
    def adapt(self, test):
1725
 
        result = unittest.TestSuite()
1726
 
        for format in self._formats:
1727
 
            new_test = deepcopy(test)
1728
 
            new_test.vfs_transport_factory = self._vfs_factory
1729
 
            new_test.transport_server = self._transport_server
1730
 
            new_test.transport_readonly_server = self._transport_readonly_server
1731
 
            new_test.bzrdir_format = format
1732
 
            def make_new_test_id():
1733
 
                new_id = "%s(%s)" % (new_test.id(), format.__class__.__name__)
1734
 
                return lambda: new_id
1735
 
            new_test.id = make_new_test_id()
1736
 
            result.addTest(new_test)
1737
 
        return result
1738
 
 
1739
 
 
1740
1705
class Converter(object):
1741
1706
    """Converts a disk format object from one format to another."""
1742
1707
 
2258
2223
    def initialize_on_transport(self, transport):
2259
2224
        try:
2260
2225
            # hand off the request to the smart server
2261
 
            medium = transport.get_smart_medium()
 
2226
            shared_medium = transport.get_shared_medium()
2262
2227
        except errors.NoSmartMedium:
2263
2228
            # TODO: lookup the local format from a server hint.
2264
2229
            local_dir_format = BzrDirMetaFormat1()
2265
2230
            return local_dir_format.initialize_on_transport(transport)
2266
 
        client = _SmartClient(medium)
 
2231
        client = _SmartClient(shared_medium)
2267
2232
        path = client.remote_path_from_transport(transport)
2268
 
        response = _SmartClient(medium).call('BzrDirFormat.initialize', path)
 
2233
        response = _SmartClient(shared_medium).call('BzrDirFormat.initialize',
 
2234
                                                    path)
2269
2235
        assert response[0] in ('ok', ), 'unexpected response code %s' % (response,)
2270
2236
        return remote.RemoteBzrDir(transport)
2271
2237