~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
29
Each version marker has 'v' and the version, then 'i' and the included
0.1.79 by Martin Pool
In the weavefile, store only the minimum revisions added, not the full
30
previous versions.  The inclusions do not need to list versions
31
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
39
# an iterator returning the weave lines...
40
0.1.73 by Martin Pool
Clean up assertions for weavefile
41
FORMAT_1 = '# bzr weave file v1\n'
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
42
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:
47
        return write_weave_v1(weave, f)
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
52
def write_weave_v1(weave, f):
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
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
56
    for version, included in enumerate(weave._v):
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
57
        print >>f, 'v', version
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
58
        if included:
0.1.79 by Martin Pool
In the weavefile, store only the minimum revisions added, not the full
59
            # find a minimal expression of it; bias towards using
60
            # later revisions
61
            li = list(included)
62
            li.sort()
63
            li.reverse()
64
65
            mininc = []
66
            gotit = set()
67
68
            for pv in li:
69
                if pv not in gotit:
70
                    mininc.append(pv)
71
                    gotit.update(weave._v[pv])
72
73
            assert mininc[0] >= 0
74
            assert mininc[-1] < version
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
75
            print >>f, 'i',
0.1.79 by Martin Pool
In the weavefile, store only the minimum revisions added, not the full
76
            for i in mininc:
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
77
                print >>f, i,
78
            print >>f
79
        else:
80
            print >>f, 'i'
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
81
        print >>f
82
83
    print >>f, 'w'
84
85
    for l in weave._l:
86
        if isinstance(l, tuple):
87
            assert l[0] in '{}[]'
88
            print >>f, '%s %d' % l
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
89
        else: # text line
90
            if not l:
91
                print >>f, ', '
92
            elif l[-1] == '\n':
0.1.73 by Martin Pool
Clean up assertions for weavefile
93
                assert l.find('\n', 0, -1) == -1
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
94
                print >>f, '.', l,
95
            else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
96
                assert l.find('\n') == -1
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
97
                print >>f, ',', l
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
98
99
    print >>f, 'W'
100
101
0.1.74 by Martin Pool
Add format-hidden readwrite methods
102
103
def read_weave(f):
104
    return read_weave_v1(f)
105
106
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
107
def read_weave_v1(f):
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
108
    from weave import Weave, WeaveFormatError
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
109
    w = Weave()
110
0.1.73 by Martin Pool
Clean up assertions for weavefile
111
    wfe = WeaveFormatError
112
    l = f.readline()
113
    if l != FORMAT_1:
114
        raise WeaveFormatError('invalid weave file header: %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
115
0.1.73 by Martin Pool
Clean up assertions for weavefile
116
    v_cnt = 0
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
117
    while True:
118
        l = f.readline()
0.1.73 by Martin Pool
Clean up assertions for weavefile
119
        if l.startswith('v '):
120
            ver = int(l[2:])
121
            if ver != v_cnt:
122
                raise WeaveFormatError('version %d!=%d out of order'
123
                                       % (ver, v_cnt))
124
            v_cnt += 1
125
            
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
126
            l = f.readline()[:-1]
127
            if l[0] != 'i':
0.1.73 by Martin Pool
Clean up assertions for weavefile
128
                raise WeaveFormatError('unexpected line %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
129
            if len(l) > 2:
130
                included = map(int, l[2:].split(' '))
0.1.79 by Martin Pool
In the weavefile, store only the minimum revisions added, not the full
131
                full = set()
132
                for pv in included:
133
                    full.add(pv)
134
                    full.update(w._v[pv])
135
                w._addversion(full)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
136
            else:
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
137
                w._addversion(None)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
138
            assert f.readline() == '\n'
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('. '):
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
149
            w._l.append(l[2:])           # include newline
0.1.73 by Martin Pool
Clean up assertions for weavefile
150
        elif l.startswith(', '):
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
151
            w._l.append(l[2:-1])        # exclude newline
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
152
        else:
153
            assert l[0] in '{}[]', l
154
            assert l[1] == ' ', l
155
            w._l.append((l[0], int(l[2:])))
156
157
    return w
158