Code review comment for lp:~vila/bzr/856261-unshelve-line-based
- 856261-unshelve-line-based
- Merge into bzr.dev
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Benoit Pierre (benoit.pierre) wrote : | # |
1 | # Bazaar merge directive format 2 (Bazaar 0.90) |
2 | # revision_id: benoit.pierre@gmail.com-20110927192241-jfqqjzm2e6ojjfq0 |
3 | # target_branch: lp:bzr |
4 | # testament_sha1: b3590b8caa798f8691f0e18ee303b9dbd983fd09 |
5 | # timestamp: 2011-09-27 21:23:43 +0200 |
6 | # base_revision_id: pqm@pqm.ubuntu.com-20110610161957-hh5ni839m7r3wsan |
7 | # |
8 | # Begin patch |
9 | === modified file 'bzrlib/shelf_ui.py' |
10 | --- bzrlib/shelf_ui.py 2010-11-04 17:48:47 +0000 |
11 | +++ bzrlib/shelf_ui.py 2011-09-27 19:22:41 +0000 |
12 | @@ -251,23 +251,8 @@ |
13 | diff_file.seek(0) |
14 | return patches.parse_patch(diff_file) |
15 | |
16 | - def prompt(self, message): |
17 | - """Prompt the user for a character. |
18 | - |
19 | - :param message: The message to prompt a user with. |
20 | - :return: A character. |
21 | - """ |
22 | - if not sys.stdin.isatty(): |
23 | - # Since there is no controlling terminal we will hang when trying |
24 | - # to prompt the user, better abort now. See |
25 | - # https://code.launchpad.net/~bialix/bzr/shelve-no-tty/+merge/14905 |
26 | - # for more context. |
27 | - raise errors.BzrError("You need a controlling terminal.") |
28 | - sys.stdout.write(message) |
29 | - char = osutils.getchar() |
30 | - sys.stdout.write("\r" + ' ' * len(message) + '\r') |
31 | - sys.stdout.flush() |
32 | - return char |
33 | + def prompt(self, message, choices, default): |
34 | + return ui.ui_factory.confirm(message, choices, default=default) |
35 | |
36 | def prompt_bool(self, question, long=False, allow_editor=False): |
37 | """Prompt the user with a yes/no question. |
38 | @@ -279,16 +264,11 @@ |
39 | """ |
40 | if self.auto: |
41 | return True |
42 | - editor_string = '' |
43 | - if long: |
44 | - if allow_editor: |
45 | - editor_string = '(E)dit manually, ' |
46 | - prompt = ' [(y)es, (N)o, %s(f)inish, or (q)uit]' % editor_string |
47 | - else: |
48 | - if allow_editor: |
49 | - editor_string = 'e' |
50 | - prompt = ' [yN%sfq?]' % editor_string |
51 | - char = self.prompt(question + prompt) |
52 | + choices = '&yes\n&No' |
53 | + if allow_editor: |
54 | + choices += '\n&edit manually' |
55 | + choices += '\n&finish\n&quit' |
56 | + char = self.prompt(question, choices, 'n') |
57 | if char == 'y': |
58 | return True |
59 | elif char == 'e' and allow_editor: |
60 | |
61 | === modified file 'bzrlib/tests/blackbox/test_break_lock.py' |
62 | --- bzrlib/tests/blackbox/test_break_lock.py 2011-03-10 13:29:54 +0000 |
63 | +++ bzrlib/tests/blackbox/test_break_lock.py 2011-09-27 19:22:41 +0000 |
64 | @@ -91,7 +91,7 @@ |
65 | self.master_branch.lock_write() |
66 | # run the break-lock |
67 | # we need 5 yes's - wt, branch, repo, bound branch, bound repo. |
68 | - self.run_bzr('break-lock checkout', stdin="y\ny\ny\ny\n") |
69 | + self.run_bzr('break-lock checkout', stdin="yyyy") |
70 | # a new tree instance should be lockable |
71 | br = branch.Branch.open('checkout') |
72 | br.lock_write() |
73 | |
74 | === modified file 'bzrlib/tests/blackbox/test_uncommit.py' |
75 | --- bzrlib/tests/blackbox/test_uncommit.py 2010-09-15 09:35:42 +0000 |
76 | +++ bzrlib/tests/blackbox/test_uncommit.py 2011-09-27 19:22:41 +0000 |
77 | @@ -72,7 +72,7 @@ |
78 | $ bzr uncommit |
79 | ... |
80 | The above revision(s) will be removed. |
81 | - 2>Uncommit these revisions? [y/n]: |
82 | + 2>Uncommit these revisions? ([y]es, [n]o): n |
83 | <n |
84 | Canceled |
85 | """) |
86 | |
87 | === modified file 'bzrlib/tests/test_script.py' |
88 | --- bzrlib/tests/test_script.py 2011-05-16 13:39:39 +0000 |
89 | +++ bzrlib/tests/test_script.py 2011-09-27 19:22:41 +0000 |
90 | @@ -580,12 +580,12 @@ |
91 | self.addCleanup(commands.builtin_command_registry.remove, 'test-confirm') |
92 | self.run_script(""" |
93 | $ bzr test-confirm |
94 | - 2>Really do it? [y/n]: |
95 | - <yes |
96 | + 2>Really do it? ([y]es, [n]o): y |
97 | + <y |
98 | Do it! |
99 | $ bzr test-confirm |
100 | - 2>Really do it? [y/n]: |
101 | - <no |
102 | + 2>Really do it? ([y]es, [n]o): n |
103 | + <n |
104 | ok, no |
105 | """) |
106 | |
107 | |
108 | === modified file 'bzrlib/tests/test_shelf_ui.py' |
109 | --- bzrlib/tests/test_shelf_ui.py 2011-06-09 14:40:22 +0000 |
110 | +++ bzrlib/tests/test_shelf_ui.py 2011-09-27 19:22:41 +0000 |
111 | @@ -41,16 +41,18 @@ |
112 | self.expected = [] |
113 | self.diff_writer = StringIO() |
114 | |
115 | - def expect(self, prompt, response): |
116 | - self.expected.append((prompt, response)) |
117 | + def expect(self, message, choices, response): |
118 | + self.expected.append((message, choices, response)) |
119 | |
120 | - def prompt(self, message): |
121 | + def prompt(self, message, choices, default): |
122 | try: |
123 | - prompt, response = self.expected.pop(0) |
124 | + expected_message, expected_choices, response = self.expected.pop(0) |
125 | except IndexError: |
126 | raise AssertionError('Unexpected prompt: %s' % message) |
127 | - if prompt != message: |
128 | + if message != expected_message: |
129 | raise AssertionError('Wrong prompt: %s' % message) |
130 | + if choices != expected_choices: |
131 | + raise AssertionError('Wrong choices: %s' % choices) |
132 | return response |
133 | |
134 | |
135 | @@ -83,7 +85,7 @@ |
136 | shelver = ExpectShelver(tree, tree.basis_tree()) |
137 | self.addCleanup(shelver.finalize) |
138 | e = self.assertRaises(AssertionError, shelver.run) |
139 | - self.assertEqual('Unexpected prompt: Shelve? [yNfq?]', str(e)) |
140 | + self.assertEqual('Unexpected prompt: Shelve?', str(e)) |
141 | |
142 | def test_wrong_prompt_failure(self): |
143 | tree = self.create_shelvable_tree() |
144 | @@ -91,9 +93,9 @@ |
145 | self.addCleanup(tree.unlock) |
146 | shelver = ExpectShelver(tree, tree.basis_tree()) |
147 | self.addCleanup(shelver.finalize) |
148 | - shelver.expect('foo', 'y') |
149 | + shelver.expect('foo', 'bar', 'y') |
150 | e = self.assertRaises(AssertionError, shelver.run) |
151 | - self.assertEqual('Wrong prompt: Shelve? [yNfq?]', str(e)) |
152 | + self.assertEqual('Wrong prompt: Shelve?', str(e)) |
153 | |
154 | def test_shelve_not_diff(self): |
155 | tree = self.create_shelvable_tree() |
156 | @@ -101,8 +103,8 @@ |
157 | self.addCleanup(tree.unlock) |
158 | shelver = ExpectShelver(tree, tree.basis_tree()) |
159 | self.addCleanup(shelver.finalize) |
160 | - shelver.expect('Shelve? [yNfq?]', 'n') |
161 | - shelver.expect('Shelve? [yNfq?]', 'n') |
162 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'n') |
163 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'n') |
164 | # No final shelving prompt because no changes were selected |
165 | shelver.run() |
166 | self.assertFileEqual(LINES_ZY, 'tree/foo') |
167 | @@ -113,9 +115,9 @@ |
168 | self.addCleanup(tree.unlock) |
169 | shelver = ExpectShelver(tree, tree.basis_tree()) |
170 | self.addCleanup(shelver.finalize) |
171 | - shelver.expect('Shelve? [yNfq?]', 'y') |
172 | - shelver.expect('Shelve? [yNfq?]', 'y') |
173 | - shelver.expect('Shelve 2 change(s)? [yNfq?]', 'n') |
174 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'y') |
175 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'y') |
176 | + shelver.expect('Shelve 2 change(s)?', '&yes\n&No\n&finish\n&quit', 'n') |
177 | shelver.run() |
178 | self.assertFileEqual(LINES_ZY, 'tree/foo') |
179 | |
180 | @@ -125,9 +127,9 @@ |
181 | self.addCleanup(tree.unlock) |
182 | shelver = ExpectShelver(tree, tree.basis_tree()) |
183 | self.addCleanup(shelver.finalize) |
184 | - shelver.expect('Shelve? [yNfq?]', 'y') |
185 | - shelver.expect('Shelve? [yNfq?]', 'y') |
186 | - shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y') |
187 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'y') |
188 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'y') |
189 | + shelver.expect('Shelve 2 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
190 | shelver.run() |
191 | self.assertFileEqual(LINES_AJ, 'tree/foo') |
192 | |
193 | @@ -137,9 +139,9 @@ |
194 | self.addCleanup(tree.unlock) |
195 | shelver = ExpectShelver(tree, tree.basis_tree()) |
196 | self.addCleanup(shelver.finalize) |
197 | - shelver.expect('Shelve? [yNfq?]', 'y') |
198 | - shelver.expect('Shelve? [yNfq?]', 'n') |
199 | - shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y') |
200 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'y') |
201 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'n') |
202 | + shelver.expect('Shelve 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
203 | shelver.run() |
204 | self.assertFileEqual(LINES_AY, 'tree/foo') |
205 | |
206 | @@ -150,8 +152,8 @@ |
207 | self.addCleanup(tree.unlock) |
208 | shelver = ExpectShelver(tree, tree.basis_tree()) |
209 | self.addCleanup(shelver.finalize) |
210 | - shelver.expect('Shelve binary changes? [yNfq?]', 'y') |
211 | - shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y') |
212 | + shelver.expect('Shelve binary changes?', '&yes\n&No\n&finish\n&quit', 'y') |
213 | + shelver.expect('Shelve 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
214 | shelver.run() |
215 | self.assertFileEqual(LINES_AJ, 'tree/foo') |
216 | |
217 | @@ -162,10 +164,10 @@ |
218 | self.addCleanup(tree.unlock) |
219 | shelver = ExpectShelver(tree, tree.basis_tree()) |
220 | self.addCleanup(shelver.finalize) |
221 | - shelver.expect('Shelve renaming "foo" => "bar"? [yNfq?]', 'y') |
222 | - shelver.expect('Shelve? [yNfq?]', 'y') |
223 | - shelver.expect('Shelve? [yNfq?]', 'y') |
224 | - shelver.expect('Shelve 3 change(s)? [yNfq?]', 'y') |
225 | + shelver.expect('Shelve renaming "foo" => "bar"?', '&yes\n&No\n&finish\n&quit', 'y') |
226 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'y') |
227 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'y') |
228 | + shelver.expect('Shelve 3 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
229 | shelver.run() |
230 | self.assertFileEqual(LINES_AJ, 'tree/foo') |
231 | |
232 | @@ -176,8 +178,8 @@ |
233 | self.addCleanup(tree.unlock) |
234 | shelver = ExpectShelver(tree, tree.basis_tree()) |
235 | self.addCleanup(shelver.finalize) |
236 | - shelver.expect('Shelve removing file "foo"? [yNfq?]', 'y') |
237 | - shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y') |
238 | + shelver.expect('Shelve removing file "foo"?', '&yes\n&No\n&finish\n&quit', 'y') |
239 | + shelver.expect('Shelve 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
240 | shelver.run() |
241 | self.assertFileEqual(LINES_AJ, 'tree/foo') |
242 | |
243 | @@ -190,8 +192,8 @@ |
244 | self.addCleanup(tree.unlock) |
245 | shelver = ExpectShelver(tree, tree.basis_tree()) |
246 | self.addCleanup(shelver.finalize) |
247 | - shelver.expect('Shelve adding file "foo"? [yNfq?]', 'y') |
248 | - shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y') |
249 | + shelver.expect('Shelve adding file "foo"?', '&yes\n&No\n&finish\n&quit', 'y') |
250 | + shelver.expect('Shelve 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
251 | shelver.run() |
252 | self.assertPathDoesNotExist('tree/foo') |
253 | |
254 | @@ -203,9 +205,9 @@ |
255 | self.addCleanup(tree.unlock) |
256 | shelver = ExpectShelver(tree, tree.basis_tree()) |
257 | self.addCleanup(shelver.finalize) |
258 | - shelver.expect('Shelve changing "foo" from file to directory? [yNfq?]', |
259 | + shelver.expect('Shelve changing "foo" from file to directory?', '&yes\n&No\n&finish\n&quit', |
260 | 'y') |
261 | - shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y') |
262 | + shelver.expect('Shelve 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
263 | |
264 | def test_shelve_modify_target(self): |
265 | self.requireFeature(tests.SymlinkFeature) |
266 | @@ -220,8 +222,8 @@ |
267 | shelver = ExpectShelver(tree, tree.basis_tree()) |
268 | self.addCleanup(shelver.finalize) |
269 | shelver.expect('Shelve changing target of "baz" from "bar" to ' |
270 | - '"vax"? [yNfq?]', 'y') |
271 | - shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y') |
272 | + '"vax"?', '&yes\n&No\n&finish\n&quit', 'y') |
273 | + shelver.expect('Shelve 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
274 | shelver.run() |
275 | self.assertEqual('bar', os.readlink('tree/baz')) |
276 | |
277 | @@ -231,8 +233,8 @@ |
278 | self.addCleanup(tree.unlock) |
279 | shelver = ExpectShelver(tree, tree.basis_tree()) |
280 | self.addCleanup(shelver.finalize) |
281 | - shelver.expect('Shelve? [yNfq?]', 'f') |
282 | - shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y') |
283 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'f') |
284 | + shelver.expect('Shelve 2 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
285 | shelver.run() |
286 | self.assertFileEqual(LINES_AJ, 'tree/foo') |
287 | |
288 | @@ -242,7 +244,7 @@ |
289 | self.addCleanup(tree.unlock) |
290 | shelver = ExpectShelver(tree, tree.basis_tree()) |
291 | self.addCleanup(shelver.finalize) |
292 | - shelver.expect('Shelve? [yNfq?]', 'q') |
293 | + shelver.expect('Shelve?', '&yes\n&No\n&finish\n&quit', 'q') |
294 | self.assertRaises(errors.UserAbort, shelver.run) |
295 | self.assertFileEqual(LINES_ZY, 'tree/foo') |
296 | |
297 | @@ -264,19 +266,8 @@ |
298 | self.addCleanup(tree.unlock) |
299 | shelver = ExpectShelver(tree, tree.basis_tree(), file_list=['bar']) |
300 | self.addCleanup(shelver.finalize) |
301 | - shelver.expect('Shelve adding file "bar"? [yNfq?]', 'y') |
302 | - shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y') |
303 | - shelver.run() |
304 | - |
305 | - def test_shelve_help(self): |
306 | - tree = self.create_shelvable_tree() |
307 | - tree.lock_tree_write() |
308 | - self.addCleanup(tree.unlock) |
309 | - shelver = ExpectShelver(tree, tree.basis_tree()) |
310 | - self.addCleanup(shelver.finalize) |
311 | - shelver.expect('Shelve? [yNfq?]', '?') |
312 | - shelver.expect('Shelve? [(y)es, (N)o, (f)inish, or (q)uit]', 'f') |
313 | - shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y') |
314 | + shelver.expect('Shelve adding file "bar"?', '&yes\n&No\n&finish\n&quit', 'y') |
315 | + shelver.expect('Shelve 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
316 | shelver.run() |
317 | |
318 | def test_shelve_destroy(self): |
319 | @@ -339,8 +330,8 @@ |
320 | shelver = ExpectShelver(tree, tree.basis_tree(), |
321 | reporter=shelf_ui.ApplyReporter()) |
322 | self.addCleanup(shelver.finalize) |
323 | - shelver.expect('Apply change? [yNfq?]', 'n') |
324 | - shelver.expect('Apply change? [yNfq?]', 'n') |
325 | + shelver.expect('Apply change?', '&yes\n&No\n&finish\n&quit', 'n') |
326 | + shelver.expect('Apply change?', '&yes\n&No\n&finish\n&quit', 'n') |
327 | # No final shelving prompt because no changes were selected |
328 | shelver.run() |
329 | self.assertFileEqual(LINES_ZY, 'tree/foo') |
330 | @@ -352,9 +343,9 @@ |
331 | shelver = ExpectShelver(tree, tree.basis_tree(), |
332 | reporter=shelf_ui.ApplyReporter()) |
333 | self.addCleanup(shelver.finalize) |
334 | - shelver.expect('Apply change? [yNfq?]', 'y') |
335 | - shelver.expect('Apply change? [yNfq?]', 'y') |
336 | - shelver.expect('Apply 2 change(s)? [yNfq?]', 'n') |
337 | + shelver.expect('Apply change?', '&yes\n&No\n&finish\n&quit', 'y') |
338 | + shelver.expect('Apply change?', '&yes\n&No\n&finish\n&quit', 'y') |
339 | + shelver.expect('Apply 2 change(s)?', '&yes\n&No\n&finish\n&quit', 'n') |
340 | shelver.run() |
341 | self.assertFileEqual(LINES_ZY, 'tree/foo') |
342 | |
343 | @@ -365,9 +356,9 @@ |
344 | shelver = ExpectShelver(tree, tree.basis_tree(), |
345 | reporter=shelf_ui.ApplyReporter()) |
346 | self.addCleanup(shelver.finalize) |
347 | - shelver.expect('Apply change? [yNfq?]', 'y') |
348 | - shelver.expect('Apply change? [yNfq?]', 'y') |
349 | - shelver.expect('Apply 2 change(s)? [yNfq?]', 'y') |
350 | + shelver.expect('Apply change?', '&yes\n&No\n&finish\n&quit', 'y') |
351 | + shelver.expect('Apply change?', '&yes\n&No\n&finish\n&quit', 'y') |
352 | + shelver.expect('Apply 2 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
353 | shelver.run() |
354 | self.assertFileEqual(LINES_AJ, 'tree/foo') |
355 | |
356 | @@ -379,8 +370,8 @@ |
357 | shelver = ExpectShelver(tree, tree.basis_tree(), |
358 | reporter=shelf_ui.ApplyReporter()) |
359 | self.addCleanup(shelver.finalize) |
360 | - shelver.expect('Apply binary changes? [yNfq?]', 'y') |
361 | - shelver.expect('Apply 1 change(s)? [yNfq?]', 'y') |
362 | + shelver.expect('Apply binary changes?', '&yes\n&No\n&finish\n&quit', 'y') |
363 | + shelver.expect('Apply 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
364 | shelver.run() |
365 | self.assertFileEqual(LINES_AJ, 'tree/foo') |
366 | |
367 | @@ -392,10 +383,10 @@ |
368 | shelver = ExpectShelver(tree, tree.basis_tree(), |
369 | reporter=shelf_ui.ApplyReporter()) |
370 | self.addCleanup(shelver.finalize) |
371 | - shelver.expect('Rename "bar" => "foo"? [yNfq?]', 'y') |
372 | - shelver.expect('Apply change? [yNfq?]', 'y') |
373 | - shelver.expect('Apply change? [yNfq?]', 'y') |
374 | - shelver.expect('Apply 3 change(s)? [yNfq?]', 'y') |
375 | + shelver.expect('Rename "bar" => "foo"?', '&yes\n&No\n&finish\n&quit', 'y') |
376 | + shelver.expect('Apply change?', '&yes\n&No\n&finish\n&quit', 'y') |
377 | + shelver.expect('Apply change?', '&yes\n&No\n&finish\n&quit', 'y') |
378 | + shelver.expect('Apply 3 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
379 | shelver.run() |
380 | self.assertFileEqual(LINES_AJ, 'tree/foo') |
381 | |
382 | @@ -407,8 +398,8 @@ |
383 | shelver = ExpectShelver(tree, tree.basis_tree(), |
384 | reporter=shelf_ui.ApplyReporter()) |
385 | self.addCleanup(shelver.finalize) |
386 | - shelver.expect('Add file "foo"? [yNfq?]', 'y') |
387 | - shelver.expect('Apply 1 change(s)? [yNfq?]', 'y') |
388 | + shelver.expect('Add file "foo"?', '&yes\n&No\n&finish\n&quit', 'y') |
389 | + shelver.expect('Apply 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
390 | shelver.run() |
391 | self.assertFileEqual(LINES_AJ, 'tree/foo') |
392 | |
393 | @@ -422,8 +413,8 @@ |
394 | shelver = ExpectShelver(tree, tree.basis_tree(), |
395 | reporter=shelf_ui.ApplyReporter()) |
396 | self.addCleanup(shelver.finalize) |
397 | - shelver.expect('Delete file "foo"? [yNfq?]', 'y') |
398 | - shelver.expect('Apply 1 change(s)? [yNfq?]', 'y') |
399 | + shelver.expect('Delete file "foo"?', '&yes\n&No\n&finish\n&quit', 'y') |
400 | + shelver.expect('Apply 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
401 | shelver.run() |
402 | self.assertPathDoesNotExist('tree/foo') |
403 | |
404 | @@ -436,8 +427,8 @@ |
405 | shelver = ExpectShelver(tree, tree.basis_tree(), |
406 | reporter=shelf_ui.ApplyReporter()) |
407 | self.addCleanup(shelver.finalize) |
408 | - shelver.expect('Change "foo" from directory to a file? [yNfq?]', 'y') |
409 | - shelver.expect('Apply 1 change(s)? [yNfq?]', 'y') |
410 | + shelver.expect('Change "foo" from directory to a file?', '&yes\n&No\n&finish\n&quit', 'y') |
411 | + shelver.expect('Apply 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
412 | |
413 | def test_shelve_modify_target(self): |
414 | self.requireFeature(tests.SymlinkFeature) |
415 | @@ -452,9 +443,9 @@ |
416 | shelver = ExpectShelver(tree, tree.basis_tree(), |
417 | reporter=shelf_ui.ApplyReporter()) |
418 | self.addCleanup(shelver.finalize) |
419 | - shelver.expect('Change target of "baz" from "vax" to "bar"? [yNfq?]', |
420 | + shelver.expect('Change target of "baz" from "vax" to "bar"?', '&yes\n&No\n&finish\n&quit', |
421 | 'y') |
422 | - shelver.expect('Apply 1 change(s)? [yNfq?]', 'y') |
423 | + shelver.expect('Apply 1 change(s)?', '&yes\n&No\n&finish\n&quit', 'y') |
424 | shelver.run() |
425 | self.assertEqual('bar', os.readlink('tree/baz')) |
426 | |
427 | |
428 | === modified file 'bzrlib/tests/test_ui.py' |
429 | --- bzrlib/tests/test_ui.py 2011-05-16 13:39:39 +0000 |
430 | +++ bzrlib/tests/test_ui.py 2011-09-27 19:22:41 +0000 |
431 | @@ -109,13 +109,14 @@ |
432 | pb.finished() |
433 | |
434 | def test_text_ui_get_boolean(self): |
435 | - stdin = tests.StringIOWrapper("y\n" # True |
436 | - "n\n" # False |
437 | - "yes with garbage\nY\n" # True |
438 | - "not an answer\nno\n" # False |
439 | - "I'm sure!\nyes\n" # True |
440 | - "NO\n" # False |
441 | - "foo\n") |
442 | + stdin = tests.StringIOWrapper("y" # True |
443 | + "n" # False |
444 | + "Y" # True |
445 | + "N" # False |
446 | + "\r\ngarbagey" # True |
447 | + "\r\ngarbagen" # False |
448 | + "foo\n" |
449 | + ) |
450 | stdout = tests.StringIOWrapper() |
451 | stderr = tests.StringIOWrapper() |
452 | factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr) |
453 | @@ -154,7 +155,7 @@ |
454 | out = test_progress._TTYStringIO() |
455 | self.overrideEnv('TERM', 'xterm') |
456 | factory = _mod_ui_text.TextUIFactory( |
457 | - stdin=tests.StringIOWrapper("yada\ny\n"), |
458 | + stdin=tests.StringIOWrapper("bar\ny"), |
459 | stdout=out, stderr=out) |
460 | factory._avail_width = lambda: 79 |
461 | pb = factory.nested_progress_bar() |
462 | @@ -171,7 +172,7 @@ |
463 | self.assertContainsRe(output, |
464 | "| foo *\r\r *\r*") |
465 | self.assertContainsRe(output, |
466 | - r"what do you want\? \[y/n\]: what do you want\? \[y/n\]: ") |
467 | + r"what do you want\? \(\[y\]es, \[n\]o\): y") |
468 | # stdin should have been totally consumed |
469 | self.assertEqual('', factory.stdin.readline()) |
470 | |
471 | |
472 | === modified file 'bzrlib/ui/__init__.py' |
473 | --- bzrlib/ui/__init__.py 2011-05-27 05:16:48 +0000 |
474 | +++ bzrlib/ui/__init__.py 2011-09-27 19:22:41 +0000 |
475 | @@ -315,6 +315,9 @@ |
476 | warnings.warn(fail) # so tests will fail etc |
477 | return fail |
478 | |
479 | + def confirm(self, msg, choices, default=None): |
480 | + raise NotImplementedError(self.confirm) |
481 | + |
482 | def get_boolean(self, prompt): |
483 | """Get a boolean question answered from the user. |
484 | |
485 | @@ -322,7 +325,8 @@ |
486 | line without terminating \\n. |
487 | :return: True or False for y/yes or n/no. |
488 | """ |
489 | - raise NotImplementedError(self.get_boolean) |
490 | + char = self.confirm(prompt + '?', '&yes\n&no', default=None) |
491 | + return 'y' == char |
492 | |
493 | def get_integer(self, prompt): |
494 | """Get an integer from the user. |
495 | @@ -477,6 +481,9 @@ |
496 | def confirm_action(self, prompt, confirmation_id, args): |
497 | return self.get_boolean(prompt % args) |
498 | |
499 | + def confirm(self, msg, choices, default=None): |
500 | + return self.responses.pop(0) |
501 | + |
502 | def get_boolean(self, prompt): |
503 | return self.responses.pop(0) |
504 | |
505 | |
506 | === modified file 'bzrlib/ui/text.py' |
507 | --- bzrlib/ui/text.py 2011-05-16 13:39:39 +0000 |
508 | +++ bzrlib/ui/text.py 2011-09-27 19:22:41 +0000 |
509 | @@ -30,6 +30,7 @@ |
510 | |
511 | from bzrlib import ( |
512 | debug, |
513 | + errors, |
514 | progress, |
515 | osutils, |
516 | trace, |
517 | @@ -61,6 +62,40 @@ |
518 | # paints progress, network activity, etc |
519 | self._progress_view = self.make_progress_view() |
520 | |
521 | + def confirm(self, msg, choices, default=None): |
522 | + if self.stdin == sys.stdin and self.stdin.isatty(): |
523 | + def getchar(): |
524 | + return osutils.getchar() |
525 | + else: |
526 | + def getchar(): |
527 | + return self.stdin.read(1) |
528 | + |
529 | + shortcuts = '' |
530 | + alternatives = [] |
531 | + for c in choices.split('\n'): |
532 | + shortcut = c.find('&') |
533 | + if -1 != shortcut and (shortcut + 1) < len(c): |
534 | + help = c[:shortcut] |
535 | + help += '[' + c[shortcut + 1] + ']' |
536 | + help += c[(shortcut + 2):] |
537 | + shortcut = c[shortcut + 1] |
538 | + else: |
539 | + help = c.strip('&') |
540 | + shortcut = c[0] |
541 | + shortcuts += shortcut.lower() |
542 | + alternatives.append(help) |
543 | + |
544 | + prompt = u'%s (%s): ' % (msg, ', '.join(alternatives)) |
545 | + self.prompt(prompt) |
546 | + |
547 | + while True: |
548 | + char = getchar().lower() |
549 | + if '\r' == char and default is not None: |
550 | + char = default |
551 | + if -1 != shortcuts.find(char): |
552 | + self.stderr.write(char + '\n') |
553 | + return char |
554 | + |
555 | def be_quiet(self, state): |
556 | if state and not self._quiet: |
557 | self.clear_term() |
558 | @@ -78,18 +113,6 @@ |
559 | # to clear it. We might need to separately check for the case of |
560 | self._progress_view.clear() |
561 | |
562 | - def get_boolean(self, prompt): |
563 | - while True: |
564 | - self.prompt(prompt + "? [y/n]: ") |
565 | - line = self.stdin.readline().lower() |
566 | - if line in ('y\n', 'yes\n'): |
567 | - return True |
568 | - elif line in ('n\n', 'no\n'): |
569 | - return False |
570 | - elif line in ('', None): |
571 | - # end-of-file; possibly should raise an error here instead |
572 | - return None |
573 | - |
574 | def get_integer(self, prompt): |
575 | while True: |
576 | self.prompt(prompt) |
577 | |
578 | # Begin bundle |
579 | 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 |
Excerpts from Vincent Ladeuil's message of Tue Sep 27 16:37:19 UTC 2011: /code.launchpad .net/~vila/ bzr/856261- unshelve- line-based/ +merge/ 77195 line_based_ input ?
> Vincent Ladeuil has proposed merging lp:~vila/bzr/856261-unshelve-line-based into lp:bzr.
>
> Requested reviews:
> bzr-core (bzr-core)
>
> For more details, see:
> https:/
>
> I've been deprived from using shelve under emacs for years.
>
> But when I ran into bug #856261 trying to reproduce bug #850594, I thought
> it may be worth to have another go at it.
>
> The fix is simple: since osutils.getchar() requires a true term (which
> neither emacs not the test scripts provide), I handle the input as a
> line-based one which is exactly what emacs does and also exactly what the
> test script interface provides :)
>
> I'd like feedback on how we want to configure this feature, knowing that an
> environment variable may be more appropriate here (not everybody use
> terminals under emacs only and the test script need a way to force the
> behavior). Or should I just consider that the fix for #491196 is around the
> corner and name the config variable... shelve.
> shelve.line_ui ? both boolean defaulting to False or shelve.input
> (defaulting to 'char' accepting 'line' ?)
I also ran into problems using shelve with my VIM plugin. Other commands
use ui.get_boolean, but there is no corresponding method for handling
more complex choices. So even after providing my own UI class
implementation, I cannot use shelve.
In VIM there is a confirm function:
confirm({msg} [, {choices} [, {default} [, {type}]]])
Which can be used like this:
confirm("Save changes?", "&Yes\n& No\n&Cancel" )
Where the letter after the '&' is the shortcut key for that choice.
So I have been working on a branch to implement something just like
this (see attached patch).
N.B.: your patch removes a call to gettext.
--
A: Because it destroys the flow of conversation.
Q: Why is top posting dumb?