PRESUBMIT.py revision 0fcaf99b716c71e721db25f37f62dabf5dcbe69a
12442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
22442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org#
32442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org# Use of this source code is governed by a BSD-style license
42442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org# that can be found in the LICENSE file in the root of the source
52442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org# tree. An additional intellectual property rights grant can be found
62442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org# in the file PATENTS.  All contributing project authors may
72442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org# be found in the AUTHORS file in the root of the source tree.
8da159d6be61ae8041ab265092c2d6ba0ca7b64f5niklase@google.com
9986ee082b628ffd3a90fbbe4b933a312489921e0kjellanderimport json
10aefe61ae2a392122994739adac54017e33cab9bfkjellander@webrtc.orgimport os
11986ee082b628ffd3a90fbbe4b933a312489921e0kjellanderimport platform
128575980e16b917b5d94e670a9c6da9029615b575kjellander@webrtc.orgimport re
13986ee082b628ffd3a90fbbe4b933a312489921e0kjellanderimport subprocess
143bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.orgimport sys
158575980e16b917b5d94e670a9c6da9029615b575kjellander@webrtc.org
168575980e16b917b5d94e670a9c6da9029615b575kjellander@webrtc.org
170fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org# Directories that will be scanned by cpplint by the presubmit script.
180fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.orgCPPLINT_DIRS = [
190fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org  'webrtc/video_engine',
200fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org]
210fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org
220fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org
2351198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.orgdef _CheckNoIOStreamInHeaders(input_api, output_api):
2451198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  """Checks to make sure no .h files include <iostream>."""
2551198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  files = []
2651198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  pattern = input_api.re.compile(r'^#include\s*<iostream>',
2751198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org                                 input_api.re.MULTILINE)
2851198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
2951198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org    if not f.LocalPath().endswith('.h'):
3051198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      continue
3151198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org    contents = input_api.ReadFile(f)
3251198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org    if pattern.search(contents):
3351198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      files.append(f)
3451198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org
3551198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  if len(files):
3657e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander    return [output_api.PresubmitError(
3751198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org        'Do not #include <iostream> in header files, since it inserts static ' +
3851198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org        'initialization into every file including the header. Instead, ' +
3951198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org        '#include <ostream>. See http://crbug.com/94794',
4057e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander        files)]
4151198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  return []
4251198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org
43e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org
4451198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.orgdef _CheckNoFRIEND_TEST(input_api, output_api):
4551198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  """Make sure that gtest's FRIEND_TEST() macro is not used, the
4651198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  FRIEND_TEST_ALL_PREFIXES() macro from testsupport/gtest_prod_util.h should be
4751198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes."""
4851198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  problems = []
4951198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org
5051198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  file_filter = lambda f: f.LocalPath().endswith(('.cc', '.h'))
5151198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  for f in input_api.AffectedFiles(file_filter=file_filter):
5251198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org    for line_num, line in f.ChangedContents():
5351198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      if 'FRIEND_TEST(' in line:
5451198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org        problems.append('    %s:%d' % (f.LocalPath(), line_num))
5551198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org
5651198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  if not problems:
5751198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org    return []
5851198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  return [output_api.PresubmitPromptWarning('WebRTC\'s code should not use '
5951198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      'gtest\'s FRIEND_TEST() macro. Include testsupport/gtest_prod_util.h and '
6051198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      'use FRIEND_TEST_ALL_PREFIXES() instead.\n' + '\n'.join(problems))]
6151198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org
62e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org
630fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.orgdef _IsLintWhitelisted(whitelist_dirs, file_path):
640fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org  """ Checks if a file is whitelisted for lint check."""
650fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org  for path in whitelist_dirs:
660fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org    if os.path.dirname(file_path).startswith(path):
670fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org      return True
680fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org  return False
690fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org
700fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org
712a45209a6d17e12419e13592eba786e7ba7b1425mflodman@webrtc.orgdef _CheckApprovedFilesLintClean(input_api, output_api,
722a45209a6d17e12419e13592eba786e7ba7b1425mflodman@webrtc.org                                 source_file_filter=None):
732a45209a6d17e12419e13592eba786e7ba7b1425mflodman@webrtc.org  """Checks that all new or whitelisted .cc and .h files pass cpplint.py.
7451198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  This check is based on _CheckChangeLintsClean in
7551198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  depot_tools/presubmit_canned_checks.py but has less filters and only checks
7651198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  added files."""
7751198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  result = []
7851198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org
7951198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  # Initialize cpplint.
8051198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  import cpplint
8151198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  # Access to a protected member _XX of a client class
8251198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  # pylint: disable=W0212
8351198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  cpplint._cpplint_state.ResetErrorCounts()
8451198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org
850fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org  # Create a platform independent whitelist for the CPPLINT_DIRS.
860fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org  whitelist_dirs = [input_api.os_path.join(*path.split('/'))
870fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org                    for path in CPPLINT_DIRS]
880fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org
8951198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  # Use the strictest verbosity level for cpplint.py (level 1) which is the
9051198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  # default when running cpplint.py from command line.
9151198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  # To make it possible to work with not-yet-converted code, we're only applying
922a45209a6d17e12419e13592eba786e7ba7b1425mflodman@webrtc.org  # it to new (or moved/renamed) files and files listed in LINT_FOLDERS.
9351198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  verbosity_level = 1
9451198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  files = []
9551198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  for f in input_api.AffectedSourceFiles(source_file_filter):
9657e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander    # Note that moved/renamed files also count as added.
970fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org    if f.Action() == 'A' or _IsLintWhitelisted(whitelist_dirs, f.LocalPath()):
9851198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      files.append(f.AbsoluteLocalPath())
992a45209a6d17e12419e13592eba786e7ba7b1425mflodman@webrtc.org
10051198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  for file_name in files:
10151198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org    cpplint.ProcessFile(file_name, verbosity_level)
10251198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org
10351198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  if cpplint._cpplint_state.error_count > 0:
10451198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org    if input_api.is_committing:
10551198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      # TODO(kjellander): Change back to PresubmitError below when we're
10651198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      # confident with the lint settings.
10751198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      res_type = output_api.PresubmitPromptWarning
10851198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org    else:
10951198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      res_type = output_api.PresubmitPromptWarning
11051198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org    result = [res_type('Changelist failed cpplint.py check.')]
11151198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org
11251198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  return result
11351198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org
11483fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.orgdef _CheckNoRtcBaseDeps(input_api, gyp_files, output_api):
11583fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org  pattern = input_api.re.compile(r"base.gyp:rtc_base\s*'")
11683fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org  violating_files = []
11783fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org  for f in gyp_files:
11836b0c1afae15e6cb47971ba81d1a8cf670045ccahenrike@webrtc.org    gyp_exceptions = (
11936b0c1afae15e6cb47971ba81d1a8cf670045ccahenrike@webrtc.org        'base_tests.gyp',
12036b0c1afae15e6cb47971ba81d1a8cf670045ccahenrike@webrtc.org        'desktop_capture.gypi',
12136b0c1afae15e6cb47971ba81d1a8cf670045ccahenrike@webrtc.org        'libjingle.gyp',
12228af64105b6dbe97e423e2f6cfde8e47a2df625ahenrike@webrtc.org        'libjingle_tests.gyp',
123e723728992de4626445fc7d3ca500cfea7c96890kjellander@webrtc.org        'p2p.gyp',
12436b0c1afae15e6cb47971ba81d1a8cf670045ccahenrike@webrtc.org        'sound.gyp',
12536b0c1afae15e6cb47971ba81d1a8cf670045ccahenrike@webrtc.org        'webrtc_test_common.gyp',
12636b0c1afae15e6cb47971ba81d1a8cf670045ccahenrike@webrtc.org        'webrtc_tests.gypi',
12736b0c1afae15e6cb47971ba81d1a8cf670045ccahenrike@webrtc.org    )
12836b0c1afae15e6cb47971ba81d1a8cf670045ccahenrike@webrtc.org    if f.LocalPath().endswith(gyp_exceptions):
12936b0c1afae15e6cb47971ba81d1a8cf670045ccahenrike@webrtc.org      continue
13083fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org    contents = input_api.ReadFile(f)
13183fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org    if pattern.search(contents):
13283fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org      violating_files.append(f)
13383fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org  if violating_files:
13483fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org    return [output_api.PresubmitError(
13583fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org        'Depending on rtc_base is not allowed. Change your dependency to '
13683fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org        'rtc_base_approved and possibly sanitize and move the desired source '
13783fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org        'file(s) to rtc_base_approved.\nChanged GYP files:',
13883fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org        items=violating_files)]
13983fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org  return []
140e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org
141f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.orgdef _CheckNoSourcesAboveGyp(input_api, gyp_files, output_api):
142f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org  # Disallow referencing source files with paths above the GYP file location.
143f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org  source_pattern = input_api.re.compile(r'sources.*?\[(.*?)\]',
144f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org                                        re.MULTILINE | re.DOTALL)
145a33f05e8d7f293b5984b3cd7695eadefd16dcabakjellander@webrtc.org  file_pattern = input_api.re.compile(r"'((\.\./.*?)|(<\(webrtc_root\).*?))'")
146f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org  violating_gyp_files = set()
147f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org  violating_source_entries = []
148f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org  for gyp_file in gyp_files:
149f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org    contents = input_api.ReadFile(gyp_file)
150f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org    for source_block_match in source_pattern.finditer(contents):
151c98f6f368a789955f4dec5a58e0163571021ac4akjellander@webrtc.org      # Find all source list entries starting with ../ in the source block
152c98f6f368a789955f4dec5a58e0163571021ac4akjellander@webrtc.org      # (exclude overrides entries).
153f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org      for file_list_match in file_pattern.finditer(source_block_match.group(0)):
154c98f6f368a789955f4dec5a58e0163571021ac4akjellander@webrtc.org        source_file = file_list_match.group(0)
155c98f6f368a789955f4dec5a58e0163571021ac4akjellander@webrtc.org        if 'overrides/' not in source_file:
156c98f6f368a789955f4dec5a58e0163571021ac4akjellander@webrtc.org          violating_source_entries.append(source_file)
157c98f6f368a789955f4dec5a58e0163571021ac4akjellander@webrtc.org          violating_gyp_files.add(gyp_file)
158f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org  if violating_gyp_files:
159f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org    return [output_api.PresubmitError(
160f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org        'Referencing source files above the directory of the GYP file is not '
161f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org        'allowed. Please introduce new GYP targets and/or GYP files in the '
162f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org        'proper location instead.\n'
163f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org        'Invalid source entries:\n'
164f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org        '%s\n'
165f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org        'Violating GYP files:' % '\n'.join(violating_source_entries),
166f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org        items=violating_gyp_files)]
167f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org  return []
168f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org
169e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.orgdef _CheckGypChanges(input_api, output_api):
170e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org  source_file_filter = lambda x: input_api.FilterSourceFile(
171e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org      x, white_list=(r'.+\.(gyp|gypi)$',))
172e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org
173e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org  gyp_files = []
174e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org  for f in input_api.AffectedSourceFiles(source_file_filter):
1753398a4ac15c9954f7d6355607897060236c3169bkjellander@webrtc.org    if f.LocalPath().startswith('webrtc'):
1763398a4ac15c9954f7d6355607897060236c3169bkjellander@webrtc.org      gyp_files.append(f)
177e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org
178e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org  result = []
179e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org  if gyp_files:
180e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org    result.append(output_api.PresubmitNotifyResult(
181e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org        'As you\'re changing GYP files: please make sure corresponding '
182e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org        'BUILD.gn files are also updated.\nChanged GYP files:',
183e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org        items=gyp_files))
18483fe69da95bde17a8a80c4e9f8aaa1fe1439be85henrike@webrtc.org    result.extend(_CheckNoRtcBaseDeps(input_api, gyp_files, output_api))
185f68ffca050438b8055b108228cca198686abc0c1kjellander@webrtc.org    result.extend(_CheckNoSourcesAboveGyp(input_api, gyp_files, output_api))
186e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org  return result
187e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org
1883bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.orgdef _CheckUnwantedDependencies(input_api, output_api):
1893bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  """Runs checkdeps on #include statements added in this
1903bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  change. Breaking - rules is an error, breaking ! rules is a
1913bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  warning.
1923bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  """
1933bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  # Copied from Chromium's src/PRESUBMIT.py.
1943bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org
1953bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  # We need to wait until we have an input_api object and use this
1963bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  # roundabout construct to import checkdeps because this file is
1973bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  # eval-ed and thus doesn't have __file__.
1983bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  original_sys_path = sys.path
1993bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  try:
200aefe61ae2a392122994739adac54017e33cab9bfkjellander@webrtc.org    checkdeps_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
201aefe61ae2a392122994739adac54017e33cab9bfkjellander@webrtc.org                                            'buildtools', 'checkdeps')
202aefe61ae2a392122994739adac54017e33cab9bfkjellander@webrtc.org    if not os.path.exists(checkdeps_path):
203aefe61ae2a392122994739adac54017e33cab9bfkjellander@webrtc.org      return [output_api.PresubmitError(
204aefe61ae2a392122994739adac54017e33cab9bfkjellander@webrtc.org          'Cannot find checkdeps at %s\nHave you run "gclient sync" to '
205aefe61ae2a392122994739adac54017e33cab9bfkjellander@webrtc.org          'download Chromium and setup the symlinks?' % checkdeps_path)]
206aefe61ae2a392122994739adac54017e33cab9bfkjellander@webrtc.org    sys.path.append(checkdeps_path)
2073bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    import checkdeps
2083bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    from cpp_checker import CppChecker
2093bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    from rules import Rule
2103bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  finally:
2113bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    # Restore sys.path to what it was before.
2123bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    sys.path = original_sys_path
2133bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org
2143bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  added_includes = []
2153bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  for f in input_api.AffectedFiles():
2163bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    if not CppChecker.IsCppFile(f.LocalPath()):
2173bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org      continue
2183bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org
21957e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander    changed_lines = [line for _, line in f.ChangedContents()]
2203bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    added_includes.append([f.LocalPath(), changed_lines])
2213bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org
2223bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
2233bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org
2243bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  error_descriptions = []
2253bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  warning_descriptions = []
2263bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
2273bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org      added_includes):
2283bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    description_with_path = '%s\n    %s' % (path, rule_description)
2293bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    if rule_type == Rule.DISALLOW:
2303bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org      error_descriptions.append(description_with_path)
2313bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    else:
2323bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org      warning_descriptions.append(description_with_path)
2333bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org
2343bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  results = []
2353bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  if error_descriptions:
2363bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    results.append(output_api.PresubmitError(
2373bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org        'You added one or more #includes that violate checkdeps rules.',
2383bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org        error_descriptions))
2393bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  if warning_descriptions:
2403bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org    results.append(output_api.PresubmitPromptOrNotify(
2413bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org        'You added one or more #includes of files that are temporarily\n'
2423bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org        'allowed but being removed. Can you avoid introducing the\n'
2433bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org        '#include? See relevant DEPS file(s) for details and contacts.',
2443bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org        warning_descriptions))
2453bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  return results
2463bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org
247e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org
2488d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellanderdef _RunPythonTests(input_api, output_api):
2498d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander  def join(*args):
2508d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander    return input_api.os_path.join(input_api.PresubmitLocalPath(), *args)
2518d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander
2528d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander  test_directories = [
2538d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander    join('tools', 'autoroller', 'unittests'),
2548d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander  ]
2558d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander
2568d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander  tests = []
2578d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander  for directory in test_directories:
2588d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander    tests.extend(
2598d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander      input_api.canned_checks.GetUnitTestsInDirectory(
2608d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander          input_api,
2618d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander          output_api,
2628d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander          directory,
2638d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander          whitelist=[r'.+_test\.py$']))
2648d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander  return input_api.RunTests(tests, parallel=True)
2658d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander
2668d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander
26753df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.orgdef _CommonChecks(input_api, output_api):
26853df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org  """Checks common to both upload and commit."""
269da159d6be61ae8041ab265092c2d6ba0ca7b64f5niklase@google.com  results = []
2700fcaf99b716c71e721db25f37f62dabf5dcbe69akjellander@webrtc.org  results.extend(_CheckApprovedFilesLintClean(input_api, output_api))
2715d37139374178479c16956a2a4eefd231206c2a1phoglund@webrtc.org  results.extend(input_api.canned_checks.RunPylint(input_api, output_api,
2725d37139374178479c16956a2a4eefd231206c2a1phoglund@webrtc.org      black_list=(r'^.*gviz_api\.py$',
2735d37139374178479c16956a2a4eefd231206c2a1phoglund@webrtc.org                  r'^.*gaeunit\.py$',
27433584f942c6e1723918d9d2b76f429ab8396751efischman@webrtc.org                  # Embedded shell-script fakes out pylint.
27514771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^build[\\\/].*\.py$',
27614771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^buildtools[\\\/].*\.py$',
27714771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^chromium[\\\/].*\.py$',
27814771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^google_apis[\\\/].*\.py$',
27914771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^net.*[\\\/].*\.py$',
28014771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^out.*[\\\/].*\.py$',
28114771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^testing[\\\/].*\.py$',
28214771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^third_party[\\\/].*\.py$',
28314771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]find_depot_tools.py$',
28414771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]clang[\\\/].*\.py$',
28514771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]generate_library_loader[\\\/].*\.py$',
28614771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]gn[\\\/].*\.py$',
28714771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]gyp[\\\/].*\.py$',
288d6d27e7340bca1598973e2197cf08d79ce9aeb04Henrik Kjellander                  r'^tools[\\\/]isolate_driver.py$',
28914771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]protoc_wrapper[\\\/].*\.py$',
29014771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]python[\\\/].*\.py$',
29114771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]python_charts[\\\/]data[\\\/].*\.py$',
29214771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]refactoring[\\\/].*\.py$',
29314771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]swarming_client[\\\/].*\.py$',
29414771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]vim[\\\/].*\.py$',
2955d37139374178479c16956a2a4eefd231206c2a1phoglund@webrtc.org                  # TODO(phoglund): should arguably be checked.
29614771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]valgrind-webrtc[\\\/].*\.py$',
29714771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]valgrind[\\\/].*\.py$',
29814771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^tools[\\\/]win[\\\/].*\.py$',
29914771ac6bfe0c66134425b99212f443f03231229Henrik Kjellander                  r'^xcodebuild.*[\\\/].*\.py$',),
3005d37139374178479c16956a2a4eefd231206c2a1phoglund@webrtc.org      disabled_warnings=['F0401',  # Failed to import x
3015d37139374178479c16956a2a4eefd231206c2a1phoglund@webrtc.org                         'E0611',  # No package y in x
3025d37139374178479c16956a2a4eefd231206c2a1phoglund@webrtc.org                         'W0232',  # Class has no __init__ method
30357e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander                        ],
30457e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander      pylintrc='pylintrc'))
30557e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander  # WebRTC can't use the presubmit_canned_checks.PanProjectChecks function since
30657e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander  # we need to have different license checks in talk/ and webrtc/ directories.
30757e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander  # Instead, hand-picked checks are included below.
308632246792fb208280a048fb2497a309c5a4d3690Henrik Kjellander
309632246792fb208280a048fb2497a309c5a4d3690Henrik Kjellander  # Skip long-lines check for DEPS, GN and GYP files.
310632246792fb208280a048fb2497a309c5a4d3690Henrik Kjellander  long_lines_sources = lambda x: input_api.FilterSourceFile(x,
311632246792fb208280a048fb2497a309c5a4d3690Henrik Kjellander      black_list=(r'.+\.gyp$', r'.+\.gypi$', r'.+\.gn$', r'.+\.gni$', 'DEPS'))
3122442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org  results.extend(input_api.canned_checks.CheckLongLines(
313632246792fb208280a048fb2497a309c5a4d3690Henrik Kjellander      input_api, output_api, maxlen=80, source_file_filter=long_lines_sources))
3142442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org  results.extend(input_api.canned_checks.CheckChangeHasNoTabs(
3152442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org      input_api, output_api))
31653df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org  results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
31753df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org      input_api, output_api))
31853df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org  results.extend(input_api.canned_checks.CheckChangeTodoHasOwner(
31953df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org      input_api, output_api))
32051198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
32151198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  results.extend(_CheckNoFRIEND_TEST(input_api, output_api))
322e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org  results.extend(_CheckGypChanges(input_api, output_api))
3233bd4156d75b12c084026e8e31c12fd4b982374d3kjellander@webrtc.org  results.extend(_CheckUnwantedDependencies(input_api, output_api))
3248d3ad82d30f3634c49af07dad210449721b9d3d1Henrik Kjellander  results.extend(_RunPythonTests(input_api, output_api))
32553df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org  return results
326da159d6be61ae8041ab265092c2d6ba0ca7b64f5niklase@google.com
327e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org
32853df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.orgdef CheckChangeOnUpload(input_api, output_api):
32953df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org  results = []
33053df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org  results.extend(_CommonChecks(input_api, output_api))
33157e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander  results.extend(
33257e5fd2e604ff7e60425c3f7654b40da03fc763cHenrik Kjellander      input_api.canned_checks.CheckGNFormatted(input_api, output_api))
3332442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.org  return results
334da159d6be61ae8041ab265092c2d6ba0ca7b64f5niklase@google.com
335e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org
3362442de1351a8d9bee0912a09317122bb5bdb08bcandrew@webrtc.orgdef CheckChangeOnCommit(input_api, output_api):
3371198db9dd6017a286590ce3a7095b1deda7b94a9niklase@google.com  results = []
33853df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org  results.extend(_CommonChecks(input_api, output_api))
3391198db9dd6017a286590ce3a7095b1deda7b94a9niklase@google.com  results.extend(input_api.canned_checks.CheckOwners(input_api, output_api))
34053df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org  results.extend(input_api.canned_checks.CheckChangeWasUploaded(
34153df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org      input_api, output_api))
34253df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org  results.extend(input_api.canned_checks.CheckChangeHasDescription(
34353df136240bc78e8054085a2ef25c4240530a745andrew@webrtc.org      input_api, output_api))
34451198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  results.extend(input_api.canned_checks.CheckChangeHasBugField(
34551198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      input_api, output_api))
34651198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org  results.extend(input_api.canned_checks.CheckChangeHasTestField(
34751198f1c683cff50986fd043dc2185bb336fed99kjellander@webrtc.org      input_api, output_api))
34812cb88cab9f3a1b4dbb60bebc4fc4fe6c705306ekjellander@webrtc.org  results.extend(input_api.canned_checks.CheckTreeIsOpen(
34912cb88cab9f3a1b4dbb60bebc4fc4fe6c705306ekjellander@webrtc.org      input_api, output_api,
35012cb88cab9f3a1b4dbb60bebc4fc4fe6c705306ekjellander@webrtc.org      json_url='http://webrtc-status.appspot.com/current?format=json'))
3511198db9dd6017a286590ce3a7095b1deda7b94a9niklase@google.com  return results
3528575980e16b917b5d94e670a9c6da9029615b575kjellander@webrtc.org
353e415864a326ce48ff2d41d4c9a3faed26c033450kjellander@webrtc.org
3548575980e16b917b5d94e670a9c6da9029615b575kjellander@webrtc.org# pylint: disable=W0613
355c7b8b2f2a75f0620a978f3e7eff057780d49ed5ckjellander@webrtc.orgdef GetPreferredTryMasters(project, change):
356986ee082b628ffd3a90fbbe4b933a312489921e0kjellander  cq_config_path = os.path.join(
35704465d286e6a1a643c88fabddd44eb870f906c38tandrii      change.RepositoryRoot(), 'infra', 'config', 'cq.cfg')
358986ee082b628ffd3a90fbbe4b933a312489921e0kjellander  # commit_queue.py below is a script in depot_tools directory, which has a
359986ee082b628ffd3a90fbbe4b933a312489921e0kjellander  # 'builders' command to retrieve a list of CQ builders from the CQ config.
360986ee082b628ffd3a90fbbe4b933a312489921e0kjellander  is_win = platform.system() == 'Windows'
361986ee082b628ffd3a90fbbe4b933a312489921e0kjellander  masters = json.loads(subprocess.check_output(
362986ee082b628ffd3a90fbbe4b933a312489921e0kjellander      ['commit_queue', 'builders', cq_config_path], shell=is_win))
363986ee082b628ffd3a90fbbe4b933a312489921e0kjellander
364986ee082b628ffd3a90fbbe4b933a312489921e0kjellander  try_config = {}
365986ee082b628ffd3a90fbbe4b933a312489921e0kjellander  for master in masters:
366986ee082b628ffd3a90fbbe4b933a312489921e0kjellander    try_config.setdefault(master, {})
367986ee082b628ffd3a90fbbe4b933a312489921e0kjellander    for builder in masters[master]:
368986ee082b628ffd3a90fbbe4b933a312489921e0kjellander      if 'presubmit' in builder:
369986ee082b628ffd3a90fbbe4b933a312489921e0kjellander        # Do not trigger presubmit builders, since they're likely to fail
370986ee082b628ffd3a90fbbe4b933a312489921e0kjellander        # (e.g. OWNERS checks before finished code review), and we're running
371986ee082b628ffd3a90fbbe4b933a312489921e0kjellander        # local presubmit anyway.
372986ee082b628ffd3a90fbbe4b933a312489921e0kjellander        pass
373986ee082b628ffd3a90fbbe4b933a312489921e0kjellander      else:
374986ee082b628ffd3a90fbbe4b933a312489921e0kjellander        try_config[master][builder] = ['defaulttests']
375986ee082b628ffd3a90fbbe4b933a312489921e0kjellander
376986ee082b628ffd3a90fbbe4b933a312489921e0kjellander  return try_config
377