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

Side by Side Diff: tools/submit_try

Issue 317823003: Fix submit_try (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments 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
« no previous file with comments | « tools/retrieve_from_googlesource.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.get(SKIA_REPO, SLAVES_CFG_PATH)
111 98
112 # Execute the slaves.cfg file to obtain the list of slaves. 99 # Execute the slaves.cfg file to obtain the list of slaves.
113 vars = {} 100 vars = {}
114 exec(slaves_cfg_text, vars) 101 exec(slaves_cfg_text, vars)
115 slaves_cfg = vars['slaves'] 102 slaves_cfg = vars['slaves']
116 103
117 # Pull the list of known builders from the slaves list. 104 # Pull the list of known builders from the slaves list.
118 trybots = set() 105 trybots = set()
119 for slave in slaves_cfg: 106 for slave in slaves_cfg:
120 for builder in slave['builder']: 107 for builder in slave['builder']:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 Error('--bot specified multiple times.') 185 Error('--bot specified multiple times.')
199 if len(argv) < 1: 186 if len(argv) < 1:
200 Error('You must specify a builder with "--bot".') 187 Error('You must specify a builder with "--bot".')
201 using_bots = [] 188 using_bots = []
202 while argv and not argv[0].startswith('-'): 189 while argv and not argv[0].startswith('-'):
203 for bot in argv.pop(0).split(','): 190 for bot in argv.pop(0).split(','):
204 if bot in ALL_ALIASES: 191 if bot in ALL_ALIASES:
205 if using_bots: 192 if using_bots:
206 Error('Cannot specify "%s" with additional builder names or ' 193 Error('Cannot specify "%s" with additional builder names or '
207 'aliases.' % bot) 194 '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: 195 elif bot == COMPILE_BUILDERS:
218 using_bots = [t for t in trybots if t.startswith('Build')] 196 using_bots = [t for t in trybots if t.startswith('Build')]
219 elif bot == CQ_BUILDERS: 197 elif bot == CQ_BUILDERS:
220 using_bots = cq_trybots 198 using_bots = cq_trybots
221 elif bot == REGEX: 199 elif bot == REGEX:
222 while True: 200 while True:
223 regex = raw_input("Enter your trybot regex: ") 201 regex = raw_input("Enter your trybot regex: ")
224 p = re.compile(regex) 202 p = re.compile(regex)
225 using_bots = [t for t in trybots if p.match(t)] 203 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( 204 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".') 215 Error('You must specify a revision with "-r".')
238 revision = argv.pop(0) 216 revision = argv.pop(0)
239 else: 217 else:
240 if changelist or not is_svn: 218 if changelist or not is_svn:
241 Error('Unknown argument: %s' % arg) 219 Error('Unknown argument: %s' % arg)
242 changelist = arg 220 changelist = arg
243 if is_svn and not changelist: 221 if is_svn and not changelist:
244 Error('You must specify a changelist name.') 222 Error('You must specify a changelist name.')
245 if not using_bots: 223 if not using_bots:
246 Error('You must specify one or more builders using --bot.') 224 Error('You must specify one or more builders using --bot.')
225 if len(using_bots) > LARGE_NUMBER_OF_BOTS:
226 are_you_sure = raw_input('Running a try on a large number of bots is very '
227 'expensive. You may be able to get enough '
228 'information by running on a smaller set of bots. '
229 'Are you sure you want to do this? [y,n]: ')
230 if are_you_sure != 'y':
231 Error()
247 return CollectedArgs(bots=using_bots, changelist=changelist, 232 return CollectedArgs(bots=using_bots, changelist=changelist,
248 revision=revision) 233 revision=revision)
249 234
250 235
251 def SubmitTryRequest(args, is_svn=True): 236 def SubmitTryRequest(trybots, revision=None):
252 """ Submits a try request for the given changelist on the given list of 237 """ Submits a try request on the given list of trybots.
253 trybots.
254 238
255 args: Object whose properties are derived from command-line arguments. If 239 Args:
256 is_svn is True, it should contain: 240 trybots: list of strings; the names of the try builders to run.
257 - changelist: string; the name of the changelist to try. 241 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 """ 242 """
265 botlist = ','.join(['%s%s' % (bot, TRYBOT_SUFFIX) for bot in args.bots]) 243 botlist = ','.join(['%s%s' % (bot, TRYBOT_SUFFIX) for bot in trybots])
266 if is_svn: 244 # Find depot_tools. This is needed to import git_cl and trychange.
267 gcl_cmd = 'gcl.bat' if os.name == 'nt' else 'gcl' 245 sys.path.append(FindDepotTools())
268 try_args = [gcl_cmd, 'try', args.changelist, 246 import git_cl
269 '--root', GetCheckoutRoot(is_svn), 247 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 248
286 cmd = [GIT, 'diff', git_cl.Changelist().GetUpstreamBranch(), 249 cmd = [GIT, 'diff', git_cl.Changelist().GetUpstreamBranch(),
287 '--no-ext-diff'] 250 '--no-ext-diff']
288 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 251 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
289 git_data = proc.communicate() 252 git_data = proc.communicate()
290 if git_data[0] is None: 253 if git_data[0] is None:
291 raise Exception('Failed to capture git diff!') 254 raise Exception('Failed to capture git diff!')
292 255
293 temp_dir = tempfile.mkdtemp() 256 temp_dir = tempfile.mkdtemp()
294 try: 257 try:
295 diff_file = os.path.join(temp_dir, 'patch.diff') 258 diff_file = os.path.join(temp_dir, 'patch.diff')
296 with open(diff_file, 'wb') as f: 259 with open(diff_file, 'wb') as f:
297 f.write(git_data[0]) 260 f.write(git_data[0])
298 f.close() 261 f.close()
299 262
300 try_args = ['--use_svn', 263 try_args = ['--use_svn',
301 '--svn_repo', GetTryRepo(), 264 '--svn_repo', GetTryRepo(),
302 '--root', GetCheckoutRoot(is_svn), 265 '--root', GetCheckoutRoot(),
303 '--bot', botlist, 266 '--bot', botlist,
304 '--diff', diff_file, 267 '--diff', diff_file,
305 ] 268 ]
306 if args.revision: 269 if revision:
307 try_args.extend(['-r', args.revision]) 270 try_args.extend(['-r', revision])
308 271
309 # Submit the try request. 272 # Submit the try request.
310 trychange.TryChange(try_args, None, False) 273 trychange.TryChange(try_args, None, False)
311 finally: 274 finally:
312 shutil.rmtree(temp_dir) 275 shutil.rmtree(temp_dir)
313 276
314 277
315 def main(): 278 def main():
316 # Retrieve the list of active try builders from the build master. 279 # Retrieve the list of active try builders from the build master.
317 trybots, cq_trybots = RetrieveTrybotList() 280 trybots, cq_trybots = RetrieveTrybotList()
318 281
319 # Determine if we're in an SVN checkout. 282 # Determine if we're in an SVN checkout.
320 is_svn = os.path.isdir('.svn') 283 is_svn = os.path.isdir('.svn')
321 284
322 # Parse and validate the command-line arguments. 285 # Parse and validate the command-line arguments.
323 args = ValidateArgs(sys.argv[1:], trybots=trybots, cq_trybots=cq_trybots, 286 args = ValidateArgs(sys.argv[1:], trybots=trybots, cq_trybots=cq_trybots,
324 is_svn=is_svn) 287 is_svn=is_svn)
325 288
326 # Submit the try request. 289 # Submit the try request.
327 SubmitTryRequest(args, is_svn=is_svn) 290 SubmitTryRequest(args.bots, args.revision)
328 291
329 292
330 if __name__ == '__main__': 293 if __name__ == '__main__':
331 sys.exit(main()) 294 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/retrieve_from_googlesource.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698