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

  • Committer: John Arbash Meinel
  • Date: 2010-01-12 22:51:31 UTC
  • mto: This revision was merged to the branch mainline in revision 4955.
  • Revision ID: john@arbash-meinel.com-20100112225131-he8h411p6aeeb947
Delay grabbing an output stream until we actually go to show a diff.

This makes the test suite happy, but it also seems to be reasonable.
If we aren't going to write anything, we don't need to hold an
output stream open.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /usr/bin/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
6
4
# it under the terms of the GNU General Public License as published by
7
5
# the Free Software Foundation; either version 2 of the License, or
8
6
# (at your option) any later version.
9
 
 
 
7
#
10
8
# This program is distributed in the hope that it will be useful,
11
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
11
# GNU General Public License for more details.
14
 
 
 
12
#
15
13
# You should have received a copy of the GNU General Public License
16
14
# 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
 
 
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
#
19
17
# Author: Martin Pool <mbp@canonical.com>
20
18
 
21
19
 
26
24
There is one format marker followed by a blank line, followed by a
27
25
series of version headers, followed by the weave itself.
28
26
 
29
 
Each version marker has 'i' and the included previous versions, then
30
 
'1' and the SHA-1 of the text, if known.  The inclusions do not need
31
 
to list versions included by a parent.
 
27
Each version marker has
 
28
 
 
29
 'i'   parent version indexes
 
30
 '1'   SHA-1 of text
 
31
 'n'   name
 
32
 
 
33
The inclusions do not need to list versions included by a parent.
32
34
 
33
35
The weave is bracketed by 'w' and 'W' lines, and includes the '{}[]'
34
36
processing instructions.  Lines of text are prefixed by '.' if the
36
38
"""
37
39
 
38
40
# TODO: When extracting a single version it'd be enough to just pass
39
 
# an iterator returning the weave lines...
 
41
# an iterator returning the weave lines...  We don't really need to
 
42
# deserialize it into memory.
40
43
 
41
 
FORMAT_1 = '# bzr weave file v3\n'
 
44
FORMAT_1 = '# bzr weave file v5\n'
42
45
 
43
46
 
44
47
def write_weave(weave, f, format=None):
45
 
    if format == None or format == 1:
46
 
        return write_weave_v1(weave, f)
 
48
    if format is None or format == 1:
 
49
        return write_weave_v5(weave, f)
47
50
    else:
48
51
        raise ValueError("unknown weave format %r" % format)
49
52
 
50
53
 
51
 
def write_weave_v1(weave, f):
 
54
def write_weave_v5(weave, f):
52
55
    """Write weave to file f."""
53
 
    print >>f, FORMAT_1,
 
56
    f.write(FORMAT_1)
54
57
 
55
58
    for version, included in enumerate(weave._parents):
56
59
        if included:
57
60
            # mininc = weave.minimal_parents(version)
58
61
            mininc = included
59
 
            print >>f, 'i',
60
 
            for i in mininc:
61
 
                print >>f, i,
62
 
            print >>f
 
62
            f.write('i ')
 
63
            f.write(' '.join(str(i) for i in mininc))
 
64
            f.write('\n')
63
65
        else:
64
 
            print >>f, 'i'
65
 
        print >>f, '1', weave._sha1s[version]
66
 
        print >>f
 
66
            f.write('i\n')
 
67
        f.write('1 ' + weave._sha1s[version] + '\n')
 
68
        f.write('n ' + weave._names[version] + '\n')
 
69
        f.write('\n')
67
70
 
68
 
    print >>f, 'w'
 
71
    f.write('w\n')
69
72
 
70
73
    for l in weave._weave:
71
74
        if isinstance(l, tuple):
72
 
            assert l[0] in '{}[]'
73
 
            print >>f, '%s %d' % l
 
75
            if l[0] == '}':
 
76
                f.write('}\n')
 
77
            else:
 
78
                f.write('%s %d\n' % l)
74
79
        else: # text line
75
80
            if not l:
76
 
                print >>f, ', '
 
81
                f.write(', \n')
77
82
            elif l[-1] == '\n':
78
 
                assert l.find('\n', 0, -1) == -1
79
 
                print >>f, '.', l,
 
83
                f.write('. ' + l)
80
84
            else:
81
 
                assert l.find('\n') == -1
82
 
                print >>f, ',', l
 
85
                f.write(', ' + l + '\n')
83
86
 
84
 
    print >>f, 'W'
 
87
    f.write('W\n')
85
88
 
86
89
 
87
90
 
88
91
def read_weave(f):
89
 
    return read_weave_v1(f)
90
 
 
91
 
 
92
 
def read_weave_v1(f):
93
 
    from weave import Weave, WeaveFormatError
94
 
    w = Weave()
95
 
 
96
 
    wfe = WeaveFormatError
97
 
    l = f.readline()
 
92
    # FIXME: detect the weave type and dispatch
 
93
    from bzrlib.trace import mutter
 
94
    from weave import Weave
 
95
    w = Weave(getattr(f, 'name', None))
 
96
    _read_weave_v5(f, w)
 
97
    return w
 
98
 
 
99
 
 
100
def _read_weave_v5(f, w):
 
101
    """Private helper routine to read a weave format 5 file into memory.
 
102
 
 
103
    This is only to be used by read_weave and WeaveFile.__init__.
 
104
    """
 
105
    #  200   0   2075.5080   1084.0360   bzrlib.weavefile:104(_read_weave_v5)
 
106
    # +60412 0    366.5900    366.5900   +<method 'readline' of 'file' objects>
 
107
    # +59982 0    320.5280    320.5280   +<method 'startswith' of 'str' objects>
 
108
    # +59363 0    297.8080    297.8080   +<method 'append' of 'list' objects>
 
109
    # replace readline call with iter over all lines ->
 
110
    # safe because we already suck on memory.
 
111
    #  200   0   1492.7170    802.6220   bzrlib.weavefile:104(_read_weave_v5)
 
112
    # +59982 0    329.9100    329.9100   +<method 'startswith' of 'str' objects>
 
113
    # +59363 0    320.2980    320.2980   +<method 'append' of 'list' objects>
 
114
    # replaced startswith with slice lookups:
 
115
    #  200   0    851.7250    501.1120   bzrlib.weavefile:104(_read_weave_v5)
 
116
    # +59363 0    311.8780    311.8780   +<method 'append' of 'list' objects>
 
117
    # +200   0     30.2500     30.2500   +<method 'readlines' of 'file' objects>
 
118
 
 
119
    from weave import WeaveFormatError
 
120
 
 
121
    lines = iter(f.readlines())
 
122
 
 
123
    try:
 
124
        l = lines.next()
 
125
    except StopIteration:
 
126
        raise WeaveFormatError('invalid weave file: no header')
 
127
 
98
128
    if l != FORMAT_1:
99
129
        raise WeaveFormatError('invalid weave file header: %r' % l)
100
130
 
101
131
    ver = 0
 
132
    # read weave header.
102
133
    while True:
103
 
        l = f.readline()
 
134
        l = lines.next()
104
135
        if l[0] == 'i':
105
 
            ver += 1
106
 
 
107
136
            if len(l) > 2:
108
 
                w._parents.append(frozenset(map(int, l[2:].split(' '))))
 
137
                w._parents.append(map(int, l[2:].split(' ')))
109
138
            else:
110
 
                w._parents.append(frozenset())
111
 
 
112
 
            l = f.readline()[:-1]
113
 
            assert l.startswith('1 ')
 
139
                w._parents.append([])
 
140
            l = lines.next()[:-1]
114
141
            w._sha1s.append(l[2:])
115
 
                
116
 
            l = f.readline()
117
 
            assert l == '\n'
 
142
            l = lines.next()
 
143
            name = l[2:-1]
 
144
            w._names.append(name)
 
145
            w._name_map[name] = ver
 
146
            l = lines.next()
 
147
            ver += 1
118
148
        elif l == 'w\n':
119
149
            break
120
150
        else:
121
151
            raise WeaveFormatError('unexpected line %r' % l)
122
152
 
 
153
    # read weave body
123
154
    while True:
124
 
        l = f.readline()
 
155
        l = lines.next()
125
156
        if l == 'W\n':
126
157
            break
127
 
        elif l.startswith('. '):
 
158
        elif '. ' == l[0:2]:
128
159
            w._weave.append(l[2:])  # include newline
129
 
        elif l.startswith(', '):
 
160
        elif ', ' == l[0:2]:
130
161
            w._weave.append(l[2:-1])        # exclude newline
 
162
        elif l == '}\n':
 
163
            w._weave.append(('}', None))
131
164
        else:
132
 
            assert l[0] in '{}[]', l
133
 
            assert l[1] == ' ', l
134
165
            w._weave.append((intern(l[0]), int(l[2:])))
135
 
 
136
166
    return w
137