| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 """Makes sure that files include headers from allowed directories. | 6 """Makes sure that files include headers from allowed directories. |
| 7 | 7 |
| 8 Checks DEPS files in the source tree for rules, and applies those rules to | 8 Checks DEPS files in the source tree for rules, and applies those rules to |
| 9 "#include" commands in source files. Any source file including something not | 9 "#include" commands in source files. Any source file including something not |
| 10 permitted by the DEPS files will fail. | 10 permitted by the DEPS files will fail. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 only lowercase. | 52 only lowercase. |
| 53 """ | 53 """ |
| 54 | 54 |
| 55 import os | 55 import os |
| 56 import optparse | 56 import optparse |
| 57 import pipes | 57 import pipes |
| 58 import re | 58 import re |
| 59 import sys | 59 import sys |
| 60 import copy | 60 import copy |
| 61 | 61 |
| 62 # Variable name used in the DEPS file to specify module-level deps. | |
| 63 DEPS_VAR_NAME = "deps" | |
| 64 | |
| 65 # Variable name used in the DEPS file to add or subtract include files from | 62 # Variable name used in the DEPS file to add or subtract include files from |
| 66 # the module-level deps. | 63 # the module-level deps. |
| 67 INCLUDE_RULES_VAR_NAME = "include_rules" | 64 INCLUDE_RULES_VAR_NAME = "include_rules" |
| 68 | 65 |
| 69 # Optionally present in the DEPS file to list subdirectories which should not | 66 # Optionally present in the DEPS file to list subdirectories which should not |
| 70 # be checked. This allows us to skip third party code, for example. | 67 # be checked. This allows us to skip third party code, for example. |
| 71 SKIP_SUBDIRS_VAR_NAME = "skip_child_includes" | 68 SKIP_SUBDIRS_VAR_NAME = "skip_child_includes" |
| 72 | 69 |
| 73 # The maximum number of lines to check in each source file before giving up. | 70 # The maximum number of lines to check in each source file before giving up. |
| 74 MAX_LINES = 150 | 71 MAX_LINES = 150 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 for rule in self._rules: | 160 for rule in self._rules: |
| 164 if rule.ChildOrMatch(allowed_dir): | 161 if rule.ChildOrMatch(allowed_dir): |
| 165 # This rule applies. | 162 # This rule applies. |
| 166 if rule._allow: | 163 if rule._allow: |
| 167 return (True, "") | 164 return (True, "") |
| 168 return (False, rule.__str__()) | 165 return (False, rule.__str__()) |
| 169 # No rules apply, fail. | 166 # No rules apply, fail. |
| 170 return (False, "no rule applying") | 167 return (False, "no rule applying") |
| 171 | 168 |
| 172 | 169 |
| 173 def ApplyRules(existing_rules, deps, includes, cur_dir): | 170 def ApplyRules(existing_rules, includes, cur_dir): |
| 174 """Applies the given deps and include rules, returning the new rules. | 171 """Applies the given include rules, returning the new rules. |
| 175 | 172 |
| 176 Args: | 173 Args: |
| 177 existing_rules: A set of existing rules that will be combined. | 174 existing_rules: A set of existing rules that will be combined. |
| 178 deps: The list of imports from the "deps" section of the DEPS file. | |
| 179 include: The list of rules from the "include_rules" section of DEPS. | 175 include: The list of rules from the "include_rules" section of DEPS. |
| 180 cur_dir: The current directory. We will create an implicit rule that | 176 cur_dir: The current directory. We will create an implicit rule that |
| 181 allows inclusion from this directory. | 177 allows inclusion from this directory. |
| 182 | 178 |
| 183 Returns: A new set of rules combining the existing_rules with the other | 179 Returns: A new set of rules combining the existing_rules with the other |
| 184 arguments. | 180 arguments. |
| 185 """ | 181 """ |
| 186 rules = copy.copy(existing_rules) | 182 rules = copy.copy(existing_rules) |
| 187 | 183 |
| 188 # First apply the implicit "allow" rule for the current directory. | 184 # First apply the implicit "allow" rule for the current directory. |
| 189 if cur_dir.lower().startswith(BASE_DIRECTORY): | 185 if cur_dir.lower().startswith(BASE_DIRECTORY): |
| 190 relative_dir = cur_dir[len(BASE_DIRECTORY) + 1:] | 186 relative_dir = cur_dir[len(BASE_DIRECTORY) + 1:] |
| 191 # Normalize path separators to slashes. | 187 # Normalize path separators to slashes. |
| 192 relative_dir = relative_dir.replace("\\", "/") | 188 relative_dir = relative_dir.replace("\\", "/") |
| 193 source = relative_dir | 189 source = relative_dir |
| 194 if len(source) == 0: | 190 if len(source) == 0: |
| 195 source = "top level" # Make the help string a little more meaningful. | 191 source = "top level" # Make the help string a little more meaningful. |
| 196 rules.AddRule("+" + relative_dir, "Default rule for " + source) | 192 rules.AddRule("+" + relative_dir, "Default rule for " + source) |
| 197 else: | 193 else: |
| 198 raise Exception("Internal error: base directory is not at the beginning" + | 194 raise Exception("Internal error: base directory is not at the beginning" + |
| 199 " for\n %s and base dir\n %s" % | 195 " for\n %s and base dir\n %s" % |
| 200 (cur_dir, BASE_DIRECTORY)) | 196 (cur_dir, BASE_DIRECTORY)) |
| 201 | 197 |
| 202 # Next apply the DEPS additions, these are all allowed. Note that DEPS start | |
| 203 # out with "src/" which we want to trim. | |
| 204 for (index, key) in enumerate(deps): | |
| 205 if key.startswith("src/"): | |
| 206 key = key[4:] | |
| 207 rules.AddRule("+" + key, relative_dir + "'s deps for " + key) | |
| 208 | |
| 209 # Last, apply the additional explicit rules. | 198 # Last, apply the additional explicit rules. |
| 210 for (index, rule_str) in enumerate(includes): | 199 for (index, rule_str) in enumerate(includes): |
| 211 if not len(relative_dir): | 200 if not len(relative_dir): |
| 212 rule_description = "the top level include_rules" | 201 rule_description = "the top level include_rules" |
| 213 else: | 202 else: |
| 214 rule_description = relative_dir + "'s include_rules" | 203 rule_description = relative_dir + "'s include_rules" |
| 215 rules.AddRule(rule_str, rule_description) | 204 rules.AddRule(rule_str, rule_description) |
| 216 | 205 |
| 217 return rules | 206 return rules |
| 218 | 207 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 } | 257 } |
| 269 deps_file = os.path.join(dir_name, "DEPS") | 258 deps_file = os.path.join(dir_name, "DEPS") |
| 270 | 259 |
| 271 if os.path.isfile(deps_file): | 260 if os.path.isfile(deps_file): |
| 272 execfile(deps_file, global_scope, local_scope) | 261 execfile(deps_file, global_scope, local_scope) |
| 273 elif VERBOSE: | 262 elif VERBOSE: |
| 274 print " No deps file found in", dir_name | 263 print " No deps file found in", dir_name |
| 275 | 264 |
| 276 # Even if a DEPS file does not exist we still invoke ApplyRules | 265 # Even if a DEPS file does not exist we still invoke ApplyRules |
| 277 # to apply the implicit "allow" rule for the current directory | 266 # to apply the implicit "allow" rule for the current directory |
| 278 deps = local_scope.get(DEPS_VAR_NAME, {}) | |
| 279 include_rules = local_scope.get(INCLUDE_RULES_VAR_NAME, []) | 267 include_rules = local_scope.get(INCLUDE_RULES_VAR_NAME, []) |
| 280 skip_subdirs = local_scope.get(SKIP_SUBDIRS_VAR_NAME, []) | 268 skip_subdirs = local_scope.get(SKIP_SUBDIRS_VAR_NAME, []) |
| 281 | 269 |
| 282 return (ApplyRules(existing_rules, deps, include_rules, dir_name), | 270 return (ApplyRules(existing_rules, include_rules, dir_name), skip_subdirs) |
| 283 skip_subdirs) | |
| 284 | 271 |
| 285 | 272 |
| 286 def ShouldCheckFile(file_name): | 273 def ShouldCheckFile(file_name): |
| 287 """Returns True if the given file is a type we want to check.""" | 274 """Returns True if the given file is a type we want to check.""" |
| 288 checked_extensions = [ | 275 checked_extensions = [ |
| 289 '.h', | 276 '.h', |
| 290 '.cc', | 277 '.cc', |
| 291 '.m', | 278 '.m', |
| 292 '.mm', | 279 '.mm', |
| 293 ] | 280 ] |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 'to "../../.." relative to the script file, which ' | 492 'to "../../.." relative to the script file, which ' |
| 506 'will normally be the repository root.') | 493 'will normally be the repository root.') |
| 507 option_parser.add_option("-v", "--verbose", action="store_true", | 494 option_parser.add_option("-v", "--verbose", action="store_true", |
| 508 default=False, help="Print debug logging") | 495 default=False, help="Print debug logging") |
| 509 options, args = option_parser.parse_args() | 496 options, args = option_parser.parse_args() |
| 510 return checkdeps(options, args) | 497 return checkdeps(options, args) |
| 511 | 498 |
| 512 | 499 |
| 513 if '__main__' == __name__: | 500 if '__main__' == __name__: |
| 514 sys.exit(main()) | 501 sys.exit(main()) |
| OLD | NEW |