Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(357)

Side by Side Diff: PRESUBMIT.py

Issue 9288045: PRESUBMIT check for JavaScript style errors (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Just 'getElementById', drop the 'document.' -- it's cleaner that way Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
12 import re 15 import re
13 16 import os.path
14 17
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
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 = []
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
56
57 def _valid(self, error):
58 '''Check whether an error is valid. Most errors are valid, with a few
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())
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()):
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 # Use closure_linter to check for several different errors
101 error_handler = ErrorHandlerImpl()
102 checker = closure_linter.checker.JavaScriptStyleChecker(error_handler)
103 checker.Check(f.LocalPath())
104
105 for error in error_handler.GetErrors():
106 errorMsg = ' line %d: E%04d: %s\n%s' % (
107 error.token.line_number,
108 error.code,
109 error.message,
110 error.token.line)
111 errorLines.append(errorMsg)
112
113 if errorLines:
114 errorLines = [
115 'Found JavaScript style violations in %s:' %
116 f.LocalPath()] + errorLines
117 results.append(output_api.PresubmitError('\n'.join(errorLines)))
118
119 if results:
120 results.append(output_api.PresubmitNotifyResult(
121 'See the JavaScript style guide at '
122 'http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml'
123 ' and contact tbreisacher@chromium.org for feedback on this'
124 ' PRESUBMIT check.'))
125
126 return results
33 127
34 def _CheckNoInterfacesInBase(input_api, output_api): 128 def _CheckNoInterfacesInBase(input_api, output_api):
35 """Checks to make sure no files in libbase.a have |@interface|.""" 129 """Checks to make sure no files in libbase.a have |@interface|."""
36 pattern = input_api.re.compile(r'^\s*@interface', input_api.re.MULTILINE) 130 pattern = input_api.re.compile(r'^\s*@interface', input_api.re.MULTILINE)
37 files = [] 131 files = []
38 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): 132 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
39 if (f.LocalPath().startswith('base/') and 133 if (f.LocalPath().startswith('base/') and
40 not f.LocalPath().endswith('_unittest.mm')): 134 not f.LocalPath().endswith('_unittest.mm')):
41 contents = input_api.ReadFile(f) 135 contents = input_api.ReadFile(f)
42 if pattern.search(contents): 136 if pattern.search(contents):
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 if not problems: 301 if not problems:
208 return [] 302 return []
209 return [output_api.PresubmitPromptWarning('The old callback system is ' 303 return [output_api.PresubmitPromptWarning('The old callback system is '
210 'deprecated. If possible, use base::Bind and base::Callback instead.\n' + 304 'deprecated. If possible, use base::Bind and base::Callback instead.\n' +
211 '\n'.join(problems))] 305 '\n'.join(problems))]
212 306
213 307
214 def _CommonChecks(input_api, output_api): 308 def _CommonChecks(input_api, output_api):
215 """Checks common to both upload and commit.""" 309 """Checks common to both upload and commit."""
216 results = [] 310 results = []
311 results.extend(_CheckJavaScriptStyle(input_api, output_api))
Dan Beam 2012/02/03 03:09:13 Damn, I guess I should be doing my checks in this
217 results.extend(input_api.canned_checks.PanProjectChecks( 312 results.extend(input_api.canned_checks.PanProjectChecks(
218 input_api, output_api, excluded_paths=_EXCLUDED_PATHS)) 313 input_api, output_api, excluded_paths=_EXCLUDED_PATHS))
219 results.extend(_CheckNoInterfacesInBase(input_api, output_api)) 314 results.extend(_CheckNoInterfacesInBase(input_api, output_api))
220 results.extend(_CheckAuthorizedAuthor(input_api, output_api)) 315 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
221 results.extend( 316 results.extend(
222 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api)) 317 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
223 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) 318 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
224 results.extend(_CheckNoNewWStrings(input_api, output_api)) 319 results.extend(_CheckNoNewWStrings(input_api, output_api))
225 results.extend(_CheckNoDEPSGIT(input_api, output_api)) 320 results.extend(_CheckNoDEPSGIT(input_api, output_api))
226 results.extend(_CheckNoFRIEND_TEST(input_api, output_api)) 321 results.extend(_CheckNoFRIEND_TEST(input_api, output_api))
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 def GetPreferredTrySlaves(project, change): 431 def GetPreferredTrySlaves(project, change):
337 only_objc_files = all( 432 only_objc_files = all(
338 f.LocalPath().endswith(('.mm', '.m')) for f in change.AffectedFiles()) 433 f.LocalPath().endswith(('.mm', '.m')) for f in change.AffectedFiles())
339 if only_objc_files: 434 if only_objc_files:
340 return ['mac_rel'] 435 return ['mac_rel']
341 preferred = ['win_rel', 'linux_rel', 'mac_rel'] 436 preferred = ['win_rel', 'linux_rel', 'mac_rel']
342 aura_re = '_aura[^/]*[.][^/]*' 437 aura_re = '_aura[^/]*[.][^/]*'
343 if any(re.search(aura_re, f.LocalPath()) for f in change.AffectedFiles()): 438 if any(re.search(aura_re, f.LocalPath()) for f in change.AffectedFiles()):
344 preferred.append('linux_chromeos_aura:compile') 439 preferred.append('linux_chromeos_aura:compile')
345 return preferred 440 return preferred
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698