/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

Move bzrlib.transport.smart to bzrlib.smart

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
# TODO: At some point, handle upgrades by just passing the whole request
 
18
# across to run on the server.
 
19
 
 
20
 
 
21
from bzrlib import bzrdir, branch, errors, repository
 
22
from bzrlib.bzrdir import BzrDir, BzrDirFormat
 
23
from bzrlib.branch import Branch, BranchFormat
 
24
from bzrlib.trace import mutter
 
25
 
 
26
 
 
27
class RemoteBzrDirFormat(bzrdir.BzrDirMetaFormat1):
 
28
    """Format representing bzrdirs accessed via a smart server"""
 
29
 
 
30
    def get_format_description(self):
 
31
        return 'bzr remote bzrdir'
 
32
    
 
33
    def probe_transport(self, transport):
 
34
        ## mutter("%r probe for bzrdir in %r" % (self, transport))
 
35
        try:
 
36
            transport.get_smart_client()
 
37
        except (NotImplementedError, AttributeError,
 
38
                errors.TransportNotPossible):
 
39
            raise errors.NoSmartServer(transport.base)
 
40
        else:
 
41
            return self
 
42
 
 
43
    def _open(self, transport):
 
44
        return RemoteBzrDir(transport)
 
45
 
 
46
    def __eq__(self, other):
 
47
        if not isinstance(other, RemoteBzrDirFormat):
 
48
            return False
 
49
        return self.get_format_description() == other.get_format_description()
 
50
 
 
51
 
 
52
class RemoteBzrDir(BzrDir):
 
53
    """Control directory on a remote server, accessed by HPSS."""
 
54
 
 
55
    def __init__(self, transport):
 
56
        BzrDir.__init__(self, transport, RemoteBzrDirFormat())
 
57
        self.client = transport.get_smart_client()
 
58
        # this object holds a delegated bzrdir that uses file-level operations
 
59
        # to talk to the other side
 
60
        # XXX: We should go into find_format, but not allow it to find
 
61
        # RemoteBzrDirFormat and make sure it finds the real underlying format.
 
62
        
 
63
        default_format = BzrDirFormat.get_default_format()
 
64
        self._real_bzrdir = default_format.open(transport, _found=True)
 
65
        self._real_bzrdir._format.probe_transport(transport)
 
66
        self._branch = None
 
67
 
 
68
    def create_repository(self, shared=False):
 
69
        return RemoteRepository(
 
70
            self, self._real_bzrdir.create_repository(shared=shared))
 
71
 
 
72
    def create_branch(self):
 
73
        real_branch = self._real_bzrdir.create_branch()
 
74
        real_repository = real_branch.repository
 
75
        remote_repository = RemoteRepository(self, real_repository)
 
76
        return RemoteBranch(self, remote_repository, real_branch)
 
77
 
 
78
    def create_workingtree(self, revision_id=None):
 
79
        real_workingtree = self._real_bzrdir.create_workingtree(revision_id=revision_id)
 
80
        return RemoteWorkingTree(self, real_workingtree)
 
81
 
 
82
    def open_repository(self):
 
83
        return RemoteRepository(self, self._real_bzrdir.open_repository())
 
84
 
 
85
    def open_branch(self, _unsupported=False):
 
86
        real_branch = self._real_bzrdir.open_branch(unsupported=_unsupported)
 
87
        if real_branch.bzrdir is self._real_bzrdir:
 
88
            # This branch accessed through the smart server, so wrap the
 
89
            # file-level objects.
 
90
            real_repository = real_branch.repository
 
91
            remote_repository = RemoteRepository(self, real_repository)
 
92
            return RemoteBranch(self, remote_repository, real_branch)
 
93
        else:
 
94
            # We were redirected to somewhere else, so don't wrap.
 
95
            return real_branch
 
96
 
 
97
    def open_workingtree(self):
 
98
        return RemoteWorkingTree(self, self._real_bzrdir.open_workingtree())
 
99
 
 
100
    def get_branch_transport(self, branch_format):
 
101
        return self._real_bzrdir.get_branch_transport(branch_format)
 
102
 
 
103
    def get_repository_transport(self, repository_format):
 
104
        return self._real_bzrdir.get_repository_transport(repository_format)
 
105
 
 
106
    def get_workingtree_transport(self, workingtree_format):
 
107
        return self._real_bzrdir.get_workingtree_transport(workingtree_format)
 
108
 
 
109
    def can_convert_format(self):
 
110
        """Upgrading of remote bzrdirs is not supported yet."""
 
111
        return False
 
112
 
 
113
    def needs_format_conversion(self, format=None):
 
114
        """Upgrading of remote bzrdirs is not supported yet."""
 
115
        return False
 
116
 
 
117
 
 
118
class RemoteRepositoryFormat(repository.RepositoryFormat):
 
119
    """Format for repositories accessed over rpc.
 
120
 
 
121
    Instances of this repository are represented by RemoteRepository
 
122
    instances.
 
123
    """
 
124
 
 
125
    _matchingbzrdir = RemoteBzrDirFormat
 
126
 
 
127
    def initialize(self, a_bzrdir, shared=False):
 
128
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
129
        return a_bzrdir.create_repository(shared=shared)
 
130
    
 
131
    def open(self, a_bzrdir):
 
132
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
133
        return a_bzrdir.open_repository()
 
134
 
 
135
    def get_format_description(self):
 
136
        return 'bzr remote repository'
 
137
 
 
138
    def __eq__(self, other):
 
139
        return self.__class__ == other.__class__
 
140
 
 
141
    rich_root_data = False
 
142
 
 
143
 
 
144
class RemoteRepository(object):
 
145
    """Repository accessed over rpc.
 
146
 
 
147
    For the moment everything is delegated to IO-like operations over
 
148
    the transport.
 
149
    """
 
150
 
 
151
    def __init__(self, remote_bzrdir, real_repository):
 
152
        self.real_repository = real_repository
 
153
        self.bzrdir = remote_bzrdir
 
154
        self._format = RemoteRepositoryFormat()
 
155
 
 
156
    def __getattr__(self, name):
 
157
        # XXX: temporary way to lazily delegate everything to the real
 
158
        # repository
 
159
        return getattr(self.real_repository, name)
 
160
 
 
161
 
 
162
class RemoteBranchFormat(branch.BranchFormat):
 
163
 
 
164
    def open(self, a_bzrdir):
 
165
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
166
        return a_bzrdir.open_branch()
 
167
 
 
168
    def initialize(self, a_bzrdir):
 
169
        assert isinstance(a_bzrdir, RemoteBzrDir)
 
170
        return a_bzrdir.create_branch()
 
171
 
 
172
 
 
173
class RemoteBranch(branch.Branch):
 
174
    """Branch stored on a server accessed by HPSS RPC.
 
175
 
 
176
    At the moment most operations are mapped down to simple file operations.
 
177
    """
 
178
 
 
179
    def __init__(self, remote_bzrdir, remote_repository, real_branch):
 
180
        self.bzrdir = remote_bzrdir
 
181
        self.transport = remote_bzrdir.transport
 
182
        self.repository = remote_repository
 
183
        self._real_branch = real_branch
 
184
        self._format = RemoteBranchFormat()
 
185
 
 
186
    def lock_read(self):
 
187
        return self._real_branch.lock_read()
 
188
 
 
189
    def lock_write(self):
 
190
        return self._real_branch.lock_write()
 
191
 
 
192
    def unlock(self):
 
193
        return self._real_branch.unlock()
 
194
 
 
195
    def break_lock(self):
 
196
        return self._real_branch.break_lock()
 
197
 
 
198
    def revision_history(self):
 
199
        return self._real_branch.revision_history()
 
200
 
 
201
    def set_revision_history(self, rev_history):
 
202
        return self._real_branch.set_revision_history(rev_history)
 
203
 
 
204
    def get_parent(self):
 
205
        return self._real_branch.get_parent()
 
206
        
 
207
    def set_parent(self, url):
 
208
        return self._real_branch.set_parent(url)
 
209
        
 
210
 
 
211
class RemoteWorkingTree(object):
 
212
 
 
213
    def __init__(self, remote_bzrdir, real_workingtree):
 
214
        self.real_workingtree = real_workingtree
 
215
        self.bzrdir = remote_bzrdir
 
216
 
 
217
    def __getattr__(self, name):
 
218
        # XXX: temporary way to lazily delegate everything to the real
 
219
        # workingtree
 
220
        return getattr(self.real_workingtree, name)
 
221
 
 
222
 
 
223
# when first loaded, register this format.
 
224
#
 
225
# TODO: Actually this needs to be done earlier; we can hold off on loading
 
226
# this code until it's needed though.
 
227
 
 
228
# We can't use register_control_format because it adds it at a lower priority
 
229
# than the existing branches, whereas this should take priority.
 
230
BzrDirFormat._control_formats.insert(0, RemoteBzrDirFormat())