~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to shelf.py

  • Committer: Aaron Bentley
  • Date: 2006-05-17 22:02:34 UTC
  • Revision ID: abentley@panoramicfeedback.com-20060517220234-51a588052d24b7d0
Start work on import plugin

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
1
3
import os
2
4
import sys
3
5
import subprocess
4
6
from datetime import datetime
5
 
from errors import CommandError, PatchFailed, PatchInvokeError
 
7
from errors import CommandError, PatchFailed
6
8
from hunk_selector import ShelveHunkSelector, UnshelveHunkSelector
7
 
from patch import run_patch
8
9
from patchsource import PatchSource, FilePatchSource
9
 
from bzrlib.osutils import rename
10
10
 
11
11
class Shelf(object):
12
12
    MESSAGE_PREFIX = "# Shelved patch: "
56
56
 
57
57
    def delete(self, patch):
58
58
        path = self.__path_from_user(patch)
59
 
        rename(path, '%s~' % path)
 
59
        os.rename(path, '%s~' % path)
60
60
 
61
 
    def display(self, patch=None):
62
 
        if patch is None:
63
 
            path = self.last_patch()
64
 
            if path is None:
65
 
                raise CommandError("No patches on shelf.")
66
 
        else:
67
 
            path = self.__path_from_user(patch)
 
61
    def display(self, patch):
 
62
        path = self.__path_from_user(patch)
68
63
        sys.stdout.write(open(path).read())
69
64
 
70
65
    def list(self):
83
78
    def __path_from_user(self, patch_id):
84
79
        try:
85
80
            patch_index = int(patch_id)
86
 
        except (TypeError, ValueError):
 
81
        except TypeError:
87
82
            raise CommandError("Invalid patch name '%s'" % patch_id)
88
83
 
89
84
        path = self.__path(patch_index)
135
130
            return None
136
131
        return patch[len(self.MESSAGE_PREFIX):patch.index('\n')]
137
132
 
138
 
    def unshelve(self, patch_source, patch_name=None, all=False, force=False,
139
 
                 no_color=False):
 
133
    def unshelve(self, patch_source, all=False, force=False):
140
134
        self._check_upgrade()
141
135
 
142
 
        if no_color is False:
143
 
            color = None
144
 
        else:
145
 
            color = False
 
136
        patch_name = self.last_patch()
 
137
 
146
138
        if patch_name is None:
147
 
            patch_path = self.last_patch()
148
 
        else:
149
 
            patch_path = self.__path_from_user(patch_name)
150
 
 
151
 
        if patch_path is None:
152
139
            raise CommandError("No patch found on shelf %s" % self.name)
153
140
 
154
 
        patches = FilePatchSource(patch_path).readpatches()
 
141
        patches = FilePatchSource(patch_name).readpatches()
155
142
        if all:
156
143
            to_unshelve = patches
157
144
            to_remain = []
158
145
        else:
159
 
            hs = UnshelveHunkSelector(patches, color)
160
 
            to_unshelve, to_remain = hs.select()
 
146
            to_unshelve, to_remain = UnshelveHunkSelector(patches).select()
161
147
 
162
148
        if len(to_unshelve) == 0:
163
149
            raise CommandError('Nothing to unshelve')
164
150
 
165
 
        message = self.get_patch_message(patch_path)
 
151
        message = self.get_patch_message(patch_name)
166
152
        if message is None:
167
153
            message = "No message saved with patch."
168
154
        self.log('Unshelving from %s/%s: "%s"\n' % \
169
 
                (self.name, os.path.basename(patch_path), message))
 
155
                (self.name, os.path.basename(patch_name), message))
170
156
 
171
157
        try:
172
158
            self._run_patch(to_unshelve, dry_run=True)
188
174
                    "longer applies cleanly to the working tree!")
189
175
 
190
176
        # Backup the shelved patch
191
 
        rename(patch_path, '%s~' % patch_path)
 
177
        os.rename(patch_name, '%s~' % patch_name)
192
178
 
193
179
        if len(to_remain) > 0:
194
 
            f = open(patch_path, 'w')
 
180
            f = open(patch_name, 'w')
195
181
            for patch in to_remain:
196
182
                f.write(str(patch))
197
183
            f.close()
198
184
 
199
 
    def shelve(self, patch_source, all=False, message=None, no_color=False):
 
185
    def shelve(self, patch_source, all=False, message=None):
200
186
        self._check_upgrade()
201
 
        if no_color is False:
202
 
            color = None
203
 
        else:
204
 
            color = False
205
187
 
206
188
        patches = patch_source.readpatches()
207
189
 
208
190
        if all:
209
191
            to_shelve = patches
210
192
        else:
211
 
            to_shelve = ShelveHunkSelector(patches, color).select()[0]
 
193
            to_shelve = ShelveHunkSelector(patches).select()[0]
212
194
 
213
195
        if len(to_shelve) == 0:
214
196
            raise CommandError('Nothing to shelve')
217
199
            timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
218
200
            message = "Changes shelved on %s" % timestamp
219
201
 
220
 
        patch_path = self.next_patch()
 
202
        patch_name = self.next_patch()
221
203
        self.log('Shelving to %s/%s: "%s"\n' % \
222
 
                (self.name, os.path.basename(patch_path), message))
 
204
                (self.name, os.path.basename(patch_name), message))
223
205
 
224
 
        f = open(patch_path, 'a')
 
206
        f = open(patch_name, 'a')
225
207
 
226
208
        assert '\n' not in message
227
209
        f.write("%s%s\n" % (self.MESSAGE_PREFIX, message))
245
227
                    "working tree!")
246
228
 
247
229
    def _run_patch(self, patches, strip=0, reverse=False, dry_run=False):
248
 
        run_patch(self.base, patches, strip, reverse, dry_run)
 
230
        args = ['patch', '-d', self.base, '-s', '-p%d' % strip, '-f']
 
231
        if reverse:
 
232
            args.append('-R')
 
233
        if dry_run:
 
234
            args.append('--dry-run')
 
235
            stdout = stderr = subprocess.PIPE
 
236
        else:
 
237
            stdout = stderr = None
 
238
 
 
239
        process = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=stdout,
 
240
                        stderr=stderr)
 
241
        for patch in patches:
 
242
            process.stdin.write(str(patch))
 
243
 
 
244
        process.communicate()
 
245
 
 
246
        result = process.wait()
 
247
        if result != 0:
 
248
            raise PatchFailed()
 
249
 
 
250
        return result
249
251
 
250
252
    def _check_upgrade(self):
251
253
        if len(self._list_old_shelves()) > 0:
302
304
            new_file.close()
303
305
            self.log('Copied %s to %s/%s\n' % (os.path.basename(patch),
304
306
                self.name, os.path.basename(new_path)))
305
 
            rename(patch, patch + '~')
 
307
            os.rename(patch, patch + '~')