# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. # # Use of this source code is governed by a BSD-style license # that can be found in the LICENSE file in the root of the source # tree. An additional intellectual property rights grant can be found # in the file PATENTS. All contributing project authors may # be found in the AUTHORS file in the root of the source tree. import os.path # All folders in LINT_FOLDERS will be scanned by cpplint by the presubmit # script. Note that subfolders are not included. LINT_FOLDERS = ['src/video_engine'] def _LicenseHeader(input_api): """Returns the license header regexp.""" # Accept any year number from 2011 to the current year current_year = int(input_api.time.strftime('%Y')) allowed_years = (str(s) for s in reversed(xrange(2011, current_year + 1))) years_re = '(' + '|'.join(allowed_years) + ')' license_header = ( r'.*? Copyright \(c\) %(year)s The WebRTC project authors\. ' r'All Rights Reserved\.\n' r'.*?\n' r'.*? Use of this source code is governed by a BSD-style license\n' r'.*? that can be found in the LICENSE file in the root of the source\n' r'.*? tree\. An additional intellectual property rights grant can be ' r'found\n' r'.*? in the file PATENTS\. All contributing project authors may\n' r'.*? be found in the AUTHORS file in the root of the source tree\.\n' ) % { 'year': years_re, } return license_header def _CheckNoIOStreamInHeaders(input_api, output_api): """Checks to make sure no .h files include .""" files = [] pattern = input_api.re.compile(r'^#include\s*', input_api.re.MULTILINE) for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): if not f.LocalPath().endswith('.h'): continue contents = input_api.ReadFile(f) if pattern.search(contents): files.append(f) if len(files): return [ output_api.PresubmitError( 'Do not #include in header files, since it inserts static ' + 'initialization into every file including the header. Instead, ' + '#include . See http://crbug.com/94794', files) ] return [] def _CheckNoFRIEND_TEST(input_api, output_api): """Make sure that gtest's FRIEND_TEST() macro is not used, the FRIEND_TEST_ALL_PREFIXES() macro from testsupport/gtest_prod_util.h should be used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes.""" problems = [] file_filter = lambda f: f.LocalPath().endswith(('.cc', '.h')) for f in input_api.AffectedFiles(file_filter=file_filter): for line_num, line in f.ChangedContents(): if 'FRIEND_TEST(' in line: problems.append(' %s:%d' % (f.LocalPath(), line_num)) if not problems: return [] return [output_api.PresubmitPromptWarning('WebRTC\'s code should not use ' 'gtest\'s FRIEND_TEST() macro. Include testsupport/gtest_prod_util.h and ' 'use FRIEND_TEST_ALL_PREFIXES() instead.\n' + '\n'.join(problems))] def _IsLintWhitelisted(file_name): """ Checks if a file is whitelisted for lint check.""" # TODO(mflodman) Include subfolders in the check. return (os.path.dirname(file_name) in LINT_FOLDERS) def _CheckApprovedFilesLintClean(input_api, output_api, source_file_filter=None): """Checks that all new or whitelisted .cc and .h files pass cpplint.py. This check is based on _CheckChangeLintsClean in depot_tools/presubmit_canned_checks.py but has less filters and only checks added files.""" result = [] # Initialize cpplint. import cpplint # Access to a protected member _XX of a client class # pylint: disable=W0212 cpplint._cpplint_state.ResetErrorCounts() # Justifications for each filter: # # - build/header_guard : WebRTC coding style says they should be prefixed # with WEBRTC_, which is not possible to configure in # cpplint.py. cpplint._SetFilters('-build/header_guard') # Use the strictest verbosity level for cpplint.py (level 1) which is the # default when running cpplint.py from command line. # To make it possible to work with not-yet-converted code, we're only applying # it to new (or moved/renamed) files and files listed in LINT_FOLDERS. verbosity_level = 1 files = [] for f in input_api.AffectedSourceFiles(source_file_filter): # Note that moved/renamed files also count as added for svn. if (f.Action() == 'A' or _IsLintWhitelisted(f.LocalPath())): files.append(f.AbsoluteLocalPath()) for file_name in files: cpplint.ProcessFile(file_name, verbosity_level) if cpplint._cpplint_state.error_count > 0: if input_api.is_committing: # TODO(kjellander): Change back to PresubmitError below when we're # confident with the lint settings. res_type = output_api.PresubmitPromptWarning else: res_type = output_api.PresubmitPromptWarning result = [res_type('Changelist failed cpplint.py check.')] return result def _CommonChecks(input_api, output_api): """Checks common to both upload and commit.""" # TODO(kjellander): Use presubmit_canned_checks.PanProjectChecks too. results = [] results.extend(input_api.canned_checks.CheckLongLines( input_api, output_api)) results.extend(input_api.canned_checks.CheckChangeHasNoTabs( input_api, output_api)) results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace( input_api, output_api)) results.extend(input_api.canned_checks.CheckChangeTodoHasOwner( input_api, output_api)) results.extend(_CheckApprovedFilesLintClean(input_api, output_api)) results.extend(input_api.canned_checks.CheckLicense( input_api, output_api, _LicenseHeader(input_api))) results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) results.extend(_CheckNoFRIEND_TEST(input_api, output_api)) return results def CheckChangeOnUpload(input_api, output_api): results = [] results.extend(_CommonChecks(input_api, output_api)) return results def CheckChangeOnCommit(input_api, output_api): results = [] results.extend(_CommonChecks(input_api, output_api)) results.extend(input_api.canned_checks.CheckOwners(input_api, output_api)) results.extend(input_api.canned_checks.CheckChangeWasUploaded( input_api, output_api)) results.extend(input_api.canned_checks.CheckChangeHasDescription( input_api, output_api)) results.extend(input_api.canned_checks.CheckChangeHasBugField( input_api, output_api)) results.extend(input_api.canned_checks.CheckChangeHasTestField( input_api, output_api)) return results