~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
2
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.
7
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.
12
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
16
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):
48
    if format == 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."""
0.1.73 by Martin Pool
Clean up assertions for weavefile
56
    print >>f, 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
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
62
            print >>f, 'i',
0.1.79 by Martin Pool
In the weavefile, store only the minimum revisions added, not the full
63
            for i in mininc:
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
64
                print >>f, i,
65
            print >>f
66
        else:
67
            print >>f, 'i'
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
68
        print >>f, '1', weave._sha1s[version]
1083 by Martin Pool
- add space to store revision-id in weave files
69
        print >>f, 'n', weave._names[version]
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
70
        print >>f
71
72
    print >>f, 'w'
73
944 by Martin Pool
- refactor member names in Weave code
74
    for l in weave._weave:
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
75
        if isinstance(l, tuple):
76
            assert l[0] in '{}[]'
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
77
            if l[0] == '}':
78
                print >>f, '}'
79
            else:
80
                print >>f, '%s %d' % l
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
81
        else: # text line
82
            if not l:
83
                print >>f, ', '
84
            elif l[-1] == '\n':
0.1.73 by Martin Pool
Clean up assertions for weavefile
85
                assert l.find('\n', 0, -1) == -1
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
86
                print >>f, '.', l,
87
            else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
88
                assert l.find('\n') == -1
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
89
                print >>f, ',', l
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
90
91
    print >>f, 'W'
92
93
0.1.74 by Martin Pool
Add format-hidden readwrite methods
94
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
95
def read_weave(f):
1563.2.1 by Robert Collins
Merge in a variation of the versionedfile api from versioned-file.
96
    # FIXME: detect the weave type and dispatch
97
    from bzrlib.trace import mutter
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
98
    from weave import Weave
1209 by Martin Pool
- Add Weave._weave_name for debugging purposes
99
    w = Weave(getattr(f, 'name', None))
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
100
    _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
    return w
102
103
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
104
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.
105
    """Private helper routine to read a weave format 5 file into memory.
106
    
107
    This is only to be used by read_weave and WeaveFile.__init__.
108
    """
109
    from weave import WeaveFormatError
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
110
0.1.73 by Martin Pool
Clean up assertions for weavefile
111
    l = f.readline()
112
    if l != FORMAT_1:
113
        raise WeaveFormatError('invalid weave file header: %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
114
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
115
    ver = 0
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
116
    while True:
117
        l = f.readline()
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
118
        if l[0] == 'i':
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
119
            if len(l) > 2:
1079 by Martin Pool
- weavefile can just use lists for read-in ancestry, not frozensets
120
                w._parents.append(map(int, l[2:].split(' ')))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
121
            else:
1079 by Martin Pool
- weavefile can just use lists for read-in ancestry, not frozensets
122
                w._parents.append([])
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
123
124
            l = f.readline()[:-1]
125
            assert l.startswith('1 ')
126
            w._sha1s.append(l[2:])
127
                
0.1.93 by Martin Pool
Fix assertion with side effects
128
            l = f.readline()
1083 by Martin Pool
- add space to store revision-id in weave files
129
            assert l.startswith('n ')
130
            name = l[2:-1]
131
            assert name not in w._name_map
132
            w._names.append(name)
133
            w._name_map[name] = ver
134
                
135
            l = f.readline()
0.1.93 by Martin Pool
Fix assertion with side effects
136
            assert l == '\n'
1083 by Martin Pool
- add space to store revision-id in weave files
137
138
            ver += 1
0.1.73 by Martin Pool
Clean up assertions for weavefile
139
        elif l == 'w\n':
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
140
            break
141
        else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
142
            raise WeaveFormatError('unexpected line %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
143
144
    while True:
145
        l = f.readline()
146
        if l == 'W\n':
147
            break
0.1.73 by Martin Pool
Clean up assertions for weavefile
148
        elif l.startswith('. '):
944 by Martin Pool
- refactor member names in Weave code
149
            w._weave.append(l[2:])  # include newline
0.1.73 by Martin Pool
Clean up assertions for weavefile
150
        elif l.startswith(', '):
944 by Martin Pool
- refactor member names in Weave code
151
            w._weave.append(l[2:-1])        # exclude newline
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
152
        elif l == '}\n':
153
            w._weave.append(('}', None))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
154
        else:
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
155
            assert l[0] in '{[]', l
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
156
            assert l[1] == ' ', l
944 by Martin Pool
- refactor member names in Weave code
157
            w._weave.append((intern(l[0]), int(l[2:])))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
158
159
    return w
160