1
# Copyright (C) 2006 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
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
17
"""Server-side bzrdir related request implmentations."""
20
from bzrlib import errors
21
from bzrlib.bzrdir import BzrDir, BzrDirFormat
22
from bzrlib.smart.request import (
23
FailedSmartServerResponse,
25
SuccessfulSmartServerResponse,
29
class SmartServerRequestOpenBzrDir(SmartServerRequest):
32
from bzrlib.bzrdir import BzrDirFormat
34
t = self.transport_from_client_path(path)
35
except errors.PathNotChild:
36
# The client is trying to ask about a path that they have no access
38
# Ideally we'd return a FailedSmartServerResponse here rather than
39
# a "successful" negative, but we want to be compatibile with
40
# clients that don't anticipate errors from this method.
43
default_format = BzrDirFormat.get_default_format()
44
real_bzrdir = default_format.open(t, _found=True)
46
real_bzrdir._format.probe_transport(t)
47
except (errors.NotBranchError, errors.UnknownFormatError):
51
return SuccessfulSmartServerResponse((answer,))
54
class SmartServerRequestFindRepository(SmartServerRequest):
56
def _boolean_to_yes_no(self, a_boolean):
62
def _find(self, path):
63
"""try to find a repository from path upwards
65
This operates precisely like 'bzrdir.find_repository'.
67
:return: (relpath, rich_root, tree_ref, external_lookup) flags. All are
68
strings, relpath is a / prefixed path, and the other three are
70
:raises errors.NoRepositoryPresent: When there is no repository
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
77
# path segments to pop-out.
78
relpath = repository.bzrdir.root_transport.relpath(
79
bzrdir.root_transport.base)
81
segments = ['..'] * len(relpath.split('/'))
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
92
class SmartServerRequestFindRepositoryV1(SmartServerRequestFindRepository):
95
"""try to find a repository from path upwards
97
This operates precisely like 'bzrdir.find_repository'.
99
If a bzrdir is not present, an exception is propogated
100
rather than 'no branch' because these are different conditions.
102
This is the initial version of this method introduced with the smart
103
server. Modern clients will try the V2 method that adds support for the
104
supports_external_lookups attribute.
106
:return: norepository or ok, relpath.
109
path, rich_root, tree_ref, external_lookup = self._find(path)
110
return SuccessfulSmartServerResponse(('ok', path, rich_root, tree_ref))
111
except errors.NoRepositoryPresent:
112
return FailedSmartServerResponse(('norepository', ))
115
class SmartServerRequestFindRepositoryV2(SmartServerRequestFindRepository):
118
"""try to find a repository from path upwards
120
This operates precisely like 'bzrdir.find_repository'.
122
If a bzrdir is not present, an exception is propogated
123
rather than 'no branch' because these are different conditions.
125
This is the second edition of this method introduced in bzr 1.3, which
126
returns information about the supports_external_lookups format
129
:return: norepository or ok, relpath.
132
path, rich_root, tree_ref, external_lookup = self._find(path)
133
return SuccessfulSmartServerResponse(
134
('ok', path, rich_root, tree_ref, external_lookup))
135
except errors.NoRepositoryPresent:
136
return FailedSmartServerResponse(('norepository', ))
139
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
142
"""Initialize a bzrdir at path.
144
The default format of the server is used.
145
:return: SmartServerResponse(('ok', ))
147
target_transport = self.transport_from_client_path(path)
148
BzrDirFormat.get_default_format().initialize_on_transport(target_transport)
149
return SuccessfulSmartServerResponse(('ok', ))
152
class SmartServerRequestOpenBranch(SmartServerRequest):
155
"""try to open a branch at path and return ok/nobranch.
157
If a bzrdir is not present, an exception is propogated
158
rather than 'no branch' because these are different conditions.
160
bzrdir = BzrDir.open_from_transport(
161
self.transport_from_client_path(path))
163
reference_url = bzrdir.get_branch_reference()
164
if reference_url is None:
165
return SuccessfulSmartServerResponse(('ok', ''))
167
return SuccessfulSmartServerResponse(('ok', reference_url))
168
except errors.NotBranchError:
169
return FailedSmartServerResponse(('nobranch', ))