~bzr-pqm/bzr/bzr.dev

0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
1
# Copyright (C) 2005 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
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
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
16
#
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
17
# Author: Martin Pool <mbp@canonical.com>
18
19
20
21
22
"""Store and retrieve weaves in files.
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
23
24
There is one format marker followed by a blank line, followed by a
25
series of version headers, followed by the weave itself.
26
1083 by Martin Pool
- add space to store revision-id in weave files
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.
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
34
35
The weave is bracketed by 'w' and 'W' lines, and includes the '{}[]'
36
processing instructions.  Lines of text are prefixed by '.' if the
37
line contains a newline, or ',' if not.
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
38
"""
39
40
# TODO: When extracting a single version it'd be enough to just pass
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
41
# an iterator returning the weave lines...  We don't really need to
42
# deserialize it into memory.
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
43
1083 by Martin Pool
- add space to store revision-id in weave files
44
FORMAT_1 = '# bzr weave file v5\n'
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
45
46
0.1.74 by Martin Pool
Add format-hidden readwrite methods
47
def write_weave(weave, f, format=None):
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
48
    if format is None or format == 1:
1083 by Martin Pool
- add space to store revision-id in weave files
49
        return write_weave_v5(weave, f)
0.1.74 by Martin Pool
Add format-hidden readwrite methods
50
    else:
51
        raise ValueError("unknown weave format %r" % format)
52
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
53
1083 by Martin Pool
- add space to store revision-id in weave files
54
def write_weave_v5(weave, f):
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
55
    """Write weave to file f."""
2911.6.3 by Blake Winton
Implemented suggestions from John Arbash Meinel.
56
    f.write(FORMAT_1)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
57
944 by Martin Pool
- refactor member names in Weave code
58
    for version, included in enumerate(weave._parents):
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
59
        if included:
892 by Martin Pool
- weave stores only direct parents, and calculates and memoizes expansion as needed
60
            # mininc = weave.minimal_parents(version)
61
            mininc = included
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
62
            f.write('i ')
2911.6.4 by Blake Winton
Fix test failures
63
            f.write(' '.join(str(i) for i in mininc))
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
64
            f.write('\n')
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
65
        else:
2911.6.2 by Blake Winton
Fix typos.
66
            f.write('i\n')
67
        f.write('1 ' + weave._sha1s[version] + '\n')
68
        f.write('n ' + weave._names[version] + '\n')
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
69
        f.write('\n')
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
70
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
71
    f.write('w\n')
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
72
944 by Martin Pool
- refactor member names in Weave code
73
    for l in weave._weave:
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
74
        if isinstance(l, tuple):
75
            assert l[0] in '{}[]'
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
76
            if l[0] == '}':
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
77
                f.write('}\n')
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
78
            else:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
79
                f.write('%s %d\n' % l)
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
80
        else: # text line
81
            if not l:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
82
                f.write(', \n')
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
83
            elif l[-1] == '\n':
0.1.73 by Martin Pool
Clean up assertions for weavefile
84
                assert l.find('\n', 0, -1) == -1
2911.6.4 by Blake Winton
Fix test failures
85
                f.write('. ' + l)
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
86
            else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
87
                assert l.find('\n') == -1
2911.6.2 by Blake Winton
Fix typos.
88
                f.write(', ' + l + '\n')
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
89
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
90
    f.write('W\n')
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
91
92
0.1.74 by Martin Pool
Add format-hidden readwrite methods
93
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
94
def read_weave(f):
1563.2.1 by Robert Collins
Merge in a variation of the versionedfile api from versioned-file.
95
    # FIXME: detect the weave type and dispatch
96
    from bzrlib.trace import mutter
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
97
    from weave import Weave
1209 by Martin Pool
- Add Weave._weave_name for debugging purposes
98
    w = Weave(getattr(f, 'name', None))
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
99
    _read_weave_v5(f, w)
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
100
    return w
101
102
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
103
def _read_weave_v5(f, w):
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
104
    """Private helper routine to read a weave format 5 file into memory.
105
    
106
    This is only to be used by read_weave and WeaveFile.__init__.
107
    """
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
108
    #  200   0   2075.5080   1084.0360   bzrlib.weavefile:104(_read_weave_v5)
109
    # +60412 0    366.5900    366.5900   +<method 'readline' of 'file' objects>
110
    # +59982 0    320.5280    320.5280   +<method 'startswith' of 'str' objects>
111
    # +59363 0    297.8080    297.8080   +<method 'append' of 'list' objects>
112
    # replace readline call with iter over all lines ->
113
    # safe because we already suck on memory.
114
    #  200   0   1492.7170    802.6220   bzrlib.weavefile:104(_read_weave_v5)
115
    # +59982 0    329.9100    329.9100   +<method 'startswith' of 'str' objects>
116
    # +59363 0    320.2980    320.2980   +<method 'append' of 'list' objects>
117
    # replaced startswith with slice lookups:
118
    #  200   0    851.7250    501.1120   bzrlib.weavefile:104(_read_weave_v5)
119
    # +59363 0    311.8780    311.8780   +<method 'append' of 'list' objects>
120
    # +200   0     30.2500     30.2500   +<method 'readlines' of 'file' objects>
121
                  
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
122
    from weave import WeaveFormatError
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
123
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
124
    lines = iter(f.readlines())
125
    
2024.1.1 by John Arbash Meinel
When a weave file is empty, we should get WeaveFormatError, not StopIteration
126
    try:
127
        l = lines.next()
128
    except StopIteration:
129
        raise WeaveFormatError('invalid weave file: no header')
130
0.1.73 by Martin Pool
Clean up assertions for weavefile
131
    if l != FORMAT_1:
132
        raise WeaveFormatError('invalid weave file header: %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
133
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
134
    ver = 0
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
135
    # read weave header.
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
136
    while True:
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
137
        l = lines.next()
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
138
        if l[0] == 'i':
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
139
            if len(l) > 2:
1079 by Martin Pool
- weavefile can just use lists for read-in ancestry, not frozensets
140
                w._parents.append(map(int, l[2:].split(' ')))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
141
            else:
1079 by Martin Pool
- weavefile can just use lists for read-in ancestry, not frozensets
142
                w._parents.append([])
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
143
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
144
            l = lines.next()[:-1]
145
            assert '1 ' == l[0:2]
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
146
            w._sha1s.append(l[2:])
147
                
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
148
            l = lines.next()
149
            assert 'n ' == l[0:2]
1083 by Martin Pool
- add space to store revision-id in weave files
150
            name = l[2:-1]
151
            assert name not in w._name_map
152
            w._names.append(name)
153
            w._name_map[name] = ver
154
                
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
155
            l = lines.next()
0.1.93 by Martin Pool
Fix assertion with side effects
156
            assert l == '\n'
1083 by Martin Pool
- add space to store revision-id in weave files
157
158
            ver += 1
0.1.73 by Martin Pool
Clean up assertions for weavefile
159
        elif l == 'w\n':
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
160
            break
161
        else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
162
            raise WeaveFormatError('unexpected line %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
163
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
164
    # read weave body
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
165
    while True:
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
166
        l = lines.next()
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
167
        if l == 'W\n':
168
            break
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
169
        elif '. ' == l[0:2]:
944 by Martin Pool
- refactor member names in Weave code
170
            w._weave.append(l[2:])  # include newline
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
171
        elif ', ' == l[0:2]:
944 by Martin Pool
- refactor member names in Weave code
172
            w._weave.append(l[2:-1])        # exclude newline
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
173
        elif l == '}\n':
174
            w._weave.append(('}', None))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
175
        else:
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
176
            assert l[0] in '{[]', l
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
177
            assert l[1] == ' ', l
944 by Martin Pool
- refactor member names in Weave code
178
            w._weave.append((intern(l[0]), int(l[2:])))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
179
180
    return w
181