Chromium Code Reviews| 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 # 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 and Gerrit.""" | 8 """A git-command for integrating reviews on Rietveld and Gerrit.""" |
| 9 | 9 |
| 10 from __future__ import print_function | 10 from __future__ import print_function |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 147 return not code | 147 return not code |
| 148 | 148 |
| 149 | 149 |
| 150 def time_sleep(seconds): | 150 def time_sleep(seconds): |
| 151 # Use this so that it can be mocked in tests without interfering with python | 151 # Use this so that it can be mocked in tests without interfering with python |
| 152 # system machinery. | 152 # system machinery. |
| 153 import time # Local import to discourage others from importing time globally. | 153 import time # Local import to discourage others from importing time globally. |
| 154 return time.sleep(seconds) | 154 return time.sleep(seconds) |
| 155 | 155 |
| 156 | 156 |
| 157 def time_time(): | |
| 158 # Use this so that it can be mocked in tests without interfering with python | |
| 159 # system machinery. | |
| 160 import time # Local import to discourage others from importing time globally. | |
| 161 return time.time() | |
| 162 | |
| 157 def ask_for_data(prompt): | 163 def ask_for_data(prompt): |
| 158 try: | 164 try: |
| 159 return raw_input(prompt) | 165 return raw_input(prompt) |
| 160 except KeyboardInterrupt: | 166 except KeyboardInterrupt: |
| 161 # Hide the exception. | 167 # Hide the exception. |
| 162 sys.exit(1) | 168 sys.exit(1) |
| 163 | 169 |
| 164 | 170 |
| 165 def _git_branch_config_key(branch, key): | 171 def _git_branch_config_key(branch, key): |
| 166 """Helper method to return Git config key for a branch.""" | 172 """Helper method to return Git config key for a branch.""" |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 451 content = _buildbucket_retry('fetching try jobs', http, url, 'GET') | 457 content = _buildbucket_retry('fetching try jobs', http, url, 'GET') |
| 452 for build in content.get('builds', []): | 458 for build in content.get('builds', []): |
| 453 builds[build['id']] = build | 459 builds[build['id']] = build |
| 454 if 'next_cursor' in content: | 460 if 'next_cursor' in content: |
| 455 params['start_cursor'] = content['next_cursor'] | 461 params['start_cursor'] = content['next_cursor'] |
| 456 else: | 462 else: |
| 457 break | 463 break |
| 458 return builds | 464 return builds |
| 459 | 465 |
| 460 | 466 |
| 467 def _count_unfinished_tryjobs(jobs): | |
| 468 """Returns number of unfinished jobs from fetch_try_jobs result.""" | |
| 469 return sum(b['status'] != 'COMPLETED' for b in jobs.itervalues()) | |
|
Sergiy Byelozyorov
2016/10/19 15:41:13
perhaps
len(b for b in jobs.itervalues() if b['s
| |
| 470 | |
| 471 | |
| 461 def print_try_jobs(options, builds): | 472 def print_try_jobs(options, builds): |
| 462 """Prints nicely result of fetch_try_jobs.""" | 473 """Prints nicely result of fetch_try_jobs.""" |
| 463 if not builds: | 474 if not builds: |
| 464 print('No try jobs scheduled') | 475 print('No try jobs scheduled') |
| 465 return | 476 return |
| 466 | 477 |
| 467 # Make a copy, because we'll be modifying builds dictionary. | 478 # Make a copy, because we'll be modifying builds dictionary. |
| 468 builds = builds.copy() | 479 builds = builds.copy() |
| 469 builder_names_cache = {} | 480 builder_names_cache = {} |
| 470 | 481 |
| (...skipping 4424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4895 group.add_option( | 4906 group.add_option( |
| 4896 '--print-master', action='store_true', help='print master name as well.') | 4907 '--print-master', action='store_true', help='print master name as well.') |
| 4897 group.add_option( | 4908 group.add_option( |
| 4898 '--color', action='store_true', default=setup_color.IS_TTY, | 4909 '--color', action='store_true', default=setup_color.IS_TTY, |
| 4899 help='force color output, useful when piping output.') | 4910 help='force color output, useful when piping output.') |
| 4900 group.add_option( | 4911 group.add_option( |
| 4901 '--buildbucket-host', default='cr-buildbucket.appspot.com', | 4912 '--buildbucket-host', default='cr-buildbucket.appspot.com', |
| 4902 help='Host of buildbucket. The default host is %default.') | 4913 help='Host of buildbucket. The default host is %default.') |
| 4903 group.add_option( | 4914 group.add_option( |
| 4904 '--json', help='Path of JSON output file to write try job results to.') | 4915 '--json', help='Path of JSON output file to write try job results to.') |
| 4916 group.add_option( | |
| 4917 '-w', '--wait-till-finished', action='store_true', default=False, | |
| 4918 help='Keep checking buildbucket until either all jobs finish. ' | |
|
Michael Achenbach
2016/10/20 09:40:35
nit: remove "either"?
| |
| 4919 'If after 1 hour jobs are still running, aborts and returns error ' | |
| 4920 'code 3.') | |
| 4905 parser.add_option_group(group) | 4921 parser.add_option_group(group) |
| 4906 auth.add_auth_options(parser) | 4922 auth.add_auth_options(parser) |
| 4907 options, args = parser.parse_args(args) | 4923 options, args = parser.parse_args(args) |
| 4908 if args: | 4924 if args: |
| 4909 parser.error('Unrecognized args: %s' % ' '.join(args)) | 4925 parser.error('Unrecognized args: %s' % ' '.join(args)) |
| 4910 | 4926 |
| 4911 auth_config = auth.extract_auth_config_from_options(options) | 4927 auth_config = auth.extract_auth_config_from_options(options) |
| 4912 cl = Changelist(auth_config=auth_config) | 4928 cl = Changelist(auth_config=auth_config) |
| 4913 if not cl.GetIssue(): | 4929 if not cl.GetIssue(): |
| 4914 parser.error('Need to upload first') | 4930 parser.error('Need to upload first') |
| 4915 | 4931 |
| 4916 patchset = options.patchset | 4932 patchset = options.patchset |
| 4917 if not patchset: | 4933 if not patchset: |
| 4918 patchset = cl.GetMostRecentPatchset() | 4934 patchset = cl.GetMostRecentPatchset() |
| 4919 if not patchset: | 4935 if not patchset: |
| 4920 parser.error('Codereview doesn\'t know about issue %s. ' | 4936 parser.error('Codereview doesn\'t know about issue %s. ' |
| 4921 'No access to issue or wrong issue number?\n' | 4937 'No access to issue or wrong issue number?\n' |
| 4922 'Either upload first, or pass --patchset explicitely' % | 4938 'Either upload first, or pass --patchset explicitely' % |
| 4923 cl.GetIssue()) | 4939 cl.GetIssue()) |
| 4924 | 4940 |
| 4925 if patchset != cl.GetPatchset(): | 4941 if patchset != cl.GetPatchset(): |
| 4926 print('Warning: Codereview server has newer patchsets (%s) than most ' | 4942 print('Warning: Codereview server has newer patchsets (%s) than most ' |
| 4927 'recent upload from local checkout (%s). Did a previous upload ' | 4943 'recent upload from local checkout (%s). Did a previous upload ' |
| 4928 'fail?\n' | 4944 'fail?\n' |
| 4929 'By default, git cl try-results uses the latest patchset from ' | 4945 'By default, git cl try-results uses the latest patchset from ' |
| 4930 'codereview, continuing to use patchset %s.\n' % | 4946 'codereview, continuing to use patchset %s.\n' % |
| 4931 (patchset, cl.GetPatchset(), patchset)) | 4947 (patchset, cl.GetPatchset(), patchset)) |
| 4932 try: | 4948 |
| 4933 jobs = fetch_try_jobs(auth_config, cl, options.buildbucket_host, patchset) | 4949 start_time = time_time() |
| 4934 except BuildbucketResponseException as ex: | 4950 while True: |
| 4935 print('Buildbucket error: %s' % ex) | 4951 try: |
| 4936 return 1 | 4952 jobs = fetch_try_jobs(auth_config, cl, options.buildbucket_host, patchset) |
| 4937 if options.json: | 4953 except BuildbucketResponseException as ex: |
| 4938 write_try_results_json(options.json, jobs) | 4954 print('Buildbucket error: %s' % ex) |
| 4939 else: | 4955 return 1 |
| 4940 print_try_jobs(options, jobs) | 4956 if options.json: |
| 4957 write_try_results_json(options.json, jobs) | |
|
Michael Achenbach
2016/10/20 09:40:35
Does this need to write the json in the loop? How
| |
| 4958 else: | |
| 4959 print_try_jobs(options, jobs) | |
| 4960 if not options.wait_till_finished: | |
| 4961 return 0 | |
|
Sergiy Byelozyorov
2016/10/19 15:41:13
Please "break", so that if someone chooses to add
| |
| 4962 | |
| 4963 # Only if --wait-till-finished is specified. | |
| 4964 unfinished = _count_unfinished_tryjobs(jobs) | |
| 4965 if not unfinished: | |
| 4966 return 0 | |
|
Sergiy Byelozyorov
2016/10/19 15:41:13
ditto
| |
| 4967 passed = time_time() - start_time | |
| 4968 print('After %.0f seconds waiting, %d jobs still running\n\n' % | |
|
Sergiy Byelozyorov
2016/10/19 15:41:13
Juse use %d instead of %.0f. It will round it to t
| |
| 4969 (passed, unfinished)) | |
| 4970 if passed > 3600: | |
|
Michael Achenbach
2016/10/20 09:40:35
Do you need a limit at all? Is this tool supposed
Sergiy Byelozyorov
2016/10/20 11:44:43
IMHO, this is useful to prevent users forgetting t
| |
| 4971 print('Ran for too long, aborting now.') | |
| 4972 return 3 | |
| 4973 time_sleep(10) # Limit unnecessary load on buildbucket. | |
|
Sergiy Byelozyorov
2016/10/19 15:41:13
If the option becomes widely popular, we may have
| |
| 4941 return 0 | 4974 return 0 |
| 4942 | 4975 |
| 4943 | 4976 |
| 4944 @subcommand.usage('[new upstream branch]') | 4977 @subcommand.usage('[new upstream branch]') |
| 4945 def CMDupstream(parser, args): | 4978 def CMDupstream(parser, args): |
| 4946 """Prints or sets the name of the upstream branch, if any.""" | 4979 """Prints or sets the name of the upstream branch, if any.""" |
| 4947 _, args = parser.parse_args(args) | 4980 _, args = parser.parse_args(args) |
| 4948 if len(args) > 1: | 4981 if len(args) > 1: |
| 4949 parser.error('Unrecognized args: %s' % ' '.join(args)) | 4982 parser.error('Unrecognized args: %s' % ' '.join(args)) |
| 4950 | 4983 |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5379 if __name__ == '__main__': | 5412 if __name__ == '__main__': |
| 5380 # These affect sys.stdout so do it outside of main() to simplify mocks in | 5413 # These affect sys.stdout so do it outside of main() to simplify mocks in |
| 5381 # unit testing. | 5414 # unit testing. |
| 5382 fix_encoding.fix_encoding() | 5415 fix_encoding.fix_encoding() |
| 5383 setup_color.init() | 5416 setup_color.init() |
| 5384 try: | 5417 try: |
| 5385 sys.exit(main(sys.argv[1:])) | 5418 sys.exit(main(sys.argv[1:])) |
| 5386 except KeyboardInterrupt: | 5419 except KeyboardInterrupt: |
| 5387 sys.stderr.write('interrupted\n') | 5420 sys.stderr.write('interrupted\n') |
| 5388 sys.exit(1) | 5421 sys.exit(1) |
| OLD | NEW |