OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2012 The Chromium Authors. All rights reserved. | 2 # Copyright 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 """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" and "import" directives in the .cpp and .java source files. | 9 "#include" and "import" directives in the .cpp, .java, and .proto source files. |
10 Any source file including something not permitted by the DEPS files will fail. | 10 Any source file including something not permitted by the DEPS files will fail. |
11 | 11 |
12 See builddeps.py for a detailed description of the DEPS format. | 12 See builddeps.py for a detailed description of the DEPS format. |
13 """ | 13 """ |
14 | 14 |
15 import os | 15 import os |
16 import optparse | 16 import optparse |
17 import re | 17 import re |
18 import sys | 18 import sys |
19 | 19 |
| 20 import proto_checker |
20 import cpp_checker | 21 import cpp_checker |
21 import java_checker | 22 import java_checker |
22 import results | 23 import results |
23 | 24 |
24 from builddeps import DepsBuilder | 25 from builddeps import DepsBuilder |
25 from rules import Rule, Rules | 26 from rules import Rule, Rules |
26 | 27 |
27 | 28 |
28 def _IsTestFile(filename): | 29 def _IsTestFile(filename): |
29 """Does a rudimentary check to try to skip test files; this could be | 30 """Does a rudimentary check to try to skip test files; this could be |
(...skipping 17 matching lines...) Expand all Loading... |
47 resolve_dotdot=True): | 48 resolve_dotdot=True): |
48 """Creates a new DepsChecker. | 49 """Creates a new DepsChecker. |
49 | 50 |
50 Args: | 51 Args: |
51 base_directory: OS-compatible path to root of checkout, e.g. C:\chr\src. | 52 base_directory: OS-compatible path to root of checkout, e.g. C:\chr\src. |
52 verbose: Set to true for debug output. | 53 verbose: Set to true for debug output. |
53 being_tested: Set to true to ignore the DEPS file at tools/checkdeps/DEPS. | 54 being_tested: Set to true to ignore the DEPS file at tools/checkdeps/DEPS. |
54 ignore_temp_rules: Ignore rules that start with Rule.TEMP_ALLOW ("!"). | 55 ignore_temp_rules: Ignore rules that start with Rule.TEMP_ALLOW ("!"). |
55 """ | 56 """ |
56 DepsBuilder.__init__( | 57 DepsBuilder.__init__( |
57 self, base_directory, extra_repos, verbose, being_tested, ignore_temp_ru
les) | 58 self, base_directory, extra_repos, verbose, being_tested, |
| 59 ignore_temp_rules) |
58 | 60 |
59 self._skip_tests = skip_tests | 61 self._skip_tests = skip_tests |
60 self._resolve_dotdot = resolve_dotdot | 62 self._resolve_dotdot = resolve_dotdot |
61 self.results_formatter = results.NormalResultsFormatter(verbose) | 63 self.results_formatter = results.NormalResultsFormatter(verbose) |
62 | 64 |
63 def Report(self): | 65 def Report(self): |
64 """Prints a report of results, and returns an exit code for the process.""" | 66 """Prints a report of results, and returns an exit code for the process.""" |
65 if self.results_formatter.GetResults(): | 67 if self.results_formatter.GetResults(): |
66 self.results_formatter.PrintResults() | 68 self.results_formatter.PrintResults() |
67 return 1 | 69 return 1 |
68 print '\nSUCCESS\n' | 70 print '\nSUCCESS\n' |
69 return 0 | 71 return 0 |
70 | 72 |
71 def CheckDirectory(self, start_dir): | 73 def CheckDirectory(self, start_dir): |
72 """Checks all relevant source files in the specified directory and | 74 """Checks all relevant source files in the specified directory and |
73 its subdirectories for compliance with DEPS rules throughout the | 75 its subdirectories for compliance with DEPS rules throughout the |
74 tree (starting at |self.base_directory|). |start_dir| must be a | 76 tree (starting at |self.base_directory|). |start_dir| must be a |
75 subdirectory of |self.base_directory|. | 77 subdirectory of |self.base_directory|. |
76 | 78 |
77 On completion, self.results_formatter has the results of | 79 On completion, self.results_formatter has the results of |
78 processing, and calling Report() will print a report of results. | 80 processing, and calling Report() will print a report of results. |
79 """ | 81 """ |
80 java = java_checker.JavaChecker(self.base_directory, self.verbose) | 82 java = java_checker.JavaChecker(self.base_directory, self.verbose) |
81 cpp = cpp_checker.CppChecker( | 83 cpp = cpp_checker.CppChecker( |
82 self.verbose, self._resolve_dotdot, self.base_directory) | 84 self.verbose, self._resolve_dotdot, self.base_directory) |
| 85 proto = proto_checker.ProtoChecker( |
| 86 self.verbose, self._resolve_dotdot, self.base_directory) |
83 checkers = dict( | 87 checkers = dict( |
84 (extension, checker) | 88 (extension, checker) |
85 for checker in [java, cpp] for extension in checker.EXTENSIONS) | 89 for checker in [java, cpp, proto] for extension in checker.EXTENSIONS) |
86 | 90 |
87 for rules, file_paths in self.GetAllRulesAndFiles(start_dir): | 91 for rules, file_paths in self.GetAllRulesAndFiles(start_dir): |
88 for full_name in file_paths: | 92 for full_name in file_paths: |
89 if self._skip_tests and _IsTestFile(os.path.basename(full_name)): | 93 if self._skip_tests and _IsTestFile(os.path.basename(full_name)): |
90 continue | 94 continue |
91 file_extension = os.path.splitext(full_name)[1] | 95 file_extension = os.path.splitext(full_name)[1] |
92 if not file_extension in checkers: | 96 if not file_extension in checkers: |
93 continue | 97 continue |
94 checker = checkers[file_extension] | 98 checker = checkers[file_extension] |
95 file_status = checker.CheckFile(rules, full_name) | 99 file_status = checker.CheckFile(rules, full_name) |
96 if file_status.HasViolations(): | 100 if file_status.HasViolations(): |
97 self.results_formatter.AddError(file_status) | 101 self.results_formatter.AddError(file_status) |
98 | 102 |
99 def CheckIncludesAndImports(self, added_lines, checker): | 103 def CheckIncludesAndImports(self, added_lines, checker): |
100 """Check new import/#include statements added in the change | 104 """Check new import/#include statements added in the change |
101 being presubmit checked. | 105 being presubmit checked. |
102 | 106 |
103 Args: | 107 Args: |
104 added_lines: ((file_path, (changed_line, changed_line, ...), ...) | 108 added_lines: ((file_path, (changed_line, changed_line, ...), ...) |
105 checker: CppChecker/JavaChecker checker instance | 109 checker: CppChecker/JavaChecker/ProtoChecker checker instance |
106 | 110 |
107 Return: | 111 Return: |
108 A list of tuples, (bad_file_path, rule_type, rule_description) | 112 A list of tuples, (bad_file_path, rule_type, rule_description) |
109 where rule_type is one of Rule.DISALLOW or Rule.TEMP_ALLOW and | 113 where rule_type is one of Rule.DISALLOW or Rule.TEMP_ALLOW and |
110 rule_description is human-readable. Empty if no problems. | 114 rule_description is human-readable. Empty if no problems. |
111 """ | 115 """ |
112 problems = [] | 116 problems = [] |
113 for file_path, changed_lines in added_lines: | 117 for file_path, changed_lines in added_lines: |
114 if not checker.ShouldCheck(file_path): | 118 if not checker.ShouldCheck(file_path): |
115 continue | 119 continue |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 | 157 |
154 Return: | 158 Return: |
155 A list of tuples, (bad_file_path, rule_type, rule_description) | 159 A list of tuples, (bad_file_path, rule_type, rule_description) |
156 where rule_type is one of Rule.DISALLOW or Rule.TEMP_ALLOW and | 160 where rule_type is one of Rule.DISALLOW or Rule.TEMP_ALLOW and |
157 rule_description is human-readable. Empty if no problems. | 161 rule_description is human-readable. Empty if no problems. |
158 """ | 162 """ |
159 return self.CheckIncludesAndImports( | 163 return self.CheckIncludesAndImports( |
160 added_imports, | 164 added_imports, |
161 java_checker.JavaChecker(self.base_directory, self.verbose)) | 165 java_checker.JavaChecker(self.base_directory, self.verbose)) |
162 | 166 |
| 167 def CheckAddedProtoImports(self, added_imports): |
| 168 """This is used from PRESUBMIT.py to check new #import statements added in |
| 169 the change being presubmit checked. |
| 170 |
| 171 Args: |
| 172 added_imports : ((file_path, (import_line, import_line, ...), ...) |
| 173 |
| 174 Return: |
| 175 A list of tuples, (bad_file_path, rule_type, rule_description) |
| 176 where rule_type is one of Rule.DISALLOW or Rule.TEMP_ALLOW and |
| 177 rule_description is human-readable. Empty if no problems. |
| 178 """ |
| 179 return self.CheckIncludesAndImports( |
| 180 added_imports, proto_checker.ProtoChecker( |
| 181 verbose=self.verbose, root_dir=self.base_directory)) |
| 182 |
163 def PrintUsage(): | 183 def PrintUsage(): |
164 print """Usage: python checkdeps.py [--root <root>] [tocheck] | 184 print """Usage: python checkdeps.py [--root <root>] [tocheck] |
165 | 185 |
166 --root ROOT Specifies the repository root. This defaults to "../../.." | 186 --root ROOT Specifies the repository root. This defaults to "../../.." |
167 relative to the script file. This will be correct given the | 187 relative to the script file. This will be correct given the |
168 normal location of the script in "<root>/tools/checkdeps". | 188 normal location of the script in "<root>/tools/checkdeps". |
169 | 189 |
170 --(others) There are a few lesser-used options; run with --help to show them. | 190 --(others) There are a few lesser-used options; run with --help to show them. |
171 | 191 |
172 tocheck Specifies the directory, relative to root, to check. This defaults | 192 tocheck Specifies the directory, relative to root, to check. This defaults |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 if options.json: | 277 if options.json: |
258 deps_checker.results_formatter = results.JSONResultsFormatter( | 278 deps_checker.results_formatter = results.JSONResultsFormatter( |
259 options.json, deps_checker.results_formatter) | 279 options.json, deps_checker.results_formatter) |
260 | 280 |
261 deps_checker.CheckDirectory(start_dir) | 281 deps_checker.CheckDirectory(start_dir) |
262 return deps_checker.Report() | 282 return deps_checker.Report() |
263 | 283 |
264 | 284 |
265 if '__main__' == __name__: | 285 if '__main__' == __name__: |
266 sys.exit(main()) | 286 sys.exit(main()) |
OLD | NEW |