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