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
33
t = self._backing_transport.clone(path)
34
default_format = BzrDirFormat.get_default_format()
35
real_bzrdir = default_format.open(t, _found=True)
37
real_bzrdir._format.probe_transport(t)
38
except (errors.NotBranchError, errors.UnknownFormatError):
42
return SuccessfulSmartServerResponse((answer,))
45
class SmartServerRequestFindRepository(SmartServerRequest):
47
def _boolean_to_yes_no(self, a_boolean):
53
def _find(self, path):
54
"""try to find a repository from path upwards
56
This operates precisely like 'bzrdir.find_repository'.
58
:return: (relpath, rich_root, tree_ref, external_lookup) flags. All are
59
strings, relpath is a / prefixed path, and the other three are
61
:raises errors.NoRepositoryPresent: When there is no repository
64
bzrdir = BzrDir.open_from_transport(self._backing_transport.clone(path))
65
repository = bzrdir.find_repository()
66
# the relpath of the bzrdir in the found repository gives us the
67
# path segments to pop-out.
68
relpath = repository.bzrdir.root_transport.relpath(bzrdir.root_transport.base)
70
segments = ['..'] * len(relpath.split('/'))
73
rich_root = self._boolean_to_yes_no(repository.supports_rich_root())
74
tree_ref = self._boolean_to_yes_no(
75
repository._format.supports_tree_reference)
76
external_lookup = self._boolean_to_yes_no(
77
repository._format.supports_external_lookups)
78
return '/'.join(segments), rich_root, tree_ref, external_lookup
81
class SmartServerRequestFindRepositoryV1(SmartServerRequestFindRepository):
84
"""try to find a repository from path upwards
86
This operates precisely like 'bzrdir.find_repository'.
88
If a bzrdir is not present, an exception is propogated
89
rather than 'no branch' because these are different conditions.
91
This is the initial version of this method introduced with the smart
92
server. Modern clients will try the V2 method that adds support for the
93
supports_external_lookups attribute.
95
:return: norepository or ok, relpath.
98
path, rich_root, tree_ref, external_lookup = self._find(path)
99
return SuccessfulSmartServerResponse(('ok', path, rich_root, tree_ref))
100
except errors.NoRepositoryPresent:
101
return FailedSmartServerResponse(('norepository', ))
104
class SmartServerRequestFindRepositoryV2(SmartServerRequestFindRepository):
107
"""try to find a repository from path upwards
109
This operates precisely like 'bzrdir.find_repository'.
111
If a bzrdir is not present, an exception is propogated
112
rather than 'no branch' because these are different conditions.
114
This is the second edition of this method introduced in bzr 1.3, which
115
returns information about the supports_external_lookups format
118
:return: norepository or ok, relpath.
121
path, rich_root, tree_ref, external_lookup = self._find(path)
122
return SuccessfulSmartServerResponse(
123
('ok', path, rich_root, tree_ref, external_lookup))
124
except errors.NoRepositoryPresent:
125
return FailedSmartServerResponse(('norepository', ))
128
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
131
"""Initialize a bzrdir at path.
133
The default format of the server is used.
134
:return: SmartServerResponse(('ok', ))
136
target_transport = self._backing_transport.clone(path)
137
BzrDirFormat.get_default_format().initialize_on_transport(target_transport)
138
return SuccessfulSmartServerResponse(('ok', ))
141
class SmartServerRequestOpenBranch(SmartServerRequest):
144
"""try to open a branch at path and return ok/nobranch.
146
If a bzrdir is not present, an exception is propogated
147
rather than 'no branch' because these are different conditions.
149
bzrdir = BzrDir.open_from_transport(self._backing_transport.clone(path))
151
reference_url = bzrdir.get_branch_reference()
152
if reference_url is None:
153
return SuccessfulSmartServerResponse(('ok', ''))
155
return SuccessfulSmartServerResponse(('ok', reference_url))
156
except errors.NotBranchError:
157
return FailedSmartServerResponse(('nobranch', ))