/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
411 by Martin Pool
- start adding more useful RemoteBranch() class
1
#! /usr/bin/env python
2
188 by mbp at sourcefrog
- experimental remote-branch support
3
# Copyright (C) 2005 Canonical Ltd
4
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
20
"""Proxy object for access to remote branches.
21
22
At the moment remote branches are only for HTTP and only for read
23
access.
24
25
"""
26
27
28
import gzip
192 by mbp at sourcefrog
- exercise the network more towards doing a remote clone
29
from sets import Set
30
from cStringIO import StringIO
188 by mbp at sourcefrog
- experimental remote-branch support
31
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
32
from errors import BzrError, BzrCheckError
411 by Martin Pool
- start adding more useful RemoteBranch() class
33
from branch import Branch
417 by Martin Pool
- trace when we fetch a URL
34
from trace import mutter
188 by mbp at sourcefrog
- experimental remote-branch support
35
193 by mbp at sourcefrog
more experiments with http get
36
# velocitynet.com.au transparently proxies connections and thereby
37
# breaks keep-alive -- sucks!
38
39
40
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
41
ENABLE_URLGRABBER = False
42
43
def get_url(url, compressed=False):
44
    import urllib2
45
    if compressed:
46
        url += '.gz'
417 by Martin Pool
- trace when we fetch a URL
47
    mutter("get_url %s" % url)
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
48
    url_f = urllib2.urlopen(url)
49
    if compressed:
50
        return gzip.GzipFile(fileobj=StringIO(url_f.read()))
51
    else:
52
        return url_f
53
417 by Martin Pool
- trace when we fetch a URL
54
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
55
if ENABLE_URLGRABBER:
56
    import urlgrabber
57
    import urlgrabber.keepalive
58
    urlgrabber.keepalive.DEBUG = 0
59
    def get_url(path, compressed=False):
60
        try:
61
            url = path
62
            if compressed:
63
                url += '.gz'
64
            url_f = urlgrabber.urlopen(url, keepalive=1, close_connection=0)
65
            if not compressed:
66
                return url_f
67
            else:
68
                return gzip.GzipFile(fileobj=StringIO(url_f.read()))
69
        except urllib2.URLError, e:
70
            raise BzrError("remote fetch failed: %r: %s" % (url, e))
188 by mbp at sourcefrog
- experimental remote-branch support
71
192 by mbp at sourcefrog
- exercise the network more towards doing a remote clone
72
416 by Martin Pool
- bzr log and bzr root now accept an http URL
73
74
def _find_remote_root(url):
75
    """Return the prefix URL that corresponds to the branch root."""
76
    orig_url = url
77
    while True:
78
        try:
79
            ff = get_url(url + '/.bzr/branch-format')
80
            ff.close()
81
            return url
82
        except urllib.URLError:
83
            pass
84
85
        try:
86
            idx = url.rindex('/')
87
        except ValueError:
88
            raise BzrError('no branch root found for URL %s' % orig_url)
89
90
        url = url[:idx]        
91
        
92
93
411 by Martin Pool
- start adding more useful RemoteBranch() class
94
class RemoteBranch(Branch):
416 by Martin Pool
- bzr log and bzr root now accept an http URL
95
    def __init__(self, baseurl, find_root=False, lock_mode='r'):
411 by Martin Pool
- start adding more useful RemoteBranch() class
96
        """Create new proxy for a remote branch."""
416 by Martin Pool
- bzr log and bzr root now accept an http URL
97
        if lock_mode not in ('', 'r'):
98
            raise BzrError('lock mode %r is not supported for remote branches'
99
                           % lock_mode)
100
        
411 by Martin Pool
- start adding more useful RemoteBranch() class
101
        self.baseurl = baseurl
102
        self._check_format()
103
417 by Martin Pool
- trace when we fetch a URL
104
    def __str__(self):
105
        return '%s(%r)' % (self.__class__.__name__, self.baseurl)
106
107
    __repr__ = __str__
108
411 by Martin Pool
- start adding more useful RemoteBranch() class
109
    def controlfile(self, filename, mode):
110
        if mode not in ('rb', 'rt', 'r'):
111
            raise BzrError("file mode %r not supported for remote branches" % mode)
112
        return get_url(self.baseurl + '/.bzr/' + filename, False)
113
114
    def _need_readlock(self):
115
        # remote branch always safe for read
116
        pass
117
118
    def _need_writelock(self):
119
        raise BzrError("cannot get write lock on HTTP remote branch")
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
120
416 by Martin Pool
- bzr log and bzr root now accept an http URL
121
    def relpath(self, path):
122
        if not path.startswith(self.baseurl):
123
            raise BzrError('path %r is not under base URL %r'
124
                           % (path, self.baseurl))
125
        pl = len(self.baseurl)
126
        return path[pl:].lstrip('/')
127
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
128
    def get_revision(self, revision_id):
129
        from revision import Revision
130
        revf = get_url(self.baseurl + '/.bzr/revision-store/' + revision_id,
131
                       True)
132
        r = Revision.read_xml(revf)
133
        if r.revision_id != revision_id:
134
            raise BzrCheckError('revision stored as {%s} actually contains {%s}'
135
                                % (revision_id, r.revision_id))
136
        return r
188 by mbp at sourcefrog
- experimental remote-branch support
137
    
411 by Martin Pool
- start adding more useful RemoteBranch() class
138
139
def simple_walk():
413 by Martin Pool
- more indicators at top of test output
140
    from revision import Revision
141
    from branch import Branch
142
    from inventory import Inventory
143
411 by Martin Pool
- start adding more useful RemoteBranch() class
144
    got_invs = Set()
145
    got_texts = Set()
146
147
    print 'read history'
148
    history = get_url('/.bzr/revision-history').readlines()
149
    num_revs = len(history)
150
    for i, rev_id in enumerate(history):
151
        rev_id = rev_id.rstrip()
152
        print 'read revision %d/%d' % (i, num_revs)
153
154
        # python gzip needs a seekable file (!!) but the HTTP response
155
        # isn't, so we need to buffer it
156
157
        rev_f = get_url('/.bzr/revision-store/%s' % rev_id,
192 by mbp at sourcefrog
- exercise the network more towards doing a remote clone
158
                        compressed=True)
411 by Martin Pool
- start adding more useful RemoteBranch() class
159
160
        rev = Revision.read_xml(rev_f)
161
        print rev.message
162
        inv_id = rev.inventory_id
163
        if inv_id not in got_invs:
164
            print 'get inventory %s' % inv_id
165
            inv_f = get_url('/.bzr/inventory-store/%s' % inv_id,
166
                            compressed=True)
167
            inv = Inventory.read_xml(inv_f)
168
            print '%4d inventory entries' % len(inv)
169
170
            for path, ie in inv.iter_entries():
171
                text_id = ie.text_id
172
                if text_id == None:
173
                    continue
174
                if text_id in got_texts:
175
                    continue
176
                print '  fetch %s text {%s}' % (path, text_id)
177
                text_f = get_url('/.bzr/text-store/%s' % text_id,
178
                                 compressed=True)
179
                got_texts.add(text_id)
180
181
            got_invs.add(inv_id)
182
183
        print '----'
184
185
186
def try_me():
413 by Martin Pool
- more indicators at top of test output
187
    BASE_URL = 'http://bazaar-ng.org/bzr/bzr.dev/'
411 by Martin Pool
- start adding more useful RemoteBranch() class
188
    b = RemoteBranch(BASE_URL)
412 by Martin Pool
- RemoteBranch displays the log of a remote branch.
189
    ## print '\n'.join(b.revision_history())
190
    from log import show_log
191
    show_log(b)
411 by Martin Pool
- start adding more useful RemoteBranch() class
192
193
194
if __name__ == '__main__':
195
    try_me()
196