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

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