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