OLD | NEW |
---|---|
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 """Applies an issue from Rietveld. | 6 """Applies an issue from Rietveld. |
7 """ | 7 """ |
8 import getpass | 8 import getpass |
9 import json | 9 import json |
10 import logging | 10 import logging |
11 import optparse | 11 import optparse |
12 import os | 12 import os |
13 import subprocess | 13 import subprocess |
14 import sys | 14 import sys |
15 import urllib2 | 15 import urllib2 |
16 | 16 |
17 import breakpad # pylint: disable=W0611 | 17 import breakpad # pylint: disable=W0611 |
18 | 18 |
19 import annotated_gclient | 19 import annotated_gclient |
20 import auth | 20 import auth |
21 import checkout | 21 import checkout |
22 import fix_encoding | 22 import fix_encoding |
23 import gclient_utils | 23 import gclient_utils |
24 import rietveld | 24 import rietveld |
25 import scm | 25 import scm |
26 | 26 |
27 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | 27 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
28 | 28 |
29 | 29 |
30 RETURN_CODE_ARG_PARSER = 2 # default in python. | 30 RETURN_CODE_OK = 0 # any other failure, likely patch apply one. |
Sergey Berezin
2015/10/05 19:06:58
drive-by nit: that's not a failure :-)
| |
31 RETURN_CODE_INFRA_FAILURE = 3 # considered as infra failure. | 31 RETURN_CODE_OTHER_FAILURE = 1 # any other failure, likely patch apply one. |
32 RETURN_CODE_OTHERWISE = 1 # any other failure, likely patch apply one. | 32 RETURN_CODE_ARGPARSE_FAILURE = 2 # default in python. |
33 RETURN_CODE_INFRA_FAILURE = 3 # considered as infra failure. | |
33 | 34 |
34 | 35 |
35 class Unbuffered(object): | 36 class Unbuffered(object): |
36 """Disable buffering on a file object.""" | 37 """Disable buffering on a file object.""" |
37 def __init__(self, stream): | 38 def __init__(self, stream): |
38 self.stream = stream | 39 self.stream = stream |
39 | 40 |
40 def write(self, data): | 41 def write(self, data): |
41 self.stream.write(data) | 42 self.stream.write(data) |
42 self.stream.flush() | 43 self.stream.flush() |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 except rietveld.upload.ClientLoginError as e: | 172 except rietveld.upload.ClientLoginError as e: |
172 # Fine, we'll do proper authentication. | 173 # Fine, we'll do proper authentication. |
173 pass | 174 pass |
174 if properties is None: | 175 if properties is None: |
175 rietveld_obj = rietveld.Rietveld(options.server, auth_config, | 176 rietveld_obj = rietveld.Rietveld(options.server, auth_config, |
176 options.email) | 177 options.email) |
177 try: | 178 try: |
178 properties = rietveld_obj.get_issue_properties(options.issue, False) | 179 properties = rietveld_obj.get_issue_properties(options.issue, False) |
179 except rietveld.upload.ClientLoginError as e: | 180 except rietveld.upload.ClientLoginError as e: |
180 print('Accessing the issue requires proper credentials.') | 181 print('Accessing the issue requires proper credentials.') |
181 return RETURN_CODE_OTHERWISE | 182 return RETURN_CODE_OTHER_FAILURE |
182 except urllib2.URLError: | 183 except urllib2.URLError: |
183 logging.exception('failed to fetch issue properties') | 184 logging.exception('failed to fetch issue properties') |
184 return RETURN_CODE_INFRA_FAILURE | 185 return RETURN_CODE_INFRA_FAILURE |
185 | 186 |
186 if not options.patchset: | 187 if not options.patchset: |
187 options.patchset = properties['patchsets'][-1] | 188 options.patchset = properties['patchsets'][-1] |
188 print('No patchset specified. Using patchset %d' % options.patchset) | 189 print('No patchset specified. Using patchset %d' % options.patchset) |
189 | 190 |
190 issues_patchsets_to_apply = [(options.issue, options.patchset)] | 191 issues_patchsets_to_apply = [(options.issue, options.patchset)] |
191 try: | 192 try: |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
234 try: | 235 try: |
235 patchset = rietveld_obj.get_patch(issue_to_apply, patchset_to_apply) | 236 patchset = rietveld_obj.get_patch(issue_to_apply, patchset_to_apply) |
236 except urllib2.HTTPError: | 237 except urllib2.HTTPError: |
237 print( | 238 print( |
238 'Failed to fetch the patch for issue %d, patchset %d.\n' | 239 'Failed to fetch the patch for issue %d, patchset %d.\n' |
239 'Try visiting %s/%d') % ( | 240 'Try visiting %s/%d') % ( |
240 issue_to_apply, patchset_to_apply, | 241 issue_to_apply, patchset_to_apply, |
241 options.server, issue_to_apply) | 242 options.server, issue_to_apply) |
242 # If we got this far, then this is likely missing patchset. | 243 # If we got this far, then this is likely missing patchset. |
243 # Thus, it's not infra failure. | 244 # Thus, it's not infra failure. |
244 return RETURN_CODE_OTHERWISE | 245 return RETURN_CODE_OTHER_FAILURE |
245 except urllib2.URLError: | 246 except urllib2.URLError: |
246 logging.exception( | 247 logging.exception( |
247 'Failed to fetch the patch for issue %d, patchset %d', | 248 'Failed to fetch the patch for issue %d, patchset %d', |
248 issue_to_apply, patchset_to_apply) | 249 issue_to_apply, patchset_to_apply) |
249 return RETURN_CODE_INFRA_FAILURE | 250 return RETURN_CODE_INFRA_FAILURE |
250 if options.whitelist: | 251 if options.whitelist: |
251 patchset.patches = [patch for patch in patchset.patches | 252 patchset.patches = [patch for patch in patchset.patches |
252 if patch.filename in options.whitelist] | 253 if patch.filename in options.whitelist] |
253 if options.blacklist: | 254 if options.blacklist: |
254 patchset.patches = [patch for patch in patchset.patches | 255 patchset.patches = [patch for patch in patchset.patches |
(...skipping 20 matching lines...) Expand all Loading... | |
275 # chromium_commands.py?view=markup | 276 # chromium_commands.py?view=markup |
276 open('.buildbot-patched', 'w').close() | 277 open('.buildbot-patched', 'w').close() |
277 | 278 |
278 print('\nApplying the patch from %s' % issue_url) | 279 print('\nApplying the patch from %s' % issue_url) |
279 try: | 280 try: |
280 scm_obj.apply_patch(patchset, verbose=True) | 281 scm_obj.apply_patch(patchset, verbose=True) |
281 except checkout.PatchApplicationFailed as e: | 282 except checkout.PatchApplicationFailed as e: |
282 print(str(e)) | 283 print(str(e)) |
283 print('CWD=%s' % os.getcwd()) | 284 print('CWD=%s' % os.getcwd()) |
284 print('Checkout path=%s' % scm_obj.project_path) | 285 print('Checkout path=%s' % scm_obj.project_path) |
285 return RETURN_CODE_OTHERWISE | 286 return RETURN_CODE_OTHER_FAILURE |
286 | 287 |
287 if ('DEPS' in map(os.path.basename, patchset.filenames) | 288 if ('DEPS' in map(os.path.basename, patchset.filenames) |
288 and not options.ignore_deps): | 289 and not options.ignore_deps): |
289 gclient_root = gclient_utils.FindGclientRoot(full_dir) | 290 gclient_root = gclient_utils.FindGclientRoot(full_dir) |
290 if gclient_root and scm_type: | 291 if gclient_root and scm_type: |
291 print( | 292 print( |
292 'A DEPS file was updated inside a gclient checkout, running gclient ' | 293 'A DEPS file was updated inside a gclient checkout, running gclient ' |
293 'sync.') | 294 'sync.') |
294 gclient_path = os.path.join(BASE_DIR, 'gclient') | 295 gclient_path = os.path.join(BASE_DIR, 'gclient') |
295 if sys.platform == 'win32': | 296 if sys.platform == 'win32': |
(...skipping 10 matching lines...) Expand all Loading... | |
306 cmd.extend(['--output-json', f]) | 307 cmd.extend(['--output-json', f]) |
307 | 308 |
308 retcode = subprocess.call(cmd, cwd=gclient_root) | 309 retcode = subprocess.call(cmd, cwd=gclient_root) |
309 | 310 |
310 if retcode == 0 and options.revision_mapping: | 311 if retcode == 0 and options.revision_mapping: |
311 revisions = annotated_gclient.parse_got_revision( | 312 revisions = annotated_gclient.parse_got_revision( |
312 f, options.revision_mapping) | 313 f, options.revision_mapping) |
313 annotated_gclient.emit_buildprops(revisions) | 314 annotated_gclient.emit_buildprops(revisions) |
314 | 315 |
315 return retcode | 316 return retcode |
316 return 0 | 317 return RETURN_CODE_OK |
317 | 318 |
318 | 319 |
319 if __name__ == "__main__": | 320 if __name__ == "__main__": |
320 fix_encoding.fix_encoding() | 321 fix_encoding.fix_encoding() |
321 try: | 322 try: |
322 sys.exit(main()) | 323 sys.exit(main()) |
323 except KeyboardInterrupt: | 324 except KeyboardInterrupt: |
324 sys.stderr.write('interrupted\n') | 325 sys.stderr.write('interrupted\n') |
325 sys.exit(RETURN_CODE_OTHERWISE) | 326 sys.exit(RETURN_CODE_OTHER_FAILURE) |
OLD | NEW |