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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 self._deps_hooks = [] | 335 self._deps_hooks = [] |
| 336 | 336 |
| 337 self._pre_deps_hooks = [] | 337 self._pre_deps_hooks = [] |
| 338 | 338 |
| 339 # Calculates properties: | 339 # Calculates properties: |
| 340 self._parsed_url = None | 340 self._parsed_url = None |
| 341 self._dependencies = [] | 341 self._dependencies = [] |
| 342 # A cache of the files affected by the current operation, necessary for | 342 # A cache of the files affected by the current operation, necessary for |
| 343 # hooks. | 343 # hooks. |
| 344 self._file_list = [] | 344 self._file_list = [] |
| 345 # List of host names from which from which dependencies are allowed. | |
| 346 # Default is None, meaning unspecified in DEPS file, and hence all are | |
| 347 # allowed. Otherwise, it's a whitelist of hosts. | |
| 348 self._allowed_hosts = None | |
| 345 # If it is not set to True, the dependency wasn't processed for its child | 349 # If it is not set to True, the dependency wasn't processed for its child |
| 346 # dependency, i.e. its DEPS wasn't read. | 350 # dependency, i.e. its DEPS wasn't read. |
| 347 self._deps_parsed = False | 351 self._deps_parsed = False |
| 348 # This dependency has been processed, i.e. checked out | 352 # This dependency has been processed, i.e. checked out |
| 349 self._processed = False | 353 self._processed = False |
| 350 # This dependency had its pre-DEPS hooks run | 354 # This dependency had its pre-DEPS hooks run |
| 351 self._pre_deps_hooks_ran = False | 355 self._pre_deps_hooks_ran = False |
| 352 # This dependency had its hook run | 356 # This dependency had its hook run |
| 353 self._hooks_ran = False | 357 self._hooks_ran = False |
| 354 # This is the scm used to checkout self.url. It may be used by dependencies | 358 # This is the scm used to checkout self.url. It may be used by dependencies |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 680 deps = rel_deps | 684 deps = rel_deps |
| 681 | 685 |
| 682 # Update recursedeps if it's set. | 686 # Update recursedeps if it's set. |
| 683 if self.recursedeps is not None: | 687 if self.recursedeps is not None: |
| 684 logging.warning('Updating recursedeps by prepending %s.', self.name) | 688 logging.warning('Updating recursedeps by prepending %s.', self.name) |
| 685 rel_deps = set() | 689 rel_deps = set() |
| 686 for d in self.recursedeps: | 690 for d in self.recursedeps: |
| 687 rel_deps.add(os.path.normpath(os.path.join(self.name, d))) | 691 rel_deps.add(os.path.normpath(os.path.join(self.name, d))) |
| 688 self.recursedeps = rel_deps | 692 self.recursedeps = rel_deps |
| 689 | 693 |
| 694 # TODO(tandrii): default for allowed_hosts, and remove logging warning. | |
| 695 self._allowed_hosts = local_scope.get('allowed_hosts') | |
| 696 if not self._allowed_hosts: | |
|
iannucci
2014/09/16 20:34:08
I think this will be the default condition... most
tandrii(chromium)
2014/09/16 21:03:20
Yep, that's why I had default "None" to preserve p
tandrii(chromium)
2014/09/18 19:59:59
Done.
| |
| 697 logging.warning("no allowed_hosts specified!") | |
| 698 # TODO(tandrii): should we fail now for normal gclient runs (sync, etc) ? | |
| 699 | |
| 690 # Convert the deps into real Dependency. | 700 # Convert the deps into real Dependency. |
| 691 deps_to_add = [] | 701 deps_to_add = [] |
| 692 for name, url in deps.iteritems(): | 702 for name, url in deps.iteritems(): |
| 693 should_process = self.recursion_limit and self.should_process | 703 should_process = self.recursion_limit and self.should_process |
| 694 deps_to_add.append(Dependency( | 704 deps_to_add.append(Dependency( |
| 695 self, name, url, None, None, None, None, None, | 705 self, name, url, None, None, None, None, None, |
| 696 self.deps_file, should_process)) | 706 self.deps_file, should_process)) |
| 697 deps_to_add.sort(key=lambda x: x.name) | 707 deps_to_add.sort(key=lambda x: x.name) |
| 698 | 708 |
| 699 # override named sets of hooks by the custom hooks | 709 # override named sets of hooks by the custom hooks |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 749 'repository.' % options.revision) | 759 'repository.' % options.revision) |
| 750 else: | 760 else: |
| 751 parent_revision_date = self.parent.used_scm.GetRevisionDate( | 761 parent_revision_date = self.parent.used_scm.GetRevisionDate( |
| 752 options.revision) | 762 options.revision) |
| 753 options.revision = gclient_utils.MakeDateRevision( | 763 options.revision = gclient_utils.MakeDateRevision( |
| 754 parent_revision_date) | 764 parent_revision_date) |
| 755 if options.verbose: | 765 if options.verbose: |
| 756 print('Using parent\'s revision date %s since we are in a ' | 766 print('Using parent\'s revision date %s since we are in a ' |
| 757 'different repository.' % options.revision) | 767 'different repository.' % options.revision) |
| 758 | 768 |
| 769 def findDepsFromNotAllowedHosts(self): | |
| 770 """Returns a list of depenecies from not allowed hosts. | |
| 771 | |
| 772 If allowed_hosts is not set, allows all hosts and returns empty list. | |
| 773 """ | |
| 774 if self._allowed_hosts is None: | |
| 775 return [] | |
| 776 bad_deps = [] | |
| 777 for dep in self._dependencies: | |
| 778 if isinstance(dep.url, basestring): | |
| 779 parsed_url = urlparse.urlparse(dep.url) | |
| 780 if parsed_url.netloc and parsed_url.netloc not in self._allowed_hosts: | |
| 781 bad_deps.append(dep) | |
| 782 # TODO(tandrii): what about other possible URL types? | |
|
iannucci
2014/09/16 20:34:08
are there other url types?
tandrii(chromium)
2014/09/17 15:16:00
Well, I check here (copied from other part of gcli
tandrii(chromium)
2014/09/18 19:59:59
Done.
| |
| 783 return bad_deps | |
| 784 | |
| 759 # Arguments number differs from overridden method | 785 # Arguments number differs from overridden method |
| 760 # pylint: disable=W0221 | 786 # pylint: disable=W0221 |
| 761 def run(self, revision_overrides, command, args, work_queue, options): | 787 def run(self, revision_overrides, command, args, work_queue, options): |
| 762 """Runs |command| then parse the DEPS file.""" | 788 """Runs |command| then parse the DEPS file.""" |
| 763 logging.info('Dependency(%s).run()' % self.name) | 789 logging.info('Dependency(%s).run()' % self.name) |
| 764 assert self._file_list == [] | 790 assert self._file_list == [] |
| 765 if not self.should_process: | 791 if not self.should_process: |
| 766 return | 792 return |
| 767 # When running runhooks, there's no need to consult the SCM. | 793 # When running runhooks, there's no need to consult the SCM. |
| 768 # All known hooks are expected to run unconditionally regardless of working | 794 # All known hooks are expected to run unconditionally regardless of working |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1046 def pre_deps_hooks_ran(self): | 1072 def pre_deps_hooks_ran(self): |
| 1047 return self._pre_deps_hooks_ran | 1073 return self._pre_deps_hooks_ran |
| 1048 | 1074 |
| 1049 @property | 1075 @property |
| 1050 @gclient_utils.lockedmethod | 1076 @gclient_utils.lockedmethod |
| 1051 def hooks_ran(self): | 1077 def hooks_ran(self): |
| 1052 return self._hooks_ran | 1078 return self._hooks_ran |
| 1053 | 1079 |
| 1054 @property | 1080 @property |
| 1055 @gclient_utils.lockedmethod | 1081 @gclient_utils.lockedmethod |
| 1082 def allowed_hosts(self): | |
| 1083 if self._allowed_hosts is None: | |
| 1084 return None | |
| 1085 return tuple(self._allowed_hosts) | |
|
iannucci
2014/09/16 20:34:08
set or frozenset
tandrii(chromium)
2014/09/18 19:59:59
Done.
| |
| 1086 | |
| 1087 @property | |
| 1088 @gclient_utils.lockedmethod | |
| 1056 def file_list(self): | 1089 def file_list(self): |
| 1057 return tuple(self._file_list) | 1090 return tuple(self._file_list) |
| 1058 | 1091 |
| 1059 @property | 1092 @property |
| 1060 def used_scm(self): | 1093 def used_scm(self): |
| 1061 """SCMWrapper instance for this dependency or None if not processed yet.""" | 1094 """SCMWrapper instance for this dependency or None if not processed yet.""" |
| 1062 return self._used_scm | 1095 return self._used_scm |
| 1063 | 1096 |
| 1064 @property | 1097 @property |
| 1065 @gclient_utils.lockedmethod | 1098 @gclient_utils.lockedmethod |
| 1066 def got_revision(self): | 1099 def got_revision(self): |
| 1067 return self._got_revision | 1100 return self._got_revision |
| 1068 | 1101 |
| 1069 @property | 1102 @property |
| 1070 def file_list_and_children(self): | 1103 def file_list_and_children(self): |
| 1071 result = list(self.file_list) | 1104 result = list(self.file_list) |
| 1072 for d in self.dependencies: | 1105 for d in self.dependencies: |
| 1073 result.extend(d.file_list_and_children) | 1106 result.extend(d.file_list_and_children) |
| 1074 return tuple(result) | 1107 return tuple(result) |
| 1075 | 1108 |
| 1076 def __str__(self): | 1109 def __str__(self): |
| 1077 out = [] | 1110 out = [] |
| 1078 for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps', | 1111 for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps', |
| 1079 'custom_vars', 'deps_hooks', 'file_list', 'should_process', | 1112 'custom_vars', 'deps_hooks', 'file_list', 'should_process', |
| 1080 'processed', 'hooks_ran', 'deps_parsed', 'requirements'): | 1113 'processed', 'hooks_ran', 'deps_parsed', 'requirements', |
| 1114 'allowed_hosts'): | |
| 1081 # First try the native property if it exists. | 1115 # First try the native property if it exists. |
| 1082 if hasattr(self, '_' + i): | 1116 if hasattr(self, '_' + i): |
| 1083 value = getattr(self, '_' + i, False) | 1117 value = getattr(self, '_' + i, False) |
| 1084 else: | 1118 else: |
| 1085 value = getattr(self, i, False) | 1119 value = getattr(self, i, False) |
| 1086 if value: | 1120 if value: |
| 1087 out.append('%s: %s' % (i, value)) | 1121 out.append('%s: %s' % (i, value)) |
| 1088 | 1122 |
| 1089 for d in self.dependencies: | 1123 for d in self.dependencies: |
| 1090 out.extend([' ' + x for x in str(d).splitlines()]) | 1124 out.extend([' ' + x for x in str(d).splitlines()]) |
| (...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2079 (options, args) = parser.parse_args(args) | 2113 (options, args) = parser.parse_args(args) |
| 2080 options.force = True | 2114 options.force = True |
| 2081 client = GClient.LoadCurrentConfig(options) | 2115 client = GClient.LoadCurrentConfig(options) |
| 2082 if not client: | 2116 if not client: |
| 2083 raise gclient_utils.Error('client not configured; see \'gclient config\'') | 2117 raise gclient_utils.Error('client not configured; see \'gclient config\'') |
| 2084 client.RunOnDeps(None, []) | 2118 client.RunOnDeps(None, []) |
| 2085 print '; '.join(' '.join(hook) for hook in client.GetHooks(options)) | 2119 print '; '.join(' '.join(hook) for hook in client.GetHooks(options)) |
| 2086 return 0 | 2120 return 0 |
| 2087 | 2121 |
| 2088 | 2122 |
| 2123 def CMDverify(parser, args): | |
| 2124 """Verifies the DEPS file allowed_hosts.""" | |
| 2125 (options, args) = parser.parse_args(args) | |
| 2126 client = GClient.LoadCurrentConfig(options) | |
| 2127 if not client: | |
| 2128 raise gclient_utils.Error('client not configured; see \'gclient config\'') | |
| 2129 # TODO(tandrii): do we want this recursively? | |
|
iannucci
2014/09/16 20:34:08
possibly, though we'd probably want to scope each
tandrii(chromium)
2014/09/18 19:59:59
Done.
| |
| 2130 # Look at each first-level dependency of this gclient only. | |
| 2131 for dep in client.dependencies: | |
| 2132 dep.ParseDepsFile() | |
| 2133 bad_deps = dep.findDepsFromNotAllowedHosts() | |
| 2134 if not bad_deps: | |
| 2135 continue | |
| 2136 print "There are deps from not allowed hosts in file %s" % dep.deps_file | |
| 2137 for bad_dep in bad_deps: | |
| 2138 print "\t%s at %s" % (bad_dep.name, bad_dep.url) | |
| 2139 print "allowed_hosts:", ', '.join(dep.allowed_hosts) | |
| 2140 raise gclient_utils.Error( | |
| 2141 'dependencies from disallowed hosts; check your DEPS file.') | |
| 2142 return 0 | |
| 2143 | |
| 2089 class OptionParser(optparse.OptionParser): | 2144 class OptionParser(optparse.OptionParser): |
| 2090 gclientfile_default = os.environ.get('GCLIENT_FILE', '.gclient') | 2145 gclientfile_default = os.environ.get('GCLIENT_FILE', '.gclient') |
| 2091 | 2146 |
| 2092 def __init__(self, **kwargs): | 2147 def __init__(self, **kwargs): |
| 2093 optparse.OptionParser.__init__( | 2148 optparse.OptionParser.__init__( |
| 2094 self, version='%prog ' + __version__, **kwargs) | 2149 self, version='%prog ' + __version__, **kwargs) |
| 2095 | 2150 |
| 2096 # Some arm boards have issues with parallel sync. | 2151 # Some arm boards have issues with parallel sync. |
| 2097 if platform.machine().startswith('arm'): | 2152 if platform.machine().startswith('arm'): |
| 2098 jobs = 1 | 2153 jobs = 1 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2194 print >> sys.stderr, 'Error: %s' % str(e) | 2249 print >> sys.stderr, 'Error: %s' % str(e) |
| 2195 return 1 | 2250 return 1 |
| 2196 finally: | 2251 finally: |
| 2197 gclient_utils.PrintWarnings() | 2252 gclient_utils.PrintWarnings() |
| 2198 | 2253 |
| 2199 | 2254 |
| 2200 if '__main__' == __name__: | 2255 if '__main__' == __name__: |
| 2201 sys.exit(Main(sys.argv[1:])) | 2256 sys.exit(Main(sys.argv[1:])) |
| 2202 | 2257 |
| 2203 # vim: ts=2:sw=2:tw=80:et: | 2258 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |