153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)# Copyright (c) 2013 The Chromium Authors. All rights reserved.
253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)# found in the LICENSE file.
453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)"""Top-level presubmit script for Blink.
653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)for more details about the presubmit API built into gcl.
953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)"""
1053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)import sys
1293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)_EXCLUDED_PATHS = ()
1553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)def _CheckForVersionControlConflictsInFile(input_api, f):
1853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$')
1953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    errors = []
2053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for line_num, line in f.ChangedContents():
2153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if pattern.match(line):
2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            errors.append('    %s:%d %s' % (f.LocalPath(), line_num, line))
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return errors
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)def _CheckForVersionControlConflicts(input_api, output_api):
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    """Usually this is not intentional and will cause a compile failure."""
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    errors = []
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for f in input_api.AffectedFiles():
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        errors.extend(_CheckForVersionControlConflictsInFile(input_api, f))
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results = []
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if errors:
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        results.append(output_api.PresubmitError(
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            'Version control conflict markers found, please resolve.', errors))
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return results
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)def _CheckWatchlist(input_api, output_api):
4051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    """Check that the WATCHLIST file parses correctly."""
4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    errors = []
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for f in input_api.AffectedFiles():
4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if f.LocalPath() != 'WATCHLISTS':
4451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            continue
4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        import StringIO
4651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        import logging
4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        import watchlists
4851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
4951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        log_buffer = StringIO.StringIO()
5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        log_handler = logging.StreamHandler(log_buffer)
5151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        log_handler.setFormatter(
5251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            logging.Formatter('%(levelname)s: %(message)s'))
5351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        logger = logging.getLogger()
5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        logger.addHandler(log_handler)
5551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        wl = watchlists.Watchlists(input_api.change.RepositoryRoot())
5751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
5851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        logger.removeHandler(log_handler)
5951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        log_handler.flush()
6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        log_buffer.flush()
6151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
6251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if log_buffer.getvalue():
6351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            errors.append(output_api.PresubmitError(
6451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                'Cannot parse WATCHLISTS file, please resolve.',
6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                log_buffer.getvalue().splitlines()))
6651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return errors
6751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
6851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
6953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)def _CommonChecks(input_api, output_api):
7053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    """Checks common to both upload and commit."""
7153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    # We should figure out what license checks we actually want to use.
7253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    license_header = r'.*'
7353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
7453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results = []
7553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results.extend(input_api.canned_checks.PanProjectChecks(
7653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        input_api, output_api, excluded_paths=_EXCLUDED_PATHS,
7753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        maxlen=800, license_header=license_header))
7853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results.extend(_CheckForVersionControlConflicts(input_api, output_api))
7953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results.extend(_CheckPatchFiles(input_api, output_api))
8053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results.extend(_CheckTestExpectations(input_api, output_api))
8193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    results.extend(_CheckUnwantedDependencies(input_api, output_api))
82521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    results.extend(_CheckChromiumPlatformMacros(input_api, output_api))
8351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    results.extend(_CheckWatchlist(input_api, output_api))
8453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return results
8553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)def _CheckSubversionConfig(input_api, output_api):
8853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  """Verifies the subversion config file is correctly setup.
8953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
9053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  Checks that autoprops are enabled, returns an error otherwise.
9153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  """
9253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  join = input_api.os_path.join
9353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  if input_api.platform == 'win32':
9453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    appdata = input_api.environ.get('APPDATA', '')
9553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if not appdata:
9653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)      return [output_api.PresubmitError('%APPDATA% is not configured.')]
9753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path = join(appdata, 'Subversion', 'config')
9853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  else:
9953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    home = input_api.environ.get('HOME', '')
10053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if not home:
10153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)      return [output_api.PresubmitError('$HOME is not configured.')]
10253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    path = join(home, '.subversion', 'config')
10353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
10453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  error_msg = (
10553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)      'Please look at http://dev.chromium.org/developers/coding-style to\n'
10653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)      'configure your subversion configuration file. This enables automatic\n'
10753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)      'properties to simplify the project maintenance.\n'
10853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)      'Pro-tip: just download and install\n'
10953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)      'http://src.chromium.org/viewvc/chrome/trunk/tools/build/slave/config\n')
11053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
11153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  try:
11253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    lines = open(path, 'r').read().splitlines()
11353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    # Make sure auto-props is enabled and check for 2 Chromium standard
11453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    # auto-prop.
11553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (not '*.cc = svn:eol-style=LF' in lines or
11653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        not '*.pdf = svn:mime-type=application/pdf' in lines or
11753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        not 'enable-auto-props = yes' in lines):
11853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)      return [
11953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)          output_api.PresubmitNotifyResult(
12053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)              'It looks like you have not configured your subversion config '
12153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)              'file or it is not up-to-date.\n' + error_msg)
12253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)      ]
12353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  except (OSError, IOError):
12453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return [
12553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        output_api.PresubmitNotifyResult(
12653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            'Can\'t find your subversion config file.\n' + error_msg)
12753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ]
12853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  return []
12953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
13053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
13153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)def _CheckPatchFiles(input_api, output_api):
13253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  problems = [f.LocalPath() for f in input_api.AffectedFiles()
13353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)      if f.LocalPath().endswith(('.orig', '.rej'))]
13453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  if problems:
13553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return [output_api.PresubmitError(
13653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        "Don't commit .rej and .orig files.", problems)]
13753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  else:
13853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return []
13953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
14053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
14153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)def _CheckTestExpectations(input_api, output_api):
14253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    local_paths = [f.LocalPath() for f in input_api.AffectedFiles()]
14353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if any(path.startswith('LayoutTests') for path in local_paths):
14453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        lint_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
14553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            'Tools', 'Scripts', 'lint-test-expectations')
14653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        _, errs = input_api.subprocess.Popen(
14753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            [input_api.python_executable, lint_path],
14853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            stdout=input_api.subprocess.PIPE,
14953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            stderr=input_api.subprocess.PIPE).communicate()
15053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if not errs:
15153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            return [output_api.PresubmitError(
15253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                "lint-test-expectations failed "
15353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                "to produce output; check by hand. ")]
15453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if errs.strip() != 'Lint succeeded.':
15553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            return [output_api.PresubmitError(errs)]
15653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return []
15753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
15853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
15953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)def _CheckStyle(input_api, output_api):
16081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    style_checker_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
16181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        'Tools', 'Scripts', 'check-webkit-style')
16281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    args = ([input_api.python_executable, style_checker_path, '--diff-files']
16381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        + [f.LocalPath() for f in input_api.AffectedFiles()])
16453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results = []
16553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
16653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    try:
16753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        child = input_api.subprocess.Popen(args,
16853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                                           stderr=input_api.subprocess.PIPE)
16953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        _, stderrdata = child.communicate()
17053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if child.returncode != 0:
17153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            results.append(output_api.PresubmitError(
17253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                'check-webkit-style failed', [stderrdata]))
17353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    except Exception as e:
17453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        results.append(output_api.PresubmitNotifyResult(
17553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            'Could not run check-webkit-style', [str(e)]))
17653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
17753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return results
17853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
17953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
18093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)def _CheckUnwantedDependencies(input_api, output_api):
18193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    """Runs checkdeps on #include statements added in this
18293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    change. Breaking - rules is an error, breaking ! rules is a
18393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    warning.
18493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    """
18593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    # We need to wait until we have an input_api object and use this
18693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    # roundabout construct to import checkdeps because this file is
18793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    # eval-ed and thus doesn't have __file__.
18893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    original_sys_path = sys.path
18993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    try:
19093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        sys.path = sys.path + [input_api.os_path.realpath(input_api.os_path.join(
19193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                input_api.PresubmitLocalPath(), '..', '..', 'tools', 'checkdeps'))]
19293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        import checkdeps
19393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        from cpp_checker import CppChecker
19493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        from rules import Rule
19593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    finally:
19693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        # Restore sys.path to what it was before.
19793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        sys.path = original_sys_path
19893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
19993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    added_includes = []
20093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for f in input_api.AffectedFiles():
20193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        if not CppChecker.IsCppFile(f.LocalPath()):
20293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            continue
20393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
20493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        changed_lines = [line for line_num, line in f.ChangedContents()]
20593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        added_includes.append([f.LocalPath(), changed_lines])
20693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
207521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    deps_checker = checkdeps.DepsChecker(
2081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        input_api.os_path.join(input_api.PresubmitLocalPath()))
20993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
21093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    error_descriptions = []
21193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    warning_descriptions = []
21293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
21393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            added_includes):
21493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        description_with_path = '%s\n    %s' % (path, rule_description)
21593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        if rule_type == Rule.DISALLOW:
21693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            error_descriptions.append(description_with_path)
21793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        else:
21893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            warning_descriptions.append(description_with_path)
21993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
22093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    results = []
22193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if error_descriptions:
22293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        results.append(output_api.PresubmitError(
22393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                'You added one or more #includes that violate checkdeps rules.',
22493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                error_descriptions))
22593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if warning_descriptions:
22693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        results.append(output_api.PresubmitPromptOrNotify(
22793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                'You added one or more #includes of files that are temporarily\n'
22893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                'allowed but being removed. Can you avoid introducing the\n'
22993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                '#include? See relevant DEPS file(s) for details and contacts.',
23093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                warning_descriptions))
23193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return results
23293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
23393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
234521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)def _CheckChromiumPlatformMacros(input_api, output_api, source_file_filter=None):
235521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    """Ensures that Blink code uses WTF's platform macros instead of
236521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    Chromium's. Using the latter has resulted in at least one subtle
237521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    build breakage."""
238521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    os_macro_re = input_api.re.compile(r'^\s*#(el)?if.*\bOS_')
239521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    errors = input_api.canned_checks._FindNewViolationsOfRule(
240521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        lambda _, x: not os_macro_re.search(x),
241521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        input_api, source_file_filter)
242521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    errors = ['Found use of Chromium OS_* macro in %s. '
243521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        'Use WTF platform macros instead.' % violation for violation in errors]
244521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if errors:
245521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return [output_api.PresubmitPromptWarning('\n'.join(errors))]
246521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return []
247521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
248521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
249591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochdef _CompileDevtoolsFrontend(input_api, output_api):
250591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if not input_api.platform.startswith('linux'):
251591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return []
252591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    local_paths = [f.LocalPath() for f in input_api.AffectedFiles()]
2530019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch    if (any("devtools/front_end" in path for path in local_paths) or
2540019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch        any("InjectedScriptSource.js" in path for path in local_paths) or
2550019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch        any("InjectedScriptCanvasModuleSource.js" in path for path in local_paths)):
256591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        lint_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
257591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            "Source", "devtools", "scripts", "compile_frontend.py")
258591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        out, _ = input_api.subprocess.Popen(
259591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            [input_api.python_executable, lint_path],
260591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            stdout=input_api.subprocess.PIPE,
261591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            stderr=input_api.subprocess.STDOUT).communicate()
262591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        if "WARNING" in out or "ERROR" in out:
263591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            return [output_api.PresubmitError(out)]
264591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    return []
265591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
266591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
26723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdochdef _CheckForPrintfDebugging(input_api, output_api):
26823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    """Generally speaking, we'd prefer not to land patches that printf
26923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    debug output."""
27023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    os_macro_re = input_api.re.compile(r'^\s*printf\(')
27123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    errors = input_api.canned_checks._FindNewViolationsOfRule(
27223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch        lambda _, x: not os_macro_re.search(x),
27323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch        input_api, None)
27423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    errors = ['  * %s' % violation for violation in errors]
27523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    if errors:
27623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch        return [output_api.PresubmitPromptOrNotify(
27723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch                    'printf debugging is best debugging! That said, it might '
27823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch                    'be a good idea to drop the following occurances from '
27923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch                    'your patch before uploading:\n%s' % '\n'.join(errors))]
28023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    return []
28123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
28223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
28306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)def _CheckForFailInFile(input_api, f):
28406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    pattern = input_api.re.compile('^FAIL')
28506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    errors = []
28606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    for line_num, line in f.ChangedContents():
28706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if pattern.match(line):
28806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            errors.append('    %s:%d %s' % (f.LocalPath(), line_num, line))
28906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    return errors
29006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
29106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
29253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)def CheckChangeOnUpload(input_api, output_api):
29353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results = []
29453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results.extend(_CommonChecks(input_api, output_api))
29553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results.extend(_CheckStyle(input_api, output_api))
29623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    results.extend(_CheckForPrintfDebugging(input_api, output_api))
297591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    results.extend(_CompileDevtoolsFrontend(input_api, output_api))
29853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return results
29953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
30053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
30153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)def CheckChangeOnCommit(input_api, output_api):
30253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results = []
30353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results.extend(_CommonChecks(input_api, output_api))
30453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results.extend(input_api.canned_checks.CheckTreeIsOpen(
30553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        input_api, output_api,
30653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        json_url='http://blink-status.appspot.com/current?format=json'))
30753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results.extend(input_api.canned_checks.CheckChangeHasDescription(
30853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        input_api, output_api))
30953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    results.extend(_CheckSubversionConfig(input_api, output_api))
31053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return results
31153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
31253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)def GetPreferredTrySlaves(project, change):
313e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)    return [
314e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)        'linux_blink_rel', 'mac_blink_rel', 'win_blink_rel',
315e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)        'linux_blink', 'mac_layout:webkit_lint', 'win_layout:webkit_lint',
316e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)    ]
317