~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
39
# an iterator returning the weave lines...
40
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
41
FORMAT_1 = '# bzr weave file v3\n'
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
42
43
0.1.74 by Martin Pool
Add format-hidden readwrite methods
44
def write_weave(weave, f, format=None):
45
    if format == None or format == 1:
46
        return write_weave_v1(weave, f)
47
    else:
48
        raise ValueError("unknown weave format %r" % format)
49
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
50
51
def write_weave_v1(weave, f):
52
    """Write weave to file f."""
0.1.73 by Martin Pool
Clean up assertions for weavefile
53
    print >>f, FORMAT_1,
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
54
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
55
    for version, included in enumerate(weave._v):
56
        if included:
0.1.79 by Martin Pool
In the weavefile, store only the minimum revisions added, not the full
57
            # find a minimal expression of it; bias towards using
58
            # later revisions
59
            li = list(included)
60
            li.sort()
61
            li.reverse()
62
63
            mininc = []
64
            gotit = set()
65
66
            for pv in li:
67
                if pv not in gotit:
68
                    mininc.append(pv)
69
                    gotit.update(weave._v[pv])
70
71
            assert mininc[0] >= 0
72
            assert mininc[-1] < version
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
73
            print >>f, 'i',
0.1.79 by Martin Pool
In the weavefile, store only the minimum revisions added, not the full
74
            for i in mininc:
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
75
                print >>f, i,
76
            print >>f
77
        else:
78
            print >>f, 'i'
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
79
        print >>f, '1', weave._sha1s[version]
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
80
        print >>f
81
82
    print >>f, 'w'
83
84
    for l in weave._l:
85
        if isinstance(l, tuple):
86
            assert l[0] in '{}[]'
87
            print >>f, '%s %d' % l
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
88
        else: # text line
89
            if not l:
90
                print >>f, ', '
91
            elif l[-1] == '\n':
0.1.73 by Martin Pool
Clean up assertions for weavefile
92
                assert l.find('\n', 0, -1) == -1
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
93
                print >>f, '.', l,
94
            else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
95
                assert l.find('\n') == -1
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
96
                print >>f, ',', l
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
97
98
    print >>f, 'W'
99
100
0.1.74 by Martin Pool
Add format-hidden readwrite methods
101
102
def read_weave(f):
103
    return read_weave_v1(f)
104
105
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
106
def read_weave_v1(f):
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
107
    from weave import Weave, WeaveFormatError
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
108
    w = Weave()
109
0.1.73 by Martin Pool
Clean up assertions for weavefile
110
    wfe = WeaveFormatError
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':
119
            ver += 1
120
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
121
            if len(l) > 2:
122
                included = map(int, l[2:].split(' '))
0.1.79 by Martin Pool
In the weavefile, store only the minimum revisions added, not the full
123
                full = set()
124
                for pv in included:
125
                    full.add(pv)
126
                    full.update(w._v[pv])
127
                w._addversion(full)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
128
            else:
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
129
                w._addversion(None)
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
130
131
            l = f.readline()[:-1]
132
            assert l.startswith('1 ')
133
            w._sha1s.append(l[2:])
134
                
0.1.93 by Martin Pool
Fix assertion with side effects
135
            l = f.readline()
136
            assert l == '\n'
0.1.73 by Martin Pool
Clean up assertions for weavefile
137
        elif l == 'w\n':
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
138
            break
139
        else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
140
            raise WeaveFormatError('unexpected line %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
141
142
    while True:
143
        l = f.readline()
144
        if l == 'W\n':
145
            break
0.1.73 by Martin Pool
Clean up assertions for weavefile
146
        elif l.startswith('. '):
0.1.95 by Martin Pool
- preliminary merge conflict detection
147
            w._l.append(intern(l[2:]))  # include newline
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:-1])        # exclude newline
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
150
        else:
151
            assert l[0] in '{}[]', l
152
            assert l[1] == ' ', l
0.1.95 by Martin Pool
- preliminary merge conflict detection
153
            w._l.append((intern(l[0]), int(l[2:])))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
154
155
    return w
156