/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: Robert Collins
  • Date: 2010-05-06 11:08:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506110810-h3j07fh5gmw54s25
Cleaner matcher matching revised unlocking protocol.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Server-side bzrdir related request implmentations."""
18
18
 
19
19
 
20
 
from bzrlib import branch, errors, repository
21
 
from bzrlib.bzrdir import BzrDir, BzrDirFormat, BzrDirMetaFormat1
 
20
from bzrlib import branch, errors, repository, urlutils
 
21
from bzrlib.bzrdir import (
 
22
    BzrDir,
 
23
    BzrDirFormat,
 
24
    BzrDirMetaFormat1,
 
25
    network_format_registry,
 
26
    )
22
27
from bzrlib.smart.request import (
23
28
    FailedSmartServerResponse,
24
29
    SmartServerRequest,
29
34
class SmartServerRequestOpenBzrDir(SmartServerRequest):
30
35
 
31
36
    def do(self, path):
32
 
        from bzrlib.bzrdir import BzrDirFormat
33
37
        try:
34
38
            t = self.transport_from_client_path(path)
35
39
        except errors.PathNotChild:
51
55
        return SuccessfulSmartServerResponse((answer,))
52
56
 
53
57
 
 
58
class SmartServerRequestOpenBzrDir_2_1(SmartServerRequest):
 
59
 
 
60
    def do(self, path):
 
61
        """Is there a BzrDir present, and if so does it have a working tree?
 
62
 
 
63
        New in 2.1.
 
64
        """
 
65
        try:
 
66
            t = self.transport_from_client_path(path)
 
67
        except errors.PathNotChild:
 
68
            # The client is trying to ask about a path that they have no access
 
69
            # to.
 
70
            return SuccessfulSmartServerResponse(('no',))
 
71
        try:
 
72
            bd = BzrDir.open_from_transport(t)
 
73
        except errors.NotBranchError:
 
74
            answer = ('no',)
 
75
        else:
 
76
            answer = ('yes',)
 
77
            if bd.has_workingtree():
 
78
                answer += ('yes',)
 
79
            else:
 
80
                answer += ('no',)
 
81
        return SuccessfulSmartServerResponse(answer)
 
82
 
 
83
 
54
84
class SmartServerRequestBzrDir(SmartServerRequest):
55
85
 
56
86
    def do(self, path, *args):
58
88
        try:
59
89
            self._bzrdir = BzrDir.open_from_transport(
60
90
                self.transport_from_client_path(path))
61
 
        except errors.NotBranchError:
62
 
            return FailedSmartServerResponse(('nobranch', ))
 
91
        except errors.NotBranchError, e:
 
92
            return FailedSmartServerResponse(('nobranch',))
63
93
        return self.do_bzrdir_request(*args)
64
94
 
65
95
    def _boolean_to_yes_no(self, a_boolean):
80
110
        """Get the relative path for repository from current_transport."""
81
111
        # the relpath of the bzrdir in the found repository gives us the
82
112
        # path segments to pop-out.
83
 
        relpath = repository.bzrdir.root_transport.relpath(
 
113
        relpath = repository.user_transport.relpath(
84
114
            current_transport.base)
85
115
        if len(relpath):
86
116
            segments = ['..'] * len(relpath.split('/'))
325
355
        return SuccessfulSmartServerResponse(('ok', ))
326
356
 
327
357
 
 
358
class SmartServerRequestBzrDirInitializeEx(SmartServerRequestBzrDir):
 
359
 
 
360
    def parse_NoneTrueFalse(self, arg):
 
361
        if not arg:
 
362
            return None
 
363
        if arg == 'False':
 
364
            return False
 
365
        if arg == 'True':
 
366
            return True
 
367
        raise AssertionError("invalid arg %r" % arg)
 
368
 
 
369
    def parse_NoneString(self, arg):
 
370
        return arg or None
 
371
 
 
372
    def _serialize_NoneTrueFalse(self, arg):
 
373
        if arg is False:
 
374
            return 'False'
 
375
        if not arg:
 
376
            return ''
 
377
        return 'True'
 
378
 
 
379
    def do(self, bzrdir_network_name, path, use_existing_dir, create_prefix,
 
380
        force_new_repo, stacked_on, stack_on_pwd, repo_format_name,
 
381
        make_working_trees, shared_repo):
 
382
        """Initialize a bzrdir at path as per
 
383
        BzrDirFormat.initialize_on_transport_ex.
 
384
 
 
385
        New in 1.16.  (Replaces BzrDirFormat.initialize_ex verb from 1.15).
 
386
 
 
387
        :return: return SuccessfulSmartServerResponse((repo_path, rich_root,
 
388
            tree_ref, external_lookup, repo_network_name,
 
389
            repo_bzrdir_network_name, bzrdir_format_network_name,
 
390
            NoneTrueFalse(stacking), final_stack, final_stack_pwd,
 
391
            repo_lock_token))
 
392
        """
 
393
        target_transport = self.transport_from_client_path(path)
 
394
        format = network_format_registry.get(bzrdir_network_name)
 
395
        use_existing_dir = self.parse_NoneTrueFalse(use_existing_dir)
 
396
        create_prefix = self.parse_NoneTrueFalse(create_prefix)
 
397
        force_new_repo = self.parse_NoneTrueFalse(force_new_repo)
 
398
        stacked_on = self.parse_NoneString(stacked_on)
 
399
        stack_on_pwd = self.parse_NoneString(stack_on_pwd)
 
400
        make_working_trees = self.parse_NoneTrueFalse(make_working_trees)
 
401
        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)
 
405
        repo, bzrdir, stacking, repository_policy = \
 
406
            format.initialize_on_transport_ex(target_transport,
 
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)
 
411
        if repo is None:
 
412
            repo_path = ''
 
413
            repo_name = ''
 
414
            rich_root = tree_ref = external_lookup = ''
 
415
            repo_bzrdir_name = ''
 
416
            final_stack = None
 
417
            final_stack_pwd = None
 
418
            repo_lock_token = ''
 
419
        else:
 
420
            repo_path = self._repo_relpath(bzrdir.root_transport, repo)
 
421
            if repo_path == '':
 
422
                repo_path = '.'
 
423
            rich_root, tree_ref, external_lookup = self._format_to_capabilities(
 
424
                repo._format)
 
425
            repo_name = repo._format.network_name()
 
426
            repo_bzrdir_name = repo.bzrdir._format.network_name()
 
427
            final_stack = repository_policy._stack_on
 
428
            final_stack_pwd = repository_policy._stack_on_pwd
 
429
            # It is returned locked, but we need to do the lock to get the lock
 
430
            # token.
 
431
            repo.unlock()
 
432
            repo_lock_token = repo.lock_write() or ''
 
433
            if repo_lock_token:
 
434
                repo.leave_lock_in_place()
 
435
            repo.unlock()
 
436
        final_stack = final_stack or ''
 
437
        final_stack_pwd = final_stack_pwd or ''
 
438
 
 
439
        # We want this to be relative to the bzrdir.
 
440
        if final_stack_pwd:
 
441
            final_stack_pwd = urlutils.relative_url(
 
442
                target_transport.base, final_stack_pwd)
 
443
 
 
444
        # Can't meaningfully return a root path.
 
445
        if final_stack.startswith('/'):
 
446
            client_path = self._root_client_path + final_stack[1:]
 
447
            final_stack = urlutils.relative_url(
 
448
                self._root_client_path, client_path)
 
449
            final_stack_pwd = '.'
 
450
 
 
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))
 
456
 
 
457
 
328
458
class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
329
459
 
330
460
    def do_bzrdir_request(self):
335
465
                return SuccessfulSmartServerResponse(('ok', ''))
336
466
            else:
337
467
                return SuccessfulSmartServerResponse(('ok', reference_url))
338
 
        except errors.NotBranchError:
339
 
            return FailedSmartServerResponse(('nobranch', ))
 
468
        except errors.NotBranchError, e:
 
469
            return FailedSmartServerResponse(('nobranch',))
340
470
 
341
471
 
342
472
class SmartServerRequestOpenBranchV2(SmartServerRequestBzrDir):
351
481
                return SuccessfulSmartServerResponse(('branch', format))
352
482
            else:
353
483
                return SuccessfulSmartServerResponse(('ref', reference_url))
354
 
        except errors.NotBranchError:
355
 
            return FailedSmartServerResponse(('nobranch', ))
 
484
        except errors.NotBranchError, e:
 
485
            return FailedSmartServerResponse(('nobranch',))
 
486
 
 
487
 
 
488
class SmartServerRequestOpenBranchV3(SmartServerRequestBzrDir):
 
489
 
 
490
    def do_bzrdir_request(self):
 
491
        """Open a branch at path and return the reference or format.
 
492
        
 
493
        This version introduced in 2.1.
 
494
 
 
495
        Differences to SmartServerRequestOpenBranchV2:
 
496
          * can return 2-element ('nobranch', extra), where 'extra' is a string
 
497
            with an explanation like 'location is a repository'.  Previously
 
498
            a 'nobranch' response would never have more than one element.
 
499
        """
 
500
        try:
 
501
            reference_url = self._bzrdir.get_branch_reference()
 
502
            if reference_url is None:
 
503
                br = self._bzrdir.open_branch(ignore_fallbacks=True)
 
504
                format = br._format.network_name()
 
505
                return SuccessfulSmartServerResponse(('branch', format))
 
506
            else:
 
507
                return SuccessfulSmartServerResponse(('ref', reference_url))
 
508
        except errors.NotBranchError, e:
 
509
            # Stringify the exception so that its .detail attribute will be
 
510
            # filled out.
 
511
            str(e)
 
512
            resp = ('nobranch',)
 
513
            detail = e.detail
 
514
            if detail:
 
515
                if detail.startswith(': '):
 
516
                    detail = detail[2:]
 
517
                resp += (detail,)
 
518
            return FailedSmartServerResponse(resp)
 
519