/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/remotebranch.py

  • Committer: Robert Collins
  • Date: 2005-09-30 02:54:51 UTC
  • mfrom: (1395)
  • mto: This revision was merged to the branch mainline in revision 1397.
  • Revision ID: robertc@robertcollins.net-20050930025451-47b9e412202be44b
symlink and weaves, whaddya know

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /usr/bin/env python
2
 
 
3
1
# Copyright (C) 2005 Canonical Ltd
4
2
 
5
3
# This program is free software; you can redistribute it and/or modify
26
24
 
27
25
import gzip
28
26
from cStringIO import StringIO
 
27
import os
29
28
import urllib2
30
 
 
31
 
from errors import BzrError, BzrCheckError
32
 
from branch import Branch, BZR_BRANCH_FORMAT
33
 
from trace import mutter
 
29
import urlparse
 
30
 
 
31
from bzrlib.errors import BzrError, BzrCheckError
 
32
from bzrlib.branch import Branch, LocalBranch, BZR_BRANCH_FORMAT_5
 
33
from bzrlib.trace import mutter
 
34
from bzrlib.weavestore import WeaveStore
 
35
from bzrlib.xml5 import serializer_v5
 
36
 
34
37
 
35
38
# velocitynet.com.au transparently proxies connections and thereby
36
39
# breaks keep-alive -- sucks!
37
40
 
38
41
 
39
 
ENABLE_URLGRABBER = True
 
42
ENABLE_URLGRABBER = False
40
43
 
41
 
from bzrlib.errors import BzrError
 
44
from bzrlib.errors import BzrError, NoSuchRevision
42
45
 
43
46
class GetFailed(BzrError):
44
47
    def __init__(self, url, status):
47
50
        self.status = status
48
51
 
49
52
if ENABLE_URLGRABBER:
50
 
    import urlgrabber
51
 
    import urlgrabber.keepalive
52
 
    urlgrabber.keepalive.DEBUG = 0
 
53
    import util.urlgrabber
 
54
    import util.urlgrabber.keepalive
 
55
    util.urlgrabber.keepalive.DEBUG = 0
53
56
    def get_url(path, compressed=False):
54
57
        try:
55
58
            url = path
56
59
            if compressed:
57
60
                url += '.gz'
58
61
            mutter("grab url %s" % url)
59
 
            url_f = urlgrabber.urlopen(url, keepalive=1, close_connection=0)
 
62
            url_f = util.urlgrabber.urlopen(url, keepalive=1, close_connection=0)
60
63
            if url_f.status != 200:
61
64
                raise GetFailed(url, url_f.status)
62
65
            if not compressed:
78
81
            return url_f
79
82
 
80
83
 
81
 
 
82
84
def _find_remote_root(url):
83
85
    """Return the prefix URL that corresponds to the branch root."""
84
86
    orig_url = url
85
87
    while True:
86
88
        try:
87
 
            ff = get_url(url + '/.bzr/branch-format')
88
 
 
 
89
            fmt_url = url + '/.bzr/branch-format'
 
90
            ff = get_url(fmt_url)
89
91
            fmt = ff.read()
90
92
            ff.close()
91
93
 
92
 
            fmt = fmt.rstrip('\r\n')
93
 
            if fmt != BZR_BRANCH_FORMAT.rstrip('\r\n'):
 
94
            if fmt != BZR_BRANCH_FORMAT_5:
94
95
                raise BzrError("sorry, branch format %r not supported at url %s"
95
96
                               % (fmt, url))
96
97
            
98
99
        except urllib2.URLError:
99
100
            pass
100
101
 
101
 
        try:
102
 
            idx = url.rindex('/')
103
 
        except ValueError:
104
 
            raise BzrError('no branch root found for URL %s' % orig_url)
105
 
 
106
 
        url = url[:idx]        
107
 
        
108
 
 
109
 
 
110
 
class RemoteBranch(Branch):
 
102
        scheme, host, path = list(urlparse.urlparse(url))[:3]
 
103
        # discard params, query, fragment
 
104
        
 
105
        # strip off one component of the path component
 
106
        idx = path.rfind('/')
 
107
        if idx == -1 or path == '/':
 
108
            raise BzrError('no branch root found for URL %s'
 
109
                           ' or enclosing directories'
 
110
                           % orig_url)
 
111
        path = path[:idx]
 
112
        url = urlparse.urlunparse((scheme, host, path, '', '', ''))
 
113
        
 
114
 
 
115
 
 
116
class RemoteBranch(LocalBranch):
 
117
 
111
118
    def __init__(self, baseurl, find_root=True):
112
119
        """Create new proxy for a remote branch."""
 
120
        # circular import protection
 
121
        from bzrlib.store import RemoteStore
113
122
        if find_root:
114
 
            self.baseurl = _find_remote_root(baseurl)
 
123
            self.base = _find_remote_root(baseurl)
115
124
        else:
116
 
            self.baseurl = baseurl
117
 
            self._check_format()
 
125
            self.base = baseurl
 
126
        self._check_format(False)
 
127
        # is guaranteed to be a v5 store
118
128
 
119
 
        self.inventory_store = RemoteStore(baseurl + '/.bzr/inventory-store/')
120
 
        self.text_store = RemoteStore(baseurl + '/.bzr/text-store/')
121
 
        self.revision_store = RemoteStore(baseurl + '/.bzr/revision-store/')
 
129
        cfn = self.controlfilename
 
130
        assert self._branch_format == 5
 
131
        self.control_weaves = WeaveStore(cfn([]), get_url)
 
132
        self.weave_store = WeaveStore(cfn('weaves'), get_url)
 
133
        self.revision_store = RemoteStore(cfn('revision-store'))
122
134
 
123
135
    def __str__(self):
124
136
        b = getattr(self, 'baseurl', 'undefined')
126
138
 
127
139
    __repr__ = __str__
128
140
 
 
141
    def setup_caching(self, cache_root):
 
142
        """Set up cached stores located under cache_root"""
 
143
        from bzrlib.meta_store import CachedStore
 
144
        for store_name in ('revision_store',):
 
145
            if not isinstance(getattr(self, store_name), CachedStore):
 
146
                cache_path = os.path.join(cache_root, store_name)
 
147
                os.mkdir(cache_path)
 
148
                new_store = CachedStore(getattr(self, store_name), cache_path)
 
149
                setattr(self, store_name, new_store)
 
150
 
129
151
    def controlfile(self, filename, mode):
130
152
        if mode not in ('rb', 'rt', 'r'):
131
153
            raise BzrError("file mode %r not supported for remote branches" % mode)
132
 
        return get_url(self.baseurl + '/.bzr/' + filename, False)
 
154
        return get_url(self.base + '/.bzr/' + filename, False)
133
155
 
134
156
 
135
157
    def lock_read(self):
139
161
    def lock_write(self):
140
162
        from errors import LockError
141
163
        raise LockError("write lock not supported for remote branch %s"
142
 
                        % self.baseurl)
 
164
                        % self.base)
143
165
 
144
166
    def unlock(self):
145
167
        pass
146
168
    
147
169
 
148
170
    def relpath(self, path):
149
 
        if not path.startswith(self.baseurl):
 
171
        if not path.startswith(self.base):
150
172
            raise BzrError('path %r is not under base URL %r'
151
 
                           % (path, self.baseurl))
152
 
        pl = len(self.baseurl)
 
173
                           % (path, self.base))
 
174
        pl = len(self.base)
153
175
        return path[pl:].lstrip('/')
154
176
 
155
177
 
156
178
    def get_revision(self, revision_id):
157
 
        from bzrlib.revision import Revision
158
 
        from bzrlib.xml import unpack_xml
159
 
        revf = self.revision_store[revision_id]
160
 
        r = unpack_xml(Revision, revf)
 
179
        try:
 
180
            revf = self.revision_store[revision_id]
 
181
        except KeyError:
 
182
            raise NoSuchRevision(self, revision_id)
 
183
        r = serializer_v5.read_revision(revf)
161
184
        if r.revision_id != revision_id:
162
185
            raise BzrCheckError('revision stored as {%s} actually contains {%s}'
163
186
                                % (revision_id, r.revision_id))
164
187
        return r
165
 
 
166
 
 
167
 
class RemoteStore(object):
168
 
    def __init__(self, baseurl):
169
 
        self._baseurl = baseurl
170
 
        
171
 
 
172
 
    def _path(self, name):
173
 
        if '/' in name:
174
 
            raise ValueError('invalid store id', name)
175
 
        return self._baseurl + '/' + name
176
 
        
177
 
    def __getitem__(self, fileid):
178
 
        p = self._path(fileid)
179
 
        try:
180
 
            return get_url(p, compressed=True)
181
 
        except:
182
 
            raise KeyError(fileid)
183
 
    
184
 
 
185