/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.16.1 by Aaron Bentley
Begin implementing UI
1
# Copyright (C) 2008 Aaron Bentley <aaron@aaronbentley.com>
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
18
from cStringIO import StringIO
0.16.5 by Aaron Bentley
Get text shelving working
19
import shutil
0.16.1 by Aaron Bentley
Begin implementing UI
20
import sys
0.16.5 by Aaron Bentley
Get text shelving working
21
import tempfile
0.16.1 by Aaron Bentley
Begin implementing UI
22
0.16.25 by Aaron Bentley
Show selected changes before shelving
23
from bzrlib import (
24
    builtins,
25
    delta,
26
    diff,
27
    errors,
28
    patches,
0.16.54 by Aaron Bentley
Inform user about shelf ids.
29
    trace,
0.16.25 by Aaron Bentley
Show selected changes before shelving
30
    workingtree)
0.16.59 by Aaron Bentley
Remove unused imports
31
from bzrlib.plugins.bzrtools import colordiff
0.16.20 by Aaron Bentley
Use new getchar from bzrtools
32
from bzrlib.plugins.bzrtools.userinteractor import getchar
0.16.31 by Aaron Bentley
Update prepare_shelf => shelf
33
from bzrlib.plugins.shelf2 import shelf
0.16.1 by Aaron Bentley
Begin implementing UI
34
35
36
class Shelver(object):
37
0.16.23 by Aaron Bentley
Improve prompting
38
    def __init__(self, work_tree, target_tree, path, auto=False,
0.16.57 by Aaron Bentley
Expose messages in the UI
39
                 auto_apply=False, file_list=None, message=None):
0.16.1 by Aaron Bentley
Begin implementing UI
40
        self.work_tree = work_tree
41
        self.target_tree = target_tree
42
        self.path = path
43
        self.diff_file = StringIO()
0.16.5 by Aaron Bentley
Get text shelving working
44
        self.text_differ = diff.DiffText(self.target_tree, self.work_tree,
0.16.1 by Aaron Bentley
Begin implementing UI
45
                                         self.diff_file)
0.16.7 by Aaron Bentley
Implement colourdiff support
46
        self.diff_writer = colordiff.DiffWriter(sys.stdout, False)
0.16.40 by Aaron Bentley
Update for ShelfManager API changes
47
        self.manager = work_tree.get_shelf_manager()
0.16.15 by Aaron Bentley
Implement auto mode
48
        self.auto = auto
0.16.23 by Aaron Bentley
Improve prompting
49
        self.auto_apply = auto_apply
0.16.47 by Aaron Bentley
Support selecting files to shelve
50
        self.file_list = file_list
0.16.57 by Aaron Bentley
Expose messages in the UI
51
        self.message = message
0.16.1 by Aaron Bentley
Begin implementing UI
52
53
    @classmethod
0.16.57 by Aaron Bentley
Expose messages in the UI
54
    def from_args(klass, revision=None, all=False, file_list=None,
55
                  message=None):
0.16.1 by Aaron Bentley
Begin implementing UI
56
        tree, path = workingtree.WorkingTree.open_containing('.')
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
57
        target_tree = builtins._get_one_revision_tree('shelf2', revision,
58
            tree.branch, tree)
0.16.57 by Aaron Bentley
Expose messages in the UI
59
        return klass(tree, target_tree, path, all, all, file_list, message)
0.16.1 by Aaron Bentley
Begin implementing UI
60
61
    def run(self):
0.16.47 by Aaron Bentley
Support selecting files to shelve
62
        creator = shelf.ShelfCreator(self.work_tree, self.target_tree,
63
                                     self.file_list)
0.16.5 by Aaron Bentley
Get text shelving working
64
        self.tempdir = tempfile.mkdtemp()
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
65
        changes_shelved = 0
0.16.1 by Aaron Bentley
Begin implementing UI
66
        try:
0.16.5 by Aaron Bentley
Get text shelving working
67
            for change in creator:
68
                if change[0] == 'modify text':
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
69
                    changes_shelved += self.handle_modify_text(creator,
70
                                                               change[1])
0.16.16 by Aaron Bentley
Allow shelving renames and creation
71
                if change[0] == 'add file':
0.16.36 by Aaron Bentley
Better prompts on add/delete
72
                    if self.prompt_bool('Shelve adding file "%s"?'
73
                                        % change[3]):
0.16.16 by Aaron Bentley
Allow shelving renames and creation
74
                        creator.shelve_creation(change[1])
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
75
                        changes_shelved += 1
0.16.19 by Aaron Bentley
Implement shelving deletion
76
                if change[0] == 'delete file':
0.16.36 by Aaron Bentley
Better prompts on add/delete
77
                    if self.prompt_bool('Shelve removing file "%s"? '
78
                                        % change[3]):
0.16.19 by Aaron Bentley
Implement shelving deletion
79
                        creator.shelve_deletion(change[1])
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
80
                        changes_shelved += 1
0.16.16 by Aaron Bentley
Allow shelving renames and creation
81
                if change[0] == 'rename':
0.16.23 by Aaron Bentley
Improve prompting
82
                    if self.prompt_bool('Shelve renaming %s => %s?' %
83
                                   change[2:]):
0.16.16 by Aaron Bentley
Allow shelving renames and creation
84
                        creator.shelve_rename(change[1])
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
85
                        changes_shelved += 1
86
            if changes_shelved > 0:
0.16.60 by Aaron Bentley
Clean up I/O handling
87
                trace.note("Selected changes:")
0.16.25 by Aaron Bentley
Show selected changes before shelving
88
                changes = creator.work_transform.iter_changes()
0.16.60 by Aaron Bentley
Clean up I/O handling
89
                reporter = delta._ChangeReporter()
0.16.25 by Aaron Bentley
Show selected changes before shelving
90
                delta.report_changes(changes, reporter)
0.16.24 by Aaron Bentley
Regularize prompts
91
                if (self.prompt_bool('Shelve %d change(s)?' %
0.16.23 by Aaron Bentley
Improve prompting
92
                    changes_shelved, auto=self.auto_apply)):
0.16.57 by Aaron Bentley
Expose messages in the UI
93
                    shelf_id = self.manager.shelve_changes(creator,
94
                                                           self.message)
0.16.54 by Aaron Bentley
Inform user about shelf ids.
95
                    trace.note('Changes shelved with id "%d".' % shelf_id)
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
96
            else:
0.16.60 by Aaron Bentley
Clean up I/O handling
97
                trace.warning('No changes to shelve.')
0.16.1 by Aaron Bentley
Begin implementing UI
98
        finally:
0.16.5 by Aaron Bentley
Get text shelving working
99
            shutil.rmtree(self.tempdir)
0.16.1 by Aaron Bentley
Begin implementing UI
100
            creator.finalize()
101
102
    def get_parsed_patch(self, file_id):
103
        old_path = self.work_tree.id2path(file_id)
104
        new_path = self.target_tree.id2path(file_id)
105
        try:
106
            patch = self.text_differ.diff(file_id, old_path, new_path, 'file',
107
                                          'file')
108
            self.diff_file.seek(0)
109
            return patches.parse_patch(self.diff_file)
110
        finally:
111
            self.diff_file.truncate(0)
112
0.16.23 by Aaron Bentley
Improve prompting
113
    def prompt_bool(self, question, auto=None):
0.16.44 by Aaron Bentley
Fix bogosity
114
        if auto is None:
0.16.23 by Aaron Bentley
Improve prompting
115
            auto = self.auto
116
        if auto:
117
            return True
0.16.26 by Aaron Bentley
Restore fancy prompting
118
        message = question + ' [yNfq]'
0.16.60 by Aaron Bentley
Clean up I/O handling
119
        sys.stdout.write(message)
0.16.20 by Aaron Bentley
Use new getchar from bzrtools
120
        char = getchar()
0.16.60 by Aaron Bentley
Clean up I/O handling
121
        sys.stdout.write("\r" + ' ' * len(message) + '\r')
122
        sys.stdout.flush()
0.16.23 by Aaron Bentley
Improve prompting
123
        if char == 'y':
124
            return True
125
        elif char == 'f':
126
            self.auto = True
127
            return True
0.16.24 by Aaron Bentley
Regularize prompts
128
        if char == 'q':
129
            sys.exit(0)
0.16.23 by Aaron Bentley
Improve prompting
130
        else:
131
            return False
0.16.1 by Aaron Bentley
Begin implementing UI
132
0.16.5 by Aaron Bentley
Get text shelving working
133
    def handle_modify_text(self, creator, file_id):
0.16.1 by Aaron Bentley
Begin implementing UI
134
        parsed = self.get_parsed_patch(file_id)
0.16.43 by Aaron Bentley
Reduce API friction.
135
        final_hunks = []
0.16.15 by Aaron Bentley
Implement auto mode
136
        if not self.auto:
0.16.41 by Aaron Bentley
Implement shelving with internal patch
137
            offset = 0
0.16.61 by Aaron Bentley
Show file name when shelving
138
            self.diff_writer.write(parsed.get_header())
0.16.15 by Aaron Bentley
Implement auto mode
139
            for hunk in parsed.hunks:
140
                self.diff_writer.write(str(hunk))
0.16.24 by Aaron Bentley
Regularize prompts
141
                if not self.prompt_bool('Shelve?'):
0.16.41 by Aaron Bentley
Implement shelving with internal patch
142
                    hunk.mod_pos += offset
0.16.43 by Aaron Bentley
Reduce API friction.
143
                    final_hunks.append(hunk)
0.16.41 by Aaron Bentley
Implement shelving with internal patch
144
                else:
145
                    offset -= (hunk.mod_range - hunk.orig_range)
0.16.62 by Aaron Bentley
Make status nicer by not shelving lines for files not being changed
146
        if len(parsed.hunks) == len(final_hunks):
147
            return 0
0.16.43 by Aaron Bentley
Reduce API friction.
148
        target_lines = self.target_tree.get_file_lines(file_id)
149
        patched = patches.iter_patched_from_hunks(target_lines, final_hunks)
0.16.45 by Aaron Bentley
switch to shelve_lines
150
        creator.shelve_lines(file_id, list(patched))
0.16.43 by Aaron Bentley
Reduce API friction.
151
        return len(parsed.hunks) - len(final_hunks)
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
152
153
154
class Unshelver(object):
155
156
    @classmethod
0.16.52 by Aaron Bentley
Allow user-specified shelves
157
    def from_args(klass, shelf_id):
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
158
        tree, path = workingtree.WorkingTree.open_containing('.')
0.16.40 by Aaron Bentley
Update for ShelfManager API changes
159
        manager = tree.get_shelf_manager()
0.16.52 by Aaron Bentley
Allow user-specified shelves
160
        if shelf_id is not None:
161
            shelf_id = int(shelf_id)
162
        else:
163
            shelf_id = manager.last_shelf()
164
            if shelf_id is None:
165
                raise errors.BzrCommandError('No changes are shelved.')
0.16.54 by Aaron Bentley
Inform user about shelf ids.
166
            trace.note('Unshelving changes with id "%d".' % shelf_id)
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
167
        return klass(tree, manager, shelf_id)
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
168
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
169
    def __init__(self, tree, manager, shelf_id):
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
170
        self.tree = tree
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
171
        self.manager = manager
172
        self.shelf_id = shelf_id
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
173
174
    def run(self):
175
        self.tree.lock_write()
0.16.37 by Aaron Bentley
Use cleanups list to reduce nested try blocks
176
        cleanups = [self.tree.unlock]
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
177
        try:
0.16.40 by Aaron Bentley
Update for ShelfManager API changes
178
            unshelver = self.manager.get_unshelver(self.shelf_id)
0.16.37 by Aaron Bentley
Use cleanups list to reduce nested try blocks
179
            cleanups.append(unshelver.finalize)
0.16.57 by Aaron Bentley
Expose messages in the UI
180
            if unshelver.message is not None:
181
                trace.note('Message: %s' % unshelver.message)
0.16.50 by Aaron Bentley
Display changes being unshelved
182
            unshelver.unshelve(delta._ChangeReporter())
0.16.37 by Aaron Bentley
Use cleanups list to reduce nested try blocks
183
            self.manager.delete_shelf(self.shelf_id)
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
184
        finally:
0.16.37 by Aaron Bentley
Use cleanups list to reduce nested try blocks
185
            for cleanup in reversed(cleanups):
186
                cleanup()