• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2015 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Checks to use in PRESUBMIT.py for HTML style violations."""
6
7import collections
8import difflib
9import re
10
11import bs4
12
13from catapult_build import parse_html
14
15
16def RunChecks(input_api, output_api, excluded_paths=None):
17
18  def ShouldCheck(affected_file):
19    path = affected_file.LocalPath()
20    if not path.endswith('.html'):
21      return False
22    if not excluded_paths:
23      return True
24    return not any(re.match(pattern, path) for pattern in excluded_paths)
25
26  affected_files = input_api.AffectedFiles(
27      file_filter=ShouldCheck, include_deletes=False)
28  results = []
29  for f in affected_files:
30    CheckAffectedFile(f, results, output_api)
31  return results
32
33
34def CheckAffectedFile(affected_file, results, output_api):
35  path = affected_file.LocalPath()
36  soup = parse_html.BeautifulSoup('\n'.join(affected_file.NewContents()))
37  for check in [CheckDoctype, CheckImportOrder]:
38    check(path, soup, results, output_api)
39
40
41def CheckDoctype(path, soup, results, output_api):
42  if _HasHtml5Declaration(soup):
43    return
44  error_text = 'Could not find "<!DOCTYPE html>" in %s.' % path
45  results.append(output_api.PresubmitError(error_text))
46
47
48def _HasHtml5Declaration(soup):
49  for item in soup.contents:
50    if isinstance(item, bs4.Doctype) and item.lower() == 'html':
51      return True
52  return False
53
54
55def CheckImportOrder(path, soup, results, output_api):
56  grouped_hrefs = collections.defaultdict(list)  # Link rel -> [link hrefs].
57  for link in soup.find_all('link'):
58    grouped_hrefs[','.join(link.get('rel'))].append(link.get('href'))
59
60  for rel, actual_hrefs in grouped_hrefs.iteritems():
61    expected_hrefs = list(sorted(set(actual_hrefs)))
62    if actual_hrefs != expected_hrefs:
63      error_text = (
64          'Invalid "%s" link sort order in %s:\n' % (rel, path) +
65          '  ' + '\n  '.join(difflib.ndiff(actual_hrefs, expected_hrefs)))
66      results.append(output_api.PresubmitError(error_text))
67