Chromium Code Reviews| 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 gcl. | 8 for more details about the presubmit API built into gcl. |
| 9 """ | 9 """ |
| 10 | 10 |
| 11 | 11 |
| 12 import closure_linter.checker | |
| 13 import closure_linter.common.errorhandler | |
| 14 import closure_linter.errors | |
| 15 import os.path | |
| 12 import re | 16 import re |
|
M-A Ruel
2012/02/06 20:29:27
This import was an oversight in http://codereview.
Tyler Breisacher (Chromium)
2012/02/06 22:00:13
Done. This means I have to move ErrorHandlerImpl i
M-A Ruel
2012/02/07 00:34:09
no. :)
| |
| 13 | 17 |
| 14 | |
| 15 _EXCLUDED_PATHS = ( | 18 _EXCLUDED_PATHS = ( |
| 16 r"^breakpad[\\\/].*", | 19 r"^breakpad[\\\/].*", |
| 17 r"^native_client_sdk[\\\/].*", | 20 r"^native_client_sdk[\\\/].*", |
| 18 r"^net[\\\/]tools[\\\/]spdyshark[\\\/].*", | 21 r"^net[\\\/]tools[\\\/]spdyshark[\\\/].*", |
| 19 r"^skia[\\\/].*", | 22 r"^skia[\\\/].*", |
| 20 r"^v8[\\\/].*", | 23 r"^v8[\\\/].*", |
| 21 r".*MakeFile$", | 24 r".*MakeFile$", |
| 22 ) | 25 ) |
| 23 | 26 |
| 24 | 27 |
| 25 _TEST_ONLY_WARNING = ( | 28 _TEST_ONLY_WARNING = ( |
| 26 'You might be calling functions intended only for testing from\n' | 29 'You might be calling functions intended only for testing from\n' |
| 27 'production code. It is OK to ignore this warning if you know what\n' | 30 'production code. It is OK to ignore this warning if you know what\n' |
| 28 'you are doing, as the heuristics used to detect the situation are\n' | 31 'you are doing, as the heuristics used to detect the situation are\n' |
| 29 'not perfect. The commit queue will not block on this warning.\n' | 32 'not perfect. The commit queue will not block on this warning.\n' |
| 30 'Email joi@chromium.org if you have questions.') | 33 'Email joi@chromium.org if you have questions.') |
| 31 | 34 |
|
M-A Ruel
2012/02/06 20:29:27
2 vertical lines between file level symbols please
Tyler Breisacher (Chromium)
2012/02/06 22:00:13
Done.
| |
| 35 class ErrorHandlerImpl(closure_linter.common.errorhandler.ErrorHandler): | |
| 36 '''Implementation of ErrorHandler that collects all errors except those | |
| 37 that don't apply for Chromium JavaScript code. | |
| 38 ''' | |
| 32 | 39 |
| 40 def __init__(self): | |
| 41 self._errors = [] | |
|
M-A Ruel
2012/02/06 20:29:27
if you used self.errors = [], then you wouldn't ne
Tyler Breisacher (Chromium)
2012/02/06 22:00:13
I think the JavaScriptStyleChecker only calls Hand
| |
| 42 | |
| 43 def HandleFile(self, filename, first_token): | |
| 44 self._filename = filename | |
| 45 | |
| 46 def HandleError(self, error): | |
| 47 if (self._valid(error)): | |
| 48 error.filename = self._filename | |
| 49 self._errors.append(error) | |
| 50 | |
| 51 def GetErrors(self): | |
| 52 return self._errors | |
| 53 | |
| 54 def HasErrors(self): | |
| 55 return not self._errors.empty | |
|
M-A Ruel
2012/02/06 20:29:27
What's list.empty?
Tyler Breisacher (Chromium)
2012/02/06 22:00:13
*facepalm*. Thank you! Done.
| |
| 56 | |
| 57 def _valid(self, error): | |
| 58 '''Check whether an error is valid. Most errors are valid, with a few | |
|
M-A Ruel
2012/02/06 20:29:27
All the rest of the file use """for docstrings""".
Tyler Breisacher (Chromium)
2012/02/06 22:00:13
Done.
| |
| 59 exceptions which are listed here. | |
| 60 ''' | |
| 61 return error.code not in [ | |
| 62 closure_linter.errors.COMMA_AT_END_OF_LITERAL, | |
| 63 closure_linter.errors.JSDOC_ILLEGAL_QUESTION_WITH_PIPE, | |
| 64 closure_linter.errors.JSDOC_TAG_DESCRIPTION_ENDS_WITH_INVALID_CHARACTER | |
| 65 ] | |
| 66 | |
| 67 def _CheckJavaScriptStyle(input_api, output_api): | |
| 68 """Check for JavaScript style violations.""" | |
| 69 | |
| 70 # Only check the following folders. OWNERS of folders containing JavaScript | |
| 71 # code can opt-in to this check by adding the folder here. | |
| 72 checked_folders = [ | |
| 73 os.path.join('chrome', 'browser', 'resources', 'ntp4'), | |
| 74 os.path.join('chrome', 'browser', 'resources', 'options2'), | |
| 75 ] | |
| 76 | |
| 77 def inCheckedFolder(affected_file): | |
| 78 return any(affected_file.LocalPath().startswith(cf) | |
| 79 for cf in checked_folders) | |
| 80 | |
| 81 def jsOrHtml(affected_file): | |
| 82 return re.search('\.(js|html?)$', affected_file.LocalPath()) | |
|
M-A Ruel
2012/02/06 20:29:27
input_api.re
Tyler Breisacher (Chromium)
2012/02/06 22:00:13
Done.
| |
| 83 | |
| 84 def fileFilter(affected_file): | |
| 85 return jsOrHtml(affected_file) and inCheckedFolder(affected_file) | |
| 86 | |
| 87 results = [] | |
| 88 | |
| 89 for f in input_api.change.AffectedFiles(file_filter=fileFilter): | |
| 90 errorLines = [] | |
| 91 | |
| 92 # check for getElementById() | |
| 93 for i, line in enumerate(f.NewContents()): | |
|
Tyler Breisacher (Chromium)
2012/02/06 22:00:13
Off by one error! The first line is line 1, not li
| |
| 94 if 'getElementById' in line: | |
| 95 errorLines.append(' line %d: %s\n%s' % ( | |
| 96 i, | |
| 97 'Use $() instead of document.getElementById()', | |
| 98 line)) | |
| 99 | |
| 100 const_re = re.compile(r'\bconst\b') | |
| 101 if const_re.search(line): | |
| 102 errorLines.append(' line %d: %s\n%s' % ( | |
| 103 i, | |
| 104 'Use |var| instead of |const|. See http://crbug.com/80149', | |
| 105 line)) | |
| 106 | |
| 107 # Use closure_linter to check for several different errors | |
| 108 error_handler = ErrorHandlerImpl() | |
| 109 checker = closure_linter.checker.JavaScriptStyleChecker(error_handler) | |
| 110 checker.Check(f.LocalPath()) | |
| 111 | |
| 112 for error in error_handler.GetErrors(): | |
| 113 errorMsg = ' line %d: E%04d: %s\n%s' % ( | |
| 114 error.token.line_number, | |
| 115 error.code, | |
| 116 error.message, | |
| 117 error.token.line) | |
| 118 errorLines.append(errorMsg) | |
| 119 | |
| 120 if errorLines: | |
| 121 errorLines = [ | |
| 122 'Found JavaScript style violations in %s:' % | |
| 123 f.LocalPath()] + errorLines | |
| 124 results.append(output_api.PresubmitError('\n'.join(errorLines))) | |
| 125 | |
| 126 if results: | |
| 127 results.append(output_api.PresubmitNotifyResult( | |
| 128 'See the JavaScript style guide at ' | |
| 129 'http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml' | |
| 130 ' and contact tbreisacher@chromium.org for feedback on this' | |
| 131 ' PRESUBMIT check.')) | |
| 132 | |
| 133 return results | |
| 33 | 134 |
| 34 def _CheckNoInterfacesInBase(input_api, output_api): | 135 def _CheckNoInterfacesInBase(input_api, output_api): |
| 35 """Checks to make sure no files in libbase.a have |@interface|.""" | 136 """Checks to make sure no files in libbase.a have |@interface|.""" |
| 36 pattern = input_api.re.compile(r'^\s*@interface', input_api.re.MULTILINE) | 137 pattern = input_api.re.compile(r'^\s*@interface', input_api.re.MULTILINE) |
| 37 files = [] | 138 files = [] |
| 38 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): | 139 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): |
| 39 if (f.LocalPath().startswith('base/') and | 140 if (f.LocalPath().startswith('base/') and |
| 40 not f.LocalPath().endswith('_unittest.mm')): | 141 not f.LocalPath().endswith('_unittest.mm')): |
| 41 contents = input_api.ReadFile(f) | 142 contents = input_api.ReadFile(f) |
| 42 if pattern.search(contents): | 143 if pattern.search(contents): |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 if not problems: | 308 if not problems: |
| 208 return [] | 309 return [] |
| 209 return [output_api.PresubmitPromptWarning('The old callback system is ' | 310 return [output_api.PresubmitPromptWarning('The old callback system is ' |
| 210 'deprecated. If possible, use base::Bind and base::Callback instead.\n' + | 311 'deprecated. If possible, use base::Bind and base::Callback instead.\n' + |
| 211 '\n'.join(problems))] | 312 '\n'.join(problems))] |
| 212 | 313 |
| 213 | 314 |
| 214 def _CommonChecks(input_api, output_api): | 315 def _CommonChecks(input_api, output_api): |
| 215 """Checks common to both upload and commit.""" | 316 """Checks common to both upload and commit.""" |
| 216 results = [] | 317 results = [] |
| 318 results.extend(_CheckJavaScriptStyle(input_api, output_api)) | |
| 217 results.extend(input_api.canned_checks.PanProjectChecks( | 319 results.extend(input_api.canned_checks.PanProjectChecks( |
| 218 input_api, output_api, excluded_paths=_EXCLUDED_PATHS)) | 320 input_api, output_api, excluded_paths=_EXCLUDED_PATHS)) |
| 219 results.extend(_CheckNoInterfacesInBase(input_api, output_api)) | 321 results.extend(_CheckNoInterfacesInBase(input_api, output_api)) |
| 220 results.extend(_CheckAuthorizedAuthor(input_api, output_api)) | 322 results.extend(_CheckAuthorizedAuthor(input_api, output_api)) |
| 221 results.extend( | 323 results.extend( |
| 222 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api)) | 324 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api)) |
| 223 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) | 325 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) |
| 224 results.extend(_CheckNoNewWStrings(input_api, output_api)) | 326 results.extend(_CheckNoNewWStrings(input_api, output_api)) |
| 225 results.extend(_CheckNoDEPSGIT(input_api, output_api)) | 327 results.extend(_CheckNoDEPSGIT(input_api, output_api)) |
| 226 results.extend(_CheckNoFRIEND_TEST(input_api, output_api)) | 328 results.extend(_CheckNoFRIEND_TEST(input_api, output_api)) |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 336 def GetPreferredTrySlaves(project, change): | 438 def GetPreferredTrySlaves(project, change): |
| 337 only_objc_files = all( | 439 only_objc_files = all( |
| 338 f.LocalPath().endswith(('.mm', '.m')) for f in change.AffectedFiles()) | 440 f.LocalPath().endswith(('.mm', '.m')) for f in change.AffectedFiles()) |
| 339 if only_objc_files: | 441 if only_objc_files: |
| 340 return ['mac_rel'] | 442 return ['mac_rel'] |
| 341 preferred = ['win_rel', 'linux_rel', 'mac_rel'] | 443 preferred = ['win_rel', 'linux_rel', 'mac_rel'] |
| 342 aura_re = '_aura[^/]*[.][^/]*' | 444 aura_re = '_aura[^/]*[.][^/]*' |
| 343 if any(re.search(aura_re, f.LocalPath()) for f in change.AffectedFiles()): | 445 if any(re.search(aura_re, f.LocalPath()) for f in change.AffectedFiles()): |
| 344 preferred.append('linux_chromeos') | 446 preferred.append('linux_chromeos') |
| 345 return preferred | 447 return preferred |
| OLD | NEW |