/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,
0.16.47 by Aaron Bentley
Support selecting files to shelve
42
                 auto_apply=False, file_list=None):
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.40 by Aaron Bentley
Update for ShelfManager API changes
50
        self.manager = work_tree.get_shelf_manager()
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.47 by Aaron Bentley
Support selecting files to shelve
53
        self.file_list = file_list
0.16.1 by Aaron Bentley
Begin implementing UI
54
55
    @classmethod
0.16.47 by Aaron Bentley
Support selecting files to shelve
56
    def from_args(klass, revision=None, all=False, file_list=None):
0.16.1 by Aaron Bentley
Begin implementing UI
57
        tree, path = workingtree.WorkingTree.open_containing('.')
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
58
        target_tree = builtins._get_one_revision_tree('shelf2', revision,
59
            tree.branch, tree)
0.16.47 by Aaron Bentley
Support selecting files to shelve
60
        return klass(tree, target_tree, path, all, all, file_list)
0.16.1 by Aaron Bentley
Begin implementing UI
61
62
    def run(self):
0.16.47 by Aaron Bentley
Support selecting files to shelve
63
        creator = shelf.ShelfCreator(self.work_tree, self.target_tree,
64
                                     self.file_list)
0.16.5 by Aaron Bentley
Get text shelving working
65
        self.tempdir = tempfile.mkdtemp()
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
66
        changes_shelved = 0
0.16.1 by Aaron Bentley
Begin implementing UI
67
        try:
0.16.5 by Aaron Bentley
Get text shelving working
68
            for change in creator:
69
                if change[0] == 'modify text':
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
70
                    changes_shelved += self.handle_modify_text(creator,
71
                                                               change[1])
0.16.16 by Aaron Bentley
Allow shelving renames and creation
72
                if change[0] == 'add file':
0.16.36 by Aaron Bentley
Better prompts on add/delete
73
                    if self.prompt_bool('Shelve adding file "%s"?'
74
                                        % change[3]):
0.16.16 by Aaron Bentley
Allow shelving renames and creation
75
                        creator.shelve_creation(change[1])
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
76
                        changes_shelved += 1
0.16.19 by Aaron Bentley
Implement shelving deletion
77
                if change[0] == 'delete file':
0.16.36 by Aaron Bentley
Better prompts on add/delete
78
                    if self.prompt_bool('Shelve removing file "%s"? '
79
                                        % change[3]):
0.16.19 by Aaron Bentley
Implement shelving deletion
80
                        creator.shelve_deletion(change[1])
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
81
                        changes_shelved += 1
0.16.16 by Aaron Bentley
Allow shelving renames and creation
82
                if change[0] == 'rename':
0.16.23 by Aaron Bentley
Improve prompting
83
                    if self.prompt_bool('Shelve renaming %s => %s?' %
84
                                   change[2:]):
0.16.16 by Aaron Bentley
Allow shelving renames and creation
85
                        creator.shelve_rename(change[1])
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
86
                        changes_shelved += 1
87
            if changes_shelved > 0:
0.16.25 by Aaron Bentley
Show selected changes before shelving
88
                print "Selected changes:"
89
                changes = creator.work_transform.iter_changes()
90
                reporter = delta._ChangeReporter(output_file=sys.stdout)
91
                delta.report_changes(changes, reporter)
0.16.24 by Aaron Bentley
Regularize prompts
92
                if (self.prompt_bool('Shelve %d change(s)?' %
0.16.23 by Aaron Bentley
Improve prompting
93
                    changes_shelved, auto=self.auto_apply)):
0.16.40 by Aaron Bentley
Update for ShelfManager API changes
94
                    self.manager.shelve_changes(creator)
0.16.22 by Aaron Bentley
Only prompt when there are changes to shelve.
95
            else:
96
                print 'No changes to shelve.'
0.16.1 by Aaron Bentley
Begin implementing UI
97
        finally:
0.16.5 by Aaron Bentley
Get text shelving working
98
            shutil.rmtree(self.tempdir)
0.16.1 by Aaron Bentley
Begin implementing UI
99
            creator.finalize()
100
101
    def get_parsed_patch(self, file_id):
102
        old_path = self.work_tree.id2path(file_id)
103
        new_path = self.target_tree.id2path(file_id)
104
        try:
105
            patch = self.text_differ.diff(file_id, old_path, new_path, 'file',
106
                                          'file')
107
            self.diff_file.seek(0)
108
            return patches.parse_patch(self.diff_file)
109
        finally:
110
            self.diff_file.truncate(0)
111
0.16.23 by Aaron Bentley
Improve prompting
112
    def prompt_bool(self, question, auto=None):
0.16.44 by Aaron Bentley
Fix bogosity
113
        if auto is None:
0.16.23 by Aaron Bentley
Improve prompting
114
            auto = self.auto
115
        if auto:
116
            return True
0.16.26 by Aaron Bentley
Restore fancy prompting
117
        message = question + ' [yNfq]'
118
        print message,
0.16.20 by Aaron Bentley
Use new getchar from bzrtools
119
        char = getchar()
0.16.26 by Aaron Bentley
Restore fancy prompting
120
        print "\r" + ' ' * len(message) + '\r',
0.16.23 by Aaron Bentley
Improve prompting
121
        if char == 'y':
122
            return True
123
        elif char == 'f':
124
            self.auto = True
125
            return True
0.16.24 by Aaron Bentley
Regularize prompts
126
        if char == 'q':
127
            sys.exit(0)
0.16.23 by Aaron Bentley
Improve prompting
128
        else:
129
            return False
0.16.1 by Aaron Bentley
Begin implementing UI
130
0.16.5 by Aaron Bentley
Get text shelving working
131
    def handle_modify_text(self, creator, file_id):
0.16.1 by Aaron Bentley
Begin implementing UI
132
        parsed = self.get_parsed_patch(file_id)
0.16.43 by Aaron Bentley
Reduce API friction.
133
        final_hunks = []
0.16.15 by Aaron Bentley
Implement auto mode
134
        if not self.auto:
0.16.41 by Aaron Bentley
Implement shelving with internal patch
135
            offset = 0
0.16.15 by Aaron Bentley
Implement auto mode
136
            for hunk in parsed.hunks:
137
                self.diff_writer.write(str(hunk))
0.16.24 by Aaron Bentley
Regularize prompts
138
                if not self.prompt_bool('Shelve?'):
0.16.41 by Aaron Bentley
Implement shelving with internal patch
139
                    hunk.mod_pos += offset
0.16.43 by Aaron Bentley
Reduce API friction.
140
                    final_hunks.append(hunk)
0.16.41 by Aaron Bentley
Implement shelving with internal patch
141
                else:
142
                    offset -= (hunk.mod_range - hunk.orig_range)
0.16.43 by Aaron Bentley
Reduce API friction.
143
        target_lines = self.target_tree.get_file_lines(file_id)
144
        patched = patches.iter_patched_from_hunks(target_lines, final_hunks)
0.16.45 by Aaron Bentley
switch to shelve_lines
145
        creator.shelve_lines(file_id, list(patched))
0.16.43 by Aaron Bentley
Reduce API friction.
146
        return len(parsed.hunks) - len(final_hunks)
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
147
148
149
class Unshelver(object):
150
151
    @classmethod
0.16.52 by Aaron Bentley
Allow user-specified shelves
152
    def from_args(klass, shelf_id):
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
153
        tree, path = workingtree.WorkingTree.open_containing('.')
0.16.40 by Aaron Bentley
Update for ShelfManager API changes
154
        manager = tree.get_shelf_manager()
0.16.52 by Aaron Bentley
Allow user-specified shelves
155
        if shelf_id is not None:
156
            shelf_id = int(shelf_id)
157
        else:
158
            shelf_id = manager.last_shelf()
159
            if shelf_id is None:
160
                raise errors.BzrCommandError('No changes are shelved.')
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
161
        return klass(tree, manager, shelf_id)
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
162
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
163
    def __init__(self, tree, manager, shelf_id):
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
164
        self.tree = tree
0.16.13 by Aaron Bentley
Appy shelve-management updates to shelver
165
        self.manager = manager
166
        self.shelf_id = shelf_id
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
167
168
    def run(self):
169
        self.tree.lock_write()
0.16.37 by Aaron Bentley
Use cleanups list to reduce nested try blocks
170
        cleanups = [self.tree.unlock]
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
171
        try:
0.16.40 by Aaron Bentley
Update for ShelfManager API changes
172
            unshelver = self.manager.get_unshelver(self.shelf_id)
0.16.37 by Aaron Bentley
Use cleanups list to reduce nested try blocks
173
            cleanups.append(unshelver.finalize)
0.16.50 by Aaron Bentley
Display changes being unshelved
174
            unshelver.unshelve(delta._ChangeReporter())
0.16.37 by Aaron Bentley
Use cleanups list to reduce nested try blocks
175
            self.manager.delete_shelf(self.shelf_id)
0.16.8 by Aaron Bentley
Implement unshelve2, tidy shelve2
176
        finally:
0.16.37 by Aaron Bentley
Use cleanups list to reduce nested try blocks
177
            for cleanup in reversed(cleanups):
178
                cleanup()