1
# Copyright (C) 2006-2010 Canonical Ltd
1
# Copyright (C) 2006 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Server-side bzrdir related request implmentations."""
20
from bzrlib import branch, errors, repository, urlutils
20
from bzrlib import branch, errors, repository
21
21
from bzrlib.bzrdir import (
27
from bzrlib.controldir import (
28
25
network_format_registry,
30
27
from bzrlib.smart.request import (
47
45
# clients that don't anticipate errors from this method.
50
bzr_prober = BzrProber()
48
default_format = BzrDirFormat.get_default_format()
49
real_bzrdir = default_format.open(t, _found=True)
52
bzr_prober.probe_transport(t)
51
real_bzrdir._format.probe_transport(t)
53
52
except (errors.NotBranchError, errors.UnknownFormatError):
57
56
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
59
class SmartServerRequestBzrDir(SmartServerRequest):
88
61
def do(self, path, *args):
89
"""Open a BzrDir at path, and return `self.do_bzrdir_request(*args)`."""
62
"""Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
91
64
self._bzrdir = BzrDir.open_from_transport(
92
65
self.transport_from_client_path(path))
93
except errors.NotBranchError, e:
94
return FailedSmartServerResponse(('nobranch',))
66
except errors.NotBranchError:
67
return FailedSmartServerResponse(('nobranch', ))
95
68
return self.do_bzrdir_request(*args)
97
70
def _boolean_to_yes_no(self, a_boolean):
112
85
"""Get the relative path for repository from current_transport."""
113
86
# the relpath of the bzrdir in the found repository gives us the
114
87
# path segments to pop-out.
115
relpath = repository.user_transport.relpath(
88
relpath = repository.bzrdir.root_transport.relpath(
116
89
current_transport.base)
118
91
segments = ['..'] * len(relpath.split('/'))
182
155
:param path: The path to the bzrdir.
183
156
:param network_name: The network name of the branch type to create.
184
:return: ('ok', branch_format, repo_path, rich_root, tree_ref,
185
external_lookup, repo_format)
157
:return: (ok, network_name)
187
159
bzrdir = BzrDir.open_from_transport(
188
160
self.transport_from_client_path(path))
382
354
def do(self, bzrdir_network_name, path, use_existing_dir, create_prefix,
383
355
force_new_repo, stacked_on, stack_on_pwd, repo_format_name,
384
356
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).
357
"""Initialize a bzrdir at path as per BzrDirFormat.initialize_ex
390
359
:return: return SuccessfulSmartServerResponse((repo_path, rich_root,
391
360
tree_ref, external_lookup, repo_network_name,
432
401
# 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 ''
404
repo_lock_token = repo.lock_write() or ''
436
405
if repo_lock_token:
437
406
repo.leave_lock_in_place()
439
408
final_stack = final_stack or ''
440
409
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
410
return SuccessfulSmartServerResponse((repo_path, rich_root, tree_ref,
455
411
external_lookup, repo_name, repo_bzrdir_name,
456
412
bzrdir._format.network_name(),
468
424
return SuccessfulSmartServerResponse(('ok', ''))
470
426
return SuccessfulSmartServerResponse(('ok', reference_url))
471
except errors.NotBranchError, e:
472
return FailedSmartServerResponse(('nobranch',))
427
except errors.NotBranchError:
428
return FailedSmartServerResponse(('nobranch', ))
475
431
class SmartServerRequestOpenBranchV2(SmartServerRequestBzrDir):
484
440
return SuccessfulSmartServerResponse(('branch', format))
486
442
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)
443
except errors.NotBranchError:
444
return FailedSmartServerResponse(('nobranch', ))