/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
import copy
19
from cStringIO import StringIO
0.16.5 by Aaron Bentley
Get text shelving working
20
import os.path
21
import shutil
0.16.1 by Aaron Bentley
Begin implementing UI
22
import sys
0.16.5 by Aaron Bentley
Get text shelving working
23
import tempfile
0.16.1 by Aaron Bentley
Begin implementing UI
24
0.16.25 by Aaron Bentley
Show selected changes before shelving
25
from bzrlib import (
26
    builtins,
27
    delta,
28
    diff,
29
    errors,
30
    osutils,
31
    patches,
32
    workingtree)
0.16.7 by Aaron Bentley
Implement colourdiff support
33
from bzrlib.plugins.bzrtools import colordiff, hunk_selector
0.16.6 by Aaron Bentley
Refactor generating patched file
34
from bzrlib.plugins.bzrtools.patch import run_patch
0.16.20 by Aaron Bentley
Use new getchar from bzrtools
35
from bzrlib.plugins.bzrtools.userinteractor import getchar
0.16.31 by Aaron Bentley
Update prepare_shelf => shelf
36
from bzrlib.plugins.shelf2 import shelf
0.16.1 by Aaron Bentley
Begin implementing UI
37
38
39
class Shelver(object):
40
0.16.23 by Aaron Bentley
Improve prompting
41
    def __init__(self, work_tree, target_tree, path, auto=False,
42
                 auto_apply=False):
0.16.1 by Aaron Bentley
Begin implementing UI
43
        self.work_tree = work_tree
44
        self.target_tree = target_tree
45
        self.path = path
46
        self.diff_file = StringIO()
0.16.5 by Aaron Bentley
Get text shelving working
47
        self.text_differ = diff.DiffText(self.target_tree, self.work_tree,
0.16.1 by Aaron Bentley
Begin implementing UI
48
                                         self.diff_file)
0.16.7 by Aaron Bentley
Implement colourdiff support
49
        self.diff_writer = colordiff.DiffWriter(sys.stdout, False)
0.16.31 by Aaron Bentley
Update prepare_shelf => shelf
50
        self.manager = shelf.ShelfManager.for_tree(work_tree)
0.16.15 by Aaron Bentley
Implement auto mode
51
        self.auto = auto
0.16.23 by Aaron Bentley
Improve prompting
52
        self.auto_apply = auto_apply
0.16.1 by Aaron Bentley
Begin implementing UI
53
54
    @classmethod
0.16.15 by Aaron Bentley
Implement auto mode
55
    def from_args(klass, revision=None, all=False):
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.23 by Aaron Bentley
Improve prompting
59
        return klass(tree, target_tree, path, all, all)
0.16.1 by Aaron Bentley
Begin implementing UI
60
61
    def run(self):
0.16.31 by Aaron Bentley
Update prepare_shelf => shelf
62
        creator = shelf.ShelfCreator(self.work_tree, self.target_tree)
0.16.5 by Aaron Bentley
Get text shelving working
63
        self.tempdir = tempfile.mkdtemp()
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
64
        changes_shelved = 0
0.16.1 by Aaron Bentley
Begin implementing UI
65
        try:
0.16.5 by Aaron Bentley
Get text shelving working
66
            for change in creator:
67
                if change[0] == 'modify text':
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
68
                    changes_shelved += self.handle_modify_text(creator,
69
                                                               change[1])
0.16.16 by Aaron Bentley
Allow shelving renames and creation
70
                if change[0] == 'add file':
0.16.23 by Aaron Bentley
Improve prompting
71
                    if self.prompt_bool('Shelve adding file?'):
0.16.16 by Aaron Bentley
Allow shelving renames and creation
72
                        creator.shelve_creation(change[1])
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
73
                        changes_shelved += 1
0.16.19 by Aaron Bentley
Implement shelving deletion
74
                if change[0] == 'delete file':
0.16.23 by Aaron Bentley
Improve prompting
75
                    if self.prompt_bool('Shelve deleting file?'):
0.16.19 by Aaron Bentley
Implement shelving deletion
76
                        creator.shelve_deletion(change[1])
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
77
                        changes_shelved += 1
0.16.16 by Aaron Bentley
Allow shelving renames and creation
78
                if change[0] == 'rename':
0.16.23 by Aaron Bentley
Improve prompting
79
                    if self.prompt_bool('Shelve renaming %s => %s?' %
80
                                   change[2:]):
0.16.16 by Aaron Bentley
Allow shelving renames and creation
81
                        creator.shelve_rename(change[1])
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
82
                        changes_shelved += 1
83
            if changes_shelved > 0:
0.16.25 by Aaron Bentley
Show selected changes before shelving
84
                print "Selected changes:"
85
                changes = creator.work_transform.iter_changes()
86
                reporter = delta._ChangeReporter(output_file=sys.stdout)
87
                delta.report_changes(changes, reporter)
0.16.24 by Aaron Bentley
Regularize prompts
88
                if (self.prompt_bool('Shelve %d change(s)?' %
0.16.23 by Aaron Bentley
Improve prompting
89
                    changes_shelved, auto=self.auto_apply)):
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
90
                    shelf_id, shelf_file = self.manager.new_shelf()
91
                    try:
92
                        creator.write_shelf(shelf_file)
93
                    finally:
94
                        shelf_file.close()
95
                    creator.transform()
96
            else:
97
                print '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):
114
        if auto == None:
115
            auto = self.auto
116
        if auto:
117
            return True
0.16.26 by Aaron Bentley
Restore fancy prompting
118
        message = question + ' [yNfq]'
119
        print message,
0.16.20 by Aaron Bentley
Use new getchar from bzrtools
120
        char = getchar()
0.16.26 by Aaron Bentley
Restore fancy prompting
121
        print "\r" + ' ' * len(message) + '\r',
0.16.23 by Aaron Bentley
Improve prompting
122
        if char == 'y':
123
            return True
124
        elif char == 'f':
125
            self.auto = True
126
            return True
0.16.24 by Aaron Bentley
Regularize prompts
127
        if char == 'q':
128
            sys.exit(0)
0.16.23 by Aaron Bentley
Improve prompting
129
        else:
130
            return False
0.16.1 by Aaron Bentley
Begin implementing UI
131
0.16.6 by Aaron Bentley
Refactor generating patched file
132
    def get_patched_text(self, file_id, patch):
133
        target_file = self.target_tree.get_file(file_id)
134
        try:
135
            if len(patch.hunks) == 0:
136
                return target_file.read()
137
            filename = os.path.join(self.tempdir, 'patch-target')
138
            outfile = open(filename, 'w+b')
139
            try:
140
                osutils.pumpfile(target_file, outfile)
141
            finally:
142
                outfile.close()
143
        finally:
144
            target_file.close()
145
        run_patch('.', [str(patch)], target_file=filename)
146
        outfile = open(filename, 'rb')
147
        try:
148
            return outfile.read()
149
        finally:
150
            outfile.close()
151
0.16.5 by Aaron Bentley
Get text shelving working
152
    def handle_modify_text(self, creator, file_id):
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
153
        shelved_hunks = 0
0.16.1 by Aaron Bentley
Begin implementing UI
154
        parsed = self.get_parsed_patch(file_id)
155
        selected_hunks = []
156
        final_patch = copy.copy(parsed)
157
        final_patch.hunks = []
0.16.15 by Aaron Bentley
Implement auto mode
158
        if not self.auto:
159
            for hunk in parsed.hunks:
160
                self.diff_writer.write(str(hunk))
0.16.24 by Aaron Bentley
Regularize prompts
161
                if not self.prompt_bool('Shelve?'):
0.16.15 by Aaron Bentley
Implement auto mode
162
                    final_patch.hunks.append(hunk)
0.16.6 by Aaron Bentley
Refactor generating patched file
163
        patched_text = self.get_patched_text(file_id, final_patch)
164
        creator.shelve_text(file_id, patched_text)
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
165
        return len(parsed.hunks) - len(final_patch.hunks)
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
166
167
168
class Unshelver(object):
169
170
    @classmethod
171
    def from_args(klass):
172
        tree, path = workingtree.WorkingTree.open_containing('.')
0.16.31 by Aaron Bentley
Update prepare_shelf => shelf
173
        manager = shelf.ShelfManager.for_tree(tree)
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
174
        shelf_id = manager.last_shelf()
175
        if shelf_id is None:
176
            raise errors.BzrCommandError('No changes are shelved.')
177
        return klass(tree, manager, shelf_id)
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
178
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
179
    def __init__(self, tree, manager, shelf_id):
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
180
        self.tree = tree
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
181
        self.manager = manager
182
        self.shelf_id = shelf_id
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
183
184
    def run(self):
185
        self.tree.lock_write()
186
        try:
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
187
            shelf_file = self.manager.read_shelf(self.shelf_id)
188
            try:
0.16.31 by Aaron Bentley
Update prepare_shelf => shelf
189
                unshelver = shelf.Unshelver.from_tree_and_shelf(
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
190
                    self.tree, shelf_file)
191
                unshelver.unshelve()
192
                self.manager.delete_shelf(self.shelf_id)
193
            finally:
194
                unshelver.finalize()
195
                shelf_file.close()
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
196
        finally:
197
            self.tree.unlock()