/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/smart/bzrdir.py

  • Committer: Marius Kruger
  • Date: 2010-07-10 21:28:56 UTC
  • mto: (5384.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5385.
  • Revision ID: marius.kruger@enerweb.co.za-20100710212856-uq4ji3go0u5se7hx
* Update documentation
* add NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Server-side bzrdir related request implmentations."""
18
18
 
19
 
from __future__ import absolute_import
20
19
 
21
 
from ... import (
22
 
    bencode,
23
 
    branch,
24
 
    errors,
25
 
    repository,
26
 
    urlutils,
27
 
    )
28
 
from .. import (
29
 
    BzrProber,
30
 
    )
31
 
from ..bzrdir import (
 
20
from bzrlib import branch, errors, repository, urlutils
 
21
from bzrlib.bzrdir import (
32
22
    BzrDir,
33
23
    BzrDirFormat,
34
 
    )
35
 
from ...controldir import (
 
24
    BzrDirMetaFormat1,
36
25
    network_format_registry,
37
26
    )
38
 
from ...sixish import PY3
39
 
from .request import (
 
27
from bzrlib.smart.request import (
40
28
    FailedSmartServerResponse,
41
29
    SmartServerRequest,
42
30
    SuccessfulSmartServerResponse,
54
42
            # Ideally we'd return a FailedSmartServerResponse here rather than
55
43
            # a "successful" negative, but we want to be compatibile with
56
44
            # clients that don't anticipate errors from this method.
57
 
            answer = b'no'
 
45
            answer = 'no'
58
46
        else:
59
 
            bzr_prober = BzrProber()
 
47
            default_format = BzrDirFormat.get_default_format()
 
48
            real_bzrdir = default_format.open(t, _found=True)
60
49
            try:
61
 
                bzr_prober.probe_transport(t)
 
50
                real_bzrdir._format.probe_transport(t)
62
51
            except (errors.NotBranchError, errors.UnknownFormatError):
63
 
                answer = b'no'
 
52
                answer = 'no'
64
53
            else:
65
 
                answer = b'yes'
 
54
                answer = 'yes'
66
55
        return SuccessfulSmartServerResponse((answer,))
67
56
 
68
57
 
78
67
        except errors.PathNotChild:
79
68
            # The client is trying to ask about a path that they have no access
80
69
            # to.
81
 
            return SuccessfulSmartServerResponse((b'no',))
 
70
            return SuccessfulSmartServerResponse(('no',))
82
71
        try:
83
72
            bd = BzrDir.open_from_transport(t)
84
73
        except errors.NotBranchError:
85
 
            answer = (b'no',)
 
74
            answer = ('no',)
86
75
        else:
87
 
            answer = (b'yes',)
 
76
            answer = ('yes',)
88
77
            if bd.has_workingtree():
89
 
                answer += (b'yes',)
 
78
                answer += ('yes',)
90
79
            else:
91
 
                answer += (b'no',)
 
80
                answer += ('no',)
92
81
        return SuccessfulSmartServerResponse(answer)
93
82
 
94
83
 
95
84
class SmartServerRequestBzrDir(SmartServerRequest):
96
85
 
97
86
    def do(self, path, *args):
98
 
        """Open a BzrDir at path, and return `self.do_bzrdir_request(*args)`."""
 
87
        """Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
99
88
        try:
100
89
            self._bzrdir = BzrDir.open_from_transport(
101
90
                self.transport_from_client_path(path))
102
 
        except errors.NotBranchError as e:
103
 
            return FailedSmartServerResponse((b'nobranch',))
 
91
        except errors.NotBranchError, e:
 
92
            return FailedSmartServerResponse(('nobranch',))
104
93
        return self.do_bzrdir_request(*args)
105
94
 
106
95
    def _boolean_to_yes_no(self, a_boolean):
107
96
        if a_boolean:
108
 
            return b'yes'
 
97
            return 'yes'
109
98
        else:
110
 
            return b'no'
 
99
            return 'no'
111
100
 
112
101
    def _format_to_capabilities(self, repo_format):
113
102
        rich_root = self._boolean_to_yes_no(repo_format.rich_root_data)
130
119
        return '/'.join(segments)
131
120
 
132
121
 
133
 
class SmartServerBzrDirRequestDestroyBranch(SmartServerRequestBzrDir):
134
 
 
135
 
    def do_bzrdir_request(self, name=None):
136
 
        """Destroy the branch with the specified name.
137
 
 
138
 
        New in 2.5.0.
139
 
        :return: On success, 'ok'.
140
 
        """
141
 
        try:
142
 
            self._bzrdir.destroy_branch(
143
 
                name.decode('utf-8') if name is not None else None)
144
 
        except errors.NotBranchError as e:
145
 
            return FailedSmartServerResponse((b'nobranch',))
146
 
        return SuccessfulSmartServerResponse((b'ok',))
147
 
 
148
 
 
149
 
class SmartServerBzrDirRequestHasWorkingTree(SmartServerRequestBzrDir):
150
 
 
151
 
    def do_bzrdir_request(self, name=None):
152
 
        """Check whether there is a working tree present.
153
 
 
154
 
        New in 2.5.0.
155
 
 
156
 
        :return: If there is a working tree present, 'yes'.
157
 
            Otherwise 'no'.
158
 
        """
159
 
        if self._bzrdir.has_workingtree():
160
 
            return SuccessfulSmartServerResponse((b'yes', ))
161
 
        else:
162
 
            return SuccessfulSmartServerResponse((b'no', ))
163
 
 
164
 
 
165
 
class SmartServerBzrDirRequestDestroyRepository(SmartServerRequestBzrDir):
166
 
 
167
 
    def do_bzrdir_request(self, name=None):
168
 
        """Destroy the repository.
169
 
 
170
 
        New in 2.5.0.
171
 
 
172
 
        :return: On success, 'ok'.
173
 
        """
174
 
        try:
175
 
            self._bzrdir.destroy_repository()
176
 
        except errors.NoRepositoryPresent as e:
177
 
            return FailedSmartServerResponse((b'norepository',))
178
 
        return SuccessfulSmartServerResponse((b'ok',))
179
 
 
180
 
 
181
122
class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
182
123
 
183
124
    def do_bzrdir_request(self, require_stacking):
184
125
        """Get the format that should be used when cloning from this dir.
185
126
 
186
127
        New in 1.13.
187
 
 
 
128
        
188
129
        :return: on success, a 3-tuple of network names for (control,
189
130
            repository, branch) directories, where '' signifies "not present".
190
131
            If this BzrDir contains a branch reference then this will fail with
199
140
            # The server shouldn't try to resolve references, and it quite
200
141
            # possibly can't reach them anyway.  The client needs to resolve
201
142
            # the branch reference to determine the cloning_metadir.
202
 
            return FailedSmartServerResponse((b'BranchReference',))
203
 
        if require_stacking == b"True":
 
143
            return FailedSmartServerResponse(('BranchReference',))
 
144
        if require_stacking == "True":
204
145
            require_stacking = True
205
146
        else:
206
147
            require_stacking = False
207
148
        control_format = self._bzrdir.cloning_metadir(
208
149
            require_stacking=require_stacking)
209
150
        control_name = control_format.network_name()
210
 
        if not control_format.fixed_components:
211
 
            branch_name = (b'branch',
212
 
                           control_format.get_branch_format().network_name())
 
151
        # XXX: There should be a method that tells us that the format does/does
 
152
        # not have subformats.
 
153
        if isinstance(control_format, BzrDirMetaFormat1):
 
154
            branch_name = ('branch',
 
155
                control_format.get_branch_format().network_name())
213
156
            repository_name = control_format.repository_format.network_name()
214
157
        else:
215
158
            # Only MetaDir has delegated formats today.
216
 
            branch_name = (b'branch', b'')
217
 
            repository_name = b''
 
159
            branch_name = ('branch', '')
 
160
            repository_name = ''
218
161
        return SuccessfulSmartServerResponse((control_name, repository_name,
219
 
                                              branch_name))
220
 
 
221
 
 
222
 
class SmartServerBzrDirRequestCheckoutMetaDir(SmartServerRequestBzrDir):
223
 
    """Get the format to use for checkouts.
224
 
 
225
 
    New in 2.5.
226
 
 
227
 
    :return: on success, a 3-tuple of network names for (control,
228
 
        repository, branch) directories, where '' signifies "not present".
229
 
        If this BzrDir contains a branch reference then this will fail with
230
 
        BranchReference; clients should resolve branch references before
231
 
        calling this RPC (they should not try to create a checkout of a
232
 
        checkout).
233
 
    """
234
 
 
235
 
    def do_bzrdir_request(self):
236
 
        try:
237
 
            branch_ref = self._bzrdir.get_branch_reference()
238
 
        except errors.NotBranchError:
239
 
            branch_ref = None
240
 
        if branch_ref is not None:
241
 
            # The server shouldn't try to resolve references, and it quite
242
 
            # possibly can't reach them anyway.  The client needs to resolve
243
 
            # the branch reference to determine the cloning_metadir.
244
 
            return FailedSmartServerResponse((b'BranchReference',))
245
 
        control_format = self._bzrdir.checkout_metadir()
246
 
        control_name = control_format.network_name()
247
 
        if not control_format.fixed_components:
248
 
            branch_name = control_format.get_branch_format().network_name()
249
 
            repo_name = control_format.repository_format.network_name()
250
 
        else:
251
 
            branch_name = b''
252
 
            repo_name = b''
253
 
        return SuccessfulSmartServerResponse(
254
 
            (control_name, repo_name, branch_name))
 
162
            branch_name))
255
163
 
256
164
 
257
165
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
271
179
 
272
180
        :param path: The path to the bzrdir.
273
181
        :param network_name: The network name of the branch type to create.
274
 
        :return: ('ok', branch_format, repo_path, rich_root, tree_ref,
275
 
            external_lookup, repo_format)
 
182
        :return: (ok, network_name)
276
183
        """
277
184
        bzrdir = BzrDir.open_from_transport(
278
185
            self.transport_from_client_path(path))
279
186
        format = branch.network_format_registry.get(network_name)
280
187
        bzrdir.branch_format = format
281
 
        result = format.initialize(bzrdir, name="")
 
188
        result = format.initialize(bzrdir)
282
189
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
283
190
            result.repository._format)
284
191
        branch_format = result._format.network_name()
285
192
        repo_format = result.repository._format.network_name()
286
193
        repo_path = self._repo_relpath(bzrdir.root_transport,
287
 
                                       result.repository)
 
194
            result.repository)
288
195
        # branch format, repo relpath, rich_root, tree_ref, external_lookup,
289
196
        # repo_network_name
290
 
        return SuccessfulSmartServerResponse((b'ok', branch_format, repo_path,
291
 
                                              rich_root, tree_ref, external_lookup, repo_format))
 
197
        return SuccessfulSmartServerResponse(('ok', branch_format, repo_path,
 
198
            rich_root, tree_ref, external_lookup, repo_format))
292
199
 
293
200
 
294
201
class SmartServerRequestCreateRepository(SmartServerRequestBzrDir):
314
221
        """
315
222
        bzrdir = BzrDir.open_from_transport(
316
223
            self.transport_from_client_path(path))
317
 
        shared = shared == b'True'
 
224
        shared = shared == 'True'
318
225
        format = repository.network_format_registry.get(network_name)
319
226
        bzrdir.repository_format = format
320
227
        result = format.initialize(bzrdir, shared=shared)
321
228
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
322
229
            result._format)
323
 
        return SuccessfulSmartServerResponse((b'ok', rich_root, tree_ref,
324
 
                                              external_lookup, result._format.network_name()))
 
230
        return SuccessfulSmartServerResponse(('ok', rich_root, tree_ref,
 
231
            external_lookup, result._format.network_name()))
325
232
 
326
233
 
327
234
class SmartServerRequestFindRepository(SmartServerRequestBzrDir):
366
273
        """
367
274
        try:
368
275
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
369
 
            return SuccessfulSmartServerResponse((b'ok', path.encode('utf-8'), rich_root, tree_ref))
 
276
            return SuccessfulSmartServerResponse(('ok', path, rich_root, tree_ref))
370
277
        except errors.NoRepositoryPresent:
371
 
            return FailedSmartServerResponse((b'norepository', ))
 
278
            return FailedSmartServerResponse(('norepository', ))
372
279
 
373
280
 
374
281
class SmartServerRequestFindRepositoryV2(SmartServerRequestFindRepository):
391
298
        try:
392
299
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
393
300
            return SuccessfulSmartServerResponse(
394
 
                (b'ok', path.encode('utf-8'), rich_root, tree_ref, external_lookup))
 
301
                ('ok', path, rich_root, tree_ref, external_lookup))
395
302
        except errors.NoRepositoryPresent:
396
 
            return FailedSmartServerResponse((b'norepository', ))
 
303
            return FailedSmartServerResponse(('norepository', ))
397
304
 
398
305
 
399
306
class SmartServerRequestFindRepositoryV3(SmartServerRequestFindRepository):
415
322
        try:
416
323
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
417
324
            return SuccessfulSmartServerResponse(
418
 
                (b'ok', path.encode('utf-8'), rich_root, tree_ref, external_lookup, name))
 
325
                ('ok', path, rich_root, tree_ref, external_lookup, name))
419
326
        except errors.NoRepositoryPresent:
420
 
            return FailedSmartServerResponse((b'norepository', ))
 
327
            return FailedSmartServerResponse(('norepository', ))
421
328
 
422
329
 
423
330
class SmartServerBzrDirRequestConfigFile(SmartServerRequestBzrDir):
424
331
 
425
332
    def do_bzrdir_request(self):
426
333
        """Get the configuration bytes for a config file in bzrdir.
427
 
 
 
334
        
428
335
        The body is not utf8 decoded - it is the literal bytestream from disk.
429
336
        """
430
337
        config = self._bzrdir._get_config()
431
338
        if config is None:
432
 
            content = b''
 
339
            content = ''
433
340
        else:
434
341
            content = config._get_config_file().read()
435
342
        return SuccessfulSmartServerResponse((), content)
436
343
 
437
344
 
438
 
class SmartServerBzrDirRequestGetBranches(SmartServerRequestBzrDir):
439
 
 
440
 
    def do_bzrdir_request(self):
441
 
        """Get the branches in a control directory.
442
 
 
443
 
        The body is a bencoded dictionary, with values similar to the return
444
 
        value of the open branch request.
445
 
        """
446
 
        branch_names = self._bzrdir.branch_names()
447
 
        ret = {}
448
 
        for name in branch_names:
449
 
            if name is None:
450
 
                name = b""
451
 
            branch_ref = self._bzrdir.get_branch_reference(name=name)
452
 
            if branch_ref is not None:
453
 
                branch_ref = urlutils.relative_url(self._bzrdir.user_url, branch_ref)
454
 
                value = (b"ref", branch_ref.encode('utf-8'))
455
 
            else:
456
 
                b = self._bzrdir.open_branch(name=name, ignore_fallbacks=True)
457
 
                value = (b"branch", b._format.network_name())
458
 
            ret[name.encode('utf-8')] = value
459
 
        return SuccessfulSmartServerResponse(
460
 
            (b"success", ), bencode.bencode(ret))
461
 
 
462
 
 
463
345
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
464
346
 
465
347
    def do(self, path):
470
352
        """
471
353
        target_transport = self.transport_from_client_path(path)
472
354
        BzrDirFormat.get_default_format().initialize_on_transport(target_transport)
473
 
        return SuccessfulSmartServerResponse((b'ok', ))
 
355
        return SuccessfulSmartServerResponse(('ok', ))
474
356
 
475
357
 
476
358
class SmartServerRequestBzrDirInitializeEx(SmartServerRequestBzrDir):
478
360
    def parse_NoneTrueFalse(self, arg):
479
361
        if not arg:
480
362
            return None
481
 
        if arg == b'False':
 
363
        if arg == 'False':
482
364
            return False
483
 
        if arg == b'True':
 
365
        if arg == 'True':
484
366
            return True
485
367
        raise AssertionError("invalid arg %r" % arg)
486
368
 
487
 
    def parse_NoneBytestring(self, arg):
 
369
    def parse_NoneString(self, arg):
488
370
        return arg or None
489
371
 
490
 
    def parse_NoneString(self, arg):
491
 
        if not arg:
492
 
            return None
493
 
        if PY3:
494
 
            return arg.decode('utf-8')
495
 
        else:
496
 
            return arg
497
 
 
498
372
    def _serialize_NoneTrueFalse(self, arg):
499
373
        if arg is False:
500
 
            return b'False'
 
374
            return 'False'
501
375
        if not arg:
502
 
            return b''
503
 
        return b'True'
 
376
            return ''
 
377
        return 'True'
504
378
 
505
379
    def do(self, bzrdir_network_name, path, use_existing_dir, create_prefix,
506
 
           force_new_repo, stacked_on, stack_on_pwd, repo_format_name,
507
 
           make_working_trees, shared_repo):
 
380
        force_new_repo, stacked_on, stack_on_pwd, repo_format_name,
 
381
        make_working_trees, shared_repo):
508
382
        """Initialize a bzrdir at path as per
509
383
        BzrDirFormat.initialize_on_transport_ex.
510
384
 
525
399
        stack_on_pwd = self.parse_NoneString(stack_on_pwd)
526
400
        make_working_trees = self.parse_NoneTrueFalse(make_working_trees)
527
401
        shared_repo = self.parse_NoneTrueFalse(shared_repo)
528
 
        if stack_on_pwd == b'.':
529
 
            stack_on_pwd = target_transport.base.encode('utf-8')
530
 
        repo_format_name = self.parse_NoneBytestring(repo_format_name)
 
402
        if stack_on_pwd == '.':
 
403
            stack_on_pwd = target_transport.base
 
404
        repo_format_name = self.parse_NoneString(repo_format_name)
531
405
        repo, bzrdir, stacking, repository_policy = \
532
406
            format.initialize_on_transport_ex(target_transport,
533
 
                                              use_existing_dir=use_existing_dir, create_prefix=create_prefix,
534
 
                                              force_new_repo=force_new_repo, stacked_on=stacked_on,
535
 
                                              stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
536
 
                                              make_working_trees=make_working_trees, shared_repo=shared_repo)
 
407
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
408
            force_new_repo=force_new_repo, stacked_on=stacked_on,
 
409
            stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
410
            make_working_trees=make_working_trees, shared_repo=shared_repo)
537
411
        if repo is None:
538
412
            repo_path = ''
539
 
            repo_name = b''
540
 
            rich_root = tree_ref = external_lookup = b''
541
 
            repo_bzrdir_name = b''
 
413
            repo_name = ''
 
414
            rich_root = tree_ref = external_lookup = ''
 
415
            repo_bzrdir_name = ''
542
416
            final_stack = None
543
417
            final_stack_pwd = None
544
 
            repo_lock_token = b''
 
418
            repo_lock_token = ''
545
419
        else:
546
420
            repo_path = self._repo_relpath(bzrdir.root_transport, repo)
547
421
            if repo_path == '':
549
423
            rich_root, tree_ref, external_lookup = self._format_to_capabilities(
550
424
                repo._format)
551
425
            repo_name = repo._format.network_name()
552
 
            repo_bzrdir_name = repo.controldir._format.network_name()
 
426
            repo_bzrdir_name = repo.bzrdir._format.network_name()
553
427
            final_stack = repository_policy._stack_on
554
428
            final_stack_pwd = repository_policy._stack_on_pwd
555
429
            # It is returned locked, but we need to do the lock to get the lock
556
430
            # token.
557
431
            repo.unlock()
558
 
            repo_lock_token = repo.lock_write().repository_token or b''
 
432
            repo_lock_token = repo.lock_write().repository_token or ''
559
433
            if repo_lock_token:
560
434
                repo.leave_lock_in_place()
561
435
            repo.unlock()
574
448
                self._root_client_path, client_path)
575
449
            final_stack_pwd = '.'
576
450
 
577
 
        return SuccessfulSmartServerResponse((repo_path.encode('utf-8'),
578
 
                                              rich_root, tree_ref, external_lookup, repo_name, repo_bzrdir_name,
579
 
                                              bzrdir._format.network_name(),
580
 
                                              self._serialize_NoneTrueFalse(
581
 
                                                  stacking), final_stack.encode('utf-8'),
582
 
                                              final_stack_pwd.encode('utf-8'), repo_lock_token))
 
451
        return SuccessfulSmartServerResponse((repo_path, rich_root, tree_ref,
 
452
            external_lookup, repo_name, repo_bzrdir_name,
 
453
            bzrdir._format.network_name(),
 
454
            self._serialize_NoneTrueFalse(stacking), final_stack,
 
455
            final_stack_pwd, repo_lock_token))
583
456
 
584
457
 
585
458
class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
589
462
        try:
590
463
            reference_url = self._bzrdir.get_branch_reference()
591
464
            if reference_url is None:
592
 
                reference_url = ''
593
 
            return SuccessfulSmartServerResponse((b'ok', reference_url.encode('utf-8')))
594
 
        except errors.NotBranchError as e:
595
 
            return FailedSmartServerResponse((b'nobranch',))
 
465
                return SuccessfulSmartServerResponse(('ok', ''))
 
466
            else:
 
467
                return SuccessfulSmartServerResponse(('ok', reference_url))
 
468
        except errors.NotBranchError, e:
 
469
            return FailedSmartServerResponse(('nobranch',))
596
470
 
597
471
 
598
472
class SmartServerRequestOpenBranchV2(SmartServerRequestBzrDir):
604
478
            if reference_url is None:
605
479
                br = self._bzrdir.open_branch(ignore_fallbacks=True)
606
480
                format = br._format.network_name()
607
 
                return SuccessfulSmartServerResponse((b'branch', format))
 
481
                return SuccessfulSmartServerResponse(('branch', format))
608
482
            else:
609
 
                return SuccessfulSmartServerResponse((b'ref', reference_url.encode('utf-8')))
610
 
        except errors.NotBranchError as e:
611
 
            return FailedSmartServerResponse((b'nobranch',))
 
483
                return SuccessfulSmartServerResponse(('ref', reference_url))
 
484
        except errors.NotBranchError, e:
 
485
            return FailedSmartServerResponse(('nobranch',))
612
486
 
613
487
 
614
488
class SmartServerRequestOpenBranchV3(SmartServerRequestBzrDir):
615
489
 
616
490
    def do_bzrdir_request(self):
617
491
        """Open a branch at path and return the reference or format.
618
 
 
 
492
        
619
493
        This version introduced in 2.1.
620
494
 
621
495
        Differences to SmartServerRequestOpenBranchV2:
628
502
            if reference_url is None:
629
503
                br = self._bzrdir.open_branch(ignore_fallbacks=True)
630
504
                format = br._format.network_name()
631
 
                return SuccessfulSmartServerResponse((b'branch', format))
 
505
                return SuccessfulSmartServerResponse(('branch', format))
632
506
            else:
633
 
                return SuccessfulSmartServerResponse((b'ref', reference_url.encode('utf-8')))
634
 
        except errors.NotBranchError as e:
 
507
                return SuccessfulSmartServerResponse(('ref', reference_url))
 
508
        except errors.NotBranchError, e:
635
509
            # Stringify the exception so that its .detail attribute will be
636
510
            # filled out.
637
511
            str(e)
638
 
            resp = (b'nobranch',)
 
512
            resp = ('nobranch',)
639
513
            detail = e.detail
640
514
            if detail:
641
515
                if detail.startswith(': '):
642
516
                    detail = detail[2:]
643
 
                resp += (detail.encode('utf-8'),)
 
517
                resp += (detail,)
644
518
            return FailedSmartServerResponse(resp)
 
519