~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/bzrdir.py

merge merge tweaks from aaron, which includes latest .dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 Canonical Ltd
2
 
#
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.
7
 
#
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.
12
 
#
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
16
 
 
17
 
"""Server-side bzrdir related request implmentations."""
18
 
 
19
 
 
20
 
from bzrlib import errors
21
 
from bzrlib.bzrdir import BzrDir, BzrDirFormat
22
 
from bzrlib.smart.request import (
23
 
    FailedSmartServerResponse,
24
 
    SmartServerRequest,
25
 
    SuccessfulSmartServerResponse,
26
 
    )
27
 
 
28
 
 
29
 
class SmartServerRequestOpenBzrDir(SmartServerRequest):
30
 
 
31
 
    def do(self, path):
32
 
        from bzrlib.bzrdir import BzrDirFormat
33
 
        try:
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
37
 
            # to.
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.
41
 
            answer = 'no'
42
 
        else:
43
 
            default_format = BzrDirFormat.get_default_format()
44
 
            real_bzrdir = default_format.open(t, _found=True)
45
 
            try:
46
 
                real_bzrdir._format.probe_transport(t)
47
 
            except (errors.NotBranchError, errors.UnknownFormatError):
48
 
                answer = 'no'
49
 
            else:
50
 
                answer = 'yes'
51
 
        return SuccessfulSmartServerResponse((answer,))
52
 
 
53
 
 
54
 
class SmartServerRequestFindRepository(SmartServerRequest):
55
 
 
56
 
    def _boolean_to_yes_no(self, a_boolean):
57
 
        if a_boolean:
58
 
            return 'yes'
59
 
        else:
60
 
            return 'no'
61
 
 
62
 
    def _find(self, path):
63
 
        """try to find a repository from path upwards
64
 
        
65
 
        This operates precisely like 'bzrdir.find_repository'.
66
 
        
67
 
        :return: (relpath, rich_root, tree_ref, external_lookup) flags. All are
68
 
            strings, relpath is a / prefixed path, and the other three are
69
 
            either 'yes' or 'no'.
70
 
        :raises errors.NoRepositoryPresent: When there is no repository
71
 
            present.
72
 
        """
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)
80
 
        if len(relpath):
81
 
            segments = ['..'] * len(relpath.split('/'))
82
 
        else:
83
 
            segments = []
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
90
 
 
91
 
 
92
 
class SmartServerRequestFindRepositoryV1(SmartServerRequestFindRepository):
93
 
 
94
 
    def do(self, path):
95
 
        """try to find a repository from path upwards
96
 
        
97
 
        This operates precisely like 'bzrdir.find_repository'.
98
 
        
99
 
        If a bzrdir is not present, an exception is propogated
100
 
        rather than 'no branch' because these are different conditions.
101
 
 
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.
105
 
 
106
 
        :return: norepository or ok, relpath.
107
 
        """
108
 
        try:
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', ))
113
 
 
114
 
 
115
 
class SmartServerRequestFindRepositoryV2(SmartServerRequestFindRepository):
116
 
 
117
 
    def do(self, path):
118
 
        """try to find a repository from path upwards
119
 
        
120
 
        This operates precisely like 'bzrdir.find_repository'.
121
 
        
122
 
        If a bzrdir is not present, an exception is propogated
123
 
        rather than 'no branch' because these are different conditions.
124
 
 
125
 
        This is the second edition of this method introduced in bzr 1.3, which
126
 
        returns information about the supports_external_lookups format
127
 
        attribute too.
128
 
 
129
 
        :return: norepository or ok, relpath.
130
 
        """
131
 
        try:
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', ))
137
 
 
138
 
 
139
 
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
140
 
 
141
 
    def do(self, path):
142
 
        """Initialize a bzrdir at path.
143
 
 
144
 
        The default format of the server is used.
145
 
        :return: SmartServerResponse(('ok', ))
146
 
        """
147
 
        target_transport = self.transport_from_client_path(path)
148
 
        BzrDirFormat.get_default_format().initialize_on_transport(target_transport)
149
 
        return SuccessfulSmartServerResponse(('ok', ))
150
 
 
151
 
 
152
 
class SmartServerRequestOpenBranch(SmartServerRequest):
153
 
 
154
 
    def do(self, path):
155
 
        """try to open a branch at path and return ok/nobranch.
156
 
        
157
 
        If a bzrdir is not present, an exception is propogated
158
 
        rather than 'no branch' because these are different conditions.
159
 
        """
160
 
        bzrdir = BzrDir.open_from_transport(
161
 
            self.transport_from_client_path(path))
162
 
        try:
163
 
            reference_url = bzrdir.get_branch_reference()
164
 
            if reference_url is None:
165
 
                return SuccessfulSmartServerResponse(('ok', ''))
166
 
            else:
167
 
                return SuccessfulSmartServerResponse(('ok', reference_url))
168
 
        except errors.NotBranchError:
169
 
            return FailedSmartServerResponse(('nobranch', ))