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', ))