~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remotebranch.py

add a clean target

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
34
 
 
35
 
# velocitynet.com.au transparently proxies connections and thereby
36
 
# breaks keep-alive -- sucks!
37
 
 
38
 
 
39
 
ENABLE_URLGRABBER = True
40
 
 
 
29
import urlparse
 
30
 
 
31
from bzrlib.errors import BzrError, BzrCheckError
 
32
from bzrlib.branch import Branch, BZR_BRANCH_FORMAT
 
33
from bzrlib.trace import mutter
 
34
from bzrlib.xml import serializer_v4
 
35
 
 
36
 
 
37
ENABLE_URLGRABBER = False
 
38
 
 
39
from bzrlib.errors import BzrError, NoSuchRevision
 
40
 
 
41
class GetFailed(BzrError):
 
42
    def __init__(self, url, status):
 
43
        BzrError.__init__(self, "Get %s failed with status %s" % (url, status))
 
44
        self.url = url
 
45
        self.status = status
41
46
 
42
47
if ENABLE_URLGRABBER:
43
 
    import urlgrabber
44
 
    import urlgrabber.keepalive
45
 
    urlgrabber.keepalive.DEBUG = 0
 
48
    import util.urlgrabber
 
49
    import util.urlgrabber.keepalive
 
50
    util.urlgrabber.keepalive.DEBUG = 0
46
51
    def get_url(path, compressed=False):
47
52
        try:
48
53
            url = path
49
54
            if compressed:
50
55
                url += '.gz'
51
56
            mutter("grab url %s" % url)
52
 
            url_f = urlgrabber.urlopen(url, keepalive=1, close_connection=0)
 
57
            url_f = util.urlgrabber.urlopen(url, keepalive=1, close_connection=0)
 
58
            if url_f.status != 200:
 
59
                raise GetFailed(url, url_f.status)
53
60
            if not compressed:
54
61
                return url_f
55
62
            else:
75
82
    orig_url = url
76
83
    while True:
77
84
        try:
78
 
            ff = get_url(url + '/.bzr/branch-format')
79
 
 
 
85
            fmt_url = url + '/.bzr/branch-format'
 
86
            ff = get_url(fmt_url)
80
87
            fmt = ff.read()
81
88
            ff.close()
82
89
 
89
96
        except urllib2.URLError:
90
97
            pass
91
98
 
92
 
        try:
93
 
            idx = url.rindex('/')
94
 
        except ValueError:
95
 
            raise BzrError('no branch root found for URL %s' % orig_url)
96
 
 
97
 
        url = url[:idx]        
 
99
        scheme, host, path = list(urlparse.urlparse(url))[:3]
 
100
        # discard params, query, fragment
 
101
        
 
102
        # strip off one component of the path component
 
103
        idx = path.rfind('/')
 
104
        if idx == -1 or path == '/':
 
105
            raise BzrError('no branch root found for URL %s'
 
106
                           ' or enclosing directories'
 
107
                           % orig_url)
 
108
        path = path[:idx]
 
109
        url = urlparse.urlunparse((scheme, host, path, '', '', ''))
98
110
        
99
111
 
100
112
 
102
114
    def __init__(self, baseurl, find_root=True):
103
115
        """Create new proxy for a remote branch."""
104
116
        if find_root:
105
 
            self.baseurl = _find_remote_root(baseurl)
 
117
            self.base = _find_remote_root(baseurl)
106
118
        else:
107
 
            self.baseurl = baseurl
 
119
            self.base = baseurl
108
120
            self._check_format()
109
121
 
110
122
        self.inventory_store = RemoteStore(baseurl + '/.bzr/inventory-store/')
120
132
    def controlfile(self, filename, mode):
121
133
        if mode not in ('rb', 'rt', 'r'):
122
134
            raise BzrError("file mode %r not supported for remote branches" % mode)
123
 
        return get_url(self.baseurl + '/.bzr/' + filename, False)
 
135
        return get_url(self.base + '/.bzr/' + filename, False)
124
136
 
125
137
 
126
138
    def lock_read(self):
130
142
    def lock_write(self):
131
143
        from errors import LockError
132
144
        raise LockError("write lock not supported for remote branch %s"
133
 
                        % self.baseurl)
 
145
                        % self.base)
134
146
 
135
147
    def unlock(self):
136
148
        pass
137
149
    
138
150
 
139
151
    def relpath(self, path):
140
 
        if not path.startswith(self.baseurl):
 
152
        if not path.startswith(self.base):
141
153
            raise BzrError('path %r is not under base URL %r'
142
 
                           % (path, self.baseurl))
143
 
        pl = len(self.baseurl)
 
154
                           % (path, self.base))
 
155
        pl = len(self.base)
144
156
        return path[pl:].lstrip('/')
145
157
 
 
158
 
146
159
    def get_revision(self, revision_id):
147
 
        from revision import Revision
148
 
        revf = get_url(self.baseurl + '/.bzr/revision-store/' + revision_id,
149
 
                       True)
150
 
        r = Revision.read_xml(revf)
 
160
        try:
 
161
            revf = self.revision_store[revision_id]
 
162
        except KeyError:
 
163
            raise NoSuchRevision(self, revision_id)
 
164
        r = serializer_v4.read_revision(revf)
151
165
        if r.revision_id != revision_id:
152
166
            raise BzrCheckError('revision stored as {%s} actually contains {%s}'
153
167
                                % (revision_id, r.revision_id))
166
180
        
167
181
    def __getitem__(self, fileid):
168
182
        p = self._path(fileid)
169
 
        return get_url(p, compressed=True)
 
183
        try:
 
184
            return get_url(p, compressed=True)
 
185
        except urllib2.URLError:
 
186
            raise KeyError(fileid)
170
187
    
171
188
 
172
 
def simple_walk():
173
 
    """For experimental purposes, traverse many parts of a remote branch"""
174
 
    from revision import Revision
175
 
    from branch import Branch
176
 
    from inventory import Inventory
177
 
 
178
 
    got_invs = {}
179
 
    got_texts = {}
180
 
 
181
 
    print 'read history'
182
 
    history = get_url('/.bzr/revision-history').readlines()
183
 
    num_revs = len(history)
184
 
    for i, rev_id in enumerate(history):
185
 
        rev_id = rev_id.rstrip()
186
 
        print 'read revision %d/%d' % (i, num_revs)
187
 
 
188
 
        # python gzip needs a seekable file (!!) but the HTTP response
189
 
        # isn't, so we need to buffer it
190
 
 
191
 
        rev_f = get_url('/.bzr/revision-store/%s' % rev_id,
192
 
                        compressed=True)
193
 
 
194
 
        rev = Revision.read_xml(rev_f)
195
 
        print rev.message
196
 
        inv_id = rev.inventory_id
197
 
        if inv_id not in got_invs:
198
 
            print 'get inventory %s' % inv_id
199
 
            inv_f = get_url('/.bzr/inventory-store/%s' % inv_id,
200
 
                            compressed=True)
201
 
            inv = Inventory.read_xml(inv_f)
202
 
            print '%4d inventory entries' % len(inv)
203
 
 
204
 
            for path, ie in inv.iter_entries():
205
 
                text_id = ie.text_id
206
 
                if text_id == None:
207
 
                    continue
208
 
                if text_id in got_texts:
209
 
                    continue
210
 
                print '  fetch %s text {%s}' % (path, text_id)
211
 
                text_f = get_url('/.bzr/text-store/%s' % text_id,
212
 
                                 compressed=True)
213
 
                got_texts[text_id] = True
214
 
 
215
 
            got_invs.add[inv_id] = True
216
 
 
217
 
        print '----'
218
 
 
219
 
 
220
 
def try_me():
221
 
    BASE_URL = 'http://bazaar-ng.org/bzr/bzr.dev/'
222
 
    b = RemoteBranch(BASE_URL)
223
 
    ## print '\n'.join(b.revision_history())
224
 
    from log import show_log
225
 
    show_log(b)
226
 
 
227
 
 
228
 
if __name__ == '__main__':
229
 
    try_me()
230
189