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