diff --git a/examples/simple-android/AndroidManifest.xml b/examples/simple-android/AndroidManifest.xml index b377777..d695316 100644 --- a/examples/simple-android/AndroidManifest.xml +++ b/examples/simple-android/AndroidManifest.xml @@ -1,7 +1,13 @@ + package="com.rules.android.lint"> - + + + + + diff --git a/examples/simple-android/BUILD.bazel b/examples/simple-android/BUILD.bazel index 40dd1c4..9f78c54 100644 --- a/examples/simple-android/BUILD.bazel +++ b/examples/simple-android/BUILD.bazel @@ -1,25 +1,53 @@ -load("@rules_android//android:rules.bzl", "android_library") +load("@rules_android//android:rules.bzl", "android_binary", "android_library") load("@rules_android_lint//rules:defs.bzl", "android_lint", "android_lint_test") load("@rules_android_lint//toolchains:toolchain.bzl", "android_lint_toolchain") android_library( name = "lib", - srcs = ["Foo.java"], + srcs = ["TestActivity.java"], custom_package = "com.rules.android.lint.examples", + manifest = "LibManifest.xml", +) + +android_binary( + name = "bin", + srcs = ["Foo.java"], + custom_package = "com.rules.android.lint", + manifest = "AndroidManifest.xml", + deps = [ + ":lib", + ], ) android_lint( name = "lib_lint", - srcs = ["Foo.java"], + srcs = ["TestActivity.java"], android_lint_config = "lint.xml", lib = ":lib", + manifest = "LibManifest.xml", ) android_lint_test( name = "lib_lint_test", - srcs = ["Foo.java"], + srcs = ["TestActivity.java"], baseline = "lib_lint_test_lint_baseline.xml", lib = ":lib", + manifest = "LibManifest.xml", +) + +android_lint( + name = "bin_lint", + srcs = ["Foo.java"], + android_lint_config = "lint.xml", + lib = ":bin", + manifest = "AndroidManifest.xml", +) + +android_lint_test( + name = "bin_lint_test", + srcs = ["Foo.java"], + baseline = "bin_lint_test_lint_baseline.xml", + lib = ":bin", ) android_lint_toolchain( diff --git a/examples/simple-android/LibManifest.xml b/examples/simple-android/LibManifest.xml new file mode 100644 index 0000000..2350be0 --- /dev/null +++ b/examples/simple-android/LibManifest.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/simple-android/TestActivity.java b/examples/simple-android/TestActivity.java new file mode 100644 index 0000000..16e24c3 --- /dev/null +++ b/examples/simple-android/TestActivity.java @@ -0,0 +1,7 @@ +package com.rules.android.lint; + +import android.app.Activity; + +public class TestActivity extends Activity { + +} diff --git a/examples/simple-android/WORKSPACE.bzlmod b/examples/simple-android/WORKSPACE.bzlmod index 9cc43bb..83430f9 100644 --- a/examples/simple-android/WORKSPACE.bzlmod +++ b/examples/simple-android/WORKSPACE.bzlmod @@ -1 +1,6 @@ android_sdk_repository(name = "androidsdk") + +android_ndk_repository( + name = "androidndk", + api_level = 30, +) diff --git a/examples/simple-android/bin_lint_test_lint_baseline.xml b/examples/simple-android/bin_lint_test_lint_baseline.xml new file mode 100644 index 0000000..7e4e40c --- /dev/null +++ b/examples/simple-android/bin_lint_test_lint_baseline.xml @@ -0,0 +1,15 @@ + + + + + + + +s \ No newline at end of file diff --git a/examples/simple-android/lib_lint_test_lint_baseline.xml b/examples/simple-android/lib_lint_test_lint_baseline.xml index b99b72d..81aea14 100644 --- a/examples/simple-android/lib_lint_test_lint_baseline.xml +++ b/examples/simple-android/lib_lint_test_lint_baseline.xml @@ -1,22 +1,15 @@ - + + id="ExpiredTargetSdkVersion" + message="Google Play requires that apps target API level 33 or higher." + errorLine1=" android:targetSdkVersion="1" />" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + column="9"/> - + \ No newline at end of file diff --git a/rules/impl.bzl b/rules/impl.bzl index 23d2a94..689ea26 100644 --- a/rules/impl.bzl +++ b/rules/impl.bzl @@ -24,6 +24,7 @@ def _run_android_lint( deps, resource_files, manifest, + merged_manifest, compile_sdk_version, java_language_level, kotlin_language_level, @@ -48,6 +49,7 @@ def _run_android_lint( deps: Depset of aars and jars to include on the classpath resource_files: The Android resource files manifest: The Android manifest file + merged_manifest: The Android merged manifest file (only for android_binary targets) compile_sdk_version: The Android compile SDK version java_language_level: The Java language level kotlin_language_level: The Kotlin language level @@ -87,6 +89,9 @@ def _run_android_lint( if manifest: args.add("--android-manifest", manifest) inputs.append(manifest) + if merged_manifest: + args.add("--android-merged-manifest", merged_manifest) + inputs.append(merged_manifest) if not regenerate and baseline: args.add("--baseline-file", baseline) inputs.append(baseline) @@ -169,9 +174,10 @@ def process_android_lint_issues(ctx, regenerate): # Append the Android manifest file. Lint requires that the input manifest files be named # exactly `AndroidManifest.xml`. manifest = ctx.file.manifest - if manifest and manifest.basename != "AndroidManifest.xml": - manifest = ctx.actions.declare_file("AndroidManifest.xml") - ctx.actions.symlink(output = manifest, target_file = ctx.file.manifest) + + merged_manifest = None + if ctx.attr.lib and AndroidManifestInfo in ctx.attr.lib and AndroidBinaryData in ctx.attr.lib: + merged_manifest = ctx.attr.lib[AndroidManifestInfo].manifest # Collect the transitive classpath jars to run lint against. deps = [] @@ -207,6 +213,7 @@ def process_android_lint_issues(ctx, regenerate): deps = depset(transitive = deps), resource_files = ctx.files.resource_files, manifest = manifest, + merged_manifest = merged_manifest, compile_sdk_version = _utils.get_android_lint_toolchain(ctx).compile_sdk_version, java_language_level = _utils.get_android_lint_toolchain(ctx).java_language_level, kotlin_language_level = _utils.get_android_lint_toolchain(ctx).kotlin_language_level, diff --git a/src/cli/AndroidLintActionArgs.kt b/src/cli/AndroidLintActionArgs.kt index 12aa735..869086f 100644 --- a/src/cli/AndroidLintActionArgs.kt +++ b/src/cli/AndroidLintActionArgs.kt @@ -50,6 +50,12 @@ internal class AndroidLintActionArgs( transform = argsParserPathTransformer, ).default { null } + val androidMergedManifest: Path? by parser.storing( + names = arrayOf("--android-merged-manifest"), + help = "Merged android manifest for Android Binary targets", + transform = argsParserPathTransformer, + ).default { null } + val baselineFile: Path? by parser.storing( names = arrayOf("--baseline-file"), help = "", diff --git a/src/cli/AndroidLintProject.kt b/src/cli/AndroidLintProject.kt index ec13328..d1d7b80 100644 --- a/src/cli/AndroidLintProject.kt +++ b/src/cli/AndroidLintProject.kt @@ -16,6 +16,7 @@ internal fun createProjectXMLString( srcs: List, resources: List, androidManifest: Path?, + androidMergedManifest: Path?, classpathJars: List, classpathAars: List, classpathExtractedAarDirectories: List>, @@ -64,6 +65,12 @@ internal fun createProjectXMLString( moduleElement.appendChild(element) } + if (androidMergedManifest != null) { + val element = document.createElement("merged-manifest") + element.setAttribute("file", androidMergedManifest.pathString) + moduleElement.appendChild(element) + } + classpathJars.forEach { jar -> val element = document.createElement("classpath") element.setAttribute("jar", jar.absolutePathString()) diff --git a/src/cli/AndroidLintRunner.kt b/src/cli/AndroidLintRunner.kt index 0e56355..9f559ed 100644 --- a/src/cli/AndroidLintRunner.kt +++ b/src/cli/AndroidLintRunner.kt @@ -52,6 +52,7 @@ internal class AndroidLintRunner { srcs = args.srcs.sortedDescending(), resources = args.resources.sortedDescending(), androidManifest = args.androidManifest, + androidMergedManifest = args.androidMergedManifest, classpathJars = jars.sortedDescending(), classpathAars = emptyList(), classpathExtractedAarDirectories = unpackedAars, diff --git a/tests/src/cli/AndroidLintActionArgsTest.kt b/tests/src/cli/AndroidLintActionArgsTest.kt index 01e77e9..7c9a7ea 100644 --- a/tests/src/cli/AndroidLintActionArgsTest.kt +++ b/tests/src/cli/AndroidLintActionArgsTest.kt @@ -25,6 +25,8 @@ class AndroidLintActionArgsTest { "path/to/resource/strings.xml", "--android-manifest", "AndroidManifest.xml", + "--android-merged-manifest", + "processed/AndroidManifest.xml", "--baseline-file", "lib_lint_baseline.xml", "--config-file", @@ -70,5 +72,8 @@ class AndroidLintActionArgsTest { assertThat(parseArgs.javaLanguageLevel).isEqualTo("1.7") assertThat(parseArgs.kotlinLanguageLevel).isEqualTo("1.8") assertThat(parseArgs.enableCheckDependencies).isTrue() + assertThat(parseArgs.androidManifest).isEqualTo(Paths.get("AndroidManifest.xml")) + assertThat(parseArgs.androidMergedManifest) + .isEqualTo(Paths.get("processed/AndroidManifest.xml")) } } diff --git a/tests/src/cli/AndroidLintProjectTest.kt b/tests/src/cli/AndroidLintProjectTest.kt index 2fd4e89..85e4db6 100644 --- a/tests/src/cli/AndroidLintProjectTest.kt +++ b/tests/src/cli/AndroidLintProjectTest.kt @@ -19,13 +19,14 @@ class AndroidLintProjectTest { @Test fun `test asXMLString does produce correct project file content`() { + val manifest = tmpDirectory.newPath("AndroidManifest.xml") assertThat( createProjectXMLString( moduleName = "test_module_name", rootDir = tmpDirectory.root.absolutePath, srcs = listOf(tmpDirectory.newPath("Foo.kt")), resources = listOf(tmpDirectory.newPath("foo.xml")), - androidManifest = tmpDirectory.newPath("AndroidManifest.xml"), + androidManifest = manifest, classpathJars = listOf(tmpDirectory.newPath("Foo.jar")), classpathAars = listOf(tmpDirectory.newPath("Foo.aar")), classpathExtractedAarDirectories = listOf( @@ -35,6 +36,7 @@ class AndroidLintProjectTest { ), ), customLintChecks = listOf(tmpDirectory.newPath("tmp/unpacked_aars/bar/lint.jar")), + androidMergedManifest = manifest, ), ).isEqualTo( """ @@ -45,6 +47,7 @@ class AndroidLintProjectTest { +