/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: Andrew Bennetts
  • Date: 2009-03-06 02:21:00 UTC
  • mto: This revision was merged to the branch mainline in revision 4084.
  • Revision ID: andrew.bennetts@canonical.com-20090306022100-cb3sz5julsdhgrpa
Fix trivial bug in my trivial bug fix :)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Server-side bzrdir related request implmentations."""
 
18
 
 
19
 
 
20
from bzrlib import branch, errors, repository
 
21
from bzrlib.bzrdir import BzrDir, BzrDirFormat, BzrDirMetaFormat1
 
22
from bzrlib.smart.request import (
 
23
    FailedSmartServerResponse,
 
24
    SmartServerRequest,
 
25
    SuccessfulSmartServerResponse,
 
26
    )
 
27
 
 
28
 
 
29
class SmartServerRequestOpenBzrDir(SmartServerRequest):
 
30
 
 
31
    def do(self, path):
 
32
        from bzrlib.bzrdir import BzrDirFormat
 
33
        try:
 
34
            t = self.transport_from_client_path(path)
 
35
        except errors.PathNotChild:
 
36
            # The client is trying to ask about a path that they have no access
 
37
            # to.
 
38
            # Ideally we'd return a FailedSmartServerResponse here rather than
 
39
            # a "successful" negative, but we want to be compatibile with
 
40
            # clients that don't anticipate errors from this method.
 
41
            answer = 'no'
 
42
        else:
 
43
            default_format = BzrDirFormat.get_default_format()
 
44
            real_bzrdir = default_format.open(t, _found=True)
 
45
            try:
 
46
                real_bzrdir._format.probe_transport(t)
 
47
            except (errors.NotBranchError, errors.UnknownFormatError):
 
48
                answer = 'no'
 
49
            else:
 
50
                answer = 'yes'
 
51
        return SuccessfulSmartServerResponse((answer,))
 
52
 
 
53
 
 
54
class SmartServerRequestBzrDir(SmartServerRequest):
 
55
 
 
56
    def do(self, path, *args):
 
57
        """Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
 
58
        self._bzrdir = BzrDir.open_from_transport(
 
59
            self.transport_from_client_path(path))
 
60
        return self.do_bzrdir_request(*args)
 
61
 
 
62
    def _boolean_to_yes_no(self, a_boolean):
 
63
        if a_boolean:
 
64
            return 'yes'
 
65
        else:
 
66
            return 'no'
 
67
 
 
68
    def _format_to_capabilities(self, repo_format):
 
69
        rich_root = self._boolean_to_yes_no(repo_format.rich_root_data)
 
70
        tree_ref = self._boolean_to_yes_no(
 
71
            repo_format.supports_tree_reference)
 
72
        external_lookup = self._boolean_to_yes_no(
 
73
            repo_format.supports_external_lookups)
 
74
        return rich_root, tree_ref, external_lookup
 
75
 
 
76
    def _repo_relpath(self, current_transport, repository):
 
77
        """Get the relative path for repository from current_transport."""
 
78
        # the relpath of the bzrdir in the found repository gives us the
 
79
        # path segments to pop-out.
 
80
        relpath = repository.bzrdir.root_transport.relpath(
 
81
            current_transport.base)
 
82
        if len(relpath):
 
83
            segments = ['..'] * len(relpath.split('/'))
 
84
        else:
 
85
            segments = []
 
86
        return '/'.join(segments)
 
87
 
 
88
 
 
89
class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
 
90
 
 
91
    def do_bzrdir_request(self, require_stacking):
 
92
        """Get the format that should be used when cloning from this dir."""
 
93
        try:
 
94
            branch_ref = self._bzrdir.get_branch_reference()
 
95
        except errors.NotBranchError:
 
96
            branch_ref = None
 
97
        if require_stacking == "True":
 
98
            require_stacking = True
 
99
        else:
 
100
            require_stacking = False
 
101
        control_format = self._bzrdir.cloning_metadir(
 
102
            require_stacking=require_stacking)
 
103
        control_name = control_format.network_name()
 
104
        # XXX: There should be a method that tells us that the format does/does not
 
105
        # have subformats.
 
106
        if isinstance(control_format, BzrDirMetaFormat1):
 
107
            if branch_ref is not None:
 
108
                # If there's a branch reference, the client will have to resolve
 
109
                # the branch reference to figure out the cloning metadir
 
110
                branch_name = ('reference', branch_ref)
 
111
            else:
 
112
                branch_name = (
 
113
                    'direct', control_format.get_branch_format().network_name())
 
114
            repository_name = control_format.repository_format.network_name()
 
115
        else:
 
116
            # Only MetaDir has delegated formats today.
 
117
            branch_name = ''
 
118
            repository_name = ''
 
119
        return SuccessfulSmartServerResponse((control_name, repository_name,
 
120
            branch_name))
 
121
 
 
122
 
 
123
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
 
124
 
 
125
    def do(self, path, network_name):
 
126
        """Create a branch in the bzr dir at path.
 
127
 
 
128
        This operates precisely like 'bzrdir.create_branch'.
 
129
 
 
130
        If a bzrdir is not present, an exception is propogated
 
131
        rather than 'no branch' because these are different conditions (and
 
132
        this method should only be called after establishing that a bzr dir
 
133
        exists anyway).
 
134
 
 
135
        This is the initial version of this method introduced to the smart
 
136
        server for 1.13.
 
137
 
 
138
        :param path: The path to the bzrdir.
 
139
        :param network_name: The network name of the branch type to create.
 
140
        :return: (ok, network_name)
 
141
        """
 
142
        bzrdir = BzrDir.open_from_transport(
 
143
            self.transport_from_client_path(path))
 
144
        format = branch.network_format_registry.get(network_name)
 
145
        bzrdir.branch_format = format
 
146
        result = format.initialize(bzrdir)
 
147
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
 
148
            result.repository._format)
 
149
        branch_format = result._format.network_name()
 
150
        repo_format = result.repository._format.network_name()
 
151
        repo_path = self._repo_relpath(bzrdir.root_transport,
 
152
            result.repository)
 
153
        # branch format, repo relpath, rich_root, tree_ref, external_lookup,
 
154
        # repo_network_name
 
155
        return SuccessfulSmartServerResponse(('ok', branch_format, repo_path,
 
156
            rich_root, tree_ref, external_lookup, repo_format))
 
157
 
 
158
 
 
159
class SmartServerRequestCreateRepository(SmartServerRequestBzrDir):
 
160
 
 
161
    def do(self, path, network_name, shared):
 
162
        """Create a repository in the bzr dir at path.
 
163
 
 
164
        This operates precisely like 'bzrdir.create_repository'.
 
165
 
 
166
        If a bzrdir is not present, an exception is propogated
 
167
        rather than 'no branch' because these are different conditions (and
 
168
        this method should only be called after establishing that a bzr dir
 
169
        exists anyway).
 
170
 
 
171
        This is the initial version of this method introduced to the smart
 
172
        server for 1.13.
 
173
 
 
174
        :param path: The path to the bzrdir.
 
175
        :param network_name: The network name of the repository type to create.
 
176
        :param shared: The value to pass create_repository for the shared
 
177
            parameter.
 
178
        :return: (ok, rich_root, tree_ref, external_lookup, network_name)
 
179
        """
 
180
        bzrdir = BzrDir.open_from_transport(
 
181
            self.transport_from_client_path(path))
 
182
        shared = shared == 'True'
 
183
        format = repository.network_format_registry.get(network_name)
 
184
        bzrdir.repository_format = format
 
185
        result = format.initialize(bzrdir, shared=shared)
 
186
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
 
187
            result._format)
 
188
        return SuccessfulSmartServerResponse(('ok', rich_root, tree_ref,
 
189
            external_lookup, result._format.network_name()))
 
190
 
 
191
 
 
192
class SmartServerRequestFindRepository(SmartServerRequestBzrDir):
 
193
 
 
194
    def _find(self, path):
 
195
        """try to find a repository from path upwards
 
196
 
 
197
        This operates precisely like 'bzrdir.find_repository'.
 
198
 
 
199
        :return: (relpath, rich_root, tree_ref, external_lookup, network_name).
 
200
            All are strings, relpath is a / prefixed path, the next three are
 
201
            either 'yes' or 'no', and the last is a repository format network
 
202
            name.
 
203
        :raises errors.NoRepositoryPresent: When there is no repository
 
204
            present.
 
205
        """
 
206
        bzrdir = BzrDir.open_from_transport(
 
207
            self.transport_from_client_path(path))
 
208
        repository = bzrdir.find_repository()
 
209
        path = self._repo_relpath(bzrdir.root_transport, repository)
 
210
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
 
211
            repository._format)
 
212
        network_name = repository._format.network_name()
 
213
        return path, rich_root, tree_ref, external_lookup, network_name
 
214
 
 
215
 
 
216
class SmartServerRequestFindRepositoryV1(SmartServerRequestFindRepository):
 
217
 
 
218
    def do(self, path):
 
219
        """try to find a repository from path upwards
 
220
 
 
221
        This operates precisely like 'bzrdir.find_repository'.
 
222
 
 
223
        If a bzrdir is not present, an exception is propogated
 
224
        rather than 'no branch' because these are different conditions.
 
225
 
 
226
        This is the initial version of this method introduced with the smart
 
227
        server. Modern clients will try the V2 method that adds support for the
 
228
        supports_external_lookups attribute.
 
229
 
 
230
        :return: norepository or ok, relpath.
 
231
        """
 
232
        try:
 
233
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
 
234
            return SuccessfulSmartServerResponse(('ok', path, rich_root, tree_ref))
 
235
        except errors.NoRepositoryPresent:
 
236
            return FailedSmartServerResponse(('norepository', ))
 
237
 
 
238
 
 
239
class SmartServerRequestFindRepositoryV2(SmartServerRequestFindRepository):
 
240
 
 
241
    def do(self, path):
 
242
        """try to find a repository from path upwards
 
243
 
 
244
        This operates precisely like 'bzrdir.find_repository'.
 
245
 
 
246
        If a bzrdir is not present, an exception is propogated
 
247
        rather than 'no branch' because these are different conditions.
 
248
 
 
249
        This is the second edition of this method introduced in bzr 1.3, which
 
250
        returns information about the supports_external_lookups format
 
251
        attribute too.
 
252
 
 
253
        :return: norepository or ok, relpath, rich_root, tree_ref,
 
254
            external_lookup.
 
255
        """
 
256
        try:
 
257
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
 
258
            return SuccessfulSmartServerResponse(
 
259
                ('ok', path, rich_root, tree_ref, external_lookup))
 
260
        except errors.NoRepositoryPresent:
 
261
            return FailedSmartServerResponse(('norepository', ))
 
262
 
 
263
 
 
264
class SmartServerRequestFindRepositoryV3(SmartServerRequestFindRepository):
 
265
 
 
266
    def do(self, path):
 
267
        """try to find a repository from path upwards
 
268
 
 
269
        This operates precisely like 'bzrdir.find_repository'.
 
270
 
 
271
        If a bzrdir is not present, an exception is propogated
 
272
        rather than 'no branch' because these are different conditions.
 
273
 
 
274
        This is the third edition of this method introduced in bzr 1.13, which
 
275
        returns information about the network name of the repository format.
 
276
 
 
277
        :return: norepository or ok, relpath, rich_root, tree_ref,
 
278
            external_lookup, network_name.
 
279
        """
 
280
        try:
 
281
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
 
282
            return SuccessfulSmartServerResponse(
 
283
                ('ok', path, rich_root, tree_ref, external_lookup, name))
 
284
        except errors.NoRepositoryPresent:
 
285
            return FailedSmartServerResponse(('norepository', ))
 
286
 
 
287
 
 
288
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
 
289
 
 
290
    def do(self, path):
 
291
        """Initialize a bzrdir at path.
 
292
 
 
293
        The default format of the server is used.
 
294
        :return: SmartServerResponse(('ok', ))
 
295
        """
 
296
        target_transport = self.transport_from_client_path(path)
 
297
        BzrDirFormat.get_default_format().initialize_on_transport(target_transport)
 
298
        return SuccessfulSmartServerResponse(('ok', ))
 
299
 
 
300
 
 
301
class SmartServerRequestOpenBranch(SmartServerRequest):
 
302
 
 
303
    def do(self, path):
 
304
        """try to open a branch at path and return ok/nobranch.
 
305
 
 
306
        If a bzrdir is not present, an exception is propogated
 
307
        rather than 'no branch' because these are different conditions.
 
308
        """
 
309
        bzrdir = BzrDir.open_from_transport(
 
310
            self.transport_from_client_path(path))
 
311
        try:
 
312
            reference_url = bzrdir.get_branch_reference()
 
313
            if reference_url is None:
 
314
                return SuccessfulSmartServerResponse(('ok', ''))
 
315
            else:
 
316
                return SuccessfulSmartServerResponse(('ok', reference_url))
 
317
        except errors.NotBranchError:
 
318
            return FailedSmartServerResponse(('nobranch', ))