~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):
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
75
            if l[0] == '}':
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
76
                f.write('}\n')
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
77
            else:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
78
                f.write('%s %d\n' % l)
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
79
        else: # text line
80
            if not l:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
81
                f.write(', \n')
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
82
            elif l[-1] == '\n':
2911.6.4 by Blake Winton
Fix test failures
83
                f.write('. ' + l)
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
84
            else:
2911.6.2 by Blake Winton
Fix typos.
85
                f.write(', ' + l + '\n')
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
86
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
87
    f.write('W\n')
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
88
89
0.1.74 by Martin Pool
Add format-hidden readwrite methods
90
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
91
def read_weave(f):
1563.2.1 by Robert Collins
Merge in a variation of the versionedfile api from versioned-file.
92
    # FIXME: detect the weave type and dispatch
93
    from bzrlib.trace import mutter
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
94
    from weave import Weave
1209 by Martin Pool
- Add Weave._weave_name for debugging purposes
95
    w = Weave(getattr(f, 'name', None))
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
96
    _read_weave_v5(f, w)
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
97
    return w
98
99
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
100
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.
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
    """
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
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
                  
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
119
    from weave import WeaveFormatError
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
120
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
121
    lines = iter(f.readlines())
122
    
2024.1.1 by John Arbash Meinel
When a weave file is empty, we should get WeaveFormatError, not StopIteration
123
    try:
124
        l = lines.next()
125
    except StopIteration:
126
        raise WeaveFormatError('invalid weave file: no header')
127
0.1.73 by Martin Pool
Clean up assertions for weavefile
128
    if l != FORMAT_1:
129
        raise WeaveFormatError('invalid weave file header: %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
130
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
131
    ver = 0
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
132
    # read weave header.
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
133
    while True:
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
134
        l = lines.next()
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
135
        if l[0] == 'i':
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
136
            if len(l) > 2:
1079 by Martin Pool
- weavefile can just use lists for read-in ancestry, not frozensets
137
                w._parents.append(map(int, l[2:].split(' ')))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
138
            else:
1079 by Martin Pool
- weavefile can just use lists for read-in ancestry, not frozensets
139
                w._parents.append([])
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
140
            l = lines.next()[:-1]
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
141
            w._sha1s.append(l[2:])
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
142
            l = lines.next()
1083 by Martin Pool
- add space to store revision-id in weave files
143
            name = l[2:-1]
144
            w._names.append(name)
145
            w._name_map[name] = ver
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
146
            l = lines.next()
1083 by Martin Pool
- add space to store revision-id in weave files
147
            ver += 1
0.1.73 by Martin Pool
Clean up assertions for weavefile
148
        elif l == 'w\n':
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
149
            break
150
        else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
151
            raise WeaveFormatError('unexpected line %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
152
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
153
    # read weave body
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
154
    while True:
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
155
        l = lines.next()
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
156
        if l == 'W\n':
157
            break
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
158
        elif '. ' == l[0:2]:
944 by Martin Pool
- refactor member names in Weave code
159
            w._weave.append(l[2:])  # include newline
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
160
        elif ', ' == l[0:2]:
944 by Martin Pool
- refactor member names in Weave code
161
            w._weave.append(l[2:-1])        # exclude newline
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
162
        elif l == '}\n':
163
            w._weave.append(('}', None))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
164
        else:
944 by Martin Pool
- refactor member names in Weave code
165
            w._weave.append((intern(l[0]), int(l[2:])))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
166
    return w