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 """Meta checkout manager supporting both Subversion and GIT.""" | 6 """Meta checkout manager supporting both Subversion and GIT.""" |
| 7 # Files | 7 # Files |
| 8 # .gclient : Current client configuration, written by 'config' command. | 8 # .gclient : Current client configuration, written by 'config' command. |
| 9 # Format is a Python script defining 'solutions', a list whose | 9 # Format is a Python script defining 'solutions', a list whose |
| 10 # entries each are maps binding the strings "name" and "url" | 10 # entries each are maps binding the strings "name" and "url" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 # | 71 # |
| 72 # If the "target_os_only" key is also present and true, then *only* the | 72 # If the "target_os_only" key is also present and true, then *only* the |
| 73 # operating systems listed in "target_os" will be used. | 73 # operating systems listed in "target_os" will be used. |
| 74 # | 74 # |
| 75 # Example: | 75 # Example: |
| 76 # target_os = [ "ios" ] | 76 # target_os = [ "ios" ] |
| 77 # target_os_only = True | 77 # target_os_only = True |
| 78 | 78 |
| 79 __version__ = '0.7' | 79 __version__ = '0.7' |
| 80 | 80 |
| 81 import atexit | |
|
borenet
2014/03/14 13:30:57
Is atexit acceptable for this? It would be nice to
iannucci
2014/03/17 17:38:40
Hm. I would probably wrap atexit instead of direct
borenet
2014/03/17 17:41:33
Alternatively, I can just call the _CheckConfig me
| |
| 81 import copy | 82 import copy |
| 82 import json | 83 import json |
| 83 import logging | 84 import logging |
| 84 import optparse | 85 import optparse |
| 85 import os | 86 import os |
| 86 import platform | 87 import platform |
| 87 import posixpath | 88 import posixpath |
| 88 import pprint | 89 import pprint |
| 89 import re | 90 import re |
| 90 import sys | 91 import sys |
| (...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1037 if options.deps_os: | 1038 if options.deps_os: |
| 1038 enforced_os = options.deps_os.split(',') | 1039 enforced_os = options.deps_os.split(',') |
| 1039 else: | 1040 else: |
| 1040 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] | 1041 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] |
| 1041 if 'all' in enforced_os: | 1042 if 'all' in enforced_os: |
| 1042 enforced_os = self.DEPS_OS_CHOICES.itervalues() | 1043 enforced_os = self.DEPS_OS_CHOICES.itervalues() |
| 1043 self._enforced_os = tuple(set(enforced_os)) | 1044 self._enforced_os = tuple(set(enforced_os)) |
| 1044 self._root_dir = root_dir | 1045 self._root_dir = root_dir |
| 1045 self.config_content = None | 1046 self.config_content = None |
| 1046 | 1047 |
| 1048 def _CheckConfig(self): | |
| 1049 """Verify that the config matches any existing checkout.""" | |
| 1050 for dep in self.dependencies: | |
| 1051 if dep.managed: | |
| 1052 scm = gclient_scm.CreateSCM(dep.url, self.root_dir, dep.name) | |
| 1053 actual_url = scm.GetActualRemoteURL() | |
| 1054 if actual_url and not scm.DoesRemoteURLMatch(): | |
| 1055 def print_warning(): | |
| 1056 print >> sys.stderr, (''' | |
| 1057 ################################################################################ | |
| 1058 ################################### WARNING! ################################### | |
| 1059 ################################################################################ | |
| 1060 | |
| 1061 Your .gclient file seems to be broken. The requested URL is different from what | |
| 1062 is actually checked out in %(checkout_path)s. In the future this will be an | |
| 1063 error. | |
| 1064 | |
| 1065 Expected: %(expected_url)s (%(expected_scm)s) | |
| 1066 Actual: %(actual_url)s (%(actual_scm)s) | |
| 1067 | |
| 1068 You should ensure that the URL listed in .gclient is correct and either change | |
| 1069 it or fix the checkout. If you're managing your own git checkout in | |
| 1070 %(checkout_path)s but the URL in .gclient is for an svn repository, you probably | |
| 1071 want to set 'managed': False in .gclient. | |
| 1072 | |
| 1073 ################################################################################ | |
| 1074 ################################################################################ | |
| 1075 ################################################################################ | |
| 1076 ''' % {'checkout_path': os.path.join(self.root_dir, dep.name), | |
| 1077 'expected_url': dep.url, | |
| 1078 'expected_scm': gclient_scm.GetScmName(dep.url), | |
| 1079 'actual_url': actual_url, | |
| 1080 'actual_scm': gclient_scm.GetScmName(actual_url)}) | |
| 1081 | |
| 1082 atexit.register(print_warning) | |
| 1083 | |
| 1047 def SetConfig(self, content): | 1084 def SetConfig(self, content): |
| 1048 assert not self.dependencies | 1085 assert not self.dependencies |
| 1049 config_dict = {} | 1086 config_dict = {} |
| 1050 self.config_content = content | 1087 self.config_content = content |
| 1051 try: | 1088 try: |
| 1052 exec(content, config_dict) | 1089 exec(content, config_dict) |
| 1053 except SyntaxError, e: | 1090 except SyntaxError, e: |
| 1054 gclient_utils.SyntaxErrorToError('.gclient', e) | 1091 gclient_utils.SyntaxErrorToError('.gclient', e) |
| 1055 | 1092 |
| 1056 # Append any target OS that is not already being enforced to the tuple. | 1093 # Append any target OS that is not already being enforced to the tuple. |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1075 s.get('managed', True), | 1112 s.get('managed', True), |
| 1076 s.get('custom_deps', {}), | 1113 s.get('custom_deps', {}), |
| 1077 s.get('custom_vars', {}), | 1114 s.get('custom_vars', {}), |
| 1078 s.get('custom_hooks', []), | 1115 s.get('custom_hooks', []), |
| 1079 s.get('deps_file', 'DEPS'), | 1116 s.get('deps_file', 'DEPS'), |
| 1080 True)) | 1117 True)) |
| 1081 except KeyError: | 1118 except KeyError: |
| 1082 raise gclient_utils.Error('Invalid .gclient file. Solution is ' | 1119 raise gclient_utils.Error('Invalid .gclient file. Solution is ' |
| 1083 'incomplete: %s' % s) | 1120 'incomplete: %s' % s) |
| 1084 self.add_dependencies_and_close(deps_to_add, config_dict.get('hooks', [])) | 1121 self.add_dependencies_and_close(deps_to_add, config_dict.get('hooks', [])) |
| 1122 self._CheckConfig() | |
| 1085 logging.info('SetConfig() done') | 1123 logging.info('SetConfig() done') |
| 1086 | 1124 |
| 1087 def SaveConfig(self): | 1125 def SaveConfig(self): |
| 1088 gclient_utils.FileWrite(os.path.join(self.root_dir, | 1126 gclient_utils.FileWrite(os.path.join(self.root_dir, |
| 1089 self._options.config_filename), | 1127 self._options.config_filename), |
| 1090 self.config_content) | 1128 self.config_content) |
| 1091 | 1129 |
| 1092 @staticmethod | 1130 @staticmethod |
| 1093 def LoadCurrentConfig(options): | 1131 def LoadCurrentConfig(options): |
| 1094 """Searches for and loads a .gclient file relative to the current working | 1132 """Searches for and loads a .gclient file relative to the current working |
| (...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1687 raise gclient_utils.Error('client not configured; see \'gclient config\'') | 1725 raise gclient_utils.Error('client not configured; see \'gclient config\'') |
| 1688 | 1726 |
| 1689 if options.revisions and options.head: | 1727 if options.revisions and options.head: |
| 1690 # TODO(maruel): Make it a parser.error if it doesn't break any builder. | 1728 # TODO(maruel): Make it a parser.error if it doesn't break any builder. |
| 1691 print('Warning: you cannot use both --head and --revision') | 1729 print('Warning: you cannot use both --head and --revision') |
| 1692 | 1730 |
| 1693 if options.verbose: | 1731 if options.verbose: |
| 1694 # Print out the .gclient file. This is longer than if we just printed the | 1732 # Print out the .gclient file. This is longer than if we just printed the |
| 1695 # client dict, but more legible, and it might contain helpful comments. | 1733 # client dict, but more legible, and it might contain helpful comments. |
| 1696 print(client.config_content) | 1734 print(client.config_content) |
| 1735 | |
| 1697 ret = client.RunOnDeps('update', args) | 1736 ret = client.RunOnDeps('update', args) |
| 1698 if options.output_json: | 1737 if options.output_json: |
| 1699 slns = {} | 1738 slns = {} |
| 1700 for d in client.subtree(True): | 1739 for d in client.subtree(True): |
| 1701 normed = d.name.replace('\\', '/').rstrip('/') + '/' | 1740 normed = d.name.replace('\\', '/').rstrip('/') + '/' |
| 1702 slns[normed] = { | 1741 slns[normed] = { |
| 1703 'revision': d.got_revision, | 1742 'revision': d.got_revision, |
| 1704 'scm': d.used_scm.name if d.used_scm else None, | 1743 'scm': d.used_scm.name if d.used_scm else None, |
| 1705 } | 1744 } |
| 1706 with open(options.output_json, 'wb') as f: | 1745 with open(options.output_json, 'wb') as f: |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1921 raise | 1960 raise |
| 1922 except (gclient_utils.Error, subprocess2.CalledProcessError), e: | 1961 except (gclient_utils.Error, subprocess2.CalledProcessError), e: |
| 1923 print >> sys.stderr, 'Error: %s' % str(e) | 1962 print >> sys.stderr, 'Error: %s' % str(e) |
| 1924 return 1 | 1963 return 1 |
| 1925 | 1964 |
| 1926 | 1965 |
| 1927 if '__main__' == __name__: | 1966 if '__main__' == __name__: |
| 1928 sys.exit(Main(sys.argv[1:])) | 1967 sys.exit(Main(sys.argv[1:])) |
| 1929 | 1968 |
| 1930 # vim: ts=2:sw=2:tw=80:et: | 1969 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |