1# Copyright 2012 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""Chromium presubmit script for src/base. 6 7See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts 8for more details on the presubmit API built into depot_tools. 9""" 10 11 12USE_PYTHON3 = True 13 14 15def CheckChangeLintsClean(input_api, output_api): 16 """Makes sure that the code is cpplint clean.""" 17 # lint_filters=[] stops the OFF_BY_DEFAULT_LINT_FILTERS from being disabled, 18 # finding many more issues. verbose_level=1 finds a small number of additional 19 # issues. 20 # The only valid extensions for cpplint are .cc, .h, .cpp, .cu, and .ch. 21 # Only process those extensions which are used in Chromium, in directories 22 # that currently lint clean. 23 CLEAN_CPP_FILES_ONLY = (r'base/win/.*\.(cc|h)$', ) 24 source_file_filter = lambda x: input_api.FilterSourceFile( 25 x, 26 files_to_check=CLEAN_CPP_FILES_ONLY, 27 files_to_skip=input_api.DEFAULT_FILES_TO_SKIP) 28 return input_api.canned_checks.CheckChangeLintsClean( 29 input_api, output_api, source_file_filter=source_file_filter, 30 lint_filters=[], verbose_level=1) 31 32 33def _CheckNoInterfacesInBase(input_api, output_api): 34 """Checks to make sure no files in libbase.a have |@interface|.""" 35 pattern = input_api.re.compile(r'^\s*@interface', input_api.re.MULTILINE) 36 files = [] 37 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): 38 if (f.LocalPath().startswith('base/') and 39 not "/ios/" in f.LocalPath() and 40 not "/test/" in f.LocalPath() and 41 not f.LocalPath().endswith('.java') and 42 not f.LocalPath().endswith('_unittest.mm') and 43 not f.LocalPath().endswith('mac/sdk_forward_declarations.h')): 44 contents = input_api.ReadFile(f) 45 if pattern.search(contents): 46 files.append(f) 47 48 if len(files): 49 return [ output_api.PresubmitError( 50 'Objective-C interfaces or categories are forbidden in libbase. ' + 51 'See http://groups.google.com/a/chromium.org/group/chromium-dev/' + 52 'browse_thread/thread/efb28c10435987fd', 53 files) ] 54 return [] 55 56 57def _FindLocations(input_api, search_regexes, files_to_check, files_to_skip): 58 """Returns locations matching one of the search_regexes.""" 59 def FilterFile(affected_file): 60 return input_api.FilterSourceFile( 61 affected_file, 62 files_to_check=files_to_check, 63 files_to_skip=files_to_skip) 64 65 no_presubmit = r"// no-presubmit-check" 66 locations = [] 67 for f in input_api.AffectedSourceFiles(FilterFile): 68 for line_num, line in f.ChangedContents(): 69 for search_regex in search_regexes: 70 if (input_api.re.search(search_regex, line) and 71 not input_api.re.search(no_presubmit, line)): 72 locations.append(" %s:%d" % (f.LocalPath(), line_num)) 73 break 74 return locations 75 76 77def _CheckNoTraceEventInclude(input_api, output_api): 78 """Verify that //base includes base_tracing.h instead of trace event headers. 79 80 Checks that files outside trace event implementation include the 81 base_tracing.h header instead of specific trace event implementation headers 82 to maintain compatibility with the gn flag "enable_base_tracing = false". 83 """ 84 discouraged_includes = [ 85 r'^#include "base/trace_event/(?!base_tracing\.h|base_tracing_forward\.h)', 86 r'^#include "third_party/perfetto/include/', 87 ] 88 89 files_to_check = [ 90 r".*\.(h|cc|mm)$", 91 ] 92 files_to_skip = [ 93 r".*/test/.*", 94 r".*/trace_event/.*", 95 r".*/tracing/.*", 96 ] 97 98 locations = _FindLocations(input_api, discouraged_includes, files_to_check, 99 files_to_skip) 100 if locations: 101 return [ output_api.PresubmitError( 102 'Base code should include "base/trace_event/base_tracing.h" instead\n' + 103 'of trace_event implementation headers. If you need to include an\n' + 104 'implementation header, verify that "gn check" and base_unittests\n' + 105 'still pass with gn arg "enable_base_tracing = false" and add\n' + 106 '"// no-presubmit-check" after the include. \n' + 107 '\n'.join(locations)) ] 108 return [] 109 110 111def _WarnPbzeroIncludes(input_api, output_api): 112 """Warn to check enable_base_tracing=false when including a pbzero header. 113 114 Emits a warning when including a perfetto pbzero header, encouraging the 115 user to verify that //base still builds with enable_base_tracing=false. 116 """ 117 warn_includes = [ 118 r'^#include "third_party/perfetto/protos/', 119 r'^#include "base/tracing/protos/', 120 ] 121 122 files_to_check = [ 123 r".*\.(h|cc|mm)$", 124 ] 125 files_to_skip = [ 126 r".*/test/.*", 127 r".*/trace_event/.*", 128 r".*/tracing/.*", 129 ] 130 131 locations = _FindLocations(input_api, warn_includes, files_to_check, 132 files_to_skip) 133 if locations: 134 return [ output_api.PresubmitPromptWarning( 135 'Please verify that "gn check" and base_unittests still pass with\n' + 136 'gn arg "enable_base_tracing = false" when adding typed trace\n' + 137 'events to //base. You can use "#if BUILDFLAG(ENABLE_BASE_TRACING)"\n' + 138 'to exclude pbzero headers and anything not supported by\n' + 139 '//base/trace_event/trace_event_stub.h.\n' + 140 '\n'.join(locations)) ] 141 return [] 142 143 144def _CommonChecks(input_api, output_api): 145 """Checks common to both upload and commit.""" 146 results = [] 147 results.extend(_CheckNoInterfacesInBase(input_api, output_api)) 148 results.extend(_CheckNoTraceEventInclude(input_api, output_api)) 149 results.extend(_WarnPbzeroIncludes(input_api, output_api)) 150 results.extend(CheckChangeLintsClean(input_api, output_api)) 151 return results 152 153 154def CheckChangeOnUpload(input_api, output_api): 155 results = [] 156 results.extend(_CommonChecks(input_api, output_api)) 157 return results 158 159 160def CheckChangeOnCommit(input_api, output_api): 161 results = [] 162 results.extend(_CommonChecks(input_api, output_api)) 163 return results 164