OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Top-level presubmit script for Chromium. | 5 """Top-level presubmit script for Chromium. |
6 | 6 |
7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts | 7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts |
8 for more details about the presubmit API built into depot_tools. | 8 for more details about the presubmit API built into depot_tools. |
9 """ | 9 """ |
10 | 10 |
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 | 1042 |
1043 results = [] | 1043 results = [] |
1044 if errors: | 1044 if errors: |
1045 results.append(output_api.PresubmitError( | 1045 results.append(output_api.PresubmitError( |
1046 'The name of PNG files should not have abbreviations. \n' | 1046 'The name of PNG files should not have abbreviations. \n' |
1047 'Use _hover.png, _center.png, instead of _h.png, _c.png.\n' | 1047 'Use _hover.png, _center.png, instead of _h.png, _c.png.\n' |
1048 'Contact oshima@chromium.org if you have questions.', errors)) | 1048 'Contact oshima@chromium.org if you have questions.', errors)) |
1049 return results | 1049 return results |
1050 | 1050 |
1051 | 1051 |
1052 def _ExtractAddRulesFromParsedDeps(parsed_deps): | 1052 def _FilesToCheckForIncomingDeps(re, changed_lines): |
1053 """Extract the rules that add dependencies from a parsed DEPS file. | |
1054 | |
1055 Args: | |
1056 parsed_deps: the locals dictionary from evaluating the DEPS file.""" | |
1057 add_rules = set() | |
1058 add_rules.update([ | |
1059 rule[1:] for rule in parsed_deps.get('include_rules', []) | |
1060 if rule.startswith('+') or rule.startswith('!') | |
1061 ]) | |
1062 for specific_file, rules in parsed_deps.get('specific_include_rules', | |
1063 {}).iteritems(): | |
1064 add_rules.update([ | |
1065 rule[1:] for rule in rules | |
1066 if rule.startswith('+') or rule.startswith('!') | |
1067 ]) | |
1068 return add_rules | |
1069 | |
1070 | |
1071 def _ParseDeps(contents): | |
1072 """Simple helper for parsing DEPS files.""" | |
1073 # Stubs for handling special syntax in the root DEPS file. | |
1074 def FromImpl(*_): | |
1075 pass # NOP function so "From" doesn't fail. | |
1076 | |
1077 def FileImpl(_): | |
1078 pass # NOP function so "File" doesn't fail. | |
1079 | |
1080 class _VarImpl: | |
1081 | |
1082 def __init__(self, local_scope): | |
1083 self._local_scope = local_scope | |
1084 | |
1085 def Lookup(self, var_name): | |
1086 """Implements the Var syntax.""" | |
1087 try: | |
1088 return self._local_scope['vars'][var_name] | |
1089 except KeyError: | |
1090 raise Exception('Var is not defined: %s' % var_name) | |
1091 | |
1092 local_scope = {} | |
1093 global_scope = { | |
1094 'File': FileImpl, | |
1095 'From': FromImpl, | |
1096 'Var': _VarImpl(local_scope).Lookup, | |
1097 } | |
1098 exec contents in global_scope, local_scope | |
1099 return local_scope | |
1100 | |
1101 | |
1102 def _CalculateAddedDeps(os_path, old_contents, new_contents): | |
1103 """Helper method for _CheckAddedDepsHaveTargetApprovals. Returns | 1053 """Helper method for _CheckAddedDepsHaveTargetApprovals. Returns |
1104 a set of DEPS entries that we should look up. | 1054 a set of DEPS entries that we should look up. |
1105 | 1055 |
1106 For a directory (rather than a specific filename) we fake a path to | 1056 For a directory (rather than a specific filename) we fake a path to |
1107 a specific filename by adding /DEPS. This is chosen as a file that | 1057 a specific filename by adding /DEPS. This is chosen as a file that |
1108 will seldom or never be subject to per-file include_rules. | 1058 will seldom or never be subject to per-file include_rules. |
1109 """ | 1059 """ |
1110 # We ignore deps entries on auto-generated directories. | 1060 # We ignore deps entries on auto-generated directories. |
1111 AUTO_GENERATED_DIRS = ['grit', 'jni'] | 1061 AUTO_GENERATED_DIRS = ['grit', 'jni'] |
1112 | 1062 |
1113 old_deps = _ExtractAddRulesFromParsedDeps(_ParseDeps(old_contents)) | 1063 # This pattern grabs the path without basename in the first |
1114 new_deps = _ExtractAddRulesFromParsedDeps(_ParseDeps(new_contents)) | 1064 # parentheses, and the basename (if present) in the second. It |
1115 | 1065 # relies on the simple heuristic that if there is a basename it will |
1116 added_deps = new_deps.difference(old_deps) | 1066 # be a header file ending in ".h". |
1117 | 1067 pattern = re.compile( |
| 1068 r"""['"]\+([^'"]+?)(/[a-zA-Z0-9_]+\.h)?['"].*""") |
1118 results = set() | 1069 results = set() |
1119 for added_dep in added_deps: | 1070 for changed_line in changed_lines: |
1120 if added_dep.split('/')[0] in AUTO_GENERATED_DIRS: | 1071 m = pattern.match(changed_line) |
1121 continue | 1072 if m: |
1122 # Assume that a rule that ends in .h is a rule for a specific file. | 1073 path = m.group(1) |
1123 if added_dep.endswith('.h'): | 1074 if path.split('/')[0] not in AUTO_GENERATED_DIRS: |
1124 results.add(added_dep) | 1075 if m.group(2): |
1125 else: | 1076 results.add('%s%s' % (path, m.group(2))) |
1126 results.add(os_path.join(added_dep, 'DEPS')) | 1077 else: |
| 1078 results.add('%s/DEPS' % path) |
1127 return results | 1079 return results |
1128 | 1080 |
1129 | 1081 |
1130 def _CheckAddedDepsHaveTargetApprovals(input_api, output_api): | 1082 def _CheckAddedDepsHaveTargetApprovals(input_api, output_api): |
1131 """When a dependency prefixed with + is added to a DEPS file, we | 1083 """When a dependency prefixed with + is added to a DEPS file, we |
1132 want to make sure that the change is reviewed by an OWNER of the | 1084 want to make sure that the change is reviewed by an OWNER of the |
1133 target file or directory, to avoid layering violations from being | 1085 target file or directory, to avoid layering violations from being |
1134 introduced. This check verifies that this happens. | 1086 introduced. This check verifies that this happens. |
1135 """ | 1087 """ |
1136 virtual_depended_on_files = set() | 1088 changed_lines = set() |
1137 | 1089 |
1138 file_filter = lambda f: not input_api.re.match( | 1090 file_filter = lambda f: not input_api.re.match( |
1139 r"^third_party[\\\/]WebKit[\\\/].*", f.LocalPath()) | 1091 r"^third_party[\\\/]WebKit[\\\/].*", f.LocalPath()) |
1140 for f in input_api.AffectedFiles(include_deletes=False, | 1092 for f in input_api.AffectedFiles(include_deletes=False, |
1141 file_filter=file_filter): | 1093 file_filter=file_filter): |
1142 filename = input_api.os_path.basename(f.LocalPath()) | 1094 filename = input_api.os_path.basename(f.LocalPath()) |
1143 if filename == 'DEPS': | 1095 if filename == 'DEPS': |
1144 virtual_depended_on_files.update(_CalculateAddedDeps( | 1096 changed_lines |= set(line.strip() |
1145 input_api.os_path, | 1097 for line_num, line |
1146 '\n'.join(f.OldContents()), | 1098 in f.ChangedContents()) |
1147 '\n'.join(f.NewContents()))) | 1099 if not changed_lines: |
| 1100 return [] |
1148 | 1101 |
| 1102 virtual_depended_on_files = _FilesToCheckForIncomingDeps(input_api.re, |
| 1103 changed_lines) |
1149 if not virtual_depended_on_files: | 1104 if not virtual_depended_on_files: |
1150 return [] | 1105 return [] |
1151 | 1106 |
1152 if input_api.is_committing: | 1107 if input_api.is_committing: |
1153 if input_api.tbr: | 1108 if input_api.tbr: |
1154 return [output_api.PresubmitNotifyResult( | 1109 return [output_api.PresubmitNotifyResult( |
1155 '--tbr was specified, skipping OWNERS check for DEPS additions')] | 1110 '--tbr was specified, skipping OWNERS check for DEPS additions')] |
1156 if input_api.dry_run: | 1111 if input_api.dry_run: |
1157 return [output_api.PresubmitNotifyResult( | 1112 return [output_api.PresubmitNotifyResult( |
1158 'This is a dry run, skipping OWNERS check for DEPS additions')] | 1113 'This is a dry run, skipping OWNERS check for DEPS additions')] |
(...skipping 1258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2417 output_api, | 2372 output_api, |
2418 json_url='http://chromium-status.appspot.com/current?format=json')) | 2373 json_url='http://chromium-status.appspot.com/current?format=json')) |
2419 | 2374 |
2420 results.extend( | 2375 results.extend( |
2421 input_api.canned_checks.CheckPatchFormatted(input_api, output_api)) | 2376 input_api.canned_checks.CheckPatchFormatted(input_api, output_api)) |
2422 results.extend(input_api.canned_checks.CheckChangeHasBugField( | 2377 results.extend(input_api.canned_checks.CheckChangeHasBugField( |
2423 input_api, output_api)) | 2378 input_api, output_api)) |
2424 results.extend(input_api.canned_checks.CheckChangeHasDescription( | 2379 results.extend(input_api.canned_checks.CheckChangeHasDescription( |
2425 input_api, output_api)) | 2380 input_api, output_api)) |
2426 return results | 2381 return results |
OLD | NEW |