This repository has been archived by the owner on Jan 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 22
/
trychooser
executable file
·490 lines (420 loc) · 15.9 KB
/
trychooser
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
#!/usr/bin/env python
"choose build options for and push to Mozilla's try server"
import sys
import re
# A node in the decision tree
class N: # Node
def __init__ (self, prompt, help, action):
self.prompt = prompt
self.help = help
self.action = action
# this deletes a character, then moves to the next option.
class D: # delete_command
def __init__(self, next):
self.next = next
class NoPrompt:
def __init__ (self, action):
self.action = action
finish = object()
error = object()
################
# Build each node with it's data
################
a = N ("Run everything", "Run all platforms, tests and talos, and don't ask any more questions", ' -b do -p all -u all -t all')
b_od = N ("Both optimized and debug", "All builds and tests will run both on optimized and debug builds", ' -b do')
b_o = N ("Just optimized", "Only use optimized builds, do not use debug builds", ' -b o')
b_d = N ("Just debug", "Only use debug builds, do not use optimized builds", ' -b d')
p_all = N ("All platforms", "Build on all platforms", ' -p all')
p_any = NoPrompt (" -p ")
p_linux = N ("Linux", "Build on i386 (32-bit) linux", 'linux,')
p_linux64 = N ("linux64", "Build on x86-64 (64-bit) linux", 'linux64,')
p_linuxqt = N ("linuxqt", "Build on Qt linux", 'linuxqt,')
p_macosx64 = N ("macosx64", "Build on Mac OSX 10.6 (x86-64, 64-bit, part of a universal binary)", 'macosx64,')
p_win32 = N ("win32", "Build on Windows (32-bit)", 'win32,')
p_win64 = N ("win64", "Build on Windows (64-bit)", 'win64,')
p_android = N ("android", "Build on Android", 'android,')
p_android_armv6 = N ("android-armv6", "Build on Android Armv6", 'android-armv6,')
p_none = NoPrompt (" -p none")
u_all = N ("All Unit tests", "Run all unit tests on all chosen platforms", ' -u all')
u_any = N ("Any unit tests", "Would you like to be asked about running each set of unit tests", ' -u ')
u_reftest = N ("reftest", "Run reftests", 'reftest,')
u_reftest_ipc = N ("reftest-ipc", "Run IPC reftests", 'reftest-ipc,')
u_reftest_naccel = N ("reftest-no-accel", "Run non-accelerated reftests (linux/win7 only)", 'reftest-no-accel,')
u_crashtest = N ("crashtest", "Run crashtest tests", 'crashtest,')
u_crashtest_ipc = N ("crashtest-ipc", "Run IPC crashtests", 'crashtest-ipc,')
u_xpcshell = N ("xpcshell", "Run xpcshell tests", 'xpcshell,')
u_jsreftest = N ("jsreftest", "Run jsreftests", 'jsreftest,')
u_jetpack = N ("jetpack", "Run jetpack tests", 'jetpack,')
u_marionette = N ("marionette", "Run marionette tests", 'marionette,')
u_mozmill = N ("mozmill", "Run mozmill tests (thunderbird-only)", 'mozmill,')
u_mochitests = N ("Run all mochitests", "Run all of the mochitests", 'mochitests,')
u_mochitests_any = N ("Run any mochitests", "Run any of the mochitests", '')
u_mochitest1 = N ("mochitest-1", "Run mochitest-1", 'mochitest-1,')
u_mochitest2 = N ("mochitest-2", "Run mochitest-2", 'mochitest-2,')
u_mochitest3 = N ("mochitest-3", "Run mochitest-3", 'mochitest-3,')
u_mochitest4 = N ("mochitest-4", "Run mochitest-4", 'mochitest-4,')
u_mochitest5 = N ("mochitest-5", "Run mochitest-5", 'mochitest-5,')
u_mochitesto = N ("mochitest-o", "Run mochitest-o", 'mochitest-o,')
## Android only suite names
u_mochitest6 = N ("mochitest-6", "Run mochitest-6 (android-only)", 'mochitest-6,')
u_mochitest7 = N ("mochitest-7", "Run mochitest-7 (android-only)", 'mochitest-7,')
u_mochitest8 = N ("mochitest-8", "Run mochitest-8 (android-only)", 'mochitest-8,')
u_reftest1 = N ("reftest-1", "Run reftest-1 (android-only)", 'reftest-1,')
u_reftest2 = N ("reftest-2", "Run reftest-2 (android-only)", 'reftest-2,')
u_reftest3 = N ("reftest-3", "Run reftest-3 (android-only)", 'reftest-3,')
u_reftest4 = N ("reftest-4", "Run reftest-4 (android-only)", 'reftest-4,')
u_crashtest1 = N ("crashtest-1", "Run crashtest-1 (android-only)", 'crashtest-1,')
u_crashtest2 = N ("crashtest-2", "Run crashtest-2 (android-only)", 'crashtest-2,')
u_crashtest3 = N ("crashtest-3", "Run crashtest-3 (android-only)", 'crashtest-3,')
u_jsreftest1 = N ("jsreftest-1", "Run jsreftests-1 (android-only)", 'jsreftest-1,')
u_jsreftest2 = N ("jsreftest-2", "Run jsreftests-2 (android-only)", 'jsreftest-2,')
u_jsreftest3 = N ("jsreftest-3", "Run jsreftests-3 (android-only)", 'jsreftest-3,')
u_robocop = N ("robocop", "Run robocop tests (android-only)", 'robocop,')
u_none = NoPrompt (" -u none")
t_all = N ("All talos tests", "Run all talos tests on all chosen platforms", ' -t all')
t_any = N ("Any talos tests", "Would you like to be asked about running each set of talos tests", ' -t ')
t_nochrome = N ("nochrome", "Run nochrome suite", 'nochrome,')
t_dromaeo = N ("dromaeo", "Run dromaeo suite", 'dromaeo,')
t_a11y = N ("a11y", "Run a11y suite", 'a11y,')
t_svg = N ("svg", "Run svg suite", 'svg,')
t_chrome = N ("chrome", "Run chrome suite", 'chrome,')
t_tp = N ("tp", "Run tp suite", 'tp,')
t_tp4 = N ("tp4", "Run tp4 suite", 'tp4,')
t_dirty = N ("dirty", "Run dirty suite", 'dirty,')
t_scroll = N ("scroll", "Run scroll suite", 'scroll,')
t_cold = N ("cold", "Run cold suite", 'cold,')
t_v8 = N ("v8", "Run v8 suite", 'v8,')
t_none = NoPrompt (" -t none")
remote_talos = ','.join(['remote-ts', 'remote-tdhtml', 'remote-tsvg', 'remote-tsspider',
'remote-tpan', 'remote-tp4m', 'remote-tp4m_nochrome',])
t_all_android = N ("All android talos tests", "Run all android talos tests", remote_talos)
t_any_android = N ("Any android talos tests", "Run any android talos tests", '')
t_svg_r = N ("remote-tsvg", "Run svg suite", 'remote-tsvg,')
t_nochrome_r = N ("remote-tp4m_nochrome", "Run tp4m nochrome suite", 'remote-tp4m_nochrome,')
t_tp4_r = N ("remote-tp4m", "Run tp4 suite", 'remote-tp4m,')
t_ts_r = N ("remote-ts", "Run ts suite", 'remote-ts,')
t_tdhtml_r = N ("remote-tdhtml", "Run tdhtml suite", 'remote-tdhtml,')
t_tsspider_r = N ("remote-tsspdier", "Run tsspider suite", 'remote-tsspider,')
t_tpan_r = N ("remote-tpan", "Run tpan suite", 'remote-tpan,')
t_none_r = NoPrompt ("")
################
# Build decision tree. Each object has a y and n property, which are chosen if
# Y or N is chosen. That property is the next question.
################
a.y = finish
a.n = b_od
b_od.y = p_all
b_od.n = b_o
b_o.y = p_all
b_o.n = b_d
b_d.y = p_all
b_d.n = error
p_all.y = u_all
p_all.n = p_any
p_any.next = p_linux
p_linux.y = p_linux64
p_linux.n = p_linux64
p_linux64.y = p_macosx64
p_linux64.n = p_macosx64
p_macosx64.y = p_win32
p_macosx64.n = p_win32
p_win32.y = p_win64
p_win32.n = p_win64
p_win64.y = p_android
p_win64.n = p_android
p_android.y = p_android_armv6
p_android.n = p_android_armv6
p_android_armv6.y = D(u_all)
p_android_armv6.n = D(u_all)
u_all.y = t_all
u_all.n = u_any
u_any.y = u_reftest
u_any.n = u_none
u_none.next = t_all
u_reftest.y = u_reftest1
u_reftest.n = u_reftest1
u_reftest1.y = u_reftest2
u_reftest1.n = u_reftest2
u_reftest2.y = u_reftest3
u_reftest2.n = u_reftest3
u_reftest3.y = u_reftest4
u_reftest3.n = u_reftest4
u_reftest4.y = u_reftest_ipc
u_reftest4.n = u_reftest_ipc
u_reftest_ipc.y = u_reftest_naccel
u_reftest_ipc.n = u_reftest_naccel
u_reftest_naccel.y = u_crashtest
u_reftest_naccel.n = u_crashtest
u_crashtest.y = u_crashtest1
u_crashtest.n = u_crashtest1
u_crashtest1.y = u_crashtest2
u_crashtest1.n = u_crashtest2
u_crashtest2.y = u_crashtest3
u_crashtest2.n = u_crashtest3
u_crashtest3.y = u_crashtest_ipc
u_crashtest3.n = u_crashtest_ipc
u_crashtest_ipc.y = u_xpcshell
u_crashtest_ipc.n = u_xpcshell
u_xpcshell.y = u_jsreftest
u_xpcshell.n = u_jsreftest
u_jsreftest.y = u_jsreftest1
u_jsreftest.n = u_jsreftest1
u_jsreftest1.y = u_jsreftest2
u_jsreftest1.n = u_jsreftest2
u_jsreftest2.y = u_jsreftest3
u_jsreftest2.n = u_jsreftest3
u_jsreftest3.y = u_jetpack
u_jsreftest3.n = u_jetpack
u_jetpack.y = u_marionette
u_jetpack.n = u_marionette
u_marionette.y = u_mozmill
u_marionette.n = u_mozmill
u_mozmill.y = u_robocop
u_mozmill.n = u_robocop
u_robocop.y = u_mochitests
u_robocop.n = u_mochitests
u_mochitests.y = D(t_all)
u_mochitests.n = u_mochitests_any
u_mochitests_any.y = u_mochitest1
u_mochitests_any.n = D(t_all)
u_mochitest1.y = u_mochitest2
u_mochitest1.n = u_mochitest2
u_mochitest2.y = u_mochitest3
u_mochitest2.n = u_mochitest3
u_mochitest3.y = u_mochitest4
u_mochitest3.n = u_mochitest4
u_mochitest4.y = u_mochitest5
u_mochitest4.n = u_mochitest5
u_mochitest5.y = u_mochitest6
u_mochitest5.n = u_mochitest6
u_mochitest6.y = u_mochitest7
u_mochitest6.n = u_mochitest7
u_mochitest7.y = u_mochitest8
u_mochitest7.n = u_mochitest8
u_mochitest8.y = u_mochitesto
u_mochitest8.n = u_mochitesto
u_mochitesto.y = D(t_all)
u_mochitesto.n = D(t_all)
t_all.y = finish
t_all.n = t_any
t_any.y = t_nochrome
t_any.n = t_none
t_none.next = finish
t_nochrome.y = t_dromaeo
t_nochrome.n = t_dromaeo
t_dromaeo.y = t_a11y
t_dromaeo.n = t_a11y
t_a11y.y = t_svg
t_a11y.n = t_svg
t_svg.y = t_chrome
t_svg.n = t_chrome
t_chrome.y = t_tp
t_chrome.n = t_tp
t_tp.y = t_tp4
t_tp.n = t_tp4
t_tp4.y = t_dirty
t_tp4.n = t_dirty
t_dirty.y = t_scroll
t_dirty.n = t_scroll
t_scroll.y = t_cold
t_scroll.n = t_cold
t_cold.y = t_v8
t_cold.n = t_v8
t_v8.y = t_all_android
t_v8.n = t_all_android
t_all_android.y = finish
t_all_android.n = t_any_android
t_any_android.y = t_svg_r
t_any_android.n = t_none_r
t_none_r.next = finish
t_svg_r.y = t_nochrome_r
t_svg_r.n = t_nochrome_r
t_nochrome_r.y = t_tp4_r
t_nochrome_r.n = t_tp4_r
t_tp4_r.y = t_ts_r
t_tp4_r.n = t_ts_r
t_ts_r.y = t_tdhtml_r
t_ts_r.n = t_tdhtml_r
t_tdhtml_r.y = t_tsspider_r
t_tdhtml_r.n = t_tsspider_r
t_tsspider_r.y = t_tpan_r
t_tsspider_r.n = t_tpan_r
t_tpan_r.y = D(finish)
t_tpan_r.n = D(finish)
################
# The actual algorithm is simple
################
def run_algorithm(state):
node = a
string = 'try:'
while node != finish:
if node == error:
state.say("Invalid selection")
state.exit(-1)
elif isinstance(node, D):
string = string[:-1] # remove last character
node = node.next
elif isinstance(node, NoPrompt):
string += node.action
node = node.next
elif isinstance(node, N):
state.say(node.prompt + '?')
input = state.prompt()
if input in 'Yy':
string += node.action
node = node.y
elif input in 'Nn':
node = node.n
elif input == '?':
state.say(node.help)
else:
state.say("Invalid option, please try again")
################
# Hard to test these above, so use string search for weird flag combination
################
platforms = 'linux,linux64,macosx,macosx64,win32,android,android-xul'.split(',')
unittests = 'reftest,crashtest,xpcshell,jsreftest,opengl,mochitest-1,mochitest-2,mochitest-3,mochitest-4,mochitest-5,mochitest-o,mochitests'.split(',')
taloss = 'nochrome,dromaeo,a11y,svg,chrome,tp,dirty,scroll,cold,v8'.split(',')
if string.find ('-p') + string.find('-a') == -2:
state.say("no platform selected")
state.say ("Invalid selection: " + string)
state.exit(-1)
if string.find ('-b') + string.find('-a') == -2:
state.say ("no build selected")
state.say ("Invalid selection: " + string)
state.exit(-1)
if string.find ('-p') != -1 and \
string.find ('-p all') == -1 and \
(sum([string.find(x) for x in platforms]) == -1*len(platforms)):
state.say ("no platforms selected, despite asking for some")
state.say ("Invalid selection: " + string)
state.exit(-1)
if string.find ('-u') != -1 and \
string.find ('-u all') == -1 and \
string.find ('-u none') == -1 and \
(sum([string.find(x) for x in unittests]) == -1*len(unittests)):
state.say ("no unit tests selected, despite asking for some")
state.say ("Invalid selection: " + string)
state.exit(-1)
if string.find ('-t') != -1 and \
string.find ('-t all') == -1 and \
string.find ('-t none') == -1 and \
(sum([string.find(x) for x in taloss]) == -1*len(taloss)):
state.say ("no talos tests selected, despite asking for some")
state.say ("Invalid selection: " + string)
state.exit(-1)
return string
if __name__ == '__main__':
class Test_interface:
# print isn't a function
def say(self, string):
print string
def prompt(self):
return raw_input('[Ynh?]\n')
def exit(self, code):
sys.exit(code)
print run_algorithm(Test_interface())
else:
from mercurial import ui
from mercurial import extensions
from mercurial.i18n import _
from mercurial import commands
from mercurial import util
class HG_interface:
def __init__ (self, ui, repo):
self.ui = ui
self.repo = repo
def say(self, string):
self.ui.write(string + '\n')
self.ui.flush()
def prompt(self):
index = self.ui.promptchoice('[Ynh?]', ['&Yes', '&no', '&h', '&?'], default=0)
return 'Ynh?'[index]
def exit(self, code):
sys.exit(code)
def suggest_results_bug(ui, repo):
ui.write('Leave a comment in a bug on completion?\n')
if ui.promptchoice('[Yn]', ['&Yes', '&no'], default=0):
return None
# Derive a suggested bug number in which to leave results (regex stolen from bzexport.py)
bug_re = re.compile(r'''# bug followed by any sequence of numbers, or
# a standalone sequence of numbers
(
(?:
bug |
b= |
# a sequence of 5+ numbers preceded by whitespace
(?=\b\#?\d{5,}) |
# numbers at the very beginning
^(?=\d)
)
(?:\s*\#?)(\d+)
)''', re.I | re.X)
rev = repo.mq.applied[-1].name
match = re.search(bug_re, repo[rev].description())
s = 'Bug number'
suggested = None
if match:
suggested = match.group(2)
s += ' (%s)' % suggested
ui.write('%s:\n' % s)
bugnum = None
while not bugnum:
try:
numstr = ui.prompt('', str(suggested))
return int(numstr)
except:
ui.write('Invalid bug number\n')
def run_mercurial_command(ui, repo, *args, **opts):
"""Build a TryChooser string by asking a few questions.
For all questions, choosing Y means adding something to the TryChooser string. Choosing ? shows context-sensitive help."""
try:
mq = extensions.find('mq')
except KeyError:
ui.warn(_("Warning: mq extension hasn't been found, this is going to print the syntax only.\n"))
string = run_algorithm(HG_interface(ui, repo))
ui.write(string + '\n')
return
if repo[None].dirty():
raise util.Abort(_("local changes found, refresh first"))
if opts.get('message'):
msg = opts.get('message')
if msg.find('try:') == -1:
msg = 'try: ' + msg
else:
msg = run_algorithm(HG_interface(ui, repo))
bugnum = suggest_results_bug(ui, repo)
if bugnum:
msg += ' --post-to-bugzilla Bug %s' % bugnum
ui.write(_("The following try message is going to be used:\n%s\n") % msg)
ui.write(_("Creates the trychooser mq entry...\n"))
mq.new(ui, repo, 'trychooser', message=msg)
if opts.get('dry_run'):
ui.write(_("Pretending to push to try server...\n"))
else:
ui.write(_("Push to try server...\n"))
try:
commands.push(ui, repo, "ssh://hg.mozilla.org/try", force=True)
except:
ui.write("ERROR: failed to push to try server!\n");
# In Mercurial 2.1 phases support was added, and until Mozilla updates to
# this version and configures the try repository to be non-publishing, we
# need to reset the pushed patches to be editable again.
try:
commands.phase(ui, repo, 'mq()', draft=True, public=False, secret=False, force=True, rev="")
except AttributeError:
pass # we're running a old Mercurial version, don't bother.
mq.pop(ui, repo)
mq.delete(ui, repo, 'trychooser')
# Mercurial interface
cmdtable = {
"trychooser":
(run_mercurial_command,
[
('n', 'dry-run', False, _('do not perform actions, just print output')),
('m', 'message', '', _('use text as try message'))
],
_('hg trychooser [-m TEXT]')
)
}
# TODO: add an MQ option to qrefresh