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

Side by Side Diff: git_cl.py

Issue 963953003: OAuth2 support in depot_tools (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: fix logging level Created 5 years, 9 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 | git_cl_oauth2.py » ('j') | git_cl_oauth2.py » ('J')
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 import base64 11 import base64
12 import glob 12 import glob
13 import httplib
13 import json 14 import json
14 import logging 15 import logging
15 import optparse 16 import optparse
16 import os 17 import os
17 import Queue 18 import Queue
18 import re 19 import re
19 import stat 20 import stat
20 import sys 21 import sys
21 import tempfile 22 import tempfile
22 import textwrap 23 import textwrap
23 import threading 24 import threading
24 import urllib2 25 import urllib2
25 import urlparse 26 import urlparse
26 import webbrowser 27 import webbrowser
27 import zlib 28 import zlib
28 29
29 try: 30 try:
30 import readline # pylint: disable=F0401,W0611 31 import readline # pylint: disable=F0401,W0611
31 except ImportError: 32 except ImportError:
32 pass 33 pass
33 34
34 35
35 from third_party import colorama 36 from third_party import colorama
37 from third_party import httplib2
36 from third_party import upload 38 from third_party import upload
39 from third_party.google_api_python_client import apiclient
37 import breakpad # pylint: disable=W0611 40 import breakpad # pylint: disable=W0611
38 import clang_format 41 import clang_format
39 import dart_format 42 import dart_format
40 import fix_encoding 43 import fix_encoding
41 import gclient_utils 44 import gclient_utils
45 import git_cl_oauth2
42 import git_common 46 import git_common
43 import owners 47 import owners
44 import owners_finder 48 import owners_finder
45 import presubmit_support 49 import presubmit_support
46 import rietveld 50 import rietveld
47 import scm 51 import scm
48 import subcommand 52 import subcommand
49 import subprocess2 53 import subprocess2
50 import watchlists 54 import watchlists
51 55
52 __version__ = '1.0' 56 __version__ = '1.0'
53 57
54 DEFAULT_SERVER = 'https://codereview.appspot.com' 58 DEFAULT_SERVER = 'https://codereview.appspot.com'
55 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' 59 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s'
56 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' 60 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup'
57 GIT_INSTRUCTIONS_URL = 'http://code.google.com/p/chromium/wiki/UsingGit' 61 GIT_INSTRUCTIONS_URL = 'http://code.google.com/p/chromium/wiki/UsingGit'
58 CHANGE_ID = 'Change-Id:' 62 CHANGE_ID = 'Change-Id:'
59 REFS_THAT_ALIAS_TO_OTHER_REFS = { 63 REFS_THAT_ALIAS_TO_OTHER_REFS = {
60 'refs/remotes/origin/lkgr': 'refs/remotes/origin/master', 64 'refs/remotes/origin/lkgr': 'refs/remotes/origin/master',
61 'refs/remotes/origin/lkcr': 'refs/remotes/origin/master', 65 'refs/remotes/origin/lkcr': 'refs/remotes/origin/master',
62 } 66 }
63 67
68 # Buildbucket-related constants
69 DISCOVERY_URL = (
70 'https://cr-buildbucket.appspot.com/_ah/api/discovery/v1/apis/'
71 '{api}/{apiVersion}/rest')
72 DEFAULT_SCOPES = 'email'
73 BUILDSET_STR = 'patch/rietveld/{hostname}/{issue}/{patch}'
74
64 # Valid extensions for files we want to lint. 75 # Valid extensions for files we want to lint.
65 DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)" 76 DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)"
66 DEFAULT_LINT_IGNORE_REGEX = r"$^" 77 DEFAULT_LINT_IGNORE_REGEX = r"$^"
67 78
68 # Shortcut since it quickly becomes redundant. 79 # Shortcut since it quickly becomes redundant.
69 Fore = colorama.Fore 80 Fore = colorama.Fore
70 81
71 # Initialized in main() 82 # Initialized in main()
72 settings = None 83 settings = None
73 84
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 if dirty: 219 if dirty:
209 print 'Cannot %s with a dirty tree. You must commit locally first.' % cmd 220 print 'Cannot %s with a dirty tree. You must commit locally first.' % cmd
210 print 'Uncommitted files: (git diff-index --name-status HEAD)' 221 print 'Uncommitted files: (git diff-index --name-status HEAD)'
211 print dirty[:4096] 222 print dirty[:4096]
212 if len(dirty) > 4096: 223 if len(dirty) > 4096:
213 print '... (run "git diff-index --name-status HEAD" to see full output).' 224 print '... (run "git diff-index --name-status HEAD" to see full output).'
214 return True 225 return True
215 return False 226 return False
216 227
217 228
229 def _prefix_master(master):
230 prefix = 'master.'
231 if master.startswith(prefix):
232 return master
233 else:
234 return '%s%s' % (prefix, master)
235
236
237 def _get_buildbucket(credentials):
238 http = httplib2.Http()
239 http = credentials.authorize(http)
240 return apiclient.discovery.build(
241 'buildbucket', 'v1',
242 http=http,
243 discoveryServiceUrl=DISCOVERY_URL,
244 )
245
246
247 def trigger_distributed_try_jobs(
nodir 2015/03/05 03:58:55 what distributed means in this context?
sheyang 2015/03/06 00:29:10 Just keep the same name. I guess the original me
248 credentials, changelist, options, masters, category):
249 buildbucket = _get_buildbucket(credentials)
250 cred_props = json.loads(credentials.to_json())
251 requester = cred_props['id_token']['email']
252 issue_props = changelist.GetIssueProperties()
253 rietveld_host = urlparse.urlparse(changelist.GetRietveldServer()).hostname
254 issue = changelist.GetIssue()
255 patchset = changelist.GetMostRecentPatchset()
256 buildset = BUILDSET_STR.format(
257 hostname=rietveld_host,
258 issue=str(issue),
259 patch=str(patchset))
260 print 'Tried jobs on:'
261 for (master, builders_and_tests) in masters.iteritems():
262 print 'Master: %s' % master
263 bb_master = _prefix_master(master)
nodir 2015/03/05 03:58:55 call it bucket
sheyang 2015/03/06 00:29:10 Done.
264 for builder, tests in builders_and_tests.iteritems():
265 req = buildbucket.put(body={
266 'bucket': bb_master,
267 'parameters_json': json.dumps({
268 'builder_name': builder,
269 'changes':[
270 {'author': {'email': issue_props['owner_email']}},
271 ],
272 'properties': {
273 'category': category,
274 'clobber': options.clobber,
275 'issue': issue,
276 'master': master,
277 'patch_project': issue_props['project'],
278 'patch_storage': 'rietveld',
279 'patchset': patchset,
280 'reason': options.name,
281 'requester': requester,
282 'revision': options.revision,
283 'rietveld': changelist.GetRietveldServer(),
284 'testfilter': tests,
285 },
286 }),
287 'tags': ['buildset:%s' % buildset,
288 'master:%s' % master,
289 'builder:%s' % builder,
290 'requester:%s' % requester]
291 })
292 req.execute()
nodir 2015/03/05 03:58:55 You ignore the result that may contain an error. I
293 print ' %s: %s' % (builder, tests)
294
295
218 def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards): 296 def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards):
219 """Return the corresponding git ref if |base_url| together with |glob_spec| 297 """Return the corresponding git ref if |base_url| together with |glob_spec|
220 matches the full |url|. 298 matches the full |url|.
221 299
222 If |allow_wildcards| is true, |glob_spec| can contain wildcards (see below). 300 If |allow_wildcards| is true, |glob_spec| can contain wildcards (see below).
223 """ 301 """
224 fetch_suburl, as_ref = glob_spec.split(':') 302 fetch_suburl, as_ref = glob_spec.split(':')
225 if allow_wildcards: 303 if allow_wildcards:
226 glob_match = re.match('(.+/)?(\*|{[^/]*})(/.+)?', fetch_suburl) 304 glob_match = re.match('(.+/)?(\*|{[^/]*})(/.+)?', fetch_suburl)
227 if glob_match: 305 if glob_match:
(...skipping 2468 matching lines...) Expand 10 before | Expand all | Expand 10 after
2696 "-c", "--clobber", action="store_true", default=False, 2774 "-c", "--clobber", action="store_true", default=False,
2697 help="Force a clobber before building; e.g. don't do an " 2775 help="Force a clobber before building; e.g. don't do an "
2698 "incremental build") 2776 "incremental build")
2699 group.add_option( 2777 group.add_option(
2700 "--project", 2778 "--project",
2701 help="Override which project to use. Projects are defined " 2779 help="Override which project to use. Projects are defined "
2702 "server-side to define what default bot set to use") 2780 "server-side to define what default bot set to use")
2703 group.add_option( 2781 group.add_option(
2704 "-n", "--name", help="Try job name; default to current branch name") 2782 "-n", "--name", help="Try job name; default to current branch name")
2705 parser.add_option_group(group) 2783 parser.add_option_group(group)
2784 git_cl_oauth2.add_oauth2_options(parser)
2706 options, args = parser.parse_args(args) 2785 options, args = parser.parse_args(args)
2707 2786
2708 if args: 2787 if args:
2709 parser.error('Unknown arguments: %s' % args) 2788 parser.error('Unknown arguments: %s' % args)
2710 2789
2711 cl = Changelist() 2790 cl = Changelist()
2712 if not cl.GetIssue(): 2791 if not cl.GetIssue():
2713 parser.error('Need to upload first') 2792 parser.error('Need to upload first')
2714 2793
2715 props = cl.GetIssueProperties() 2794 props = cl.GetIssueProperties()
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2791 'Bot list: %s' % builders) 2870 'Bot list: %s' % builders)
2792 return 1 2871 return 1
2793 2872
2794 patchset = cl.GetMostRecentPatchset() 2873 patchset = cl.GetMostRecentPatchset()
2795 if patchset and patchset != cl.GetPatchset(): 2874 if patchset and patchset != cl.GetPatchset():
2796 print( 2875 print(
2797 '\nWARNING Mismatch between local config and server. Did a previous ' 2876 '\nWARNING Mismatch between local config and server. Did a previous '
2798 'upload fail?\ngit-cl try always uses latest patchset from rietveld. ' 2877 'upload fail?\ngit-cl try always uses latest patchset from rietveld. '
2799 'Continuing using\npatchset %s.\n' % patchset) 2878 'Continuing using\npatchset %s.\n' % patchset)
2800 try: 2879 try:
2801 cl.RpcServer().trigger_distributed_try_jobs( 2880 creds = git_cl_oauth2.get_oauth2_cred(
2802 cl.GetIssue(), patchset, options.name, options.clobber, 2881 options,
2803 options.revision, masters) 2882 urlparse.urlparse(cl.GetRietveldServer()).hostname)
2804 except urllib2.HTTPError, e: 2883 trigger_distributed_try_jobs(creds, cl, options, masters, 'git cl try')
nodir 2015/03/05 03:58:55 Please do not commit this CL until we move/replica
sheyang 2015/03/06 00:29:10 I won't - see COMMIT=false in the description.
nodir 2015/03/10 22:39:39 Acknowledged.
2805 if e.code == 404: 2884 except apiclient.errors.HttpError as ex:
2806 print('404 from rietveld; ' 2885 status = ex.resp.status if ex.resp else None
2807 'did you mean to use "git try" instead of "git cl try"?') 2886 if status == httplib.FORBIDDEN:
2808 return 1 2887 print 'ERROR: Access denied. Please verify you have tryjob access.'
2809 print('Tried jobs on:') 2888 else:
2810 2889 print 'Tryjob request failed: %s.' % e
nodir 2015/03/05 03:58:55 typo: ex
sheyang 2015/03/06 00:29:10 Done.
2811 for (master, builders) in masters.iteritems(): 2890 return 1
2812 if master: 2891 except Exception as e:
2813 print 'Master: %s' % master 2892 print 'Unexcpected error when trying to trigger tryjobs: %s.' % e
2814 length = max(len(builder) for builder in builders) 2893 return 1
2815 for builder in sorted(builders):
2816 print ' %*s: %s' % (length, builder, ','.join(builders[builder]))
2817 return 0 2894 return 0
2818 2895
2819 2896
2820 @subcommand.usage('[new upstream branch]') 2897 @subcommand.usage('[new upstream branch]')
2821 def CMDupstream(parser, args): 2898 def CMDupstream(parser, args):
2822 """Prints or sets the name of the upstream branch, if any.""" 2899 """Prints or sets the name of the upstream branch, if any."""
2823 _, args = parser.parse_args(args) 2900 _, args = parser.parse_args(args)
2824 if len(args) > 1: 2901 if len(args) > 1:
2825 parser.error('Unrecognized args: %s' % ' '.join(args)) 2902 parser.error('Unrecognized args: %s' % ' '.join(args))
2826 2903
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
3118 if __name__ == '__main__': 3195 if __name__ == '__main__':
3119 # These affect sys.stdout so do it outside of main() to simplify mocks in 3196 # These affect sys.stdout so do it outside of main() to simplify mocks in
3120 # unit testing. 3197 # unit testing.
3121 fix_encoding.fix_encoding() 3198 fix_encoding.fix_encoding()
3122 colorama.init() 3199 colorama.init()
3123 try: 3200 try:
3124 sys.exit(main(sys.argv[1:])) 3201 sys.exit(main(sys.argv[1:]))
3125 except KeyboardInterrupt: 3202 except KeyboardInterrupt:
3126 sys.stderr.write('interrupted\n') 3203 sys.stderr.write('interrupted\n')
3127 sys.exit(1) 3204 sys.exit(1)
OLDNEW
« no previous file with comments | « no previous file | git_cl_oauth2.py » ('j') | git_cl_oauth2.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698