~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/bzrdir.py

  • Committer: John Arbash Meinel
  • Author(s): Mark Hammond
  • Date: 2008-09-09 17:02:21 UTC
  • mto: This revision was merged to the branch mainline in revision 3697.
  • Revision ID: john@arbash-meinel.com-20080909170221-svim3jw2mrz0amp3
An updated transparent icon for bzr.

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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
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 errors
 
21
from bzrlib.bzrdir import BzrDir, BzrDirFormat
22
22
from bzrlib.smart.request import (
23
23
    FailedSmartServerResponse,
24
24
    SmartServerRequest,
51
51
        return SuccessfulSmartServerResponse((answer,))
52
52
 
53
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
 
        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)
 
54
class SmartServerRequestFindRepository(SmartServerRequest):
64
55
 
65
56
    def _boolean_to_yes_no(self, a_boolean):
66
57
        if a_boolean:
68
59
        else:
69
60
            return 'no'
70
61
 
71
 
    def _format_to_capabilities(self, repo_format):
72
 
        rich_root = self._boolean_to_yes_no(repo_format.rich_root_data)
73
 
        tree_ref = self._boolean_to_yes_no(
74
 
            repo_format.supports_tree_reference)
75
 
        external_lookup = self._boolean_to_yes_no(
76
 
            repo_format.supports_external_lookups)
77
 
        return rich_root, tree_ref, external_lookup
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
 
62
    def _find(self, path):
 
63
        """try to find a repository from path upwards
 
64
        
 
65
        This operates precisely like 'bzrdir.find_repository'.
 
66
        
 
67
        :return: (relpath, rich_root, tree_ref, external_lookup) flags. All are
 
68
            strings, relpath is a / prefixed path, and the other three are
 
69
            either 'yes' or 'no'.
 
70
        :raises errors.NoRepositoryPresent: When there is no repository
 
71
            present.
 
72
        """
 
73
        bzrdir = BzrDir.open_from_transport(
 
74
            self.transport_from_client_path(path))
 
75
        repository = bzrdir.find_repository()
 
76
        # the relpath of the bzrdir in the found repository gives us the 
82
77
        # path segments to pop-out.
83
78
        relpath = repository.bzrdir.root_transport.relpath(
84
 
            current_transport.base)
 
79
            bzrdir.root_transport.base)
85
80
        if len(relpath):
86
81
            segments = ['..'] * len(relpath.split('/'))
87
82
        else:
88
83
            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
 
 
170
 
 
171
 
class SmartServerRequestCreateRepository(SmartServerRequestBzrDir):
172
 
 
173
 
    def do(self, path, network_name, shared):
174
 
        """Create a repository in the bzr dir at path.
175
 
 
176
 
        This operates precisely like 'bzrdir.create_repository'.
177
 
 
178
 
        If a bzrdir is not present, an exception is propogated
179
 
        rather than 'no branch' because these are different conditions (and
180
 
        this method should only be called after establishing that a bzr dir
181
 
        exists anyway).
182
 
 
183
 
        This is the initial version of this method introduced to the smart
184
 
        server for 1.13.
185
 
 
186
 
        :param path: The path to the bzrdir.
187
 
        :param network_name: The network name of the repository type to create.
188
 
        :param shared: The value to pass create_repository for the shared
189
 
            parameter.
190
 
        :return: (ok, rich_root, tree_ref, external_lookup, network_name)
191
 
        """
192
 
        bzrdir = BzrDir.open_from_transport(
193
 
            self.transport_from_client_path(path))
194
 
        shared = shared == 'True'
195
 
        format = repository.network_format_registry.get(network_name)
196
 
        bzrdir.repository_format = format
197
 
        result = format.initialize(bzrdir, shared=shared)
198
 
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
199
 
            result._format)
200
 
        return SuccessfulSmartServerResponse(('ok', rich_root, tree_ref,
201
 
            external_lookup, result._format.network_name()))
202
 
 
203
 
 
204
 
class SmartServerRequestFindRepository(SmartServerRequestBzrDir):
205
 
 
206
 
    def _find(self, path):
207
 
        """try to find a repository from path upwards
208
 
 
209
 
        This operates precisely like 'bzrdir.find_repository'.
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.
215
 
        :raises errors.NoRepositoryPresent: When there is no repository
216
 
            present.
217
 
        """
218
 
        bzrdir = BzrDir.open_from_transport(
219
 
            self.transport_from_client_path(path))
220
 
        repository = bzrdir.find_repository()
221
 
        path = self._repo_relpath(bzrdir.root_transport, repository)
222
 
        rich_root, tree_ref, external_lookup = self._format_to_capabilities(
223
 
            repository._format)
224
 
        network_name = repository._format.network_name()
225
 
        return path, rich_root, tree_ref, external_lookup, network_name
 
84
        rich_root = self._boolean_to_yes_no(repository.supports_rich_root())
 
85
        tree_ref = self._boolean_to_yes_no(
 
86
            repository._format.supports_tree_reference)
 
87
        external_lookup = self._boolean_to_yes_no(
 
88
            repository._format.supports_external_lookups)
 
89
        return '/'.join(segments), rich_root, tree_ref, external_lookup
226
90
 
227
91
 
228
92
class SmartServerRequestFindRepositoryV1(SmartServerRequestFindRepository):
229
93
 
230
94
    def do(self, path):
231
95
        """try to find a repository from path upwards
232
 
 
 
96
        
233
97
        This operates precisely like 'bzrdir.find_repository'.
234
 
 
 
98
        
235
99
        If a bzrdir is not present, an exception is propogated
236
100
        rather than 'no branch' because these are different conditions.
237
101
 
242
106
        :return: norepository or ok, relpath.
243
107
        """
244
108
        try:
245
 
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
 
109
            path, rich_root, tree_ref, external_lookup = self._find(path)
246
110
            return SuccessfulSmartServerResponse(('ok', path, rich_root, tree_ref))
247
111
        except errors.NoRepositoryPresent:
248
112
            return FailedSmartServerResponse(('norepository', ))
252
116
 
253
117
    def do(self, path):
254
118
        """try to find a repository from path upwards
255
 
 
 
119
        
256
120
        This operates precisely like 'bzrdir.find_repository'.
257
 
 
 
121
        
258
122
        If a bzrdir is not present, an exception is propogated
259
123
        rather than 'no branch' because these are different conditions.
260
124
 
262
126
        returns information about the supports_external_lookups format
263
127
        attribute too.
264
128
 
265
 
        :return: norepository or ok, relpath, rich_root, tree_ref,
266
 
            external_lookup.
 
129
        :return: norepository or ok, relpath.
267
130
        """
268
131
        try:
269
 
            path, rich_root, tree_ref, external_lookup, name = self._find(path)
 
132
            path, rich_root, tree_ref, external_lookup = self._find(path)
270
133
            return SuccessfulSmartServerResponse(
271
134
                ('ok', path, rich_root, tree_ref, external_lookup))
272
135
        except errors.NoRepositoryPresent:
273
136
            return FailedSmartServerResponse(('norepository', ))
274
137
 
275
138
 
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
 
 
300
139
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
301
140
 
302
141
    def do(self, path):
310
149
        return SuccessfulSmartServerResponse(('ok', ))
311
150
 
312
151
 
313
 
class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
 
152
class SmartServerRequestOpenBranch(SmartServerRequest):
314
153
 
315
 
    def do_bzrdir_request(self):
316
 
        """open a branch at path and return the branch reference or branch."""
 
154
    def do(self, path):
 
155
        """try to open a branch at path and return ok/nobranch.
 
156
        
 
157
        If a bzrdir is not present, an exception is propogated
 
158
        rather than 'no branch' because these are different conditions.
 
159
        """
 
160
        bzrdir = BzrDir.open_from_transport(
 
161
            self.transport_from_client_path(path))
317
162
        try:
318
 
            reference_url = self._bzrdir.get_branch_reference()
 
163
            reference_url = bzrdir.get_branch_reference()
319
164
            if reference_url is None:
320
165
                return SuccessfulSmartServerResponse(('ok', ''))
321
166
            else:
322
167
                return SuccessfulSmartServerResponse(('ok', reference_url))
323
168
        except errors.NotBranchError:
324
169
            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', ))