~bzr-pqm/bzr/bzr.dev

0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
1
#! /usr/bin/python
2
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
# Author: Martin Pool <mbp@canonical.com>
20
21
22
23
24
"""Store and retrieve weaves in files.
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
25
26
There is one format marker followed by a blank line, followed by a
27
series of version headers, followed by the weave itself.
28
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
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.
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
32
33
The weave is bracketed by 'w' and 'W' lines, and includes the '{}[]'
34
processing instructions.  Lines of text are prefixed by '.' if the
35
line contains a newline, or ',' if not.
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
36
"""
37
38
# 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
39
# an iterator returning the weave lines...  We don't really need to
40
# deserialize it into memory.
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
41
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
42
FORMAT_1 = '# bzr weave file v4\n'
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
43
44
0.1.74 by Martin Pool
Add format-hidden readwrite methods
45
def write_weave(weave, f, format=None):
46
    if format == None or format == 1:
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
47
        return write_weave_v4(weave, f)
0.1.74 by Martin Pool
Add format-hidden readwrite methods
48
    else:
49
        raise ValueError("unknown weave format %r" % format)
50
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
51
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
52
def write_weave_v4(weave, f):
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
53
    """Write weave to file f."""
0.1.73 by Martin Pool
Clean up assertions for weavefile
54
    print >>f, FORMAT_1,
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
55
944 by Martin Pool
- refactor member names in Weave code
56
    for version, included in enumerate(weave._parents):
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
57
        if included:
892 by Martin Pool
- weave stores only direct parents, and calculates and memoizes expansion as needed
58
            # mininc = weave.minimal_parents(version)
59
            mininc = included
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
60
            print >>f, 'i',
0.1.79 by Martin Pool
In the weavefile, store only the minimum revisions added, not the full
61
            for i in mininc:
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
62
                print >>f, i,
63
            print >>f
64
        else:
65
            print >>f, 'i'
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
66
        print >>f, '1', weave._sha1s[version]
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
67
        print >>f
68
69
    print >>f, 'w'
70
944 by Martin Pool
- refactor member names in Weave code
71
    for l in weave._weave:
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
72
        if isinstance(l, tuple):
73
            assert l[0] in '{}[]'
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
74
            if l[0] == '}':
75
                print >>f, '}'
76
            else:
77
                print >>f, '%s %d' % l
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
78
        else: # text line
79
            if not l:
80
                print >>f, ', '
81
            elif l[-1] == '\n':
0.1.73 by Martin Pool
Clean up assertions for weavefile
82
                assert l.find('\n', 0, -1) == -1
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
83
                print >>f, '.', l,
84
            else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
85
                assert l.find('\n') == -1
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
86
                print >>f, ',', l
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
87
88
    print >>f, 'W'
89
90
0.1.74 by Martin Pool
Add format-hidden readwrite methods
91
92
def read_weave(f):
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
93
    return read_weave_v4(f)
94
95
96
def read_weave_v4(f):
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
97
    from weave import Weave, WeaveFormatError
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
98
    w = Weave()
99
0.1.73 by Martin Pool
Clean up assertions for weavefile
100
    wfe = WeaveFormatError
101
    l = f.readline()
102
    if l != FORMAT_1:
103
        raise WeaveFormatError('invalid weave file header: %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
104
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
105
    ver = 0
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
106
    while True:
107
        l = f.readline()
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
108
        if l[0] == 'i':
109
            ver += 1
110
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
111
            if len(l) > 2:
1079 by Martin Pool
- weavefile can just use lists for read-in ancestry, not frozensets
112
                w._parents.append(map(int, l[2:].split(' ')))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
113
            else:
1079 by Martin Pool
- weavefile can just use lists for read-in ancestry, not frozensets
114
                w._parents.append([])
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
115
116
            l = f.readline()[:-1]
117
            assert l.startswith('1 ')
118
            w._sha1s.append(l[2:])
119
                
0.1.93 by Martin Pool
Fix assertion with side effects
120
            l = f.readline()
121
            assert l == '\n'
0.1.73 by Martin Pool
Clean up assertions for weavefile
122
        elif l == 'w\n':
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
123
            break
124
        else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
125
            raise WeaveFormatError('unexpected line %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
126
127
    while True:
128
        l = f.readline()
129
        if l == 'W\n':
130
            break
0.1.73 by Martin Pool
Clean up assertions for weavefile
131
        elif l.startswith('. '):
944 by Martin Pool
- refactor member names in Weave code
132
            w._weave.append(l[2:])  # include newline
0.1.73 by Martin Pool
Clean up assertions for weavefile
133
        elif l.startswith(', '):
944 by Martin Pool
- refactor member names in Weave code
134
            w._weave.append(l[2:-1])        # exclude newline
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
135
        elif l == '}\n':
136
            w._weave.append(('}', None))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
137
        else:
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
138
            assert l[0] in '{[]', l
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
139
            assert l[1] == ' ', l
944 by Martin Pool
- refactor member names in Weave code
140
            w._weave.append((intern(l[0]), int(l[2:])))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
141
142
    return w
143