/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 breezy/bzr/smart/bzrdir.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2018-09-22 02:38:35 UTC
  • mfrom: (7058.5.4 upload-symlin)
  • Revision ID: breezy.the.bot@gmail.com-20180922023835-wb9nczxp63jpeudb
Add symlink support to 'brz upload'.

Merged from https://code.launchpad.net/~jelmer/brz/upload-symlinks/+merge/355061

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
19
20
 
20
 
from bzrlib import branch, errors, repository, urlutils
21
 
from bzrlib.bzrdir import (
 
21
from ... import (
 
22
    bencode,
 
23
    branch,
 
24
    errors,
 
25
    repository,
 
26
    urlutils,
 
27
    )
 
28
from .. import (
 
29
    BzrProber,
 
30
    )
 
31
from ..bzrdir import (
22
32
    BzrDir,
23
33
    BzrDirFormat,
24
 
    BzrDirMetaFormat1,
 
34
    )
 
35
from ...controldir import (
25
36
    network_format_registry,
26
37
    )
27
 
from bzrlib.smart.request import (
 
38
from ...sixish import PY3
 
39
from .request import (
28
40
    FailedSmartServerResponse,
29
41
    SmartServerRequest,
30
42
    SuccessfulSmartServerResponse,
42
54
            # Ideally we'd return a FailedSmartServerResponse here rather than
43
55
            # a "successful" negative, but we want to be compatibile with
44
56
            # clients that don't anticipate errors from this method.
45
 
            answer = 'no'
 
57
            answer = b'no'
46
58
        else:
47
 
            default_format = BzrDirFormat.get_default_format()
48
 
            real_bzrdir = default_format.open(t, _found=True)
 
59
            bzr_prober = BzrProber()
49
60
            try:
50
 
                real_bzrdir._format.probe_transport(t)
 
61
                bzr_prober.probe_transport(t)
51
62
            except (errors.NotBranchError, errors.UnknownFormatError):
52
 
                answer = 'no'
 
63
                answer = b'no'
53
64
            else:
54
 
                answer = 'yes'
 
65
                answer = b'yes'
55
66
        return SuccessfulSmartServerResponse((answer,))
56
67
 
57
68
 
67
78
        except errors.PathNotChild:
68
79
            # The client is trying to ask about a path that they have no access
69
80
            # to.
70
 
            return SuccessfulSmartServerResponse(('no',))
 
81
            return SuccessfulSmartServerResponse((b'no',))
71
82
        try:
72
83
            bd = BzrDir.open_from_transport(t)
73
84
        except errors.NotBranchError:
74
 
            answer = ('no',)
 
85
            answer = (b'no',)
75
86
        else:
76
 
            answer = ('yes',)
 
87
            answer = (b'yes',)
77
88
            if bd.has_workingtree():
78
 
                answer += ('yes',)
 
89
                answer += (b'yes',)
79
90
            else:
80
 
                answer += ('no',)
 
91
                answer += (b'no',)
81
92
        return SuccessfulSmartServerResponse(answer)
82
93
 
83
94
 
84
95
class SmartServerRequestBzrDir(SmartServerRequest):
85
96
 
86
97
    def do(self, path, *args):
87
 
        """Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
 
98
        """Open a BzrDir at path, and return `self.do_bzrdir_request(*args)`."""
88
99
        try:
89
100
            self._bzrdir = BzrDir.open_from_transport(
90
101
                self.transport_from_client_path(path))
91
 
        except errors.NotBranchError, e:
92
 
            return FailedSmartServerResponse(('nobranch',))
 
102
        except errors.NotBranchError as e:
 
103
            return FailedSmartServerResponse((b'nobranch',))
93
104
        return self.do_bzrdir_request(*args)
94
105
 
95
106
    def _boolean_to_yes_no(self, a_boolean):
96
107
        if a_boolean:
97
 
            return 'yes'
 
108
            return b'yes'
98
109
        else:
99
 
            return 'no'
 
110
            return b'no'
100
111
 
101
112
    def _format_to_capabilities(self, repo_format):
102
113
        rich_root = self._boolean_to_yes_no(repo_format.rich_root_data)
119
130
        return '/'.join(segments)
120
131
 
121
132
 
 
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
 
122
181
class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
123
182
 
124
183
    def do_bzrdir_request(self, require_stacking):
140
199
            # The server shouldn't try to resolve references, and it quite
141
200
            # possibly can't reach them anyway.  The client needs to resolve
142
201
            # the branch reference to determine the cloning_metadir.
143
 
            return FailedSmartServerResponse(('BranchReference',))
144
 
        if require_stacking == "True":
 
202
            return FailedSmartServerResponse((b'BranchReference',))
 
203
        if require_stacking == b"True":
145
204
            require_stacking = True
146
205
        else:
147
206
            require_stacking = False
148
207
        control_format = self._bzrdir.cloning_metadir(
149
208
            require_stacking=require_stacking)
150
209
        control_name = control_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',
 
210
        if not control_format.fixed_components:
 
211
            branch_name = (b'branch',
155
212
                control_format.get_branch_format().network_name())
156
213
            repository_name = control_format.repository_format.network_name()
157
214
        else:
158
215
            # Only MetaDir has delegated formats today.
159
 
            branch_name = ('branch', '')
160
 
            repository_name = ''
 
216
            branch_name = (b'branch', b'')
 
217
            repository_name = b''
161
218
        return SuccessfulSmartServerResponse((control_name, repository_name,
162
219
            branch_name))
163
220
 
164
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))
 
255
 
 
256
 
165
257
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
166
258
 
167
259
    def do(self, path, network_name):
179
271
 
180
272
        :param path: The path to the bzrdir.
181
273
        :param network_name: The network name of the branch type to create.
182
 
        :return: (ok, network_name)
 
274
        :return: ('ok', branch_format, repo_path, rich_root, tree_ref,
 
275
            external_lookup, repo_format)
183
276
        """
184
277
        bzrdir = BzrDir.open_from_transport(
185
278
            self.transport_from_client_path(path))
186
279
        format = branch.network_format_registry.get(network_name)
187
280
        bzrdir.branch_format = format
188
 
        result = format.initialize(bzrdir)
 
281
        result = format.initialize(bzrdir, name="")
189
282
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
190
283
            result.repository._format)
191
284
        branch_format = result._format.network_name()
194
287
            result.repository)
195
288
        # branch format, repo relpath, rich_root, tree_ref, external_lookup,
196
289
        # repo_network_name
197
 
        return SuccessfulSmartServerResponse(('ok', branch_format, repo_path,
 
290
        return SuccessfulSmartServerResponse((b'ok', branch_format, repo_path,
198
291
            rich_root, tree_ref, external_lookup, repo_format))
199
292
 
200
293
 
221
314
        """
222
315
        bzrdir = BzrDir.open_from_transport(
223
316
            self.transport_from_client_path(path))
224
 
        shared = shared == 'True'
 
317
        shared = shared == b'True'
225
318
        format = repository.network_format_registry.get(network_name)
226
319
        bzrdir.repository_format = format
227
320
        result = format.initialize(bzrdir, shared=shared)
228
321
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
229
322
            result._format)
230
 
        return SuccessfulSmartServerResponse(('ok', rich_root, tree_ref,
 
323
        return SuccessfulSmartServerResponse((b'ok', rich_root, tree_ref,
231
324
            external_lookup, result._format.network_name()))
232
325
 
233
326
 
273
366
        """
274
367
        try:
275
368
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
276
 
            return SuccessfulSmartServerResponse(('ok', path, rich_root, tree_ref))
 
369
            return SuccessfulSmartServerResponse((b'ok', path.encode('utf-8'), rich_root, tree_ref))
277
370
        except errors.NoRepositoryPresent:
278
 
            return FailedSmartServerResponse(('norepository', ))
 
371
            return FailedSmartServerResponse((b'norepository', ))
279
372
 
280
373
 
281
374
class SmartServerRequestFindRepositoryV2(SmartServerRequestFindRepository):
298
391
        try:
299
392
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
300
393
            return SuccessfulSmartServerResponse(
301
 
                ('ok', path, rich_root, tree_ref, external_lookup))
 
394
                (b'ok', path.encode('utf-8'), rich_root, tree_ref, external_lookup))
302
395
        except errors.NoRepositoryPresent:
303
 
            return FailedSmartServerResponse(('norepository', ))
 
396
            return FailedSmartServerResponse((b'norepository', ))
304
397
 
305
398
 
306
399
class SmartServerRequestFindRepositoryV3(SmartServerRequestFindRepository):
322
415
        try:
323
416
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
324
417
            return SuccessfulSmartServerResponse(
325
 
                ('ok', path, rich_root, tree_ref, external_lookup, name))
 
418
                (b'ok', path.encode('utf-8'), rich_root, tree_ref, external_lookup, name))
326
419
        except errors.NoRepositoryPresent:
327
 
            return FailedSmartServerResponse(('norepository', ))
 
420
            return FailedSmartServerResponse((b'norepository', ))
328
421
 
329
422
 
330
423
class SmartServerBzrDirRequestConfigFile(SmartServerRequestBzrDir):
331
424
 
332
425
    def do_bzrdir_request(self):
333
426
        """Get the configuration bytes for a config file in bzrdir.
334
 
        
 
427
 
335
428
        The body is not utf8 decoded - it is the literal bytestream from disk.
336
429
        """
337
430
        config = self._bzrdir._get_config()
338
431
        if config is None:
339
 
            content = ''
 
432
            content = b''
340
433
        else:
341
434
            content = config._get_config_file().read()
342
435
        return SuccessfulSmartServerResponse((), content)
343
436
 
344
437
 
 
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
        branches = self._bzrdir.get_branches()
 
447
        ret = {}
 
448
        for name, b in branches.items():
 
449
            if name is None:
 
450
                name = b""
 
451
            ret[name.encode('utf-8')] = (b"branch", b._format.network_name())
 
452
        return SuccessfulSmartServerResponse(
 
453
            (b"success", ), bencode.bencode(ret))
 
454
 
 
455
 
345
456
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
346
457
 
347
458
    def do(self, path):
352
463
        """
353
464
        target_transport = self.transport_from_client_path(path)
354
465
        BzrDirFormat.get_default_format().initialize_on_transport(target_transport)
355
 
        return SuccessfulSmartServerResponse(('ok', ))
 
466
        return SuccessfulSmartServerResponse((b'ok', ))
356
467
 
357
468
 
358
469
class SmartServerRequestBzrDirInitializeEx(SmartServerRequestBzrDir):
360
471
    def parse_NoneTrueFalse(self, arg):
361
472
        if not arg:
362
473
            return None
363
 
        if arg == 'False':
 
474
        if arg == b'False':
364
475
            return False
365
 
        if arg == 'True':
 
476
        if arg == b'True':
366
477
            return True
367
478
        raise AssertionError("invalid arg %r" % arg)
368
479
 
 
480
    def parse_NoneBytestring(self, arg):
 
481
        return arg or None
 
482
 
369
483
    def parse_NoneString(self, arg):
370
 
        return arg or None
 
484
        if not arg:
 
485
            return None
 
486
        if PY3:
 
487
            return arg.decode('utf-8')
 
488
        else:
 
489
            return arg
371
490
 
372
491
    def _serialize_NoneTrueFalse(self, arg):
373
492
        if arg is False:
374
 
            return 'False'
 
493
            return b'False'
375
494
        if not arg:
376
 
            return ''
377
 
        return 'True'
 
495
            return b''
 
496
        return b'True'
378
497
 
379
498
    def do(self, bzrdir_network_name, path, use_existing_dir, create_prefix,
380
499
        force_new_repo, stacked_on, stack_on_pwd, repo_format_name,
399
518
        stack_on_pwd = self.parse_NoneString(stack_on_pwd)
400
519
        make_working_trees = self.parse_NoneTrueFalse(make_working_trees)
401
520
        shared_repo = self.parse_NoneTrueFalse(shared_repo)
402
 
        if stack_on_pwd == '.':
403
 
            stack_on_pwd = target_transport.base
404
 
        repo_format_name = self.parse_NoneString(repo_format_name)
 
521
        if stack_on_pwd == b'.':
 
522
            stack_on_pwd = target_transport.base.encode('utf-8')
 
523
        repo_format_name = self.parse_NoneBytestring(repo_format_name)
405
524
        repo, bzrdir, stacking, repository_policy = \
406
525
            format.initialize_on_transport_ex(target_transport,
407
526
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
410
529
            make_working_trees=make_working_trees, shared_repo=shared_repo)
411
530
        if repo is None:
412
531
            repo_path = ''
413
 
            repo_name = ''
414
 
            rich_root = tree_ref = external_lookup = ''
415
 
            repo_bzrdir_name = ''
 
532
            repo_name = b''
 
533
            rich_root = tree_ref = external_lookup = b''
 
534
            repo_bzrdir_name = b''
416
535
            final_stack = None
417
536
            final_stack_pwd = None
418
 
            repo_lock_token = ''
 
537
            repo_lock_token = b''
419
538
        else:
420
539
            repo_path = self._repo_relpath(bzrdir.root_transport, repo)
421
540
            if repo_path == '':
423
542
            rich_root, tree_ref, external_lookup = self._format_to_capabilities(
424
543
                repo._format)
425
544
            repo_name = repo._format.network_name()
426
 
            repo_bzrdir_name = repo.bzrdir._format.network_name()
 
545
            repo_bzrdir_name = repo.controldir._format.network_name()
427
546
            final_stack = repository_policy._stack_on
428
547
            final_stack_pwd = repository_policy._stack_on_pwd
429
548
            # It is returned locked, but we need to do the lock to get the lock
430
549
            # token.
431
550
            repo.unlock()
432
 
            repo_lock_token = repo.lock_write() or ''
 
551
            repo_lock_token = repo.lock_write().repository_token or b''
433
552
            if repo_lock_token:
434
553
                repo.leave_lock_in_place()
435
554
            repo.unlock()
448
567
                self._root_client_path, client_path)
449
568
            final_stack_pwd = '.'
450
569
 
451
 
        return SuccessfulSmartServerResponse((repo_path, rich_root, tree_ref,
452
 
            external_lookup, repo_name, repo_bzrdir_name,
 
570
        return SuccessfulSmartServerResponse((repo_path.encode('utf-8'),
 
571
            rich_root, tree_ref, external_lookup, repo_name, repo_bzrdir_name,
453
572
            bzrdir._format.network_name(),
454
 
            self._serialize_NoneTrueFalse(stacking), final_stack,
455
 
            final_stack_pwd, repo_lock_token))
 
573
            self._serialize_NoneTrueFalse(stacking), final_stack.encode('utf-8'),
 
574
            final_stack_pwd.encode('utf-8'), repo_lock_token))
456
575
 
457
576
 
458
577
class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
462
581
        try:
463
582
            reference_url = self._bzrdir.get_branch_reference()
464
583
            if reference_url is None:
465
 
                return SuccessfulSmartServerResponse(('ok', ''))
466
 
            else:
467
 
                return SuccessfulSmartServerResponse(('ok', reference_url))
468
 
        except errors.NotBranchError, e:
469
 
            return FailedSmartServerResponse(('nobranch',))
 
584
                reference_url = ''
 
585
            return SuccessfulSmartServerResponse((b'ok', reference_url.encode('utf-8')))
 
586
        except errors.NotBranchError as e:
 
587
            return FailedSmartServerResponse((b'nobranch',))
470
588
 
471
589
 
472
590
class SmartServerRequestOpenBranchV2(SmartServerRequestBzrDir):
478
596
            if reference_url is None:
479
597
                br = self._bzrdir.open_branch(ignore_fallbacks=True)
480
598
                format = br._format.network_name()
481
 
                return SuccessfulSmartServerResponse(('branch', format))
 
599
                return SuccessfulSmartServerResponse((b'branch', format))
482
600
            else:
483
 
                return SuccessfulSmartServerResponse(('ref', reference_url))
484
 
        except errors.NotBranchError, e:
485
 
            return FailedSmartServerResponse(('nobranch',))
 
601
                return SuccessfulSmartServerResponse((b'ref', reference_url.encode('utf-8')))
 
602
        except errors.NotBranchError as e:
 
603
            return FailedSmartServerResponse((b'nobranch',))
486
604
 
487
605
 
488
606
class SmartServerRequestOpenBranchV3(SmartServerRequestBzrDir):
502
620
            if reference_url is None:
503
621
                br = self._bzrdir.open_branch(ignore_fallbacks=True)
504
622
                format = br._format.network_name()
505
 
                return SuccessfulSmartServerResponse(('branch', format))
 
623
                return SuccessfulSmartServerResponse((b'branch', format))
506
624
            else:
507
 
                return SuccessfulSmartServerResponse(('ref', reference_url))
508
 
        except errors.NotBranchError, e:
 
625
                return SuccessfulSmartServerResponse((b'ref', reference_url.encode('utf-8')))
 
626
        except errors.NotBranchError as e:
509
627
            # Stringify the exception so that its .detail attribute will be
510
628
            # filled out.
511
629
            str(e)
512
 
            resp = ('nobranch',)
 
630
            resp = (b'nobranch',)
513
631
            detail = e.detail
514
632
            if detail:
515
633
                if detail.startswith(': '):
516
634
                    detail = detail[2:]
517
 
                resp += (detail,)
 
635
                resp += (detail.encode('utf-8'),)
518
636
            return FailedSmartServerResponse(resp)
519
637