Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: tools/submit_try

Issue 317823003: Fix submit_try (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 7
8 """ 8 """
9 submit_try: Submit a try request. 9 submit_try: Submit a try request.
10 10
11 This is a thin wrapper around the try request utilities in depot_tools which 11 This is a thin wrapper around the try request utilities in depot_tools which
12 adds some validation and supports both git and svn. 12 adds some validation and supports both git and svn.
13 """ 13 """
14 14
15 15
16 import httplib 16 import httplib
17 import json 17 import json
18 import os 18 import os
19 import re 19 import re
20 import shutil 20 import shutil
21 import subprocess 21 import subprocess
22 import svn 22 import svn
23 import sys 23 import sys
24 import tempfile 24 import tempfile
25 25
26 import buildbot_globals 26 import retrieve_from_googlesource
27 27
28 28
29 # Alias which can be used to run a try on every builder. 29 # Alias which can be used to run a try on every builder.
30 ALL_BUILDERS = 'all' 30 ALL_BUILDERS = 'all'
31 # Alias which can be used to run a try on all compile builders. 31 # Alias which can be used to run a try on all compile builders.
32 COMPILE_BUILDERS = 'compile' 32 COMPILE_BUILDERS = 'compile'
33 # Alias which can be used to run a try on all builders that are run in the CQ. 33 # Alias which can be used to run a try on all builders that are run in the CQ.
34 CQ_BUILDERS = 'cq' 34 CQ_BUILDERS = 'cq'
35 # Alias which can be used to specify a regex to choose builders. 35 # Alias which can be used to specify a regex to choose builders.
36 REGEX = 'regex' 36 REGEX = 'regex'
37 37
38 ALL_ALIASES = [ALL_BUILDERS, COMPILE_BUILDERS, REGEX, CQ_BUILDERS] 38 ALL_ALIASES = [ALL_BUILDERS, COMPILE_BUILDERS, REGEX, CQ_BUILDERS]
39 39
40 LARGE_NUMBER_OF_BOTS = 5
41
40 GIT = 'git.bat' if os.name == 'nt' else 'git' 42 GIT = 'git.bat' if os.name == 'nt' else 'git'
41 43
42 # URL of the slaves.cfg file in the Skia buildbot sources. 44 # URL of the slaves.cfg file in the Skia buildbot sources.
43 SLAVES_CFG_URL = ('https://skia.googlesource.com/buildbot/+/master/' 45 SKIA_REPO = 'https://skia.googlesource.com/buildbot'
44 'master/slaves.cfg') 46 SLAVES_CFG_PATH = 'master/slaves.cfg'
45 47
46 # All try builders have this suffix. 48 # All try builders have this suffix.
47 TRYBOT_SUFFIX = '-Trybot' 49 TRYBOT_SUFFIX = '-Trybot'
48 50
49 # String for matching the svn url of the try server inside codereview.settings. 51 # String for matching the svn url of the try server inside codereview.settings.
50 TRYSERVER_SVN_URL = 'TRYSERVER_SVN_URL: ' 52 TRYSERVER_SVN_URL = 'TRYSERVER_SVN_URL: '
51 53
52 # Strings used for matching svn config properties. 54 # Strings used for matching svn config properties.
53 URL_STR = 'URL' 55 URL_STR = 'URL'
54 REPO_ROOT_STR = 'Repository Root' 56 REPO_ROOT_STR = 'Repository Root'
55 57
56 58
57 def FindDepotTools(): 59 def FindDepotTools():
58 """ Find depot_tools on the local machine and return its location. """ 60 """ Find depot_tools on the local machine and return its location. """
59 which_cmd = 'where' if os.name == 'nt' else 'which' 61 which_cmd = 'where' if os.name == 'nt' else 'which'
60 cmd = [which_cmd, 'gcl'] 62 cmd = [which_cmd, 'gcl']
61 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 63 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
62 if proc.wait() != 0: 64 if proc.wait() != 0:
63 raise Exception('Couldn\'t find depot_tools in PATH!') 65 raise Exception('Couldn\'t find depot_tools in PATH!')
64 gcl = proc.communicate()[0].split('\n')[0].rstrip() 66 gcl = proc.communicate()[0].split('\n')[0].rstrip()
65 depot_tools_dir = os.path.dirname(gcl) 67 depot_tools_dir = os.path.dirname(gcl)
66 return depot_tools_dir 68 return depot_tools_dir
67 69
68 70
69 def GetCheckoutRoot(is_svn=True): 71 def GetCheckoutRoot():
70 """ Determine where the local checkout is rooted. 72 """ Determine where the local checkout is rooted."""
71 73 cmd = ['git', 'rev-parse', '--show-toplevel']
72 is_svn: boolean; whether we're in an SVN checkout. If False, assume we're in 74 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
73 a git checkout. 75 stderr=subprocess.STDOUT)
74 """ 76 if proc.wait() != 0:
75 if is_svn: 77 raise Exception('Couldn\'t find checkout root!')
76 repo = svn.Svn(os.curdir) 78 return os.path.basename(proc.communicate()[0])
77 svn_info = repo.GetInfo()
78 url = svn_info.get(URL_STR, None)
79 repo_root = svn_info.get(REPO_ROOT_STR, None)
80 if not url or not repo_root:
81 raise Exception('Couldn\'t find checkout root!')
82 if url == repo_root:
83 return 'svn'
84 return url[len(repo_root)+1:]
85 else:
86 cmd = ['git', 'rev-parse', '--show-toplevel']
87 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
88 stderr=subprocess.STDOUT)
89 if proc.wait() != 0:
90 raise Exception('Couldn\'t find checkout root!')
91 return os.path.basename(proc.communicate()[0])
92 79
93 80
94 def GetTryRepo(): 81 def GetTryRepo():
95 """Determine the TRYSERVER_SVN_URL from the codereview.settings file.""" 82 """Determine the TRYSERVER_SVN_URL from the codereview.settings file."""
96 codereview_settings_file = os.path.join(os.path.dirname(__file__), os.pardir, 83 codereview_settings_file = os.path.join(os.path.dirname(__file__), os.pardir,
97 'codereview.settings') 84 'codereview.settings')
98 with open(codereview_settings_file) as f: 85 with open(codereview_settings_file) as f:
99 for line in f: 86 for line in f:
100 if line.startswith(TRYSERVER_SVN_URL): 87 if line.startswith(TRYSERVER_SVN_URL):
101 return line[len(TRYSERVER_SVN_URL):].rstrip() 88 return line[len(TRYSERVER_SVN_URL):].rstrip()
102 raise Exception('Couldn\'t determine the TRYSERVER_SVN_URL. Make sure it is ' 89 raise Exception('Couldn\'t determine the TRYSERVER_SVN_URL. Make sure it is '
103 'defined in the %s file.' % codereview_settings_file) 90 'defined in the %s file.' % codereview_settings_file)
104 91
105 92
106 def RetrieveTrybotList(): 93 def RetrieveTrybotList():
107 """Retrieve the list of known trybots from the checked-in buildbot 94 """Retrieve the list of known trybots from the checked-in buildbot
108 configuration.""" 95 configuration."""
109 # Retrieve the slaves.cfg file from the repository. 96 # Retrieve the slaves.cfg file from the repository.
110 slaves_cfg_text = buildbot_globals.retrieve_from_googlesource(SLAVES_CFG_URL) 97 slaves_cfg_text = retrieve_from_googlesource.retrieve_from_googlesource(
98 SKIA_REPO, SLAVES_CFG_PATH)
111 99
112 # Execute the slaves.cfg file to obtain the list of slaves. 100 # Execute the slaves.cfg file to obtain the list of slaves.
113 vars = {} 101 vars = {}
114 exec(slaves_cfg_text, vars) 102 exec(slaves_cfg_text, vars)
115 slaves_cfg = vars['slaves'] 103 slaves_cfg = vars['slaves']
116 104
117 # Pull the list of known builders from the slaves list. 105 # Pull the list of known builders from the slaves list.
118 trybots = set() 106 trybots = set()
119 for slave in slaves_cfg: 107 for slave in slaves_cfg:
120 for builder in slave['builder']: 108 for builder in slave['builder']:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 Error('--bot specified multiple times.') 186 Error('--bot specified multiple times.')
199 if len(argv) < 1: 187 if len(argv) < 1:
200 Error('You must specify a builder with "--bot".') 188 Error('You must specify a builder with "--bot".')
201 using_bots = [] 189 using_bots = []
202 while argv and not argv[0].startswith('-'): 190 while argv and not argv[0].startswith('-'):
203 for bot in argv.pop(0).split(','): 191 for bot in argv.pop(0).split(','):
204 if bot in ALL_ALIASES: 192 if bot in ALL_ALIASES:
205 if using_bots: 193 if using_bots:
206 Error('Cannot specify "%s" with additional builder names or ' 194 Error('Cannot specify "%s" with additional builder names or '
207 'aliases.' % bot) 195 'aliases.' % bot)
208 if bot == ALL_BUILDERS:
209 are_you_sure = raw_input('Running a try on every bot is very '
210 'expensive. You may be able to get '
211 'enough information by running on a '
212 'smaller set of bots. Are you sure you '
213 'want to run your try job on all of the '
214 'trybots? [y,n]: ')
215 if are_you_sure == 'y':
216 using_bots = trybots
217 elif bot == COMPILE_BUILDERS: 196 elif bot == COMPILE_BUILDERS:
218 using_bots = [t for t in trybots if t.startswith('Build')] 197 using_bots = [t for t in trybots if t.startswith('Build')]
219 elif bot == CQ_BUILDERS: 198 elif bot == CQ_BUILDERS:
220 using_bots = cq_trybots 199 using_bots = cq_trybots
221 elif bot == REGEX: 200 elif bot == REGEX:
222 while True: 201 while True:
223 regex = raw_input("Enter your trybot regex: ") 202 regex = raw_input("Enter your trybot regex: ")
224 p = re.compile(regex) 203 p = re.compile(regex)
225 using_bots = [t for t in trybots if p.match(t)] 204 using_bots = [t for t in trybots if p.match(t)]
226 print '\n\nTrybots that match your regex:\n%s\n\n' % '\n'.join( 205 print '\n\nTrybots that match your regex:\n%s\n\n' % '\n'.join(
(...skipping 10 matching lines...) Expand all
237 Error('You must specify a revision with "-r".') 216 Error('You must specify a revision with "-r".')
238 revision = argv.pop(0) 217 revision = argv.pop(0)
239 else: 218 else:
240 if changelist or not is_svn: 219 if changelist or not is_svn:
241 Error('Unknown argument: %s' % arg) 220 Error('Unknown argument: %s' % arg)
242 changelist = arg 221 changelist = arg
243 if is_svn and not changelist: 222 if is_svn and not changelist:
244 Error('You must specify a changelist name.') 223 Error('You must specify a changelist name.')
245 if not using_bots: 224 if not using_bots:
246 Error('You must specify one or more builders using --bot.') 225 Error('You must specify one or more builders using --bot.')
226 if len(using_bots) > LARGE_NUMBER_OF_BOTS:
227 are_you_sure = raw_input('Running a try on a large number of bots is very '
228 'expensive. You may be able to get enough '
229 'information by running on a smaller set of bots. '
230 'Are you sure you want to do this? [y,n]: ')
231 if are_you_sure != 'y':
232 Error('You must specify one or more builders using --bot.')
epoger 2014/06/05 14:02:16 please use a different error message
borenet 2014/06/05 14:09:49 I just removed the message, since the user will kn
epoger 2014/06/05 14:12:45 Personally, I would just go with Error ('Cancell
247 return CollectedArgs(bots=using_bots, changelist=changelist, 233 return CollectedArgs(bots=using_bots, changelist=changelist,
248 revision=revision) 234 revision=revision)
249 235
250 236
251 def SubmitTryRequest(args, is_svn=True): 237 def SubmitTryRequest(trybots, revision=None):
252 """ Submits a try request for the given changelist on the given list of 238 """ Submits a try request on the given list of trybots.
253 trybots.
254 239
255 args: Object whose properties are derived from command-line arguments. If 240 Args:
256 is_svn is True, it should contain: 241 trybots: list of strings; the names of the try builders to run.
257 - changelist: string; the name of the changelist to try. 242 revision: optional string; the revision from which to run the try.
258 - bot: list of strings; the names of the try builders to run.
259 - revision: optional, int; the revision number from which to run the try.
260 If is_svn is False, it should contain:
261 - bot: list of strings; the names of the try builders to run.
262 - revision: optional, int; the revision number from which to run the try.
263 is_svn: boolean; are we in an SVN repo?
264 """ 243 """
265 botlist = ','.join(['%s%s' % (bot, TRYBOT_SUFFIX) for bot in args.bots]) 244 botlist = ','.join(['%s%s' % (bot, TRYBOT_SUFFIX) for bot in trybots])
266 if is_svn: 245 # Find depot_tools. This is needed to import git_cl and trychange.
267 gcl_cmd = 'gcl.bat' if os.name == 'nt' else 'gcl' 246 sys.path.append(FindDepotTools())
268 try_args = [gcl_cmd, 'try', args.changelist, 247 import git_cl
269 '--root', GetCheckoutRoot(is_svn), 248 import trychange
270 '--bot', botlist]
271 if args.revision:
272 try_args.extend(['-r', args.revision])
273 print ' '.join(try_args)
274 proc = subprocess.Popen(try_args, stdout=subprocess.PIPE,
275 stderr=subprocess.STDOUT)
276 if proc.wait() != 0:
277 raise Exception('Failed to submit try request: %s' % (
278 proc.communicate()[0]))
279 print proc.communicate()[0]
280 else:
281 # Find depot_tools. This is needed to import git_cl and trychange.
282 sys.path.append(FindDepotTools())
283 import git_cl
284 import trychange
285 249
286 cmd = [GIT, 'diff', git_cl.Changelist().GetUpstreamBranch(), 250 cmd = [GIT, 'diff', git_cl.Changelist().GetUpstreamBranch(),
287 '--no-ext-diff'] 251 '--no-ext-diff']
288 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 252 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
289 git_data = proc.communicate() 253 git_data = proc.communicate()
290 if git_data[0] is None: 254 if git_data[0] is None:
291 raise Exception('Failed to capture git diff!') 255 raise Exception('Failed to capture git diff!')
292 256
293 temp_dir = tempfile.mkdtemp() 257 temp_dir = tempfile.mkdtemp()
294 try: 258 try:
295 diff_file = os.path.join(temp_dir, 'patch.diff') 259 diff_file = os.path.join(temp_dir, 'patch.diff')
296 with open(diff_file, 'wb') as f: 260 with open(diff_file, 'wb') as f:
297 f.write(git_data[0]) 261 f.write(git_data[0])
298 f.close() 262 f.close()
299 263
300 try_args = ['--use_svn', 264 try_args = ['--use_svn',
301 '--svn_repo', GetTryRepo(), 265 '--svn_repo', GetTryRepo(),
302 '--root', GetCheckoutRoot(is_svn), 266 '--root', GetCheckoutRoot(),
303 '--bot', botlist, 267 '--bot', botlist,
304 '--diff', diff_file, 268 '--diff', diff_file,
305 ] 269 ]
306 if args.revision: 270 if revision:
307 try_args.extend(['-r', args.revision]) 271 try_args.extend(['-r', revision])
308 272
309 # Submit the try request. 273 # Submit the try request.
310 trychange.TryChange(try_args, None, False) 274 trychange.TryChange(try_args, None, False)
311 finally: 275 finally:
312 shutil.rmtree(temp_dir) 276 shutil.rmtree(temp_dir)
313 277
314 278
315 def main(): 279 def main():
316 # Retrieve the list of active try builders from the build master. 280 # Retrieve the list of active try builders from the build master.
317 trybots, cq_trybots = RetrieveTrybotList() 281 trybots, cq_trybots = RetrieveTrybotList()
318 282
319 # Determine if we're in an SVN checkout. 283 # Determine if we're in an SVN checkout.
320 is_svn = os.path.isdir('.svn') 284 is_svn = os.path.isdir('.svn')
321 285
322 # Parse and validate the command-line arguments. 286 # Parse and validate the command-line arguments.
323 args = ValidateArgs(sys.argv[1:], trybots=trybots, cq_trybots=cq_trybots, 287 args = ValidateArgs(sys.argv[1:], trybots=trybots, cq_trybots=cq_trybots,
324 is_svn=is_svn) 288 is_svn=is_svn)
325 289
326 # Submit the try request. 290 # Submit the try request.
327 SubmitTryRequest(args, is_svn=is_svn) 291 SubmitTryRequest(args.bots, args.revision)
328 292
329 293
330 if __name__ == '__main__': 294 if __name__ == '__main__':
331 sys.exit(main()) 295 sys.exit(main())
OLDNEW
« tools/retrieve_from_googlesource.py ('K') | « tools/retrieve_from_googlesource.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698