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

Side by Side Diff: git_cl.py

Issue 1063103002: git cl try uses buildbucket via OAuth2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: remove debugging Created 5 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 # Copyright (C) 2008 Evan Martin <martine@danga.com> 6 # Copyright (C) 2008 Evan Martin <martine@danga.com>
7 7
8 """A git-command for integrating reviews on Rietveld.""" 8 """A git-command for integrating reviews on Rietveld."""
9 9
10 from distutils.version import LooseVersion 10 from distutils.version import LooseVersion
11 from multiprocessing.pool import ThreadPool 11 from multiprocessing.pool import ThreadPool
12 import base64 12 import base64
13 import glob 13 import glob
14 import httplib
14 import json 15 import json
15 import logging 16 import logging
16 import optparse 17 import optparse
17 import os 18 import os
18 import Queue 19 import Queue
19 import re 20 import re
20 import stat 21 import stat
21 import sys 22 import sys
22 import tempfile 23 import tempfile
23 import textwrap 24 import textwrap
25 import time
26 import traceback
24 import urllib2 27 import urllib2
25 import urlparse 28 import urlparse
26 import webbrowser 29 import webbrowser
27 import zlib 30 import zlib
28 31
29 try: 32 try:
30 import readline # pylint: disable=F0401,W0611 33 import readline # pylint: disable=F0401,W0611
31 except ImportError: 34 except ImportError:
32 pass 35 pass
33 36
34
35 from third_party import colorama 37 from third_party import colorama
38 from third_party import httplib2
36 from third_party import upload 39 from third_party import upload
37 import auth 40 import auth
38 import breakpad # pylint: disable=W0611 41 import breakpad # pylint: disable=W0611
39 import clang_format 42 import clang_format
40 import dart_format 43 import dart_format
41 import fix_encoding 44 import fix_encoding
42 import gclient_utils 45 import gclient_utils
43 import git_common 46 import git_common
44 import owners 47 import owners
45 import owners_finder 48 import owners_finder
46 import presubmit_support 49 import presubmit_support
47 import rietveld 50 import rietveld
48 import scm 51 import scm
49 import subcommand 52 import subcommand
50 import subprocess2 53 import subprocess2
51 import watchlists 54 import watchlists
52 55
53 __version__ = '1.0' 56 __version__ = '1.0'
54 57
55 DEFAULT_SERVER = 'https://codereview.appspot.com' 58 DEFAULT_SERVER = 'https://codereview.appspot.com'
56 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' 59 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s'
57 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' 60 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup'
58 GIT_INSTRUCTIONS_URL = 'http://code.google.com/p/chromium/wiki/UsingGit' 61 GIT_INSTRUCTIONS_URL = 'http://code.google.com/p/chromium/wiki/UsingGit'
59 CHANGE_ID = 'Change-Id:' 62 CHANGE_ID = 'Change-Id:'
60 REFS_THAT_ALIAS_TO_OTHER_REFS = { 63 REFS_THAT_ALIAS_TO_OTHER_REFS = {
61 'refs/remotes/origin/lkgr': 'refs/remotes/origin/master', 64 'refs/remotes/origin/lkgr': 'refs/remotes/origin/master',
62 'refs/remotes/origin/lkcr': 'refs/remotes/origin/master', 65 'refs/remotes/origin/lkcr': 'refs/remotes/origin/master',
63 } 66 }
64 67
68 # Buildbucket-related constants
69 BUILDBUCKET_PUT_URL = (
70 'https://cr-buildbucket.appspot.com/_ah/api/buildbucket/v1/builds/batch')
71 BUILDSET_STR = 'patch/rietveld/{hostname}/{issue}/{patch}'
72
65 # Valid extensions for files we want to lint. 73 # Valid extensions for files we want to lint.
66 DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)" 74 DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)"
67 DEFAULT_LINT_IGNORE_REGEX = r"$^" 75 DEFAULT_LINT_IGNORE_REGEX = r"$^"
68 76
69 # Shortcut since it quickly becomes redundant. 77 # Shortcut since it quickly becomes redundant.
70 Fore = colorama.Fore 78 Fore = colorama.Fore
71 79
72 # Initialized in main() 80 # Initialized in main()
73 settings = None 81 settings = None
74 82
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 else: 203 else:
196 git_set_branch_value('git-find-copies', int(options.find_copies)) 204 git_set_branch_value('git-find-copies', int(options.find_copies))
197 205
198 print('Using %d%% similarity for rename/copy detection. ' 206 print('Using %d%% similarity for rename/copy detection. '
199 'Override with --similarity.' % options.similarity) 207 'Override with --similarity.' % options.similarity)
200 208
201 return options, args 209 return options, args
202 parser.parse_args = Parse 210 parser.parse_args = Parse
203 211
204 212
213 def _prefix_master(master):
214 prefix = 'master.'
215 if master.startswith(prefix):
216 return master
217 else:
218 return '%s%s' % (prefix, master)
219
220
221 def trigger_distributed_try_jobs(
nodir 2015/04/18 05:17:56 I'd call something like "trigger_buildbucket_build
222 auth_config, changelist, options, masters, category):
223 rietveld_url = settings.GetDefaultServerUrl()
224 rietveld_host = urlparse.urlparse(rietveld_url).hostname
225 authenticator = auth.get_authenticator_for_host(rietveld_host, auth_config)
226 http = authenticator.authorize(httplib2.Http())
227 http.force_exception_to_status_code = True
228 issue_props = changelist.GetIssueProperties()
229 issue = changelist.GetIssue()
230 patchset = changelist.GetMostRecentPatchset()
231 buildset = BUILDSET_STR.format(
232 hostname=rietveld_host,
233 issue=issue,
234 patch=patchset)
235
236 batch_req_body = {'builds': []}
237 print_text = []
238 print_text.append('Trying jobs on:')
239 for master, builders_and_tests in masters.iteritems():
240 print_text.append('Master: %s' % master)
241 bucket = _prefix_master(master)
242 for builder, tests in builders_and_tests.iteritems():
243 print_text.append(' %s: %s' % (builder, tests))
244 batch_req_body['builds'].append(
245 {
nodir 2015/04/18 05:17:56 nit: I think it is fine to merge lines 244 and 245
246 'bucket': bucket,
247 'parameters_json': json.dumps({
248 'builder_name': builder,
249 'changes':[
250 {'author': {'email': issue_props['owner_email']}},
251 ],
252 'properties': {
253 'category': category,
254 'clobber': options.clobber,
nodir 2015/04/18 05:17:56 As smut said in https://code.google.com/p/chromium
255 'issue': issue,
256 'master': master,
257 'patch_project': issue_props['project'],
258 'patch_storage': 'rietveld',
259 'patchset': patchset,
260 'reason': options.name,
261 'revision': options.revision,
262 'rietveld': rietveld_url,
263 'testfilter': tests,
264 },
265 }),
266 'tags': ['buildset:%s' % buildset,
267 'master:%s' % master,
268 'builder:%s' % builder,
269 'user_agent:git-cl-try']
nodir 2015/04/18 06:46:17 please sort
270 }
271 )
272
273 wait = 1
274 try_count = 3
275 while try_count > 0:
276 try_count -= 1
277 response, content = http.request(
278 BUILDBUCKET_PUT_URL,
279 "PUT",
nodir 2015/04/18 05:17:56 use '
280 body=json.dumps(batch_req_body),
281 headers={'Content-type': 'application/json'},
nodir 2015/04/18 05:17:56 nit: capital t: Content-Type
282 )
283 content_json = None
284 try:
285 content_json = json.loads(content)
286 except ValueError:
287 pass
288
289 # Buildbbucket could return an error even status==200.
nodir 2015/04/18 05:17:56 "even if"
nodir 2015/04/18 05:17:56 typo: double b
290 if content_json and content_json.get('error'):
291 msg = 'Error in response. Code: %d. Reason: %s. Message: %s.' % (
292 content_json['error'].get('code', ''),
293 content_json['error'].get('reason', ''),
294 content_json['error'].get('message', ''))
295 raise BuildbucketResponseException(msg)
296
297 if response.status == 200:
298 break
299
300 if response.status < 500 or try_count <= 0:
301 raise httplib2.HttpLib2Error(content)
302
303 # status >= 500 means transient failures.
304 logging.debug('Transient errors when triggering tryjobs. '
305 'Will retry in %d seconds.', wait)
306 time.sleep(wait)
307 wait *= 2
308
309 print '\n'.join(print_text)
nodir 2015/04/18 05:17:56 Move this before the loop. Otherwise it says "tryi
310
311
205 def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards): 312 def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards):
206 """Return the corresponding git ref if |base_url| together with |glob_spec| 313 """Return the corresponding git ref if |base_url| together with |glob_spec|
207 matches the full |url|. 314 matches the full |url|.
208 315
209 If |allow_wildcards| is true, |glob_spec| can contain wildcards (see below). 316 If |allow_wildcards| is true, |glob_spec| can contain wildcards (see below).
210 """ 317 """
211 fetch_suburl, as_ref = glob_spec.split(':') 318 fetch_suburl, as_ref = glob_spec.split(':')
212 if allow_wildcards: 319 if allow_wildcards:
213 glob_match = re.match('(.+/)?(\*|{[^/]*})(/.+)?', fetch_suburl) 320 glob_match = re.match('(.+/)?(\*|{[^/]*})(/.+)?', fetch_suburl)
214 if glob_match: 321 if glob_match:
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 try: 369 try:
263 stdout = sys.stdout.fileno() 370 stdout = sys.stdout.fileno()
264 except AttributeError: 371 except AttributeError:
265 stdout = None 372 stdout = None
266 return subprocess2.call( 373 return subprocess2.call(
267 ['git', 374 ['git',
268 'diff', '--no-ext-diff', '--stat'] + similarity_options + args, 375 'diff', '--no-ext-diff', '--stat'] + similarity_options + args,
269 stdout=stdout, env=env) 376 stdout=stdout, env=env)
270 377
271 378
379 class BuildbucketResponseException(Exception):
380 pass
381
382
272 class Settings(object): 383 class Settings(object):
273 def __init__(self): 384 def __init__(self):
274 self.default_server = None 385 self.default_server = None
275 self.cc = None 386 self.cc = None
276 self.root = None 387 self.root = None
277 self.is_git_svn = None 388 self.is_git_svn = None
278 self.svn_branch = None 389 self.svn_branch = None
279 self.tree_status_url = None 390 self.tree_status_url = None
280 self.viewvc_url = None 391 self.viewvc_url = None
281 self.updated = False 392 self.updated = False
(...skipping 2571 matching lines...) Expand 10 before | Expand all | Expand 10 after
2853 'Bot list: %s' % builders) 2964 'Bot list: %s' % builders)
2854 return 1 2965 return 1
2855 2966
2856 patchset = cl.GetMostRecentPatchset() 2967 patchset = cl.GetMostRecentPatchset()
2857 if patchset and patchset != cl.GetPatchset(): 2968 if patchset and patchset != cl.GetPatchset():
2858 print( 2969 print(
2859 '\nWARNING Mismatch between local config and server. Did a previous ' 2970 '\nWARNING Mismatch between local config and server. Did a previous '
2860 'upload fail?\ngit-cl try always uses latest patchset from rietveld. ' 2971 'upload fail?\ngit-cl try always uses latest patchset from rietveld. '
2861 'Continuing using\npatchset %s.\n' % patchset) 2972 'Continuing using\npatchset %s.\n' % patchset)
2862 try: 2973 try:
2863 cl.RpcServer().trigger_distributed_try_jobs( 2974 trigger_distributed_try_jobs(
2864 cl.GetIssue(), patchset, options.name, options.clobber, 2975 auth_config, cl, options, masters, 'git cl try')
2865 options.revision, masters) 2976 except BuildbucketResponseException as ex:
2866 except urllib2.HTTPError, e: 2977 print 'ERROR: %s' % ex
2867 if e.code == 404: 2978 return 1
2868 print('404 from rietveld; ' 2979 except Exception as e:
2869 'did you mean to use "git try" instead of "git cl try"?') 2980 stacktrace = (''.join(traceback.format_stack()) + traceback.format_exc())
2870 return 1 2981 print 'ERROR: Exception when trying to trigger tryjobs: %s\n%s' % (
2871 print('Tried jobs on:') 2982 e, stacktrace)
nodir 2015/04/18 05:17:56 I think logging.exception('ERROR: Exception when t
2872 2983 return 1
2873 for (master, builders) in masters.iteritems():
2874 if master:
2875 print 'Master: %s' % master
2876 length = max(len(builder) for builder in builders)
2877 for builder in sorted(builders):
2878 print ' %*s: %s' % (length, builder, ','.join(builders[builder]))
2879 return 0 2984 return 0
2880 2985
2881 2986
2882 @subcommand.usage('[new upstream branch]') 2987 @subcommand.usage('[new upstream branch]')
2883 def CMDupstream(parser, args): 2988 def CMDupstream(parser, args):
2884 """Prints or sets the name of the upstream branch, if any.""" 2989 """Prints or sets the name of the upstream branch, if any."""
2885 _, args = parser.parse_args(args) 2990 _, args = parser.parse_args(args)
2886 if len(args) > 1: 2991 if len(args) > 1:
2887 parser.error('Unrecognized args: %s' % ' '.join(args)) 2992 parser.error('Unrecognized args: %s' % ' '.join(args))
2888 2993
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
3202 if __name__ == '__main__': 3307 if __name__ == '__main__':
3203 # These affect sys.stdout so do it outside of main() to simplify mocks in 3308 # These affect sys.stdout so do it outside of main() to simplify mocks in
3204 # unit testing. 3309 # unit testing.
3205 fix_encoding.fix_encoding() 3310 fix_encoding.fix_encoding()
3206 colorama.init() 3311 colorama.init()
3207 try: 3312 try:
3208 sys.exit(main(sys.argv[1:])) 3313 sys.exit(main(sys.argv[1:]))
3209 except KeyboardInterrupt: 3314 except KeyboardInterrupt:
3210 sys.stderr.write('interrupted\n') 3315 sys.stderr.write('interrupted\n')
3211 sys.exit(1) 3316 sys.exit(1)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698