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
11
11
class Shelf(object):
12
12
MESSAGE_PREFIX = "# Shelved patch: "
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)
61
def display(self, patch=None):
63
path = self.last_patch()
65
raise CommandError("No patches on shelf.")
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())
83
78
def __path_from_user(self, patch_id):
85
80
patch_index = int(patch_id)
86
except (TypeError, ValueError):
87
82
raise CommandError("Invalid patch name '%s'" % patch_id)
89
84
path = self.__path(patch_index)
136
131
return patch[len(self.MESSAGE_PREFIX):patch.index('\n')]
138
def unshelve(self, patch_source, patch_name=None, all=False, force=False,
133
def unshelve(self, patch_source, all=False, force=False):
140
134
self._check_upgrade()
142
if no_color is False:
136
patch_name = self.last_patch()
146
138
if patch_name is None:
147
patch_path = self.last_patch()
149
patch_path = self.__path_from_user(patch_name)
151
if patch_path is None:
152
139
raise CommandError("No patch found on shelf %s" % self.name)
154
patches = FilePatchSource(patch_path).readpatches()
141
patches = FilePatchSource(patch_name).readpatches()
156
143
to_unshelve = patches
159
hs = UnshelveHunkSelector(patches, color)
160
to_unshelve, to_remain = hs.select()
146
to_unshelve, to_remain = UnshelveHunkSelector(patches).select()
162
148
if len(to_unshelve) == 0:
163
149
raise CommandError('Nothing to unshelve')
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))
172
158
self._run_patch(to_unshelve, dry_run=True)
188
174
"longer applies cleanly to the working tree!")
190
176
# Backup the shelved patch
191
rename(patch_path, '%s~' % patch_path)
177
os.rename(patch_name, '%s~' % patch_name)
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))
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:
206
188
patches = patch_source.readpatches()
209
191
to_shelve = patches
211
to_shelve = ShelveHunkSelector(patches, color).select()[0]
193
to_shelve = ShelveHunkSelector(patches).select()[0]
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
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))
224
f = open(patch_path, 'a')
206
f = open(patch_name, 'a')
226
208
assert '\n' not in message
227
209
f.write("%s%s\n" % (self.MESSAGE_PREFIX, message))
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']
234
args.append('--dry-run')
235
stdout = stderr = subprocess.PIPE
237
stdout = stderr = None
239
process = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=stdout,
241
for patch in patches:
242
process.stdin.write(str(patch))
244
process.communicate()
246
result = process.wait()
250
252
def _check_upgrade(self):
251
253
if len(self._list_old_shelves()) > 0:
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 + '~')