/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.64.1 by Ian Clatworthy
1st cut: gfi parser + --info processing method
1
# Copyright (C) 2008 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
"""Processor of import commands.
18
19
This module provides core processing functionality including an abstract class
20
for basing real processors on. See the processors package for examples.
21
"""
22
0.77.6 by Ian Clatworthy
no filtering tests
23
import sys
0.78.1 by Ian Clatworthy
move note/message/debug into higher level classes
24
import time
25
26
from bzrlib import debug
0.64.37 by Ian Clatworthy
create branches as required
27
from bzrlib.errors import NotBranchError
0.78.1 by Ian Clatworthy
move note/message/debug into higher level classes
28
from bzrlib.trace import (
29
    mutter,
30
    note,
31
    warning,
32
    )
0.64.1 by Ian Clatworthy
1st cut: gfi parser + --info processing method
33
import errors
34
35
36
class ImportProcessor(object):
37
    """Base class for import processors.
38
    
39
    Subclasses should override the pre_*, post_* and *_handler
40
    methods as appropriate.
41
    """
42
0.64.12 by Ian Clatworthy
lightweight tags, filter processor and param validation
43
    known_params = []
44
0.64.212 by Ian Clatworthy
configrable output stream for InfoProcessor
45
    def __init__(self, bzrdir, params=None, verbose=False, outf=None):
46
        if outf is None:
47
            self.outf = sys.stdout
48
        else:
49
            self.outf = outf
0.64.12 by Ian Clatworthy
lightweight tags, filter processor and param validation
50
        self.verbose = verbose
51
        if params is None:
0.65.3 by James Westby
ImportProcessor.params is a dict, not a list.
52
            self.params = {}
0.64.12 by Ian Clatworthy
lightweight tags, filter processor and param validation
53
        else:
54
            self.params = params
55
            self.validate_parameters()
0.64.6 by Ian Clatworthy
generic processing method working for one revision in one branch
56
        self.bzrdir = bzrdir
57
        if bzrdir is None:
58
            # Some 'importers' don't need a repository to write to
0.64.37 by Ian Clatworthy
create branches as required
59
            self.working_tree = None
0.64.6 by Ian Clatworthy
generic processing method working for one revision in one branch
60
            self.branch = None
61
            self.repo = None
62
        else:
0.64.37 by Ian Clatworthy
create branches as required
63
            try:
64
                # Might be inside a branch
65
                (self.working_tree, self.branch) = bzrdir._get_tree_branch()
66
                self.repo = self.branch.repository
67
            except NotBranchError:
68
                # Must be inside a repository
69
                self.working_tree = None
70
                self.branch = None
71
                self.repo = bzrdir.open_repository()
0.64.9 by Ian Clatworthy
dump parameter for info processor
72
0.64.28 by Ian Clatworthy
checkpoint and count params to generic processor
73
        # Handlers can set this to request exiting cleanly without
74
        # iterating through the remaining commands
75
        self.finished = False
76
0.64.12 by Ian Clatworthy
lightweight tags, filter processor and param validation
77
    def validate_parameters(self):
78
        """Validate that the parameters are correctly specified."""
79
        for p in self.params:
80
            if p not in self.known_params:
81
                raise errors.UnknownParameter(p, self.known_params)
0.64.1 by Ian Clatworthy
1st cut: gfi parser + --info processing method
82
83
    def process(self, command_iter):
84
        """Import data into Bazaar by processing a stream of commands.
85
86
        :param command_iter: an iterator providing commands
87
        """
0.64.6 by Ian Clatworthy
generic processing method working for one revision in one branch
88
        if self.working_tree is not None:
89
            self.working_tree.lock_write()
90
        elif self.branch is not None:
91
            self.branch.lock_write()
0.64.37 by Ian Clatworthy
create branches as required
92
        elif self.repo is not None:
93
            self.repo.lock_write()
0.64.6 by Ian Clatworthy
generic processing method working for one revision in one branch
94
        try:
95
            self._process(command_iter)
96
        finally:
0.64.46 by Ian Clatworthy
abort write_group when an unexpected exception occurs so we see the latter
97
            # If an unhandled exception occurred, abort the write group
98
            if self.repo is not None and self.repo.is_in_write_group():
99
                self.repo.abort_write_group()
100
            # Release the locks
0.64.6 by Ian Clatworthy
generic processing method working for one revision in one branch
101
            if self.working_tree is not None:
102
                self.working_tree.unlock()
103
            elif self.branch is not None:
104
                self.branch.unlock()
0.64.37 by Ian Clatworthy
create branches as required
105
            elif self.repo is not None:
106
                self.repo.unlock()
0.64.6 by Ian Clatworthy
generic processing method working for one revision in one branch
107
108
    def _process(self, command_iter):
0.64.1 by Ian Clatworthy
1st cut: gfi parser + --info processing method
109
        self.pre_process()
110
        for cmd in command_iter():
111
            try:
112
                handler = self.__class__.__dict__[cmd.name + "_handler"]
113
            except KeyError:
114
                raise errors.MissingHandler(cmd.name)
115
            else:
0.64.9 by Ian Clatworthy
dump parameter for info processor
116
                self.pre_handler(cmd)
0.64.1 by Ian Clatworthy
1st cut: gfi parser + --info processing method
117
                handler(self, cmd)
0.64.9 by Ian Clatworthy
dump parameter for info processor
118
                self.post_handler(cmd)
0.64.28 by Ian Clatworthy
checkpoint and count params to generic processor
119
            if self.finished:
120
                break
0.64.1 by Ian Clatworthy
1st cut: gfi parser + --info processing method
121
        self.post_process()
122
0.78.1 by Ian Clatworthy
move note/message/debug into higher level classes
123
    def note(self, msg, *args):
124
        """Output a note but timestamp it."""
125
        msg = "%s %s" % (self._time_of_day(), msg)
126
        note(msg, *args)
127
128
    def warning(self, msg, *args):
129
        """Output a warning but timestamp it."""
130
        msg = "%s WARNING: %s" % (self._time_of_day(), msg)
131
        warning(msg, *args)
132
133
    def debug(self, mgs, *args):
134
        """Output a debug message if the appropriate -D option was given."""
135
        if "fast-import" in debug.debug_flags:
136
            msg = "%s DEBUG: %s" % (self._time_of_day(), msg)
137
            mutter(msg, *args)
138
139
    def _time_of_day(self):
140
        """Time of day as a string."""
141
        # Note: this is a separate method so tests can patch in a fixed value
142
        return time.strftime("%H:%M:%S")
143
0.64.1 by Ian Clatworthy
1st cut: gfi parser + --info processing method
144
    def pre_process(self):
145
        """Hook for logic at start of processing."""
146
        pass
147
148
    def post_process(self):
149
        """Hook for logic at end of processing."""
150
        pass
151
0.64.9 by Ian Clatworthy
dump parameter for info processor
152
    def pre_handler(self, cmd):
153
        """Hook for logic before each handler starts."""
154
        pass
155
156
    def post_handler(self, cmd):
157
        """Hook for logic after each handler finishes."""
158
        pass
159
0.64.1 by Ian Clatworthy
1st cut: gfi parser + --info processing method
160
    def progress_handler(self, cmd):
161
        """Process a ProgressCommand."""
162
        raise NotImplementedError(self.progress_handler)
163
164
    def blob_handler(self, cmd):
165
        """Process a BlobCommand."""
166
        raise NotImplementedError(self.blob_handler)
167
168
    def checkpoint_handler(self, cmd):
169
        """Process a CheckpointCommand."""
170
        raise NotImplementedError(self.checkpoint_handler)
171
172
    def commit_handler(self, cmd):
173
        """Process a CommitCommand."""
174
        raise NotImplementedError(self.commit_handler)
175
176
    def reset_handler(self, cmd):
177
        """Process a ResetCommand."""
178
        raise NotImplementedError(self.reset_handler)
179
180
    def tag_handler(self, cmd):
181
        """Process a TagCommand."""
182
        raise NotImplementedError(self.tag_handler)
0.64.4 by Ian Clatworthy
abstract CommitHandler
183
0.102.9 by Ian Clatworthy
parsing of multiple authors and commit properties
184
    def feature_handler(self, cmd):
185
        """Process a FeatureCommand."""
186
        raise NotImplementedError(self.feature_handler)
187
0.64.4 by Ian Clatworthy
abstract CommitHandler
188
189
class CommitHandler(object):
190
    """Base class for commit handling.
191
    
192
    Subclasses should override the pre_*, post_* and *_handler
193
    methods as appropriate.
194
    """
195
196
    def __init__(self, command):
197
        self.command = command
198
199
    def process(self):
200
        self.pre_process_files()
201
        for fc in self.command.file_iter():
202
            try:
0.64.20 by Ian Clatworthy
clean-up fixes after filtering enhancements
203
                handler = self.__class__.__dict__[fc.name[4:] + "_handler"]
0.64.4 by Ian Clatworthy
abstract CommitHandler
204
            except KeyError:
205
                raise errors.MissingHandler(fc.name)
206
            else:
207
                handler(self, fc)
208
        self.post_process_files()
209
0.78.1 by Ian Clatworthy
move note/message/debug into higher level classes
210
    def note(self, msg, *args):
211
        """Output a note but add context."""
212
        msg = "%s (%s)" % (msg, self.command.id)
213
        note(msg, *args)
214
215
    def warning(self, msg, *args):
216
        """Output a warning but add context."""
217
        msg = "WARNING: %s (%s)" % (msg, self.command.id)
218
        warning(msg, *args)
219
0.64.148 by Ian Clatworthy
handle delete of unknown file in chk formats & reduce noise
220
    def mutter(self, msg, *args):
221
        """Output a mutter but add context."""
222
        msg = "%s (%s)" % (msg, self.command.id)
223
        mutter(msg, *args)
224
0.78.1 by Ian Clatworthy
move note/message/debug into higher level classes
225
    def debug(self, msg, *args):
226
        """Output a mutter if the appropriate -D option was given."""
227
        if "fast-import" in debug.debug_flags:
228
            msg = "%s (%s)" % (msg, self.command.id)
229
            mutter(msg, *args)
230
0.64.4 by Ian Clatworthy
abstract CommitHandler
231
    def pre_process_files(self):
232
        """Prepare for committing."""
233
        pass
234
235
    def post_process_files(self):
236
        """Save the revision."""
237
        pass
238
239
    def modify_handler(self, filecmd):
240
        """Handle a filemodify command."""
241
        raise NotImplementedError(self.modify_handler)
242
243
    def delete_handler(self, filecmd):
244
        """Handle a filedelete command."""
245
        raise NotImplementedError(self.delete_handler)
246
247
    def copy_handler(self, filecmd):
248
        """Handle a filecopy command."""
249
        raise NotImplementedError(self.copy_handler)
250
251
    def rename_handler(self, filecmd):
252
        """Handle a filerename command."""
253
        raise NotImplementedError(self.rename_handler)
254
255
    def deleteall_handler(self, filecmd):
256
        """Handle a filedeleteall command."""
257
        raise NotImplementedError(self.deleteall_handler)