~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/shelf_ui.py

  • Committer: Aaron Bentley
  • Date: 2009-07-12 13:55:32 UTC
  • mto: (4526.6.5)
  • mto: This revision was merged to the branch mainline in revision 4534.
  • Revision ID: aaron@aaronbentley.com-20090712135532-sib7az25qkd6mphh
Make vocabulary part of reporter.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
 
37
37
 
38
38
class ShelfReporter(object):
 
39
    vocab = {'add file': 'Shelve adding file "%(path)s"?',
 
40
             'binary': 'Shelve binary changes?',
 
41
             'change kind': 'Shelve changing "%s" from %(other)s'
 
42
             ' to %(this)s?',
 
43
             'delete file': 'Shelve removing file "%(path)s"?',
 
44
             'final': 'Shelve %d change(s)?',
 
45
             'hunk': 'Shelve?',
 
46
             'modify target': 'Shelve changing target of'
 
47
             ' "%(path)s" from "%(other)s" to "%(this)s"?',
 
48
             'rename': 'Shelve renaming "%(other)s" =>'
 
49
                        ' "%(this)s"?'
 
50
             }
 
51
 
 
52
    invert_diff = False
39
53
 
40
54
    def __init__(self):
41
55
        self.delta_reporter = delta._ChangeReporter()
46
60
    def shelved_id(self, shelf_id):
47
61
        trace.note('Changes shelved with id "%d".' % shelf_id)
48
62
 
 
63
    def changes_destroyed(self):
 
64
        trace.note('Selected changes destroyed.')
 
65
 
49
66
    def selected_changes(self, transform):
50
67
        trace.note("Selected changes:")
51
68
        changes = transform.iter_changes()
52
69
        delta.report_changes(changes, self.delta_reporter)
53
70
 
 
71
    def prompt_change(self, change):
 
72
        if change[0] == 'rename':
 
73
            vals = {'this': change[3], 'other': change[2]}
 
74
        elif change[0] == 'change kind':
 
75
            vals = {'path': change[4], 'other': change[2], 'this': change[3]}
 
76
        elif change[0] == 'modify target':
 
77
            vals = {'path': change[2], 'other': change[3], 'this': change[4]}
 
78
        else:
 
79
            vals = {'path': change[3]}
 
80
        prompt = self.vocab[change[0]] % vals
 
81
        return prompt
 
82
 
 
83
 
 
84
class ApplyReporter(ShelfReporter):
 
85
 
 
86
    vocab = {'add file': 'Delete file "%(path)s"?',
 
87
             'binary': 'Apply binary changes?',
 
88
             'change kind': 'Change "%(path)s" from %(this)s'
 
89
             ' to %(other)s?',
 
90
             'delete file': 'Add file "%(path)s"?',
 
91
             'final': 'Apply %d change(s)?',
 
92
             'hunk': 'Apply change?',
 
93
             'modify target': 'Change target of'
 
94
             ' "%(path)s" from "%(this)s" to "%(other)s"?',
 
95
             'rename': 'Rename "%(this)s" => "%(other)s"?',
 
96
             }
 
97
 
 
98
    invert_diff = True
 
99
 
 
100
    def changes_destroyed(self):
 
101
        pass
 
102
 
54
103
 
55
104
class Shelver(object):
56
105
    """Interactively shelve the changes in a working tree."""
57
106
 
58
107
    def __init__(self, work_tree, target_tree, diff_writer=None, auto=False,
59
108
                 auto_apply=False, file_list=None, message=None,
60
 
                 destroy=False, manager=None, reporter=None,
61
 
                 vocab_apply=False):
 
109
                 destroy=False, manager=None, reporter=None):
62
110
        """Constructor.
63
111
 
64
112
        :param work_tree: The working tree to shelve changes from.
88
136
        if reporter is None:
89
137
            reporter = ShelfReporter()
90
138
        self.reporter = reporter
91
 
        self.vocab_apply=vocab_apply
92
 
        if self.vocab_apply:
93
 
            self.vocab = {'add file': 'Delete file "%(path)s"?',
94
 
                          'binary': 'Apply binary changes?',
95
 
                          'change kind': 'Change "%(path)s" from %(this)s'
96
 
                          ' to %(other)s?',
97
 
                          'delete file': 'Add file "%(path)s"?',
98
 
                          'final': 'Apply %d change(s)?',
99
 
                          'hunk': 'Apply change?',
100
 
                          'modify target': 'Change target of'
101
 
                          ' "%(path)s" from "%(this)s" to "%(other)s"?',
102
 
                          'rename': 'Rename "%(this)s" => "%(other)s"?',
103
 
                          }
104
 
        else:
105
 
            self.vocab = {'add file': 'Shelve adding file "%(path)s"?',
106
 
                          'binary': 'Shelve binary changes?',
107
 
                          'change kind': 'Shelve changing "%s" from %(other)s'
108
 
                          ' to %(this)s?',
109
 
                          'delete file': 'Shelve removing file "%(path)s"?',
110
 
                          'final': 'Shelve %d change(s)?',
111
 
                          'hunk': 'Shelve?',
112
 
                          'modify target': 'Shelve changing target of'
113
 
                          ' "%(path)s" from "%(other)s" to "%(this)s"?',
114
 
                          'rename': 'Shelve renaming "%(other)s" =>'
115
 
                                     ' "%(this)s"?'
116
 
                          }
117
 
 
118
139
 
119
140
    @classmethod
120
141
    def from_args(klass, diff_writer, revision=None, all=False, file_list=None,
149
170
                        changes_shelved += self.handle_modify_text(creator,
150
171
                                                                   change[1])
151
172
                    except errors.BinaryFile:
152
 
                        if self.prompt_bool(self.vocab['binary']):
 
173
                        if self.prompt_bool(self.reporter.vocab['binary']):
153
174
                            changes_shelved += 1
154
175
                            creator.shelve_content_change(change[1])
155
176
                else:
156
 
                    if self.prompt_change(change):
 
177
                    if self.prompt_bool(self.reporter.prompt_change(change)):
157
178
                        creator.shelve_change(change)
158
179
                        changes_shelved += 1
159
180
            if changes_shelved > 0:
160
181
                self.reporter.selected_changes(creator.work_transform)
161
 
                if (self.auto_apply or self.prompt_bool(self.vocab['final']
162
 
                    % changes_shelved)):
 
182
                if (self.auto_apply or self.prompt_bool(
 
183
                    self.reporter.vocab['final'] % changes_shelved)):
163
184
                    if self.destroy:
164
185
                        creator.transform()
165
 
                        trace.note('Selected changes destroyed.')
 
186
                        self.reporter.changes_destroyed()
166
187
                    else:
167
188
                        shelf_id = self.manager.shelve_changes(creator,
168
189
                                                               self.message)
173
194
            shutil.rmtree(self.tempdir)
174
195
            creator.finalize()
175
196
 
176
 
    def prompt_change(self, change):
177
 
        if change[0] == 'rename':
178
 
            vals = {'this': change[3], 'other': change[2]}
179
 
        elif change[0] == 'change kind':
180
 
            vals = {'path': change[4], 'other': change[2], 'this': change[3]}
181
 
        elif change[0] == 'modify target':
182
 
            vals = {'path': change[2], 'other': change[3], 'this': change[4]}
183
 
        else:
184
 
            vals = {'path': change[3]}
185
 
        prompt = self.vocab[change[0]] % vals
186
 
        return self.prompt_bool(prompt)
187
 
 
188
197
    def get_parsed_patch(self, file_id, invert=False):
189
198
        """Return a parsed version of a file's patch.
190
199
 
191
200
        :param file_id: The id of the file to generate a patch for.
192
201
        :return: A patches.Patch.
193
202
        """
194
 
        old_path = self.target_tree.id2path(file_id)
195
 
        new_path = self.work_tree.id2path(file_id)
196
203
        diff_file = StringIO()
197
204
        if invert:
198
205
            old_tree = self.work_tree
200
207
        else:
201
208
            old_tree = self.target_tree
202
209
            new_tree = self.work_tree
 
210
        old_path = old_tree.id2path(file_id)
 
211
        new_path = new_tree.id2path(file_id)
203
212
        text_differ = diff.DiffText(old_tree, new_tree, diff_file)
204
213
        patch = text_differ.diff(file_id, old_path, new_path, 'file', 'file')
205
214
        diff_file.seek(0)
251
260
        :param file_id: The id of the file to shelve.
252
261
        :return: number of shelved hunks.
253
262
        """
254
 
        if self.vocab_apply:
 
263
        if self.reporter.invert_diff:
255
264
            target_lines = self.work_tree.get_file_lines(file_id)
256
265
        else:
257
266
            target_lines = self.target_tree.get_file_lines(file_id)
258
267
        textfile.check_text_lines(self.work_tree.get_file_lines(file_id))
259
268
        textfile.check_text_lines(target_lines)
260
 
        parsed = self.get_parsed_patch(file_id, self.vocab_apply)
 
269
        parsed = self.get_parsed_patch(file_id, self.reporter.invert_diff)
261
270
        final_hunks = []
262
271
        if not self.auto:
263
272
            offset = 0
264
273
            self.diff_writer.write(parsed.get_header())
265
274
            for hunk in parsed.hunks:
266
275
                self.diff_writer.write(str(hunk))
267
 
                selected = self.prompt_bool(self.vocab['hunk'])
268
 
                if not self.vocab_apply:
 
276
                selected = self.prompt_bool(self.reporter.vocab['hunk'])
 
277
                if not self.reporter.invert_diff:
269
278
                    selected = (not selected)
270
279
                if selected:
271
280
                    hunk.mod_pos += offset
273
282
                else:
274
283
                    offset -= (hunk.mod_range - hunk.orig_range)
275
284
        sys.stdout.flush()
276
 
        if not self.vocab_apply and len(parsed.hunks) == len(final_hunks):
 
285
        if not self.reporter.invert_diff and (
 
286
            len(parsed.hunks) == len(final_hunks)):
277
287
            return 0
278
 
        if self.vocab_apply and len(final_hunks) == 0:
 
288
        if self.reporter.invert_diff and len(final_hunks) == 0:
279
289
            return 0
280
290
        patched = patches.iter_patched_from_hunks(target_lines, final_hunks)
281
291
        creator.shelve_lines(file_id, list(patched))
282
 
        if self.vocab_apply:
 
292
        if self.reporter.invert_diff:
283
293
            return len(final_hunks)
284
294
        return len(parsed.hunks) - len(final_hunks)
285
295