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 4665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4676 """Fetches the tree status from a json url and returns the message | 4676 """Fetches the tree status from a json url and returns the message |
4677 with the reason for the tree to be opened or closed.""" | 4677 with the reason for the tree to be opened or closed.""" |
4678 url = settings.GetTreeStatusUrl() | 4678 url = settings.GetTreeStatusUrl() |
4679 json_url = urlparse.urljoin(url, '/current?format=json') | 4679 json_url = urlparse.urljoin(url, '/current?format=json') |
4680 connection = urllib2.urlopen(json_url) | 4680 connection = urllib2.urlopen(json_url) |
4681 status = json.loads(connection.read()) | 4681 status = json.loads(connection.read()) |
4682 connection.close() | 4682 connection.close() |
4683 return status['message'] | 4683 return status['message'] |
4684 | 4684 |
4685 | 4685 |
4686 def GetBuilderMaster(bot_list): | 4686 def GetBuilderMasters(bot_list): |
4687 """For a given builder, fetch the master from AE if available.""" | 4687 """Returns a map of masters to builders for the given builders.""" |
4688 map_url = 'https://builders-map.appspot.com/' | 4688 map_url = 'https://builders-map.appspot.com/' |
4689 try: | 4689 try: |
4690 master_map = json.load(urllib2.urlopen(map_url)) | 4690 builders_map = json.load(urllib2.urlopen(map_url)) |
4691 except urllib2.URLError as e: | 4691 except urllib2.URLError as e: |
4692 return None, ('Failed to fetch builder-to-master map from %s. Error: %s.' % | 4692 return None, ('Failed to fetch builder-to-master map from %s. Error: %s.' % |
4693 (map_url, e)) | 4693 (map_url, e)) |
4694 except ValueError as e: | 4694 except ValueError as e: |
4695 return None, ('Invalid json string from %s. Error: %s.' % (map_url, e)) | 4695 return None, ('Invalid json string from %s. Error: %s.' % (map_url, e)) |
tandrii(chromium)
2016/10/23 17:00:02
this Go-style error reporting makes me sad in Pyth
qyearsley
2016/10/24 21:33:39
Yeah -- I guess another way to do it is to raise a
| |
4696 if not master_map: | 4696 if not builders_map: |
4697 return None, 'Failed to build master map.' | 4697 return None, 'Failed to build master map.' |
4698 | 4698 |
4699 result_master = '' | 4699 master_map = {} |
4700 for bot in bot_list: | 4700 for bot in bot_list: |
4701 builder = bot.split(':', 1)[0] | 4701 builder = bot.split(':', 1)[0] |
4702 master_list = master_map.get(builder, []) | 4702 master_list = builders_map.get(builder, []) |
4703 if not master_list: | 4703 if not master_list: |
4704 return None, ('No matching master for builder %s.' % builder) | 4704 return None, ('No matching master for builder %s.' % builder) |
4705 elif len(master_list) > 1: | 4705 elif len(master_list) > 1: |
4706 return None, ('The builder name %s exists in multiple masters %s.' % | 4706 return None, ('The builder name %s exists in multiple masters %s.' % |
4707 (builder, master_list)) | 4707 (builder, master_list)) |
4708 else: | 4708 else: |
4709 cur_master = master_list[0] | 4709 master = master_list[0] |
4710 if not result_master: | 4710 master_map.setdefault(master, []) |
4711 result_master = cur_master | 4711 master_map[master].append(bot) |
4712 elif result_master != cur_master: | 4712 |
4713 return None, 'The builders do not belong to the same master.' | 4713 return master_map, None |
4714 return result_master, None | |
4715 | 4714 |
4716 | 4715 |
4717 def CMDtree(parser, args): | 4716 def CMDtree(parser, args): |
4718 """Shows the status of the tree.""" | 4717 """Shows the status of the tree.""" |
4719 _, args = parser.parse_args(args) | 4718 _, args = parser.parse_args(args) |
4720 status = GetTreeStatus() | 4719 status = GetTreeStatus() |
4721 if 'unset' == status: | 4720 if 'unset' == status: |
4722 print('You must configure your tree status URL by running "git cl config".') | 4721 print('You must configure your tree status URL by running "git cl config".') |
4723 return 2 | 4722 return 2 |
4724 | 4723 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4800 error_message = cl.CannotTriggerTryJobReason() | 4799 error_message = cl.CannotTriggerTryJobReason() |
4801 if error_message: | 4800 if error_message: |
4802 parser.error('Can\'t trigger try jobs: %s') | 4801 parser.error('Can\'t trigger try jobs: %s') |
4803 | 4802 |
4804 if not options.name: | 4803 if not options.name: |
4805 options.name = cl.GetBranch() | 4804 options.name = cl.GetBranch() |
4806 | 4805 |
4807 if options.bucket and options.master: | 4806 if options.bucket and options.master: |
4808 parser.error('Only one of --bucket and --master may be used.') | 4807 parser.error('Only one of --bucket and --master may be used.') |
4809 | 4808 |
4810 if options.bot and not options.master and not options.bucket: | |
4811 options.master, err_msg = GetBuilderMaster(options.bot) | |
4812 if err_msg: | |
4813 parser.error('Tryserver master cannot be found because: %s\n' | |
4814 'Please manually specify the tryserver master' | |
4815 ', e.g. "-m tryserver.chromium.linux".' % err_msg) | |
4816 | |
4817 def GetMasterMap(): | 4809 def GetMasterMap(): |
4818 # Process --bot. | 4810 # Process --bot. |
4819 if not options.bot: | 4811 if not options.bot: |
4820 change = cl.GetChange(cl.GetCommonAncestorWithUpstream(), None) | 4812 change = cl.GetChange(cl.GetCommonAncestorWithUpstream(), None) |
4821 | 4813 |
4822 # Get try masters from PRESUBMIT.py files. | 4814 # Get try masters from PRESUBMIT.py files. |
4823 masters = presubmit_support.DoGetTryMasters( | 4815 masters = presubmit_support.DoGetTryMasters( |
4824 change, | 4816 change, |
4825 change.LocalPaths(), | 4817 change.LocalPaths(), |
4826 settings.GetRoot(), | 4818 settings.GetRoot(), |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4863 | 4855 |
4864 # Return a master map with one master to be backwards compatible. The | 4856 # Return a master map with one master to be backwards compatible. The |
4865 # master name defaults to an empty string, which will cause the master | 4857 # master name defaults to an empty string, which will cause the master |
4866 # not to be set on rietveld (deprecated). | 4858 # not to be set on rietveld (deprecated). |
4867 bucket = '' | 4859 bucket = '' |
4868 if options.master: | 4860 if options.master: |
4869 # Add the "master." prefix to the master name to obtain the bucket name. | 4861 # Add the "master." prefix to the master name to obtain the bucket name. |
4870 bucket = _prefix_master(options.master) | 4862 bucket = _prefix_master(options.master) |
4871 return {bucket: builders_and_tests} | 4863 return {bucket: builders_and_tests} |
4872 | 4864 |
4873 if options.bucket: | 4865 if options.bot and not options.master and not options.bucket: |
4866 masters, err_msg = GetBuilderMasters(options.bot) | |
4867 if err_msg: | |
4868 parser.error('Try server masters cannot be found because: %s\n' | |
4869 'Please manually specify the try server masters' | |
4870 ', e.g. "-m tryserver.chromium.linux".' % err_msg) | |
4871 buckets = {} | |
4872 for master, builders in masters.iteritems(): | |
4873 buckets[_prefix_master(master)] = {b: [] for b in builders} | |
4874 elif options.bucket: | |
4874 buckets = {options.bucket: {b: [] for b in options.bot}} | 4875 buckets = {options.bucket: {b: [] for b in options.bot}} |
4875 else: | 4876 else: |
4876 buckets = GetMasterMap() | 4877 buckets = GetMasterMap() |
4877 if not buckets: | 4878 if not buckets: |
4878 # Default to triggering Dry Run (see http://crbug.com/625697). | 4879 # Default to triggering Dry Run (see http://crbug.com/625697). |
4879 if options.verbose: | 4880 if options.verbose: |
4880 print('git cl try with no bots now defaults to CQ Dry Run.') | 4881 print('git cl try with no bots now defaults to CQ Dry Run.') |
4881 try: | 4882 try: |
4882 cl.SetCQState(_CQState.DRY_RUN) | 4883 cl.SetCQState(_CQState.DRY_RUN) |
4883 print('scheduled CQ Dry Run on %s' % cl.GetIssueURL()) | 4884 print('scheduled CQ Dry Run on %s' % cl.GetIssueURL()) |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5414 if __name__ == '__main__': | 5415 if __name__ == '__main__': |
5415 # These affect sys.stdout so do it outside of main() to simplify mocks in | 5416 # These affect sys.stdout so do it outside of main() to simplify mocks in |
5416 # unit testing. | 5417 # unit testing. |
5417 fix_encoding.fix_encoding() | 5418 fix_encoding.fix_encoding() |
5418 setup_color.init() | 5419 setup_color.init() |
5419 try: | 5420 try: |
5420 sys.exit(main(sys.argv[1:])) | 5421 sys.exit(main(sys.argv[1:])) |
5421 except KeyboardInterrupt: | 5422 except KeyboardInterrupt: |
5422 sys.stderr.write('interrupted\n') | 5423 sys.stderr.write('interrupted\n') |
5423 sys.exit(1) | 5424 sys.exit(1) |
OLD | NEW |