/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to read_changeset.py

  • Committer: John Arbash Meinel
  • Date: 2005-06-19 23:49:57 UTC
  • mto: (0.5.85) (1185.82.1 bzr-w-changeset)
  • mto: This revision was merged to the branch mainline in revision 1738.
  • Revision ID: john@arbash-meinel.com-20050619234957-4e9542e7d2f3d832
Now adding the patch information to the ChangesetInfo

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
import bzrlib, bzrlib.changeset
7
7
import common
8
8
 
9
 
class BadChangeset(Exception):
10
 
    pass
11
 
class MalformedHeader(BadChangeset):
12
 
    pass
13
 
class MalformedFooter(BadChangeset):
14
 
    pass
 
9
class BadChangeset(Exception): pass
 
10
class MalformedHeader(BadChangeset): pass
 
11
class MalformedPatches(BadChangeset): pass
 
12
class MalformedFooter(BadChangeset): pass
15
13
 
16
14
 
17
15
class ChangesetInfo(object):
18
 
    """This is the intermediate class that gets filled out as the file is read.
 
16
    """This is the intermediate class that gets filled out as
 
17
    the file is read.
19
18
    """
20
19
    def __init__(self):
21
20
        self.committer = None
42
41
        return pprint.pformat(self.__dict__)
43
42
 
44
43
    def create_maps(self):
45
 
        """Go through the individual id sections, and generate the id2path and path2id maps.
 
44
        """Go through the individual id sections, and generate the 
 
45
        id2path and path2id maps.
46
46
        """
47
47
        # Rather than use an empty path, the changeset code seems 
48
48
        # to like to use "./." for the tree root.
58
58
                    self.path2id[path] = f_id
59
59
                    self.id2parent[f_id] = parent_id
60
60
 
61
 
 
62
61
class ChangesetReader(object):
63
 
    """This class reads in a changeset from a file, and returns a Changeset object,
64
 
    which can then be applied against a tree.
 
62
    """This class reads in a changeset from a file, and returns
 
63
    a Changeset object, which can then be applied against a tree.
65
64
    """
66
65
    def __init__(self, from_file):
67
66
        """Read in the changeset from the file.
78
77
        # can create a proper changeset.
79
78
        self._read_header()
80
79
        next_line = self._read_patches()
81
 
        self._read_footer(next_line)
 
80
        if next_line is not None:
 
81
            self._read_footer(next_line)
82
82
 
83
83
    def get_changeset(self):
84
84
        """Create the actual changeset object.
90
90
        """Read the bzr header"""
91
91
        header = common.get_header()
92
92
        for head_line, line in zip(header, self.from_file):
93
 
            if line[:2] != '# ' or line[-1] != '\n' or line[2:-1] != head_line:
94
 
                raise MalformedHeader('Did not read the opening header information.')
 
93
            if (line[:2] != '# '
 
94
                    or line[-1] != '\n'
 
95
                    or line[2:-1] != head_line):
 
96
                raise MalformedHeader('Did not read the opening'
 
97
                    ' header information.')
95
98
 
96
99
        for line in self.from_file:
97
100
            if self._handle_info_line(line) is not None:
100
103
    def _handle_info_line(self, line, in_footer=False):
101
104
        """Handle reading a single line.
102
105
 
103
 
        This may call itself, in the case that we read_multi, and then had a dangling
104
 
        line on the end.
 
106
        This may call itself, in the case that we read_multi,
 
107
        and then had a dangling line on the end.
105
108
        """
106
 
        # The bzr header is terminated with a blank line which does not start with #
 
109
        # The bzr header is terminated with a blank line
 
110
        # which does not start with #
107
111
        next_line = None
108
112
        if line[:1] == '\n':
109
113
            return 'break'
121
125
        if loc != -1:
122
126
            key = line[:loc]
123
127
            value = line[loc+2:]
 
128
            if not value:
 
129
                value, next_line = self._read_many()
124
130
        else:
125
131
            if line[-1:] == ':':
126
132
                key = line[:-1]
127
133
                value, next_line = self._read_many()
128
134
            else:
129
 
                raise MalformedHeader('While looking for key: value pairs, did not find the : %r' % (line))
 
135
                raise MalformedHeader('While looking for key: value pairs,'
 
136
                        ' did not find the colon %r' % (line))
130
137
 
131
138
        key = key.replace(' ', '_')
132
139
        if hasattr(self.info, key):
142
149
            self._handle_info_line(next_line, in_footer=in_footer)
143
150
 
144
151
    def _read_many(self):
145
 
        """If a line ends with no entry, that means that it should be followed with
146
 
        multiple lines of values.
 
152
        """If a line ends with no entry, that means that it should be
 
153
        followed with multiple lines of values.
147
154
 
148
 
        This detects the end of the list, because it will be a line that does not
149
 
        start with '#    '. Because it has to read that extra line, it returns the
150
 
        tuple: (values, next_line)
 
155
        This detects the end of the list, because it will be a line that
 
156
        does not start with '#    '. Because it has to read that extra
 
157
        line, it returns the tuple: (values, next_line)
151
158
        """
152
159
        values = []
153
160
        for line in self.from_file:
156
163
            values.append(line[5:-1])
157
164
        return values, None
158
165
 
 
166
    def _read_one_patch(self, first_line=None):
 
167
        """Read in one patch, return the complete patch, along with
 
168
        the next line.
 
169
 
 
170
        :return: action, lines, next_line, do_continue
 
171
        """
 
172
        first = True
 
173
        action = None
 
174
 
 
175
        def parse_firstline(line):
 
176
            if line[:1] == '#':
 
177
                return None
 
178
            if line[:3] != '***':
 
179
                raise MalformedPatches('The first line of all patches'
 
180
                    ' should be a bzr meta line "***"')
 
181
            return line[4:-1]
 
182
 
 
183
        if first_line is not None:
 
184
            action = parse_firstline(first_line)
 
185
            first = False
 
186
            if action is None:
 
187
                return None, [], first_line, False
 
188
 
 
189
        lines = []
 
190
        for line in self.from_file:
 
191
            if first:
 
192
                action = parse_firstline(line)
 
193
                first = False
 
194
                if action is None:
 
195
                    return None, [], line, False
 
196
            else:
 
197
                if line[:3] == '***':
 
198
                    return action, lines, line, True
 
199
                elif line[:1] == '#':
 
200
                    return action, lines, line, False
 
201
                lines.append(line)
 
202
        return action, lines, None, False
 
203
            
159
204
    def _read_patches(self):
160
 
        for line in self.from_file:
161
 
            if line[:3] == '***': # This is a bzr meta field
162
 
                self._parse_meta(line)
163
 
            elif line[:3] == '---': # This is the 'pre' line for a pre+post patch
164
 
                pass
165
 
            elif line[:3] == '+++': # This is the 'post' line for the pre+post patch
166
 
                pass
167
 
            if line[0] == '#':
168
 
                return line
 
205
        next_line = None
 
206
        do_continue = True
 
207
        while do_continue:
 
208
            action, lines, next_line, do_continue = \
 
209
                    self._read_one_patch(next_line)
 
210
            if action is not None:
 
211
                self.info.actions.append((action, lines))
 
212
        return next_line
169
213
 
170
214
    def _read_footer(self, first_line=None):
171
215
        """Read the rest of the meta information.
172
216
 
173
 
        :param first_line:  The previous step may iterate passed what it can handle.
174
 
                            That extra line can be passed here.
 
217
        :param first_line:  The previous step iterates past what it
 
218
                            can handle. That extra line is given here.
175
219
        """
176
220
        if first_line is not None:
177
 
            self._handle_info_line(first_line, in_footer=True)
 
221
            if self._handle_info_line(first_line, in_footer=True) is not None:
 
222
                return
178
223
        for line in self.from_file:
179
224
            if self._handle_info_line(line, in_footer=True) is not None:
180
225
                break