~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/bzrdir.py

(jelmer) Use the absolute_import feature everywhere in bzrlib,
 and add a source test to make sure it's used everywhere. (Jelmer Vernooij)

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
16
16
 
17
17
"""Server-side bzrdir related request implmentations."""
18
18
 
 
19
from __future__ import absolute_import
19
20
 
20
21
from bzrlib import branch, errors, repository, urlutils
21
22
from bzrlib.bzrdir import (
22
23
    BzrDir,
23
24
    BzrDirFormat,
24
 
    BzrDirMetaFormat1,
 
25
    BzrProber,
 
26
    )
 
27
from bzrlib.controldir import (
25
28
    network_format_registry,
26
29
    )
27
30
from bzrlib.smart.request import (
44
47
            # clients that don't anticipate errors from this method.
45
48
            answer = 'no'
46
49
        else:
47
 
            default_format = BzrDirFormat.get_default_format()
48
 
            real_bzrdir = default_format.open(t, _found=True)
 
50
            bzr_prober = BzrProber()
49
51
            try:
50
 
                real_bzrdir._format.probe_transport(t)
 
52
                bzr_prober.probe_transport(t)
51
53
            except (errors.NotBranchError, errors.UnknownFormatError):
52
54
                answer = 'no'
53
55
            else:
84
86
class SmartServerRequestBzrDir(SmartServerRequest):
85
87
 
86
88
    def do(self, path, *args):
87
 
        """Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
 
89
        """Open a BzrDir at path, and return `self.do_bzrdir_request(*args)`."""
88
90
        try:
89
91
            self._bzrdir = BzrDir.open_from_transport(
90
92
                self.transport_from_client_path(path))
91
 
        except errors.NotBranchError:
92
 
            return FailedSmartServerResponse(('nobranch', ))
 
93
        except errors.NotBranchError, e:
 
94
            return FailedSmartServerResponse(('nobranch',))
93
95
        return self.do_bzrdir_request(*args)
94
96
 
95
97
    def _boolean_to_yes_no(self, a_boolean):
110
112
        """Get the relative path for repository from current_transport."""
111
113
        # the relpath of the bzrdir in the found repository gives us the
112
114
        # path segments to pop-out.
113
 
        relpath = repository.bzrdir.root_transport.relpath(
 
115
        relpath = repository.user_transport.relpath(
114
116
            current_transport.base)
115
117
        if len(relpath):
116
118
            segments = ['..'] * len(relpath.split('/'))
119
121
        return '/'.join(segments)
120
122
 
121
123
 
 
124
class SmartServerBzrDirRequestDestroyBranch(SmartServerRequestBzrDir):
 
125
 
 
126
    def do_bzrdir_request(self, name=None):
 
127
        """Destroy the branch with the specified name.
 
128
 
 
129
        New in 2.5.0.
 
130
        :return: On success, 'ok'.
 
131
        """
 
132
        try:
 
133
            self._bzrdir.destroy_branch(name)
 
134
        except errors.NotBranchError, e:
 
135
            return FailedSmartServerResponse(('nobranch',))
 
136
        return SuccessfulSmartServerResponse(('ok',))
 
137
 
 
138
 
 
139
class SmartServerBzrDirRequestHasWorkingTree(SmartServerRequestBzrDir):
 
140
 
 
141
    def do_bzrdir_request(self, name=None):
 
142
        """Check whether there is a working tree present.
 
143
 
 
144
        New in 2.5.0.
 
145
 
 
146
        :return: If there is a working tree present, 'yes'.
 
147
            Otherwise 'no'.
 
148
        """
 
149
        if self._bzrdir.has_workingtree():
 
150
            return SuccessfulSmartServerResponse(('yes', ))
 
151
        else:
 
152
            return SuccessfulSmartServerResponse(('no', ))
 
153
 
 
154
 
 
155
class SmartServerBzrDirRequestDestroyRepository(SmartServerRequestBzrDir):
 
156
 
 
157
    def do_bzrdir_request(self, name=None):
 
158
        """Destroy the repository.
 
159
 
 
160
        New in 2.5.0.
 
161
 
 
162
        :return: On success, 'ok'.
 
163
        """
 
164
        try:
 
165
            self._bzrdir.destroy_repository()
 
166
        except errors.NoRepositoryPresent, e:
 
167
            return FailedSmartServerResponse(('norepository',))
 
168
        return SuccessfulSmartServerResponse(('ok',))
 
169
 
 
170
 
122
171
class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
123
172
 
124
173
    def do_bzrdir_request(self, require_stacking):
148
197
        control_format = self._bzrdir.cloning_metadir(
149
198
            require_stacking=require_stacking)
150
199
        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):
 
200
        if not control_format.fixed_components:
154
201
            branch_name = ('branch',
155
202
                control_format.get_branch_format().network_name())
156
203
            repository_name = control_format.repository_format.network_name()
162
209
            branch_name))
163
210
 
164
211
 
 
212
class SmartServerBzrDirRequestCheckoutMetaDir(SmartServerRequestBzrDir):
 
213
    """Get the format to use for checkouts.
 
214
 
 
215
    New in 2.5.
 
216
 
 
217
    :return: on success, a 3-tuple of network names for (control,
 
218
        repository, branch) directories, where '' signifies "not present".
 
219
        If this BzrDir contains a branch reference then this will fail with
 
220
        BranchReference; clients should resolve branch references before
 
221
        calling this RPC (they should not try to create a checkout of a
 
222
        checkout).
 
223
    """
 
224
 
 
225
    def do_bzrdir_request(self):
 
226
        try:
 
227
            branch_ref = self._bzrdir.get_branch_reference()
 
228
        except errors.NotBranchError:
 
229
            branch_ref = None
 
230
        if branch_ref is not None:
 
231
            # The server shouldn't try to resolve references, and it quite
 
232
            # possibly can't reach them anyway.  The client needs to resolve
 
233
            # the branch reference to determine the cloning_metadir.
 
234
            return FailedSmartServerResponse(('BranchReference',))
 
235
        control_format = self._bzrdir.checkout_metadir()
 
236
        control_name = control_format.network_name()
 
237
        if not control_format.fixed_components:
 
238
            branch_name = control_format.get_branch_format().network_name()
 
239
            repo_name = control_format.repository_format.network_name()
 
240
        else:
 
241
            branch_name = ''
 
242
            repo_name = ''
 
243
        return SuccessfulSmartServerResponse(
 
244
            (control_name, repo_name, branch_name))
 
245
 
 
246
 
165
247
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
166
248
 
167
249
    def do(self, path, network_name):
179
261
 
180
262
        :param path: The path to the bzrdir.
181
263
        :param network_name: The network name of the branch type to create.
182
 
        :return: (ok, network_name)
 
264
        :return: ('ok', branch_format, repo_path, rich_root, tree_ref,
 
265
            external_lookup, repo_format)
183
266
        """
184
267
        bzrdir = BzrDir.open_from_transport(
185
268
            self.transport_from_client_path(path))
429
512
            # It is returned locked, but we need to do the lock to get the lock
430
513
            # token.
431
514
            repo.unlock()
432
 
            repo_lock_token = repo.lock_write() or ''
 
515
            repo_lock_token = repo.lock_write().repository_token or ''
433
516
            if repo_lock_token:
434
517
                repo.leave_lock_in_place()
435
518
            repo.unlock()
465
548
                return SuccessfulSmartServerResponse(('ok', ''))
466
549
            else:
467
550
                return SuccessfulSmartServerResponse(('ok', reference_url))
468
 
        except errors.NotBranchError:
469
 
            return FailedSmartServerResponse(('nobranch', ))
 
551
        except errors.NotBranchError, e:
 
552
            return FailedSmartServerResponse(('nobranch',))
470
553
 
471
554
 
472
555
class SmartServerRequestOpenBranchV2(SmartServerRequestBzrDir):
481
564
                return SuccessfulSmartServerResponse(('branch', format))
482
565
            else:
483
566
                return SuccessfulSmartServerResponse(('ref', reference_url))
484
 
        except errors.NotBranchError:
485
 
            return FailedSmartServerResponse(('nobranch', ))
 
567
        except errors.NotBranchError, e:
 
568
            return FailedSmartServerResponse(('nobranch',))
 
569
 
 
570
 
 
571
class SmartServerRequestOpenBranchV3(SmartServerRequestBzrDir):
 
572
 
 
573
    def do_bzrdir_request(self):
 
574
        """Open a branch at path and return the reference or format.
 
575
        
 
576
        This version introduced in 2.1.
 
577
 
 
578
        Differences to SmartServerRequestOpenBranchV2:
 
579
          * can return 2-element ('nobranch', extra), where 'extra' is a string
 
580
            with an explanation like 'location is a repository'.  Previously
 
581
            a 'nobranch' response would never have more than one element.
 
582
        """
 
583
        try:
 
584
            reference_url = self._bzrdir.get_branch_reference()
 
585
            if reference_url is None:
 
586
                br = self._bzrdir.open_branch(ignore_fallbacks=True)
 
587
                format = br._format.network_name()
 
588
                return SuccessfulSmartServerResponse(('branch', format))
 
589
            else:
 
590
                return SuccessfulSmartServerResponse(('ref', reference_url))
 
591
        except errors.NotBranchError, e:
 
592
            # Stringify the exception so that its .detail attribute will be
 
593
            # filled out.
 
594
            str(e)
 
595
            resp = ('nobranch',)
 
596
            detail = e.detail
 
597
            if detail:
 
598
                if detail.startswith(': '):
 
599
                    detail = detail[2:]
 
600
                resp += (detail,)
 
601
            return FailedSmartServerResponse(resp)
 
602