~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/bzrdir.py

  • Committer: Matt Nordhoff
  • Date: 2009-04-04 02:50:01 UTC
  • mfrom: (4253 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4256.
  • Revision ID: mnordhoff@mattnordhoff.com-20090404025001-z1403k0tatmc8l91
Merge bzr.dev, fixing conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Server-side bzrdir related request implmentations."""
18
18
 
19
19
 
20
 
from bzrlib import errors
21
 
from bzrlib.bzrdir import BzrDir, BzrDirFormat
 
20
from bzrlib import branch, errors, repository
 
21
from bzrlib.bzrdir import BzrDir, BzrDirFormat, BzrDirMetaFormat1
22
22
from bzrlib.smart.request import (
23
23
    FailedSmartServerResponse,
24
24
    SmartServerRequest,
25
25
    SuccessfulSmartServerResponse,
26
26
    )
27
 
from bzrlib.repository import network_format_registry
28
27
 
29
28
 
30
29
class SmartServerRequestOpenBzrDir(SmartServerRequest):
54
53
 
55
54
class SmartServerRequestBzrDir(SmartServerRequest):
56
55
 
 
56
    def do(self, path, *args):
 
57
        """Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
 
58
        try:
 
59
            self._bzrdir = BzrDir.open_from_transport(
 
60
                self.transport_from_client_path(path))
 
61
        except errors.NotBranchError:
 
62
            return FailedSmartServerResponse(('nobranch', ))
 
63
        return self.do_bzrdir_request(*args)
 
64
 
57
65
    def _boolean_to_yes_no(self, a_boolean):
58
66
        if a_boolean:
59
67
            return 'yes'
68
76
            repo_format.supports_external_lookups)
69
77
        return rich_root, tree_ref, external_lookup
70
78
 
 
79
    def _repo_relpath(self, current_transport, repository):
 
80
        """Get the relative path for repository from current_transport."""
 
81
        # the relpath of the bzrdir in the found repository gives us the
 
82
        # path segments to pop-out.
 
83
        relpath = repository.bzrdir.root_transport.relpath(
 
84
            current_transport.base)
 
85
        if len(relpath):
 
86
            segments = ['..'] * len(relpath.split('/'))
 
87
        else:
 
88
            segments = []
 
89
        return '/'.join(segments)
 
90
 
 
91
 
 
92
class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
 
93
 
 
94
    def do_bzrdir_request(self, require_stacking):
 
95
        """Get the format that should be used when cloning from this dir.
 
96
 
 
97
        New in 1.13.
 
98
        
 
99
        :return: on success, a 3-tuple of network names for (control,
 
100
            repository, branch) directories, where '' signifies "not present".
 
101
            If this BzrDir contains a branch reference then this will fail with
 
102
            BranchReference; clients should resolve branch references before
 
103
            calling this RPC.
 
104
        """
 
105
        try:
 
106
            branch_ref = self._bzrdir.get_branch_reference()
 
107
        except errors.NotBranchError:
 
108
            branch_ref = None
 
109
        if branch_ref is not None:
 
110
            # The server shouldn't try to resolve references, and it quite
 
111
            # possibly can't reach them anyway.  The client needs to resolve
 
112
            # the branch reference to determine the cloning_metadir.
 
113
            return FailedSmartServerResponse(('BranchReference',))
 
114
        if require_stacking == "True":
 
115
            require_stacking = True
 
116
        else:
 
117
            require_stacking = False
 
118
        control_format = self._bzrdir.cloning_metadir(
 
119
            require_stacking=require_stacking)
 
120
        control_name = control_format.network_name()
 
121
        # XXX: There should be a method that tells us that the format does/does
 
122
        # not have subformats.
 
123
        if isinstance(control_format, BzrDirMetaFormat1):
 
124
            branch_name = ('branch',
 
125
                control_format.get_branch_format().network_name())
 
126
            repository_name = control_format.repository_format.network_name()
 
127
        else:
 
128
            # Only MetaDir has delegated formats today.
 
129
            branch_name = ('branch', '')
 
130
            repository_name = ''
 
131
        return SuccessfulSmartServerResponse((control_name, repository_name,
 
132
            branch_name))
 
133
 
 
134
 
 
135
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
 
136
 
 
137
    def do(self, path, network_name):
 
138
        """Create a branch in the bzr dir at path.
 
139
 
 
140
        This operates precisely like 'bzrdir.create_branch'.
 
141
 
 
142
        If a bzrdir is not present, an exception is propogated
 
143
        rather than 'no branch' because these are different conditions (and
 
144
        this method should only be called after establishing that a bzr dir
 
145
        exists anyway).
 
146
 
 
147
        This is the initial version of this method introduced to the smart
 
148
        server for 1.13.
 
149
 
 
150
        :param path: The path to the bzrdir.
 
151
        :param network_name: The network name of the branch type to create.
 
152
        :return: (ok, network_name)
 
153
        """
 
154
        bzrdir = BzrDir.open_from_transport(
 
155
            self.transport_from_client_path(path))
 
156
        format = branch.network_format_registry.get(network_name)
 
157
        bzrdir.branch_format = format
 
158
        result = format.initialize(bzrdir)
 
159
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
 
160
            result.repository._format)
 
161
        branch_format = result._format.network_name()
 
162
        repo_format = result.repository._format.network_name()
 
163
        repo_path = self._repo_relpath(bzrdir.root_transport,
 
164
            result.repository)
 
165
        # branch format, repo relpath, rich_root, tree_ref, external_lookup,
 
166
        # repo_network_name
 
167
        return SuccessfulSmartServerResponse(('ok', branch_format, repo_path,
 
168
            rich_root, tree_ref, external_lookup, repo_format))
 
169
 
71
170
 
72
171
class SmartServerRequestCreateRepository(SmartServerRequestBzrDir):
73
172
 
74
173
    def do(self, path, network_name, shared):
75
174
        """Create a repository in the bzr dir at path.
76
 
        
 
175
 
77
176
        This operates precisely like 'bzrdir.create_repository'.
78
 
        
 
177
 
79
178
        If a bzrdir is not present, an exception is propagated
80
179
        rather than 'no branch' because these are different conditions (and
81
180
        this method should only be called after establishing that a bzr dir
93
192
        bzrdir = BzrDir.open_from_transport(
94
193
            self.transport_from_client_path(path))
95
194
        shared = shared == 'True'
96
 
        format = network_format_registry.get(network_name)
 
195
        format = repository.network_format_registry.get(network_name)
97
196
        bzrdir.repository_format = format
98
197
        result = format.initialize(bzrdir, shared=shared)
99
198
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
106
205
 
107
206
    def _find(self, path):
108
207
        """try to find a repository from path upwards
109
 
        
 
208
 
110
209
        This operates precisely like 'bzrdir.find_repository'.
111
 
        
112
 
        :return: (relpath, rich_root, tree_ref, external_lookup) flags. All are
113
 
            strings, relpath is a / prefixed path, and the other three are
114
 
            either 'yes' or 'no'.
 
210
 
 
211
        :return: (relpath, rich_root, tree_ref, external_lookup, network_name).
 
212
            All are strings, relpath is a / prefixed path, the next three are
 
213
            either 'yes' or 'no', and the last is a repository format network
 
214
            name.
115
215
        :raises errors.NoRepositoryPresent: When there is no repository
116
216
            present.
117
217
        """
118
218
        bzrdir = BzrDir.open_from_transport(
119
219
            self.transport_from_client_path(path))
120
220
        repository = bzrdir.find_repository()
121
 
        # the relpath of the bzrdir in the found repository gives us the 
122
 
        # path segments to pop-out.
123
 
        relpath = repository.bzrdir.root_transport.relpath(
124
 
            bzrdir.root_transport.base)
125
 
        if len(relpath):
126
 
            segments = ['..'] * len(relpath.split('/'))
127
 
        else:
128
 
            segments = []
 
221
        path = self._repo_relpath(bzrdir.root_transport, repository)
129
222
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
130
223
            repository._format)
131
 
        return '/'.join(segments), rich_root, tree_ref, external_lookup
 
224
        network_name = repository._format.network_name()
 
225
        return path, rich_root, tree_ref, external_lookup, network_name
132
226
 
133
227
 
134
228
class SmartServerRequestFindRepositoryV1(SmartServerRequestFindRepository):
135
229
 
136
230
    def do(self, path):
137
231
        """try to find a repository from path upwards
138
 
        
 
232
 
139
233
        This operates precisely like 'bzrdir.find_repository'.
140
 
        
 
234
 
141
235
        If a bzrdir is not present, an exception is propagated
142
236
        rather than 'no branch' because these are different conditions.
143
237
 
148
242
        :return: norepository or ok, relpath.
149
243
        """
150
244
        try:
151
 
            path, rich_root, tree_ref, external_lookup = self._find(path)
 
245
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
152
246
            return SuccessfulSmartServerResponse(('ok', path, rich_root, tree_ref))
153
247
        except errors.NoRepositoryPresent:
154
248
            return FailedSmartServerResponse(('norepository', ))
158
252
 
159
253
    def do(self, path):
160
254
        """try to find a repository from path upwards
161
 
        
 
255
 
162
256
        This operates precisely like 'bzrdir.find_repository'.
163
 
        
 
257
 
164
258
        If a bzrdir is not present, an exception is propagated
165
259
        rather than 'no branch' because these are different conditions.
166
260
 
168
262
        returns information about the supports_external_lookups format
169
263
        attribute too.
170
264
 
171
 
        :return: norepository or ok, relpath.
 
265
        :return: norepository or ok, relpath, rich_root, tree_ref,
 
266
            external_lookup.
172
267
        """
173
268
        try:
174
 
            path, rich_root, tree_ref, external_lookup = self._find(path)
 
269
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
175
270
            return SuccessfulSmartServerResponse(
176
271
                ('ok', path, rich_root, tree_ref, external_lookup))
177
272
        except errors.NoRepositoryPresent:
178
273
            return FailedSmartServerResponse(('norepository', ))
179
274
 
180
275
 
 
276
class SmartServerRequestFindRepositoryV3(SmartServerRequestFindRepository):
 
277
 
 
278
    def do(self, path):
 
279
        """try to find a repository from path upwards
 
280
 
 
281
        This operates precisely like 'bzrdir.find_repository'.
 
282
 
 
283
        If a bzrdir is not present, an exception is propogated
 
284
        rather than 'no branch' because these are different conditions.
 
285
 
 
286
        This is the third edition of this method introduced in bzr 1.13, which
 
287
        returns information about the network name of the repository format.
 
288
 
 
289
        :return: norepository or ok, relpath, rich_root, tree_ref,
 
290
            external_lookup, network_name.
 
291
        """
 
292
        try:
 
293
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
 
294
            return SuccessfulSmartServerResponse(
 
295
                ('ok', path, rich_root, tree_ref, external_lookup, name))
 
296
        except errors.NoRepositoryPresent:
 
297
            return FailedSmartServerResponse(('norepository', ))
 
298
 
 
299
 
181
300
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
182
301
 
183
302
    def do(self, path):
191
310
        return SuccessfulSmartServerResponse(('ok', ))
192
311
 
193
312
 
194
 
class SmartServerRequestOpenBranch(SmartServerRequest):
 
313
class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
195
314
 
196
 
    def do(self, path):
197
 
        """try to open a branch at path and return ok/nobranch.
198
 
        
199
 
        If a bzrdir is not present, an exception is propagated
200
 
        rather than 'no branch' because these are different conditions.
201
 
        """
202
 
        bzrdir = BzrDir.open_from_transport(
203
 
            self.transport_from_client_path(path))
 
315
    def do_bzrdir_request(self):
 
316
        """open a branch at path and return the branch reference or branch."""
204
317
        try:
205
 
            reference_url = bzrdir.get_branch_reference()
 
318
            reference_url = self._bzrdir.get_branch_reference()
206
319
            if reference_url is None:
207
320
                return SuccessfulSmartServerResponse(('ok', ''))
208
321
            else:
209
322
                return SuccessfulSmartServerResponse(('ok', reference_url))
210
323
        except errors.NotBranchError:
211
324
            return FailedSmartServerResponse(('nobranch', ))
 
325
 
 
326
 
 
327
class SmartServerRequestOpenBranchV2(SmartServerRequestBzrDir):
 
328
 
 
329
    def do_bzrdir_request(self):
 
330
        """open a branch at path and return the reference or format."""
 
331
        try:
 
332
            reference_url = self._bzrdir.get_branch_reference()
 
333
            if reference_url is None:
 
334
                br = self._bzrdir.open_branch(ignore_fallbacks=True)
 
335
                format = br._format.network_name()
 
336
                return SuccessfulSmartServerResponse(('branch', format))
 
337
            else:
 
338
                return SuccessfulSmartServerResponse(('ref', reference_url))
 
339
        except errors.NotBranchError:
 
340
            return FailedSmartServerResponse(('nobranch', ))