PRESUBMIT.py revision f2e7bc6b6ac3ec7761a6a164a41c8d708bc1ef33
1# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2# 3# Use of this source code is governed by a BSD-style license 4# that can be found in the LICENSE file in the root of the source 5# tree. An additional intellectual property rights grant can be found 6# in the file PATENTS. All contributing project authors may 7# be found in the AUTHORS file in the root of the source tree. 8 9def _LicenseHeader(input_api): 10 """Returns the license header regexp.""" 11 # Accept any year number from 2011 to the current year 12 current_year = int(input_api.time.strftime('%Y')) 13 allowed_years = (str(s) for s in reversed(xrange(2011, current_year + 1))) 14 years_re = '(' + '|'.join(allowed_years) + ')' 15 license_header = ( 16 r'.*? Copyright \(c\) %(year)s The WebRTC project authors\. ' 17 r'All Rights Reserved\.\n' 18 r'.*?\n' 19 r'.*? Use of this source code is governed by a BSD-style license\n' 20 r'.*? that can be found in the LICENSE file in the root of the source\n' 21 r'.*? tree\. An additional intellectual property rights grant can be ' 22 r'found\n' 23 r'.*? in the file PATENTS\. All contributing project authors may\n' 24 r'.*? be found in the AUTHORS file in the root of the source tree\.\n' 25 ) % { 26 'year': years_re, 27 } 28 return license_header 29 30def _CheckNoIOStreamInHeaders(input_api, output_api): 31 """Checks to make sure no .h files include <iostream>.""" 32 files = [] 33 pattern = input_api.re.compile(r'^#include\s*<iostream>', 34 input_api.re.MULTILINE) 35 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): 36 if not f.LocalPath().endswith('.h'): 37 continue 38 contents = input_api.ReadFile(f) 39 if pattern.search(contents): 40 files.append(f) 41 42 if len(files): 43 return [ output_api.PresubmitError( 44 'Do not #include <iostream> in header files, since it inserts static ' + 45 'initialization into every file including the header. Instead, ' + 46 '#include <ostream>. See http://crbug.com/94794', 47 files) ] 48 return [] 49 50def _CheckNoFRIEND_TEST(input_api, output_api): 51 """Make sure that gtest's FRIEND_TEST() macro is not used, the 52 FRIEND_TEST_ALL_PREFIXES() macro from testsupport/gtest_prod_util.h should be 53 used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes.""" 54 problems = [] 55 56 file_filter = lambda f: f.LocalPath().endswith(('.cc', '.h')) 57 for f in input_api.AffectedFiles(file_filter=file_filter): 58 for line_num, line in f.ChangedContents(): 59 if 'FRIEND_TEST(' in line: 60 problems.append(' %s:%d' % (f.LocalPath(), line_num)) 61 62 if not problems: 63 return [] 64 return [output_api.PresubmitPromptWarning('WebRTC\'s code should not use ' 65 'gtest\'s FRIEND_TEST() macro. Include testsupport/gtest_prod_util.h and ' 66 'use FRIEND_TEST_ALL_PREFIXES() instead.\n' + '\n'.join(problems))] 67 68def _CheckApprovedFilesLintClean(input_api, output_api, 69 source_file_filter=None): 70 """Checks that all new or whitelisted .cc and .h files pass cpplint.py. 71 This check is based on _CheckChangeLintsClean in 72 depot_tools/presubmit_canned_checks.py but has less filters and only checks 73 added files.""" 74 result = [] 75 76 # Initialize cpplint. 77 import cpplint 78 # Access to a protected member _XX of a client class 79 # pylint: disable=W0212 80 cpplint._cpplint_state.ResetErrorCounts() 81 82 # Justifications for each filter: 83 # 84 # - build/header_guard : WebRTC coding style says they should be prefixed 85 # with WEBRTC_, which is not possible to configure in 86 # cpplint.py. 87 cpplint._SetFilters('-build/header_guard') 88 89 # Use the strictest verbosity level for cpplint.py (level 1) which is the 90 # default when running cpplint.py from command line. 91 # To make it possible to work with not-yet-converted code, we're only applying 92 # it to new (or moved/renamed) files and files listed in LINT_FOLDERS. 93 verbosity_level = 1 94 files = [] 95 for f in input_api.AffectedSourceFiles(source_file_filter): 96 # Note that moved/renamed files also count as added for svn. 97 if (f.Action() == 'A'): 98 files.append(f.AbsoluteLocalPath()) 99 100 for file_name in files: 101 cpplint.ProcessFile(file_name, verbosity_level) 102 103 if cpplint._cpplint_state.error_count > 0: 104 if input_api.is_committing: 105 # TODO(kjellander): Change back to PresubmitError below when we're 106 # confident with the lint settings. 107 res_type = output_api.PresubmitPromptWarning 108 else: 109 res_type = output_api.PresubmitPromptWarning 110 result = [res_type('Changelist failed cpplint.py check.')] 111 112 return result 113 114def _CommonChecks(input_api, output_api): 115 """Checks common to both upload and commit.""" 116 # TODO(kjellander): Use presubmit_canned_checks.PanProjectChecks too. 117 results = [] 118 results.extend(input_api.canned_checks.RunPylint(input_api, output_api, 119 black_list=(r'^.*gviz_api\.py$', 120 r'^.*gaeunit\.py$', 121 r'^third_party/.*\.py$', 122 r'^testing/.*\.py$', 123 r'^tools/gyp/.*\.py$', 124 r'^tools/perf_expectations/.*\.py$', 125 r'^tools/python/.*\.py$', 126 r'^tools/python_charts/data/.*\.py$', 127 r'^tools/refactoring.*\.py$', 128 # TODO(phoglund): should arguably be checked. 129 r'^tools/valgrind-webrtc/.*\.py$', 130 r'^tools/valgrind/.*\.py$', 131 # TODO(phoglund): should arguably be checked. 132 r'^webrtc/build/.*\.py$', 133 r'^build/.*\.py$', 134 r'^out/.*\.py$',), 135 disabled_warnings=['F0401', # Failed to import x 136 'E0611', # No package y in x 137 'W0232', # Class has no __init__ method 138 ])) 139 results.extend(input_api.canned_checks.CheckLongLines( 140 input_api, output_api, maxlen=80)) 141 results.extend(input_api.canned_checks.CheckChangeHasNoTabs( 142 input_api, output_api)) 143 results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace( 144 input_api, output_api)) 145 results.extend(input_api.canned_checks.CheckChangeTodoHasOwner( 146 input_api, output_api)) 147 results.extend(_CheckApprovedFilesLintClean(input_api, output_api)) 148 results.extend(input_api.canned_checks.CheckLicense( 149 input_api, output_api, _LicenseHeader(input_api))) 150 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) 151 results.extend(_CheckNoFRIEND_TEST(input_api, output_api)) 152 return results 153 154def CheckChangeOnUpload(input_api, output_api): 155 results = [] 156 results.extend(_CommonChecks(input_api, output_api)) 157 return results 158 159def CheckChangeOnCommit(input_api, output_api): 160 results = [] 161 results.extend(_CommonChecks(input_api, output_api)) 162 results.extend(input_api.canned_checks.CheckOwners(input_api, output_api)) 163 results.extend(input_api.canned_checks.CheckChangeWasUploaded( 164 input_api, output_api)) 165 results.extend(input_api.canned_checks.CheckChangeHasDescription( 166 input_api, output_api)) 167 results.extend(input_api.canned_checks.CheckChangeHasBugField( 168 input_api, output_api)) 169 results.extend(input_api.canned_checks.CheckChangeHasTestField( 170 input_api, output_api)) 171 return results 172 173