1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*8975f5c5SAndroid Build Coastguard Worker# 3*8975f5c5SAndroid Build Coastguard Worker# Copyright 2013 The Chromium Authors 4*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 5*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file. 6*8975f5c5SAndroid Build Coastguard Worker"""Runs Android's lint tool.""" 7*8975f5c5SAndroid Build Coastguard Worker 8*8975f5c5SAndroid Build Coastguard Workerimport argparse 9*8975f5c5SAndroid Build Coastguard Workerimport logging 10*8975f5c5SAndroid Build Coastguard Workerimport os 11*8975f5c5SAndroid Build Coastguard Workerimport shutil 12*8975f5c5SAndroid Build Coastguard Workerimport sys 13*8975f5c5SAndroid Build Coastguard Workerimport time 14*8975f5c5SAndroid Build Coastguard Workerfrom xml.dom import minidom 15*8975f5c5SAndroid Build Coastguard Workerfrom xml.etree import ElementTree 16*8975f5c5SAndroid Build Coastguard Worker 17*8975f5c5SAndroid Build Coastguard Workerfrom util import build_utils 18*8975f5c5SAndroid Build Coastguard Workerfrom util import manifest_utils 19*8975f5c5SAndroid Build Coastguard Workerfrom util import server_utils 20*8975f5c5SAndroid Build Coastguard Workerimport action_helpers # build_utils adds //build to sys.path. 21*8975f5c5SAndroid Build Coastguard Worker 22*8975f5c5SAndroid Build Coastguard Worker_LINT_MD_URL = 'https://chromium.googlesource.com/chromium/src/+/main/build/android/docs/lint.md' # pylint: disable=line-too-long 23*8975f5c5SAndroid Build Coastguard Worker 24*8975f5c5SAndroid Build Coastguard Worker# These checks are not useful for chromium. 25*8975f5c5SAndroid Build Coastguard Worker_DISABLED_ALWAYS = [ 26*8975f5c5SAndroid Build Coastguard Worker "AppCompatResource", # Lint does not correctly detect our appcompat lib. 27*8975f5c5SAndroid Build Coastguard Worker "AppLinkUrlError", # As a browser, we have intent filters without a host. 28*8975f5c5SAndroid Build Coastguard Worker "Assert", # R8 --force-enable-assertions is used to enable java asserts. 29*8975f5c5SAndroid Build Coastguard Worker "InflateParams", # Null is ok when inflating views for dialogs. 30*8975f5c5SAndroid Build Coastguard Worker "InlinedApi", # Constants are copied so they are always available. 31*8975f5c5SAndroid Build Coastguard Worker "LintBaseline", # Don't warn about using baseline.xml files. 32*8975f5c5SAndroid Build Coastguard Worker "LintBaselineFixed", # We dont care if baseline.xml has unused entries. 33*8975f5c5SAndroid Build Coastguard Worker "MissingInflatedId", # False positives https://crbug.com/1394222 34*8975f5c5SAndroid Build Coastguard Worker "MissingApplicationIcon", # False positive for non-production targets. 35*8975f5c5SAndroid Build Coastguard Worker "MissingVersion", # We set versions via aapt2, which runs after lint. 36*8975f5c5SAndroid Build Coastguard Worker "NetworkSecurityConfig", # Breaks on library certificates b/269783280. 37*8975f5c5SAndroid Build Coastguard Worker "ObsoleteLintCustomCheck", # We have no control over custom lint checks. 38*8975f5c5SAndroid Build Coastguard Worker "OldTargetApi", # We sometimes need targetSdkVersion to not be latest. 39*8975f5c5SAndroid Build Coastguard Worker "StringFormatCount", # Has false-positives. 40*8975f5c5SAndroid Build Coastguard Worker "SwitchIntDef", # Many C++ enums are not used at all in java. 41*8975f5c5SAndroid Build Coastguard Worker "Typos", # Strings are committed in English first and later translated. 42*8975f5c5SAndroid Build Coastguard Worker "VisibleForTests", # Does not recognize "ForTesting" methods. 43*8975f5c5SAndroid Build Coastguard Worker "UniqueConstants", # Chromium enums allow aliases. 44*8975f5c5SAndroid Build Coastguard Worker "UnusedAttribute", # Chromium apks have various minSdkVersion values. 45*8975f5c5SAndroid Build Coastguard Worker "NullSafeMutableLiveData", # Broken. See b/370586513. 46*8975f5c5SAndroid Build Coastguard Worker] 47*8975f5c5SAndroid Build Coastguard Worker 48*8975f5c5SAndroid Build Coastguard Worker_RES_ZIP_DIR = 'RESZIPS' 49*8975f5c5SAndroid Build Coastguard Worker_SRCJAR_DIR = 'SRCJARS' 50*8975f5c5SAndroid Build Coastguard Worker_AAR_DIR = 'AARS' 51*8975f5c5SAndroid Build Coastguard Worker 52*8975f5c5SAndroid Build Coastguard Worker 53*8975f5c5SAndroid Build Coastguard Workerdef _SrcRelative(path): 54*8975f5c5SAndroid Build Coastguard Worker """Returns relative path to top-level src dir.""" 55*8975f5c5SAndroid Build Coastguard Worker return os.path.relpath(path, build_utils.DIR_SOURCE_ROOT) 56*8975f5c5SAndroid Build Coastguard Worker 57*8975f5c5SAndroid Build Coastguard Worker 58*8975f5c5SAndroid Build Coastguard Workerdef _GenerateProjectFile(android_manifest, 59*8975f5c5SAndroid Build Coastguard Worker android_sdk_root, 60*8975f5c5SAndroid Build Coastguard Worker cache_dir, 61*8975f5c5SAndroid Build Coastguard Worker partials_dir, 62*8975f5c5SAndroid Build Coastguard Worker sources=None, 63*8975f5c5SAndroid Build Coastguard Worker classpath=None, 64*8975f5c5SAndroid Build Coastguard Worker srcjar_sources=None, 65*8975f5c5SAndroid Build Coastguard Worker resource_sources=None, 66*8975f5c5SAndroid Build Coastguard Worker custom_lint_jars=None, 67*8975f5c5SAndroid Build Coastguard Worker custom_annotation_zips=None, 68*8975f5c5SAndroid Build Coastguard Worker android_sdk_version=None, 69*8975f5c5SAndroid Build Coastguard Worker baseline_path=None): 70*8975f5c5SAndroid Build Coastguard Worker project = ElementTree.Element('project') 71*8975f5c5SAndroid Build Coastguard Worker root = ElementTree.SubElement(project, 'root') 72*8975f5c5SAndroid Build Coastguard Worker # Run lint from output directory: crbug.com/1115594 73*8975f5c5SAndroid Build Coastguard Worker root.set('dir', os.getcwd()) 74*8975f5c5SAndroid Build Coastguard Worker sdk = ElementTree.SubElement(project, 'sdk') 75*8975f5c5SAndroid Build Coastguard Worker # Lint requires that the sdk path be an absolute path. 76*8975f5c5SAndroid Build Coastguard Worker sdk.set('dir', os.path.abspath(android_sdk_root)) 77*8975f5c5SAndroid Build Coastguard Worker if baseline_path is not None: 78*8975f5c5SAndroid Build Coastguard Worker baseline = ElementTree.SubElement(project, 'baseline') 79*8975f5c5SAndroid Build Coastguard Worker baseline.set('file', baseline_path) 80*8975f5c5SAndroid Build Coastguard Worker cache = ElementTree.SubElement(project, 'cache') 81*8975f5c5SAndroid Build Coastguard Worker cache.set('dir', cache_dir) 82*8975f5c5SAndroid Build Coastguard Worker main_module = ElementTree.SubElement(project, 'module') 83*8975f5c5SAndroid Build Coastguard Worker main_module.set('name', 'main') 84*8975f5c5SAndroid Build Coastguard Worker main_module.set('android', 'true') 85*8975f5c5SAndroid Build Coastguard Worker main_module.set('library', 'false') 86*8975f5c5SAndroid Build Coastguard Worker # Required to make lint-resources.xml be written to a per-target path. 87*8975f5c5SAndroid Build Coastguard Worker # https://crbug.com/1515070 and b/324598620 88*8975f5c5SAndroid Build Coastguard Worker main_module.set('partial-results-dir', partials_dir) 89*8975f5c5SAndroid Build Coastguard Worker if android_sdk_version: 90*8975f5c5SAndroid Build Coastguard Worker main_module.set('compile_sdk_version', android_sdk_version) 91*8975f5c5SAndroid Build Coastguard Worker manifest = ElementTree.SubElement(main_module, 'manifest') 92*8975f5c5SAndroid Build Coastguard Worker manifest.set('file', android_manifest) 93*8975f5c5SAndroid Build Coastguard Worker if srcjar_sources: 94*8975f5c5SAndroid Build Coastguard Worker for srcjar_file in srcjar_sources: 95*8975f5c5SAndroid Build Coastguard Worker src = ElementTree.SubElement(main_module, 'src') 96*8975f5c5SAndroid Build Coastguard Worker src.set('file', srcjar_file) 97*8975f5c5SAndroid Build Coastguard Worker # Cannot add generated="true" since then lint does not scan them, and 98*8975f5c5SAndroid Build Coastguard Worker # we get "UnusedResources" lint errors when resources are used only by 99*8975f5c5SAndroid Build Coastguard Worker # generated files. 100*8975f5c5SAndroid Build Coastguard Worker if sources: 101*8975f5c5SAndroid Build Coastguard Worker for source in sources: 102*8975f5c5SAndroid Build Coastguard Worker src = ElementTree.SubElement(main_module, 'src') 103*8975f5c5SAndroid Build Coastguard Worker src.set('file', source) 104*8975f5c5SAndroid Build Coastguard Worker # Cannot set test="true" since we sometimes put Test.java files beside 105*8975f5c5SAndroid Build Coastguard Worker # non-test files, which lint does not allow: 106*8975f5c5SAndroid Build Coastguard Worker # "Test sources cannot be in the same source root as production files" 107*8975f5c5SAndroid Build Coastguard Worker if classpath: 108*8975f5c5SAndroid Build Coastguard Worker for file_path in classpath: 109*8975f5c5SAndroid Build Coastguard Worker classpath_element = ElementTree.SubElement(main_module, 'classpath') 110*8975f5c5SAndroid Build Coastguard Worker classpath_element.set('file', file_path) 111*8975f5c5SAndroid Build Coastguard Worker if resource_sources: 112*8975f5c5SAndroid Build Coastguard Worker for resource_file in resource_sources: 113*8975f5c5SAndroid Build Coastguard Worker resource = ElementTree.SubElement(main_module, 'resource') 114*8975f5c5SAndroid Build Coastguard Worker resource.set('file', resource_file) 115*8975f5c5SAndroid Build Coastguard Worker if custom_lint_jars: 116*8975f5c5SAndroid Build Coastguard Worker for lint_jar in custom_lint_jars: 117*8975f5c5SAndroid Build Coastguard Worker lint = ElementTree.SubElement(main_module, 'lint-checks') 118*8975f5c5SAndroid Build Coastguard Worker lint.set('file', lint_jar) 119*8975f5c5SAndroid Build Coastguard Worker if custom_annotation_zips: 120*8975f5c5SAndroid Build Coastguard Worker for annotation_zip in custom_annotation_zips: 121*8975f5c5SAndroid Build Coastguard Worker annotation = ElementTree.SubElement(main_module, 'annotations') 122*8975f5c5SAndroid Build Coastguard Worker annotation.set('file', annotation_zip) 123*8975f5c5SAndroid Build Coastguard Worker return project 124*8975f5c5SAndroid Build Coastguard Worker 125*8975f5c5SAndroid Build Coastguard Worker 126*8975f5c5SAndroid Build Coastguard Workerdef _RetrieveBackportedMethods(backported_methods_path): 127*8975f5c5SAndroid Build Coastguard Worker with open(backported_methods_path) as f: 128*8975f5c5SAndroid Build Coastguard Worker methods = f.read().splitlines() 129*8975f5c5SAndroid Build Coastguard Worker # Methods look like: 130*8975f5c5SAndroid Build Coastguard Worker # java/util/Set#of(Ljava/lang/Object;)Ljava/util/Set; 131*8975f5c5SAndroid Build Coastguard Worker # But error message looks like: 132*8975f5c5SAndroid Build Coastguard Worker # Call requires API level R (current min is 21): java.util.Set#of [NewApi] 133*8975f5c5SAndroid Build Coastguard Worker methods = (m.replace('/', '\\.') for m in methods) 134*8975f5c5SAndroid Build Coastguard Worker methods = (m[:m.index('(')] for m in methods) 135*8975f5c5SAndroid Build Coastguard Worker return sorted(set(methods)) 136*8975f5c5SAndroid Build Coastguard Worker 137*8975f5c5SAndroid Build Coastguard Worker 138*8975f5c5SAndroid Build Coastguard Workerdef _GenerateConfigXmlTree(orig_config_path, backported_methods): 139*8975f5c5SAndroid Build Coastguard Worker if orig_config_path: 140*8975f5c5SAndroid Build Coastguard Worker root_node = ElementTree.parse(orig_config_path).getroot() 141*8975f5c5SAndroid Build Coastguard Worker else: 142*8975f5c5SAndroid Build Coastguard Worker root_node = ElementTree.fromstring('<lint/>') 143*8975f5c5SAndroid Build Coastguard Worker 144*8975f5c5SAndroid Build Coastguard Worker issue_node = ElementTree.SubElement(root_node, 'issue') 145*8975f5c5SAndroid Build Coastguard Worker issue_node.attrib['id'] = 'NewApi' 146*8975f5c5SAndroid Build Coastguard Worker ignore_node = ElementTree.SubElement(issue_node, 'ignore') 147*8975f5c5SAndroid Build Coastguard Worker ignore_node.attrib['regexp'] = '|'.join(backported_methods) 148*8975f5c5SAndroid Build Coastguard Worker return root_node 149*8975f5c5SAndroid Build Coastguard Worker 150*8975f5c5SAndroid Build Coastguard Worker 151*8975f5c5SAndroid Build Coastguard Workerdef _GenerateAndroidManifest(original_manifest_path, extra_manifest_paths, 152*8975f5c5SAndroid Build Coastguard Worker min_sdk_version, android_sdk_version): 153*8975f5c5SAndroid Build Coastguard Worker # Set minSdkVersion in the manifest to the correct value. 154*8975f5c5SAndroid Build Coastguard Worker doc, manifest, app_node = manifest_utils.ParseManifest(original_manifest_path) 155*8975f5c5SAndroid Build Coastguard Worker 156*8975f5c5SAndroid Build Coastguard Worker # TODO(crbug.com/40148088): Should this be done using manifest merging? 157*8975f5c5SAndroid Build Coastguard Worker # Add anything in the application node of the extra manifests to the main 158*8975f5c5SAndroid Build Coastguard Worker # manifest to prevent unused resource errors. 159*8975f5c5SAndroid Build Coastguard Worker for path in extra_manifest_paths: 160*8975f5c5SAndroid Build Coastguard Worker _, _, extra_app_node = manifest_utils.ParseManifest(path) 161*8975f5c5SAndroid Build Coastguard Worker for node in extra_app_node: 162*8975f5c5SAndroid Build Coastguard Worker app_node.append(node) 163*8975f5c5SAndroid Build Coastguard Worker 164*8975f5c5SAndroid Build Coastguard Worker uses_sdk = manifest.find('./uses-sdk') 165*8975f5c5SAndroid Build Coastguard Worker if uses_sdk is None: 166*8975f5c5SAndroid Build Coastguard Worker uses_sdk = ElementTree.Element('uses-sdk') 167*8975f5c5SAndroid Build Coastguard Worker manifest.insert(0, uses_sdk) 168*8975f5c5SAndroid Build Coastguard Worker uses_sdk.set('{%s}minSdkVersion' % manifest_utils.ANDROID_NAMESPACE, 169*8975f5c5SAndroid Build Coastguard Worker min_sdk_version) 170*8975f5c5SAndroid Build Coastguard Worker uses_sdk.set('{%s}targetSdkVersion' % manifest_utils.ANDROID_NAMESPACE, 171*8975f5c5SAndroid Build Coastguard Worker android_sdk_version) 172*8975f5c5SAndroid Build Coastguard Worker return doc 173*8975f5c5SAndroid Build Coastguard Worker 174*8975f5c5SAndroid Build Coastguard Worker 175*8975f5c5SAndroid Build Coastguard Workerdef _WriteXmlFile(root, path): 176*8975f5c5SAndroid Build Coastguard Worker logging.info('Writing xml file %s', path) 177*8975f5c5SAndroid Build Coastguard Worker build_utils.MakeDirectory(os.path.dirname(path)) 178*8975f5c5SAndroid Build Coastguard Worker with action_helpers.atomic_output(path) as f: 179*8975f5c5SAndroid Build Coastguard Worker # Although we can write it just with ElementTree.tostring, using minidom 180*8975f5c5SAndroid Build Coastguard Worker # makes it a lot easier to read as a human (also on code search). 181*8975f5c5SAndroid Build Coastguard Worker f.write( 182*8975f5c5SAndroid Build Coastguard Worker minidom.parseString(ElementTree.tostring( 183*8975f5c5SAndroid Build Coastguard Worker root, encoding='utf-8')).toprettyxml(indent=' ').encode('utf-8')) 184*8975f5c5SAndroid Build Coastguard Worker 185*8975f5c5SAndroid Build Coastguard Worker 186*8975f5c5SAndroid Build Coastguard Workerdef _RunLint(custom_lint_jar_path, 187*8975f5c5SAndroid Build Coastguard Worker lint_jar_path, 188*8975f5c5SAndroid Build Coastguard Worker backported_methods_path, 189*8975f5c5SAndroid Build Coastguard Worker config_path, 190*8975f5c5SAndroid Build Coastguard Worker manifest_path, 191*8975f5c5SAndroid Build Coastguard Worker extra_manifest_paths, 192*8975f5c5SAndroid Build Coastguard Worker sources, 193*8975f5c5SAndroid Build Coastguard Worker classpath, 194*8975f5c5SAndroid Build Coastguard Worker cache_dir, 195*8975f5c5SAndroid Build Coastguard Worker android_sdk_version, 196*8975f5c5SAndroid Build Coastguard Worker aars, 197*8975f5c5SAndroid Build Coastguard Worker srcjars, 198*8975f5c5SAndroid Build Coastguard Worker min_sdk_version, 199*8975f5c5SAndroid Build Coastguard Worker resource_sources, 200*8975f5c5SAndroid Build Coastguard Worker resource_zips, 201*8975f5c5SAndroid Build Coastguard Worker android_sdk_root, 202*8975f5c5SAndroid Build Coastguard Worker lint_gen_dir, 203*8975f5c5SAndroid Build Coastguard Worker baseline, 204*8975f5c5SAndroid Build Coastguard Worker create_cache, 205*8975f5c5SAndroid Build Coastguard Worker warnings_as_errors=False): 206*8975f5c5SAndroid Build Coastguard Worker logging.info('Lint starting') 207*8975f5c5SAndroid Build Coastguard Worker if not cache_dir: 208*8975f5c5SAndroid Build Coastguard Worker # Use per-target cache directory when --cache-dir is not used. 209*8975f5c5SAndroid Build Coastguard Worker cache_dir = os.path.join(lint_gen_dir, 'cache') 210*8975f5c5SAndroid Build Coastguard Worker # Lint complains if the directory does not exist. 211*8975f5c5SAndroid Build Coastguard Worker # When --create-cache is used, ninja will create this directory because the 212*8975f5c5SAndroid Build Coastguard Worker # stamp file is created within it. 213*8975f5c5SAndroid Build Coastguard Worker os.makedirs(cache_dir, exist_ok=True) 214*8975f5c5SAndroid Build Coastguard Worker 215*8975f5c5SAndroid Build Coastguard Worker if baseline and not os.path.exists(baseline): 216*8975f5c5SAndroid Build Coastguard Worker # Generating new baselines is only done locally, and requires more memory to 217*8975f5c5SAndroid Build Coastguard Worker # avoid OOMs. 218*8975f5c5SAndroid Build Coastguard Worker creating_baseline = True 219*8975f5c5SAndroid Build Coastguard Worker lint_xmx = '4G' 220*8975f5c5SAndroid Build Coastguard Worker else: 221*8975f5c5SAndroid Build Coastguard Worker creating_baseline = False 222*8975f5c5SAndroid Build Coastguard Worker lint_xmx = '3G' 223*8975f5c5SAndroid Build Coastguard Worker 224*8975f5c5SAndroid Build Coastguard Worker # Lint requires this directory to exist and be cleared. 225*8975f5c5SAndroid Build Coastguard Worker # See b/324598620 226*8975f5c5SAndroid Build Coastguard Worker partials_dir = os.path.join(lint_gen_dir, 'partials') 227*8975f5c5SAndroid Build Coastguard Worker shutil.rmtree(partials_dir, ignore_errors=True) 228*8975f5c5SAndroid Build Coastguard Worker os.makedirs(partials_dir) 229*8975f5c5SAndroid Build Coastguard Worker 230*8975f5c5SAndroid Build Coastguard Worker # All paths in lint are based off of relative paths from root with root as the 231*8975f5c5SAndroid Build Coastguard Worker # prefix. Path variable substitution is based off of prefix matching so custom 232*8975f5c5SAndroid Build Coastguard Worker # path variables need to match exactly in order to show up in baseline files. 233*8975f5c5SAndroid Build Coastguard Worker # e.g. lint_path=path/to/output/dir/../../file/in/src 234*8975f5c5SAndroid Build Coastguard Worker root_path = os.getcwd() # This is usually the output directory. 235*8975f5c5SAndroid Build Coastguard Worker pathvar_src = os.path.join( 236*8975f5c5SAndroid Build Coastguard Worker root_path, os.path.relpath(build_utils.DIR_SOURCE_ROOT, start=root_path)) 237*8975f5c5SAndroid Build Coastguard Worker 238*8975f5c5SAndroid Build Coastguard Worker cmd = build_utils.JavaCmd(xmx=lint_xmx) + [ 239*8975f5c5SAndroid Build Coastguard Worker '-cp', 240*8975f5c5SAndroid Build Coastguard Worker '{}:{}'.format(lint_jar_path, custom_lint_jar_path), 241*8975f5c5SAndroid Build Coastguard Worker 'org.chromium.build.CustomLint', 242*8975f5c5SAndroid Build Coastguard Worker '--sdk-home', 243*8975f5c5SAndroid Build Coastguard Worker android_sdk_root, 244*8975f5c5SAndroid Build Coastguard Worker '--jdk-home', 245*8975f5c5SAndroid Build Coastguard Worker build_utils.JAVA_HOME, 246*8975f5c5SAndroid Build Coastguard Worker '--path-variables', 247*8975f5c5SAndroid Build Coastguard Worker f'SRC={pathvar_src}', 248*8975f5c5SAndroid Build Coastguard Worker '--offline', 249*8975f5c5SAndroid Build Coastguard Worker '--quiet', # Silences lint's "." progress updates. 250*8975f5c5SAndroid Build Coastguard Worker '--stacktrace', # Prints full stacktraces for internal lint errors. 251*8975f5c5SAndroid Build Coastguard Worker ] 252*8975f5c5SAndroid Build Coastguard Worker 253*8975f5c5SAndroid Build Coastguard Worker # Only disable for real runs since otherwise you get UnknownIssueId warnings 254*8975f5c5SAndroid Build Coastguard Worker # when disabling custom lint checks since they are not passed during cache 255*8975f5c5SAndroid Build Coastguard Worker # creation. 256*8975f5c5SAndroid Build Coastguard Worker if not create_cache: 257*8975f5c5SAndroid Build Coastguard Worker cmd += [ 258*8975f5c5SAndroid Build Coastguard Worker '--disable', 259*8975f5c5SAndroid Build Coastguard Worker ','.join(_DISABLED_ALWAYS), 260*8975f5c5SAndroid Build Coastguard Worker ] 261*8975f5c5SAndroid Build Coastguard Worker 262*8975f5c5SAndroid Build Coastguard Worker if not manifest_path: 263*8975f5c5SAndroid Build Coastguard Worker manifest_path = os.path.join(build_utils.DIR_SOURCE_ROOT, 'build', 264*8975f5c5SAndroid Build Coastguard Worker 'android', 'AndroidManifest.xml') 265*8975f5c5SAndroid Build Coastguard Worker 266*8975f5c5SAndroid Build Coastguard Worker logging.info('Generating config.xml') 267*8975f5c5SAndroid Build Coastguard Worker backported_methods = _RetrieveBackportedMethods(backported_methods_path) 268*8975f5c5SAndroid Build Coastguard Worker config_xml_node = _GenerateConfigXmlTree(config_path, backported_methods) 269*8975f5c5SAndroid Build Coastguard Worker generated_config_path = os.path.join(lint_gen_dir, 'config.xml') 270*8975f5c5SAndroid Build Coastguard Worker _WriteXmlFile(config_xml_node, generated_config_path) 271*8975f5c5SAndroid Build Coastguard Worker cmd.extend(['--config', generated_config_path]) 272*8975f5c5SAndroid Build Coastguard Worker 273*8975f5c5SAndroid Build Coastguard Worker logging.info('Generating Android manifest file') 274*8975f5c5SAndroid Build Coastguard Worker android_manifest_tree = _GenerateAndroidManifest(manifest_path, 275*8975f5c5SAndroid Build Coastguard Worker extra_manifest_paths, 276*8975f5c5SAndroid Build Coastguard Worker min_sdk_version, 277*8975f5c5SAndroid Build Coastguard Worker android_sdk_version) 278*8975f5c5SAndroid Build Coastguard Worker # Just use a hardcoded name, since we may have different target names (and 279*8975f5c5SAndroid Build Coastguard Worker # thus different manifest_paths) using the same lint baseline. Eg. 280*8975f5c5SAndroid Build Coastguard Worker # trichrome_chrome_bundle and trichrome_chrome_32_64_bundle. 281*8975f5c5SAndroid Build Coastguard Worker lint_android_manifest_path = os.path.join(lint_gen_dir, 'AndroidManifest.xml') 282*8975f5c5SAndroid Build Coastguard Worker _WriteXmlFile(android_manifest_tree.getroot(), lint_android_manifest_path) 283*8975f5c5SAndroid Build Coastguard Worker 284*8975f5c5SAndroid Build Coastguard Worker resource_root_dir = os.path.join(lint_gen_dir, _RES_ZIP_DIR) 285*8975f5c5SAndroid Build Coastguard Worker # These are zip files with generated resources (e. g. strings from GRD). 286*8975f5c5SAndroid Build Coastguard Worker logging.info('Extracting resource zips') 287*8975f5c5SAndroid Build Coastguard Worker for resource_zip in resource_zips: 288*8975f5c5SAndroid Build Coastguard Worker # Use a consistent root and name rather than a temporary file so that 289*8975f5c5SAndroid Build Coastguard Worker # suppressions can be local to the lint target and the resource target. 290*8975f5c5SAndroid Build Coastguard Worker resource_dir = os.path.join(resource_root_dir, resource_zip) 291*8975f5c5SAndroid Build Coastguard Worker shutil.rmtree(resource_dir, True) 292*8975f5c5SAndroid Build Coastguard Worker os.makedirs(resource_dir) 293*8975f5c5SAndroid Build Coastguard Worker resource_sources.extend( 294*8975f5c5SAndroid Build Coastguard Worker build_utils.ExtractAll(resource_zip, path=resource_dir)) 295*8975f5c5SAndroid Build Coastguard Worker 296*8975f5c5SAndroid Build Coastguard Worker logging.info('Extracting aars') 297*8975f5c5SAndroid Build Coastguard Worker aar_root_dir = os.path.join(lint_gen_dir, _AAR_DIR) 298*8975f5c5SAndroid Build Coastguard Worker custom_lint_jars = [] 299*8975f5c5SAndroid Build Coastguard Worker custom_annotation_zips = [] 300*8975f5c5SAndroid Build Coastguard Worker if aars: 301*8975f5c5SAndroid Build Coastguard Worker for aar in aars: 302*8975f5c5SAndroid Build Coastguard Worker # Use relative source for aar files since they are not generated. 303*8975f5c5SAndroid Build Coastguard Worker aar_dir = os.path.join(aar_root_dir, 304*8975f5c5SAndroid Build Coastguard Worker os.path.splitext(_SrcRelative(aar))[0]) 305*8975f5c5SAndroid Build Coastguard Worker shutil.rmtree(aar_dir, True) 306*8975f5c5SAndroid Build Coastguard Worker os.makedirs(aar_dir) 307*8975f5c5SAndroid Build Coastguard Worker aar_files = build_utils.ExtractAll(aar, path=aar_dir) 308*8975f5c5SAndroid Build Coastguard Worker for f in aar_files: 309*8975f5c5SAndroid Build Coastguard Worker if f.endswith('lint.jar'): 310*8975f5c5SAndroid Build Coastguard Worker custom_lint_jars.append(f) 311*8975f5c5SAndroid Build Coastguard Worker elif f.endswith('annotations.zip'): 312*8975f5c5SAndroid Build Coastguard Worker custom_annotation_zips.append(f) 313*8975f5c5SAndroid Build Coastguard Worker 314*8975f5c5SAndroid Build Coastguard Worker logging.info('Extracting srcjars') 315*8975f5c5SAndroid Build Coastguard Worker srcjar_root_dir = os.path.join(lint_gen_dir, _SRCJAR_DIR) 316*8975f5c5SAndroid Build Coastguard Worker srcjar_sources = [] 317*8975f5c5SAndroid Build Coastguard Worker if srcjars: 318*8975f5c5SAndroid Build Coastguard Worker for srcjar in srcjars: 319*8975f5c5SAndroid Build Coastguard Worker # Use path without extensions since otherwise the file name includes 320*8975f5c5SAndroid Build Coastguard Worker # .srcjar and lint treats it as a srcjar. 321*8975f5c5SAndroid Build Coastguard Worker srcjar_dir = os.path.join(srcjar_root_dir, os.path.splitext(srcjar)[0]) 322*8975f5c5SAndroid Build Coastguard Worker shutil.rmtree(srcjar_dir, True) 323*8975f5c5SAndroid Build Coastguard Worker os.makedirs(srcjar_dir) 324*8975f5c5SAndroid Build Coastguard Worker # Sadly lint's srcjar support is broken since it only considers the first 325*8975f5c5SAndroid Build Coastguard Worker # srcjar. Until we roll a lint version with that fixed, we need to extract 326*8975f5c5SAndroid Build Coastguard Worker # it ourselves. 327*8975f5c5SAndroid Build Coastguard Worker srcjar_sources.extend(build_utils.ExtractAll(srcjar, path=srcjar_dir)) 328*8975f5c5SAndroid Build Coastguard Worker 329*8975f5c5SAndroid Build Coastguard Worker logging.info('Generating project file') 330*8975f5c5SAndroid Build Coastguard Worker project_file_root = _GenerateProjectFile( 331*8975f5c5SAndroid Build Coastguard Worker lint_android_manifest_path, android_sdk_root, cache_dir, partials_dir, 332*8975f5c5SAndroid Build Coastguard Worker sources, classpath, srcjar_sources, resource_sources, custom_lint_jars, 333*8975f5c5SAndroid Build Coastguard Worker custom_annotation_zips, android_sdk_version, baseline) 334*8975f5c5SAndroid Build Coastguard Worker 335*8975f5c5SAndroid Build Coastguard Worker project_xml_path = os.path.join(lint_gen_dir, 'project.xml') 336*8975f5c5SAndroid Build Coastguard Worker _WriteXmlFile(project_file_root, project_xml_path) 337*8975f5c5SAndroid Build Coastguard Worker cmd += ['--project', project_xml_path] 338*8975f5c5SAndroid Build Coastguard Worker 339*8975f5c5SAndroid Build Coastguard Worker def stdout_filter(output): 340*8975f5c5SAndroid Build Coastguard Worker filter_patterns = [ 341*8975f5c5SAndroid Build Coastguard Worker # This filter is necessary for JDK11. 342*8975f5c5SAndroid Build Coastguard Worker 'No issues found', 343*8975f5c5SAndroid Build Coastguard Worker # Custom checks are not always available in every lint run so an 344*8975f5c5SAndroid Build Coastguard Worker # UnknownIssueId warning is sometimes printed for custom checks in the 345*8975f5c5SAndroid Build Coastguard Worker # _DISABLED_ALWAYS list. 346*8975f5c5SAndroid Build Coastguard Worker r'\[UnknownIssueId\]', 347*8975f5c5SAndroid Build Coastguard Worker # If all the warnings are filtered, we should not fail on the final 348*8975f5c5SAndroid Build Coastguard Worker # summary line. 349*8975f5c5SAndroid Build Coastguard Worker r'\d+ errors, \d+ warnings', 350*8975f5c5SAndroid Build Coastguard Worker ] 351*8975f5c5SAndroid Build Coastguard Worker return build_utils.FilterLines(output, '|'.join(filter_patterns)) 352*8975f5c5SAndroid Build Coastguard Worker 353*8975f5c5SAndroid Build Coastguard Worker def stderr_filter(output): 354*8975f5c5SAndroid Build Coastguard Worker output = build_utils.FilterReflectiveAccessJavaWarnings(output) 355*8975f5c5SAndroid Build Coastguard Worker # Presumably a side-effect of our manual manifest merging, but does not 356*8975f5c5SAndroid Build Coastguard Worker # seem to actually break anything: 357*8975f5c5SAndroid Build Coastguard Worker # "Manifest merger failed with multiple errors, see logs" 358*8975f5c5SAndroid Build Coastguard Worker return build_utils.FilterLines(output, 'Manifest merger failed') 359*8975f5c5SAndroid Build Coastguard Worker 360*8975f5c5SAndroid Build Coastguard Worker start = time.time() 361*8975f5c5SAndroid Build Coastguard Worker logging.debug('Lint command %s', ' '.join(cmd)) 362*8975f5c5SAndroid Build Coastguard Worker failed = False 363*8975f5c5SAndroid Build Coastguard Worker 364*8975f5c5SAndroid Build Coastguard Worker if creating_baseline and not warnings_as_errors: 365*8975f5c5SAndroid Build Coastguard Worker # Allow error code 6 when creating a baseline: ERRNO_CREATED_BASELINE 366*8975f5c5SAndroid Build Coastguard Worker fail_func = lambda returncode, _: returncode not in (0, 6) 367*8975f5c5SAndroid Build Coastguard Worker else: 368*8975f5c5SAndroid Build Coastguard Worker fail_func = lambda returncode, _: returncode != 0 369*8975f5c5SAndroid Build Coastguard Worker 370*8975f5c5SAndroid Build Coastguard Worker try: 371*8975f5c5SAndroid Build Coastguard Worker build_utils.CheckOutput(cmd, 372*8975f5c5SAndroid Build Coastguard Worker print_stdout=True, 373*8975f5c5SAndroid Build Coastguard Worker stdout_filter=stdout_filter, 374*8975f5c5SAndroid Build Coastguard Worker stderr_filter=stderr_filter, 375*8975f5c5SAndroid Build Coastguard Worker fail_on_output=warnings_as_errors, 376*8975f5c5SAndroid Build Coastguard Worker fail_func=fail_func) 377*8975f5c5SAndroid Build Coastguard Worker except build_utils.CalledProcessError as e: 378*8975f5c5SAndroid Build Coastguard Worker failed = True 379*8975f5c5SAndroid Build Coastguard Worker # Do not output the python stacktrace because it is lengthy and is not 380*8975f5c5SAndroid Build Coastguard Worker # relevant to the actual lint error. 381*8975f5c5SAndroid Build Coastguard Worker sys.stderr.write(e.output) 382*8975f5c5SAndroid Build Coastguard Worker finally: 383*8975f5c5SAndroid Build Coastguard Worker # When not treating warnings as errors, display the extra footer. 384*8975f5c5SAndroid Build Coastguard Worker is_debug = os.environ.get('LINT_DEBUG', '0') != '0' 385*8975f5c5SAndroid Build Coastguard Worker 386*8975f5c5SAndroid Build Coastguard Worker end = time.time() - start 387*8975f5c5SAndroid Build Coastguard Worker logging.info('Lint command took %ss', end) 388*8975f5c5SAndroid Build Coastguard Worker if not is_debug: 389*8975f5c5SAndroid Build Coastguard Worker shutil.rmtree(aar_root_dir, ignore_errors=True) 390*8975f5c5SAndroid Build Coastguard Worker shutil.rmtree(resource_root_dir, ignore_errors=True) 391*8975f5c5SAndroid Build Coastguard Worker shutil.rmtree(srcjar_root_dir, ignore_errors=True) 392*8975f5c5SAndroid Build Coastguard Worker os.unlink(project_xml_path) 393*8975f5c5SAndroid Build Coastguard Worker shutil.rmtree(partials_dir, ignore_errors=True) 394*8975f5c5SAndroid Build Coastguard Worker 395*8975f5c5SAndroid Build Coastguard Worker if failed: 396*8975f5c5SAndroid Build Coastguard Worker print('- For more help with lint in Chrome:', _LINT_MD_URL) 397*8975f5c5SAndroid Build Coastguard Worker if is_debug: 398*8975f5c5SAndroid Build Coastguard Worker print('- DEBUG MODE: Here is the project.xml: {}'.format( 399*8975f5c5SAndroid Build Coastguard Worker _SrcRelative(project_xml_path))) 400*8975f5c5SAndroid Build Coastguard Worker else: 401*8975f5c5SAndroid Build Coastguard Worker print('- Run with LINT_DEBUG=1 to enable lint configuration debugging') 402*8975f5c5SAndroid Build Coastguard Worker sys.exit(1) 403*8975f5c5SAndroid Build Coastguard Worker 404*8975f5c5SAndroid Build Coastguard Worker logging.info('Lint completed') 405*8975f5c5SAndroid Build Coastguard Worker 406*8975f5c5SAndroid Build Coastguard Worker 407*8975f5c5SAndroid Build Coastguard Workerdef _ParseArgs(argv): 408*8975f5c5SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 409*8975f5c5SAndroid Build Coastguard Worker action_helpers.add_depfile_arg(parser) 410*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--target-name', help='Fully qualified GN target name.') 411*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--skip-build-server', 412*8975f5c5SAndroid Build Coastguard Worker action='store_true', 413*8975f5c5SAndroid Build Coastguard Worker help='Avoid using the build server.') 414*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--use-build-server', 415*8975f5c5SAndroid Build Coastguard Worker action='store_true', 416*8975f5c5SAndroid Build Coastguard Worker help='Always use the build server.') 417*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--experimental-build-server', 418*8975f5c5SAndroid Build Coastguard Worker action='store_true', 419*8975f5c5SAndroid Build Coastguard Worker help='Use experimental build server features.') 420*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--lint-jar-path', 421*8975f5c5SAndroid Build Coastguard Worker required=True, 422*8975f5c5SAndroid Build Coastguard Worker help='Path to the lint jar.') 423*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--custom-lint-jar-path', 424*8975f5c5SAndroid Build Coastguard Worker required=True, 425*8975f5c5SAndroid Build Coastguard Worker help='Path to our custom lint jar.') 426*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--backported-methods', 427*8975f5c5SAndroid Build Coastguard Worker help='Path to backported methods file created by R8.') 428*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--cache-dir', 429*8975f5c5SAndroid Build Coastguard Worker help='Path to the directory in which the android cache ' 430*8975f5c5SAndroid Build Coastguard Worker 'directory tree should be stored.') 431*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--config-path', help='Path to lint suppressions file.') 432*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--lint-gen-dir', 433*8975f5c5SAndroid Build Coastguard Worker required=True, 434*8975f5c5SAndroid Build Coastguard Worker help='Path to store generated xml files.') 435*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--stamp', help='Path to stamp upon success.') 436*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--android-sdk-version', 437*8975f5c5SAndroid Build Coastguard Worker help='Version (API level) of the Android SDK used for ' 438*8975f5c5SAndroid Build Coastguard Worker 'building.') 439*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--min-sdk-version', 440*8975f5c5SAndroid Build Coastguard Worker required=True, 441*8975f5c5SAndroid Build Coastguard Worker help='Minimal SDK version to lint against.') 442*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--android-sdk-root', 443*8975f5c5SAndroid Build Coastguard Worker required=True, 444*8975f5c5SAndroid Build Coastguard Worker help='Lint needs an explicit path to the android sdk.') 445*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--create-cache', 446*8975f5c5SAndroid Build Coastguard Worker action='store_true', 447*8975f5c5SAndroid Build Coastguard Worker help='Whether this invocation is just warming the cache.') 448*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--warnings-as-errors', 449*8975f5c5SAndroid Build Coastguard Worker action='store_true', 450*8975f5c5SAndroid Build Coastguard Worker help='Treat all warnings as errors.') 451*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--sources', 452*8975f5c5SAndroid Build Coastguard Worker help='A list of files containing java and kotlin source ' 453*8975f5c5SAndroid Build Coastguard Worker 'files.') 454*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--aars', help='GN list of included aars.') 455*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--srcjars', help='GN list of included srcjars.') 456*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--manifest-path', 457*8975f5c5SAndroid Build Coastguard Worker help='Path to original AndroidManifest.xml') 458*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--extra-manifest-paths', 459*8975f5c5SAndroid Build Coastguard Worker action='append', 460*8975f5c5SAndroid Build Coastguard Worker help='GYP-list of manifest paths to merge into the ' 461*8975f5c5SAndroid Build Coastguard Worker 'original AndroidManifest.xml') 462*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--resource-sources', 463*8975f5c5SAndroid Build Coastguard Worker default=[], 464*8975f5c5SAndroid Build Coastguard Worker action='append', 465*8975f5c5SAndroid Build Coastguard Worker help='GYP-list of resource sources files, similar to ' 466*8975f5c5SAndroid Build Coastguard Worker 'java sources files, but for resource files.') 467*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--resource-zips', 468*8975f5c5SAndroid Build Coastguard Worker default=[], 469*8975f5c5SAndroid Build Coastguard Worker action='append', 470*8975f5c5SAndroid Build Coastguard Worker help='GYP-list of resource zips, zip files of generated ' 471*8975f5c5SAndroid Build Coastguard Worker 'resource files.') 472*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--classpath', 473*8975f5c5SAndroid Build Coastguard Worker help='List of jars to add to the classpath.') 474*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--baseline', 475*8975f5c5SAndroid Build Coastguard Worker help='Baseline file to ignore existing errors and fail ' 476*8975f5c5SAndroid Build Coastguard Worker 'on new errors.') 477*8975f5c5SAndroid Build Coastguard Worker 478*8975f5c5SAndroid Build Coastguard Worker args = parser.parse_args(build_utils.ExpandFileArgs(argv)) 479*8975f5c5SAndroid Build Coastguard Worker args.sources = action_helpers.parse_gn_list(args.sources) 480*8975f5c5SAndroid Build Coastguard Worker args.aars = action_helpers.parse_gn_list(args.aars) 481*8975f5c5SAndroid Build Coastguard Worker args.srcjars = action_helpers.parse_gn_list(args.srcjars) 482*8975f5c5SAndroid Build Coastguard Worker args.resource_sources = action_helpers.parse_gn_list(args.resource_sources) 483*8975f5c5SAndroid Build Coastguard Worker args.extra_manifest_paths = action_helpers.parse_gn_list( 484*8975f5c5SAndroid Build Coastguard Worker args.extra_manifest_paths) 485*8975f5c5SAndroid Build Coastguard Worker args.resource_zips = action_helpers.parse_gn_list(args.resource_zips) 486*8975f5c5SAndroid Build Coastguard Worker args.classpath = action_helpers.parse_gn_list(args.classpath) 487*8975f5c5SAndroid Build Coastguard Worker 488*8975f5c5SAndroid Build Coastguard Worker if args.baseline: 489*8975f5c5SAndroid Build Coastguard Worker assert os.path.basename(args.baseline) == 'lint-baseline.xml', ( 490*8975f5c5SAndroid Build Coastguard Worker 'The baseline file needs to be named "lint-baseline.xml" in order for ' 491*8975f5c5SAndroid Build Coastguard Worker 'the autoroller to find and update it whenever lint is rolled to a new ' 492*8975f5c5SAndroid Build Coastguard Worker 'version.') 493*8975f5c5SAndroid Build Coastguard Worker 494*8975f5c5SAndroid Build Coastguard Worker return args 495*8975f5c5SAndroid Build Coastguard Worker 496*8975f5c5SAndroid Build Coastguard Worker 497*8975f5c5SAndroid Build Coastguard Workerdef main(): 498*8975f5c5SAndroid Build Coastguard Worker build_utils.InitLogging('LINT_DEBUG') 499*8975f5c5SAndroid Build Coastguard Worker args = _ParseArgs(sys.argv[1:]) 500*8975f5c5SAndroid Build Coastguard Worker 501*8975f5c5SAndroid Build Coastguard Worker sources = [] 502*8975f5c5SAndroid Build Coastguard Worker for sources_file in args.sources: 503*8975f5c5SAndroid Build Coastguard Worker sources.extend(build_utils.ReadSourcesList(sources_file)) 504*8975f5c5SAndroid Build Coastguard Worker resource_sources = [] 505*8975f5c5SAndroid Build Coastguard Worker for resource_sources_file in args.resource_sources: 506*8975f5c5SAndroid Build Coastguard Worker resource_sources.extend(build_utils.ReadSourcesList(resource_sources_file)) 507*8975f5c5SAndroid Build Coastguard Worker 508*8975f5c5SAndroid Build Coastguard Worker possible_depfile_deps = (args.srcjars + args.resource_zips + sources + 509*8975f5c5SAndroid Build Coastguard Worker resource_sources + [ 510*8975f5c5SAndroid Build Coastguard Worker args.baseline, 511*8975f5c5SAndroid Build Coastguard Worker args.manifest_path, 512*8975f5c5SAndroid Build Coastguard Worker ]) 513*8975f5c5SAndroid Build Coastguard Worker depfile_deps = [p for p in possible_depfile_deps if p] 514*8975f5c5SAndroid Build Coastguard Worker 515*8975f5c5SAndroid Build Coastguard Worker if args.depfile: 516*8975f5c5SAndroid Build Coastguard Worker action_helpers.write_depfile(args.depfile, args.stamp, depfile_deps) 517*8975f5c5SAndroid Build Coastguard Worker 518*8975f5c5SAndroid Build Coastguard Worker # TODO(wnwen): Consider removing lint cache now that there are only two lint 519*8975f5c5SAndroid Build Coastguard Worker # invocations. 520*8975f5c5SAndroid Build Coastguard Worker # Avoid parallelizing cache creation since lint runs without the cache defeat 521*8975f5c5SAndroid Build Coastguard Worker # the purpose of creating the cache in the first place. Forward the command 522*8975f5c5SAndroid Build Coastguard Worker # after the depfile has been written as siso requires it. 523*8975f5c5SAndroid Build Coastguard Worker if (not args.create_cache and not args.skip_build_server 524*8975f5c5SAndroid Build Coastguard Worker and server_utils.MaybeRunCommand( 525*8975f5c5SAndroid Build Coastguard Worker name=args.target_name, 526*8975f5c5SAndroid Build Coastguard Worker argv=sys.argv, 527*8975f5c5SAndroid Build Coastguard Worker stamp_file=args.stamp, 528*8975f5c5SAndroid Build Coastguard Worker force=args.use_build_server, 529*8975f5c5SAndroid Build Coastguard Worker experimental=args.experimental_build_server)): 530*8975f5c5SAndroid Build Coastguard Worker return 531*8975f5c5SAndroid Build Coastguard Worker 532*8975f5c5SAndroid Build Coastguard Worker _RunLint(args.custom_lint_jar_path, 533*8975f5c5SAndroid Build Coastguard Worker args.lint_jar_path, 534*8975f5c5SAndroid Build Coastguard Worker args.backported_methods, 535*8975f5c5SAndroid Build Coastguard Worker args.config_path, 536*8975f5c5SAndroid Build Coastguard Worker args.manifest_path, 537*8975f5c5SAndroid Build Coastguard Worker args.extra_manifest_paths, 538*8975f5c5SAndroid Build Coastguard Worker sources, 539*8975f5c5SAndroid Build Coastguard Worker args.classpath, 540*8975f5c5SAndroid Build Coastguard Worker args.cache_dir, 541*8975f5c5SAndroid Build Coastguard Worker args.android_sdk_version, 542*8975f5c5SAndroid Build Coastguard Worker args.aars, 543*8975f5c5SAndroid Build Coastguard Worker args.srcjars, 544*8975f5c5SAndroid Build Coastguard Worker args.min_sdk_version, 545*8975f5c5SAndroid Build Coastguard Worker resource_sources, 546*8975f5c5SAndroid Build Coastguard Worker args.resource_zips, 547*8975f5c5SAndroid Build Coastguard Worker args.android_sdk_root, 548*8975f5c5SAndroid Build Coastguard Worker args.lint_gen_dir, 549*8975f5c5SAndroid Build Coastguard Worker args.baseline, 550*8975f5c5SAndroid Build Coastguard Worker args.create_cache, 551*8975f5c5SAndroid Build Coastguard Worker warnings_as_errors=args.warnings_as_errors) 552*8975f5c5SAndroid Build Coastguard Worker logging.info('Creating stamp file') 553*8975f5c5SAndroid Build Coastguard Worker build_utils.Touch(args.stamp) 554*8975f5c5SAndroid Build Coastguard Worker 555*8975f5c5SAndroid Build Coastguard Worker 556*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__': 557*8975f5c5SAndroid Build Coastguard Worker sys.exit(main()) 558