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
17
17
"""Server-side bzrdir related request implmentations."""
20
from bzrlib import branch, errors, repository, urlutils
21
from bzrlib.bzrdir import (
27
from bzrlib.controldir import (
28
network_format_registry,
20
from bzrlib import branch, errors, repository
21
from bzrlib.bzrdir import BzrDir, BzrDirFormat, BzrDirMetaFormat1
30
22
from bzrlib.smart.request import (
31
23
FailedSmartServerResponse,
32
24
SmartServerRequest,
57
51
return SuccessfulSmartServerResponse((answer,))
60
class SmartServerRequestOpenBzrDir_2_1(SmartServerRequest):
63
"""Is there a BzrDir present, and if so does it have a working tree?
68
t = self.transport_from_client_path(path)
69
except errors.PathNotChild:
70
# The client is trying to ask about a path that they have no access
72
return SuccessfulSmartServerResponse(('no',))
74
bd = BzrDir.open_from_transport(t)
75
except errors.NotBranchError:
79
if bd.has_workingtree():
83
return SuccessfulSmartServerResponse(answer)
86
54
class SmartServerRequestBzrDir(SmartServerRequest):
88
56
def do(self, path, *args):
89
"""Open a BzrDir at path, and return `self.do_bzrdir_request(*args)`."""
57
"""Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
91
59
self._bzrdir = BzrDir.open_from_transport(
92
60
self.transport_from_client_path(path))
93
except errors.NotBranchError, e:
94
return FailedSmartServerResponse(('nobranch',))
61
except errors.NotBranchError:
62
return FailedSmartServerResponse(('nobranch', ))
95
63
return self.do_bzrdir_request(*args)
97
65
def _boolean_to_yes_no(self, a_boolean):
124
92
class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
126
94
def do_bzrdir_request(self, require_stacking):
127
"""Get the format that should be used when cloning from this dir.
131
:return: on success, a 3-tuple of network names for (control,
132
repository, branch) directories, where '' signifies "not present".
133
If this BzrDir contains a branch reference then this will fail with
134
BranchReference; clients should resolve branch references before
95
"""Get the format that should be used when cloning from this dir."""
138
97
branch_ref = self._bzrdir.get_branch_reference()
139
98
except errors.NotBranchError:
141
if branch_ref is not None:
142
# The server shouldn't try to resolve references, and it quite
143
# possibly can't reach them anyway. The client needs to resolve
144
# the branch reference to determine the cloning_metadir.
145
return FailedSmartServerResponse(('BranchReference',))
146
100
if require_stacking == "True":
147
101
require_stacking = True
150
104
control_format = self._bzrdir.cloning_metadir(
151
105
require_stacking=require_stacking)
152
106
control_name = control_format.network_name()
153
# XXX: There should be a method that tells us that the format does/does
154
# not have subformats.
107
# XXX: There should be a method that tells us that the format does/does not
155
109
if isinstance(control_format, BzrDirMetaFormat1):
156
branch_name = ('branch',
157
control_format.get_branch_format().network_name())
110
if branch_ref is not None:
111
# If there's a branch reference, the client will have to resolve
112
# the branch reference to figure out the cloning metadir
113
branch_name = ('ref', branch_ref)
115
branch_name = ('branch',
116
control_format.get_branch_format().network_name())
158
117
repository_name = control_format.repository_format.network_name()
160
119
# Only MetaDir has delegated formats today.
358
301
return SuccessfulSmartServerResponse(('ok', ))
361
class SmartServerRequestBzrDirInitializeEx(SmartServerRequestBzrDir):
363
def parse_NoneTrueFalse(self, arg):
370
raise AssertionError("invalid arg %r" % arg)
372
def parse_NoneString(self, arg):
375
def _serialize_NoneTrueFalse(self, arg):
382
def do(self, bzrdir_network_name, path, use_existing_dir, create_prefix,
383
force_new_repo, stacked_on, stack_on_pwd, repo_format_name,
384
make_working_trees, shared_repo):
385
"""Initialize a bzrdir at path as per
386
BzrDirFormat.initialize_on_transport_ex.
388
New in 1.16. (Replaces BzrDirFormat.initialize_ex verb from 1.15).
390
:return: return SuccessfulSmartServerResponse((repo_path, rich_root,
391
tree_ref, external_lookup, repo_network_name,
392
repo_bzrdir_network_name, bzrdir_format_network_name,
393
NoneTrueFalse(stacking), final_stack, final_stack_pwd,
396
target_transport = self.transport_from_client_path(path)
397
format = network_format_registry.get(bzrdir_network_name)
398
use_existing_dir = self.parse_NoneTrueFalse(use_existing_dir)
399
create_prefix = self.parse_NoneTrueFalse(create_prefix)
400
force_new_repo = self.parse_NoneTrueFalse(force_new_repo)
401
stacked_on = self.parse_NoneString(stacked_on)
402
stack_on_pwd = self.parse_NoneString(stack_on_pwd)
403
make_working_trees = self.parse_NoneTrueFalse(make_working_trees)
404
shared_repo = self.parse_NoneTrueFalse(shared_repo)
405
if stack_on_pwd == '.':
406
stack_on_pwd = target_transport.base
407
repo_format_name = self.parse_NoneString(repo_format_name)
408
repo, bzrdir, stacking, repository_policy = \
409
format.initialize_on_transport_ex(target_transport,
410
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
411
force_new_repo=force_new_repo, stacked_on=stacked_on,
412
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
413
make_working_trees=make_working_trees, shared_repo=shared_repo)
417
rich_root = tree_ref = external_lookup = ''
418
repo_bzrdir_name = ''
420
final_stack_pwd = None
423
repo_path = self._repo_relpath(bzrdir.root_transport, repo)
426
rich_root, tree_ref, external_lookup = self._format_to_capabilities(
428
repo_name = repo._format.network_name()
429
repo_bzrdir_name = repo.bzrdir._format.network_name()
430
final_stack = repository_policy._stack_on
431
final_stack_pwd = repository_policy._stack_on_pwd
432
# It is returned locked, but we need to do the lock to get the lock
435
repo_lock_token = repo.lock_write().repository_token or ''
437
repo.leave_lock_in_place()
439
final_stack = final_stack or ''
440
final_stack_pwd = final_stack_pwd or ''
442
# We want this to be relative to the bzrdir.
444
final_stack_pwd = urlutils.relative_url(
445
target_transport.base, final_stack_pwd)
447
# Can't meaningfully return a root path.
448
if final_stack.startswith('/'):
449
client_path = self._root_client_path + final_stack[1:]
450
final_stack = urlutils.relative_url(
451
self._root_client_path, client_path)
452
final_stack_pwd = '.'
454
return SuccessfulSmartServerResponse((repo_path, rich_root, tree_ref,
455
external_lookup, repo_name, repo_bzrdir_name,
456
bzrdir._format.network_name(),
457
self._serialize_NoneTrueFalse(stacking), final_stack,
458
final_stack_pwd, repo_lock_token))
461
304
class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
463
306
def do_bzrdir_request(self):
480
323
reference_url = self._bzrdir.get_branch_reference()
481
324
if reference_url is None:
482
br = self._bzrdir.open_branch(ignore_fallbacks=True)
483
format = br._format.network_name()
484
return SuccessfulSmartServerResponse(('branch', format))
486
return SuccessfulSmartServerResponse(('ref', reference_url))
487
except errors.NotBranchError, e:
488
return FailedSmartServerResponse(('nobranch',))
491
class SmartServerRequestOpenBranchV3(SmartServerRequestBzrDir):
493
def do_bzrdir_request(self):
494
"""Open a branch at path and return the reference or format.
496
This version introduced in 2.1.
498
Differences to SmartServerRequestOpenBranchV2:
499
* can return 2-element ('nobranch', extra), where 'extra' is a string
500
with an explanation like 'location is a repository'. Previously
501
a 'nobranch' response would never have more than one element.
504
reference_url = self._bzrdir.get_branch_reference()
505
if reference_url is None:
506
br = self._bzrdir.open_branch(ignore_fallbacks=True)
507
format = br._format.network_name()
508
return SuccessfulSmartServerResponse(('branch', format))
510
return SuccessfulSmartServerResponse(('ref', reference_url))
511
except errors.NotBranchError, e:
512
# Stringify the exception so that its .detail attribute will be
518
if detail.startswith(': '):
521
return FailedSmartServerResponse(resp)
325
format = self._bzrdir.open_branch()._format.network_name()
326
return SuccessfulSmartServerResponse(('branch', format))
328
return SuccessfulSmartServerResponse(('ref', reference_url))
329
except errors.NotBranchError:
330
return FailedSmartServerResponse(('nobranch', ))