51
63
return SuccessfulSmartServerResponse((answer,))
66
class SmartServerRequestOpenBzrDir_2_1(SmartServerRequest):
69
"""Is there a BzrDir present, and if so does it have a working tree?
74
t = self.transport_from_client_path(path)
75
except errors.PathNotChild:
76
# The client is trying to ask about a path that they have no access
78
return SuccessfulSmartServerResponse(('no',))
80
bd = BzrDir.open_from_transport(t)
81
except errors.NotBranchError:
85
if bd.has_workingtree():
89
return SuccessfulSmartServerResponse(answer)
54
92
class SmartServerRequestBzrDir(SmartServerRequest):
56
94
def do(self, path, *args):
57
"""Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
95
"""Open a BzrDir at path, and return `self.do_bzrdir_request(*args)`."""
59
97
self._bzrdir = BzrDir.open_from_transport(
60
98
self.transport_from_client_path(path))
61
except errors.NotBranchError:
62
return FailedSmartServerResponse(('nobranch', ))
99
except errors.NotBranchError, e:
100
return FailedSmartServerResponse(('nobranch',))
63
101
return self.do_bzrdir_request(*args)
65
103
def _boolean_to_yes_no(self, a_boolean):
89
127
return '/'.join(segments)
130
class SmartServerBzrDirRequestDestroyBranch(SmartServerRequestBzrDir):
132
def do_bzrdir_request(self, name=None):
133
"""Destroy the branch with the specified name.
136
:return: On success, 'ok'.
139
self._bzrdir.destroy_branch(name)
140
except errors.NotBranchError, e:
141
return FailedSmartServerResponse(('nobranch',))
142
return SuccessfulSmartServerResponse(('ok',))
145
class SmartServerBzrDirRequestHasWorkingTree(SmartServerRequestBzrDir):
147
def do_bzrdir_request(self, name=None):
148
"""Check whether there is a working tree present.
152
:return: If there is a working tree present, 'yes'.
155
if self._bzrdir.has_workingtree():
156
return SuccessfulSmartServerResponse(('yes', ))
158
return SuccessfulSmartServerResponse(('no', ))
161
class SmartServerBzrDirRequestDestroyRepository(SmartServerRequestBzrDir):
163
def do_bzrdir_request(self, name=None):
164
"""Destroy the repository.
168
:return: On success, 'ok'.
171
self._bzrdir.destroy_repository()
172
except errors.NoRepositoryPresent, e:
173
return FailedSmartServerResponse(('norepository',))
174
return SuccessfulSmartServerResponse(('ok',))
92
177
class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
94
179
def do_bzrdir_request(self, require_stacking):
218
class SmartServerBzrDirRequestCheckoutMetaDir(SmartServerRequestBzrDir):
219
"""Get the format to use for checkouts.
223
:return: on success, a 3-tuple of network names for (control,
224
repository, branch) directories, where '' signifies "not present".
225
If this BzrDir contains a branch reference then this will fail with
226
BranchReference; clients should resolve branch references before
227
calling this RPC (they should not try to create a checkout of a
231
def do_bzrdir_request(self):
233
branch_ref = self._bzrdir.get_branch_reference()
234
except errors.NotBranchError:
236
if branch_ref is not None:
237
# The server shouldn't try to resolve references, and it quite
238
# possibly can't reach them anyway. The client needs to resolve
239
# the branch reference to determine the cloning_metadir.
240
return FailedSmartServerResponse(('BranchReference',))
241
control_format = self._bzrdir.checkout_metadir()
242
control_name = control_format.network_name()
243
if not control_format.fixed_components:
244
branch_name = control_format.get_branch_format().network_name()
245
repo_name = control_format.repository_format.network_name()
249
return SuccessfulSmartServerResponse(
250
(control_name, repo_name, branch_name))
135
253
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
137
255
def do(self, path, network_name):
150
268
:param path: The path to the bzrdir.
151
269
:param network_name: The network name of the branch type to create.
152
:return: (ok, network_name)
270
:return: ('ok', branch_format, repo_path, rich_root, tree_ref,
271
external_lookup, repo_format)
154
273
bzrdir = BzrDir.open_from_transport(
155
274
self.transport_from_client_path(path))
156
275
format = branch.network_format_registry.get(network_name)
157
276
bzrdir.branch_format = format
158
result = format.initialize(bzrdir)
277
result = format.initialize(bzrdir, name="")
159
278
rich_root, tree_ref, external_lookup = self._format_to_capabilities(
160
279
result.repository._format)
161
280
branch_format = result._format.network_name()
312
431
return SuccessfulSmartServerResponse((), content)
434
class SmartServerBzrDirRequestGetBranches(SmartServerRequestBzrDir):
436
def do_bzrdir_request(self):
437
"""Get the branches in a control directory.
439
The body is a bencoded dictionary, with values similar to the return
440
value of the open branch request.
442
branches = self._bzrdir.get_branches()
444
for name, b in branches.iteritems():
447
ret[name] = ("branch", b._format.network_name())
448
return SuccessfulSmartServerResponse(
449
("success", ), bencode.bencode(ret))
315
452
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
317
454
def do(self, path):
325
462
return SuccessfulSmartServerResponse(('ok', ))
465
class SmartServerRequestBzrDirInitializeEx(SmartServerRequestBzrDir):
467
def parse_NoneTrueFalse(self, arg):
474
raise AssertionError("invalid arg %r" % arg)
476
def parse_NoneString(self, arg):
479
def _serialize_NoneTrueFalse(self, arg):
486
def do(self, bzrdir_network_name, path, use_existing_dir, create_prefix,
487
force_new_repo, stacked_on, stack_on_pwd, repo_format_name,
488
make_working_trees, shared_repo):
489
"""Initialize a bzrdir at path as per
490
BzrDirFormat.initialize_on_transport_ex.
492
New in 1.16. (Replaces BzrDirFormat.initialize_ex verb from 1.15).
494
:return: return SuccessfulSmartServerResponse((repo_path, rich_root,
495
tree_ref, external_lookup, repo_network_name,
496
repo_bzrdir_network_name, bzrdir_format_network_name,
497
NoneTrueFalse(stacking), final_stack, final_stack_pwd,
500
target_transport = self.transport_from_client_path(path)
501
format = network_format_registry.get(bzrdir_network_name)
502
use_existing_dir = self.parse_NoneTrueFalse(use_existing_dir)
503
create_prefix = self.parse_NoneTrueFalse(create_prefix)
504
force_new_repo = self.parse_NoneTrueFalse(force_new_repo)
505
stacked_on = self.parse_NoneString(stacked_on)
506
stack_on_pwd = self.parse_NoneString(stack_on_pwd)
507
make_working_trees = self.parse_NoneTrueFalse(make_working_trees)
508
shared_repo = self.parse_NoneTrueFalse(shared_repo)
509
if stack_on_pwd == '.':
510
stack_on_pwd = target_transport.base
511
repo_format_name = self.parse_NoneString(repo_format_name)
512
repo, bzrdir, stacking, repository_policy = \
513
format.initialize_on_transport_ex(target_transport,
514
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
515
force_new_repo=force_new_repo, stacked_on=stacked_on,
516
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
517
make_working_trees=make_working_trees, shared_repo=shared_repo)
521
rich_root = tree_ref = external_lookup = ''
522
repo_bzrdir_name = ''
524
final_stack_pwd = None
527
repo_path = self._repo_relpath(bzrdir.root_transport, repo)
530
rich_root, tree_ref, external_lookup = self._format_to_capabilities(
532
repo_name = repo._format.network_name()
533
repo_bzrdir_name = repo.bzrdir._format.network_name()
534
final_stack = repository_policy._stack_on
535
final_stack_pwd = repository_policy._stack_on_pwd
536
# It is returned locked, but we need to do the lock to get the lock
539
repo_lock_token = repo.lock_write().repository_token or ''
541
repo.leave_lock_in_place()
543
final_stack = final_stack or ''
544
final_stack_pwd = final_stack_pwd or ''
546
# We want this to be relative to the bzrdir.
548
final_stack_pwd = urlutils.relative_url(
549
target_transport.base, final_stack_pwd)
551
# Can't meaningfully return a root path.
552
if final_stack.startswith('/'):
553
client_path = self._root_client_path + final_stack[1:]
554
final_stack = urlutils.relative_url(
555
self._root_client_path, client_path)
556
final_stack_pwd = '.'
558
return SuccessfulSmartServerResponse((repo_path, rich_root, tree_ref,
559
external_lookup, repo_name, repo_bzrdir_name,
560
bzrdir._format.network_name(),
561
self._serialize_NoneTrueFalse(stacking), final_stack,
562
final_stack_pwd, repo_lock_token))
328
565
class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
330
567
def do_bzrdir_request(self):
351
588
return SuccessfulSmartServerResponse(('branch', format))
353
590
return SuccessfulSmartServerResponse(('ref', reference_url))
354
except errors.NotBranchError:
355
return FailedSmartServerResponse(('nobranch', ))
591
except errors.NotBranchError, e:
592
return FailedSmartServerResponse(('nobranch',))
595
class SmartServerRequestOpenBranchV3(SmartServerRequestBzrDir):
597
def do_bzrdir_request(self):
598
"""Open a branch at path and return the reference or format.
600
This version introduced in 2.1.
602
Differences to SmartServerRequestOpenBranchV2:
603
* can return 2-element ('nobranch', extra), where 'extra' is a string
604
with an explanation like 'location is a repository'. Previously
605
a 'nobranch' response would never have more than one element.
608
reference_url = self._bzrdir.get_branch_reference()
609
if reference_url is None:
610
br = self._bzrdir.open_branch(ignore_fallbacks=True)
611
format = br._format.network_name()
612
return SuccessfulSmartServerResponse(('branch', format))
614
return SuccessfulSmartServerResponse(('ref', reference_url))
615
except errors.NotBranchError, e:
616
# Stringify the exception so that its .detail attribute will be
622
if detail.startswith(': '):
625
return FailedSmartServerResponse(resp)