~abentley/bzrtools/bzrtools.dev

0.1.18 by Michael Ellerman
Split out HunkSelector class.
1
#!/usr/bin/python
2
0.1.48 by Michael Ellerman
Move UserInteractor into a seperate file.
3
from userinteractor import UserInteractor, UserOption
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
4
0.1.18 by Michael Ellerman
Split out HunkSelector class.
5
class HunkSelector:
6
    def __init__(self, patches):
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
7
        self.standard_options = [
0.1.49 by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully
8
            UserOption('y', self.shelve, 'shelve this change.', default=True),
9
            UserOption('n', self.keep, 'keep this change in your tree.'),
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
10
            UserOption('d', UserInteractor.FINISH, 'done, skip to the end.'),
11
            UserOption('i', self.invert,
0.1.49 by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully
12
                'invert the current selection status of all hunks.'),
13
            UserOption('s', self.status, 'show selection status of all hunks.'),
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
14
            UserOption('q', UserInteractor.QUIT, 'quit')
15
        ]
16
17
        self.end_options = [
18
            UserOption('y', UserInteractor.FINISH,
0.1.49 by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully
19
                'shelve selected changes.', default=True),
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
20
            UserOption('r', UserInteractor.RESTART,
21
                'restart the hunk selection loop.'),
0.1.49 by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully
22
            UserOption('s', self.status, 'show selection status of all hunks.'),
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
23
            UserOption('i', self.invert,
0.1.49 by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully
24
                'invert the current selection status of all hunks.'),
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
25
            UserOption('q', UserInteractor.QUIT, 'quit')
26
        ]
27
0.1.18 by Michael Ellerman
Split out HunkSelector class.
28
        self.patches = patches
29
        self.total_hunks = 0
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
30
31
        self.last_printed = -1
32
        self.interactor = UserInteractor()
33
        self.interactor.set_item_callback(self.hunk_callback)
34
        self.interactor.set_start_callback(self.start_callback)
35
        self.interactor.set_end_callback(self.end_callback)
36
0.1.18 by Michael Ellerman
Split out HunkSelector class.
37
        for patch in patches:
38
            for hunk in patch.hunks:
39
                # everything's shelved by default
40
                hunk.selected = True
41
                self.total_hunks += 1
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
42
                # we need a back pointer in the callbacks
43
                hunk.patch = patch
44
                self.interactor.add_item(hunk)
45
46
    # Called at the start of the main loop
47
    def start_callback(self):
0.1.49 by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully
48
        self.interactor.set_prompt('Shelve this change? ' \
49
            '(%(count)d of %(total)d)')
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
50
        self.interactor.set_options(self.standard_options)
51
52
    # Called at the end of the item loop, return False to indicate that the
53
    # interaction isn't finished and the confirmation prompt should be displayed
54
    def end_callback(self):
55
        self.status()
0.1.49 by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully
56
        self.interactor.set_prompt("Shelve these changes?")
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
57
        self.interactor.set_options(self.end_options)
58
        return False
59
60
    # Called once for each hunk
61
    def hunk_callback(self, hunk, count):
62
        if self.last_printed != count:
63
            print hunk.patch.get_header(), hunk
64
            self.last_printed = count
65
66
        if hunk.selected:
0.1.49 by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully
67
            self.interactor.get_option('y').default = True
68
            self.interactor.get_option('n').default = False
69
        else:
70
            self.interactor.get_option('y').default = False
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
71
            self.interactor.get_option('n').default = True
72
73
    # The user chooses to shelve a hunk
74
    def shelve(self, hunk):
75
        hunk.selected = True
76
        return True
77
78
    # The user chooses to keep a hunk
79
    def keep(self, hunk):
80
        hunk.selected = False
81
        return True
82
83
    # The user chooses to invert the selection
84
    def invert(self, hunk):
0.1.18 by Michael Ellerman
Split out HunkSelector class.
85
        for patch in self.patches:
86
            for hunk in patch.hunks:
87
                if hunk.__dict__.has_key('selected'):
88
                    hunk.selected = not hunk.selected
89
                else:
90
                    hunk.selected = True
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
91
        self.status()
92
        return False
0.1.18 by Michael Ellerman
Split out HunkSelector class.
93
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
94
    # The user wants to see the status
95
    def status(self, hunk=None):
0.1.18 by Michael Ellerman
Split out HunkSelector class.
96
        print '\nStatus:'
97
        for patch in self.patches:
98
            print '  %s' % patch.oldname
99
            shelve = 0
100
            keep = 0
101
            for hunk in patch.hunks:
102
                if hunk.selected:
103
                    shelve += 1
104
                else:
105
                    keep += 1
106
107
            print '    %d hunks to be shelved' % shelve
108
            print '    %d hunks to be kept' % keep
109
            print
110
0.1.47 by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class.
111
        # Tell the interactor we're not done with this item
112
        return False
113
114
    def select(self):
115
        if self.total_hunks == 0:
116
            return []
117
118
        if not self.interactor.interact():
119
            # False from interact means they quit
120
            return []
121
122
        for patch in self.patches:
123
            tmp = []
124
            for hunk in patch.hunks:
125
                if hunk.selected:
126
                    tmp.append(hunk)
127
            patch.hunks = tmp
128
129
        tmp = []
130
        for patch in self.patches:
131
            if len(patch.hunks):
132
                tmp.append(patch)
133
        self.patches = tmp
134
135
        return self.patches