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 """Presubmit script for Chromium WebUI resources. | 5 """Presubmit script for Chromium WebUI resources. |
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/git cl, and see | 8 for more details about the presubmit API built into gcl/git cl, and see |
9 http://www.chromium.org/developers/web-development-style-guide for the rules | 9 http://www.chromium.org/developers/web-development-style-guide for the rules |
10 we're checking against here. | 10 we're checking against here. |
(...skipping 10 matching lines...) Expand all Loading... |
21 def RunChecks(self): | 21 def RunChecks(self): |
22 # We use this a lot, so make a nick name variable. | 22 # We use this a lot, so make a nick name variable. |
23 re = self.input_api.re | 23 re = self.input_api.re |
24 | 24 |
25 def _collapseable_hex(s): | 25 def _collapseable_hex(s): |
26 return (len(s) == 6 and s[0] == s[1] and s[2] == s[3] and s[4] == s[5]) | 26 return (len(s) == 6 and s[0] == s[1] and s[2] == s[3] and s[4] == s[5]) |
27 | 27 |
28 def _is_gray(s): | 28 def _is_gray(s): |
29 return s[0] == s[1] == s[2] if len(s) == 3 else s[0:2] == s[2:4] == s[4:6] | 29 return s[0] == s[1] == s[2] if len(s) == 3 else s[0:2] == s[2:4] == s[4:6] |
30 | 30 |
| 31 def _remove_all(s): |
| 32 return _remove_grit(_remove_ats(_remove_comments(s))) |
| 33 |
31 def _remove_ats(s): | 34 def _remove_ats(s): |
32 return re.sub(re.compile(r'@\w+.*?{(.*{.*?})+.*?}', re.DOTALL), '\\1', s) | 35 return re.sub(re.compile(r'@\w+.*?{(.*{.*?})+.*?}', re.DOTALL), '\\1', s) |
33 | 36 |
34 def _remove_comments(s): | 37 def _remove_comments(s): |
35 return re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', s) | 38 return re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', s) |
36 | 39 |
| 40 def _remove_grit(s): |
| 41 grit_reg = r'<if[^>]*>.*<\s*/\s*if[^>]*>|<include[^>]+>' |
| 42 return re.sub(re.compile(grit_reg, re.DOTALL), '', s) |
| 43 |
37 def _rgb_from_hex(s): | 44 def _rgb_from_hex(s): |
38 if len(s) == 3: | 45 if len(s) == 3: |
39 r, g, b = s[0] + s[0], s[1] + s[1], s[2] + s[2] | 46 r, g, b = s[0] + s[0], s[1] + s[1], s[2] + s[2] |
40 else: | 47 else: |
41 r, g, b = s[0:2], s[2:4], s[4:6] | 48 r, g, b = s[0:2], s[2:4], s[4:6] |
42 return int(r, base=16), int(g, base=16), int(b, base=16) | 49 return int(r, base=16), int(g, base=16), int(b, base=16) |
43 | 50 |
44 def alphabetize_props(contents): | 51 def alphabetize_props(contents): |
45 errors = [] | 52 errors = [] |
46 for rule in re.finditer(r'{(.*?)}', contents, re.DOTALL): | 53 for rule in re.finditer(r'{(.*?)}', contents, re.DOTALL): |
47 rules = filter(lambda r: r.find(': ') >= 0, | 54 semis = map(lambda t: t.strip(), rule.group(1).split(';'))[:-1] |
48 map(lambda t: t.strip(), rule.group(1).split(';'))[0:-1]) | 55 rules = filter(lambda r: ': ' in r, semis) |
49 props = map(lambda r: r[0:r.find(':')], rules) | 56 props = map(lambda r: r[0:r.find(':')], rules) |
50 if props != sorted(props): | 57 if props != sorted(props): |
51 errors.append(' %s;\n' % (';\n '.join(rules))) | 58 errors.append(' %s;\n' % (';\n '.join(rules))) |
52 return errors | 59 return errors |
53 | 60 |
54 def braces_have_space_before_and_nothing_after(line): | 61 def braces_have_space_before_and_nothing_after(line): |
55 return re.search(r'(?:^|\S){|{\s*\S+\s*$', line) | 62 return re.search(r'(?:^|\S){|{\s*\S+\s*$', line) |
56 | 63 |
57 def classes_use_dashes(line): | 64 def classes_use_dashes(line): |
58 # Intentionally dumbed down version of CSS 2.1 grammar for class without | 65 # Intentionally dumbed down version of CSS 2.1 grammar for class without |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 'hsl() or part of @keyframe.', | 170 'hsl() or part of @keyframe.', |
164 'test': zero_length_values, | 171 'test': zero_length_values, |
165 }, | 172 }, |
166 ] | 173 ] |
167 | 174 |
168 results = [] | 175 results = [] |
169 affected_files = self.input_api.AffectedFiles(include_deletes=False, | 176 affected_files = self.input_api.AffectedFiles(include_deletes=False, |
170 file_filter=self.file_filter) | 177 file_filter=self.file_filter) |
171 files = [] | 178 files = [] |
172 for f in affected_files: | 179 for f in affected_files: |
173 # Remove all /*comments*/ and @at-keywords; we're not using a real parser. | 180 # Remove all /*comments*/, @at-keywords, and grit <if|include> tags; we're |
174 file_contents = _remove_ats(_remove_comments('\n'.join(f.NewContents()))) | 181 # not using a real parser. TODO(dbeam): Check alpha in <if> blocks. |
| 182 file_contents = _remove_all('\n'.join(f.NewContents())) |
175 files.append((f.LocalPath(), file_contents)) | 183 files.append((f.LocalPath(), file_contents)) |
176 | 184 |
177 # Only look at CSS files for now. | 185 # Only look at CSS files for now. |
178 for f in filter(lambda f: f[0].endswith('.css'), files): | 186 for f in filter(lambda f: f[0].endswith('.css'), files): |
179 file_errors = [] | 187 file_errors = [] |
180 for check in added_or_modified_files_checks: | 188 for check in added_or_modified_files_checks: |
181 # If the check is multiline, it receieves the whole file and gives us | 189 # If the check is multiline, it receieves the whole file and gives us |
182 # back a list of things wrong. If the check isn't multiline, we pass it | 190 # back a list of things wrong. If the check isn't multiline, we pass it |
183 # each line and the check returns something truthy if there's an issue. | 191 # each line and the check returns something truthy if there's an issue. |
184 if ('multiline' in check and check['multiline']): | 192 if ('multiline' in check and check['multiline']): |
(...skipping 20 matching lines...) Expand all Loading... |
205 '%s:\n%s' % (f[0], '\n\n'.join(file_errors)))) | 213 '%s:\n%s' % (f[0], '\n\n'.join(file_errors)))) |
206 | 214 |
207 if results: | 215 if results: |
208 # Add your name if you're here often mucking around in the code. | 216 # Add your name if you're here often mucking around in the code. |
209 authors = ['dbeam@chromium.org'] | 217 authors = ['dbeam@chromium.org'] |
210 results.append(self.output_api.PresubmitNotifyResult( | 218 results.append(self.output_api.PresubmitNotifyResult( |
211 'Was the CSS checker useful? Send feedback or hate mail to %s.' % | 219 'Was the CSS checker useful? Send feedback or hate mail to %s.' % |
212 ', '.join(authors))) | 220 ', '.join(authors))) |
213 | 221 |
214 return results | 222 return results |
OLD | NEW |