From c091f6bdcbb62a6a5b3613d2990ba63070d07158 Mon Sep 17 00:00:00 2001 From: Arunkumar Date: Fri, 15 Dec 2023 14:51:31 +0800 Subject: [PATCH 1/6] Pass merged manifest to Android Lint --- examples/simple-android/AndroidManifest.xml | 8 +++++ examples/simple-android/BUILD.bazel | 34 +++++++++++++++++-- examples/simple-android/LibManifest.xml | 7 ++++ examples/simple-android/TestActivity.java | 7 ++++ examples/simple-android/WORKSPACE.bzlmod | 1 + .../bin_lint_test_lint_baseline.xml | 22 ++++++++++++ .../lib_lint_test_lint_baseline.xml | 26 +++++++------- rules/impl.bzl | 9 +++++ src/cli/AndroidLintActionArgs.kt | 6 ++++ src/cli/AndroidLintProject.kt | 7 ++++ src/cli/AndroidLintRunner.kt | 1 + tests/src/cli/AndroidLintActionArgsTest.kt | 5 +++ tests/src/cli/AndroidLintProjectTest.kt | 5 ++- 13 files changed, 121 insertions(+), 17 deletions(-) create mode 100644 examples/simple-android/LibManifest.xml create mode 100644 examples/simple-android/TestActivity.java create mode 100644 examples/simple-android/bin_lint_test_lint_baseline.xml diff --git a/examples/simple-android/AndroidManifest.xml b/examples/simple-android/AndroidManifest.xml index b377777..91edeac 100644 --- a/examples/simple-android/AndroidManifest.xml +++ b/examples/simple-android/AndroidManifest.xml @@ -2,6 +2,14 @@ + + + + + + diff --git a/examples/simple-android/BUILD.bazel b/examples/simple-android/BUILD.bazel index 40dd1c4..0582ed2 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 = ["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.examples", + 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..96cca3d --- /dev/null +++ b/examples/simple-android/TestActivity.java @@ -0,0 +1,7 @@ +package com.rules.android.lint.examples; + +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..11ea151 100644 --- a/examples/simple-android/WORKSPACE.bzlmod +++ b/examples/simple-android/WORKSPACE.bzlmod @@ -1 +1,2 @@ android_sdk_repository(name = "androidsdk") +android_ndk_repository(name = "androidndk") 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..b99b72d --- /dev/null +++ b/examples/simple-android/bin_lint_test_lint_baseline.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/examples/simple-android/lib_lint_test_lint_baseline.xml b/examples/simple-android/lib_lint_test_lint_baseline.xml index b99b72d..8e80cdd 100644 --- a/examples/simple-android/lib_lint_test_lint_baseline.xml +++ b/examples/simple-android/lib_lint_test_lint_baseline.xml @@ -2,21 +2,21 @@ + id="ExpiredTargetSdkVersion" + severity="Fatal" + message="Google Play requires that apps target API level 33 or higher." + category="Compliance" + priority="8" + summary="TargetSdkVersion No Longer Supported" + explanation="Configuring your app to target a recent API level ensures that users benefit from significant security and performance improvements, while still allowing your app to run on older Android versions (down to the `minSdkVersion`). To update your `targetSdkVersion`, follow the steps from "Meeting Google Play requirements for target API level", https://developer.android.com/distribute/best-practices/develop/target-sdk.html" + url="https://support.google.com/googleplay/android-developer/answer/113469#targetsdk" + urls="https://support.google.com/googleplay/android-developer/answer/113469#targetsdk,https://developer.android.com/distribute/best-practices/develop/target-sdk.html" + errorLine1=" android:targetSdkVersion="1" />" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + column="9"/> diff --git a/rules/impl.bzl b/rules/impl.bzl index 23d2a94..32e0c5e 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, @@ -87,6 +88,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) @@ -173,6 +177,10 @@ def process_android_lint_issues(ctx, regenerate): 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 = [] for dep in ctx.attr.deps: @@ -207,6 +215,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..6b7e92a 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 { + From 453d9244bad4762429b41bdb45b1b2d396f57df0 Mon Sep 17 00:00:00 2001 From: Arunkumar Date: Fri, 22 Dec 2023 23:31:24 +0800 Subject: [PATCH 2/6] Fix failing tests --- rules/impl.bzl | 1 + tests/src/cli/AndroidLintActionArgsTest.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/impl.bzl b/rules/impl.bzl index 32e0c5e..d1f80ef 100644 --- a/rules/impl.bzl +++ b/rules/impl.bzl @@ -49,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 diff --git a/tests/src/cli/AndroidLintActionArgsTest.kt b/tests/src/cli/AndroidLintActionArgsTest.kt index 6b7e92a..7c9a7ea 100644 --- a/tests/src/cli/AndroidLintActionArgsTest.kt +++ b/tests/src/cli/AndroidLintActionArgsTest.kt @@ -74,6 +74,6 @@ class AndroidLintActionArgsTest { assertThat(parseArgs.enableCheckDependencies).isTrue() assertThat(parseArgs.androidManifest).isEqualTo(Paths.get("AndroidManifest.xml")) assertThat(parseArgs.androidMergedManifest) - .isEqualTo(Paths.get("/processed/AndroidManifest.xml")) + .isEqualTo(Paths.get("processed/AndroidManifest.xml")) } } From aca41180c0c84dc96e84a0368e3f25d6da3ee0b9 Mon Sep 17 00:00:00 2001 From: Arunkumar Date: Fri, 22 Dec 2023 23:45:17 +0800 Subject: [PATCH 3/6] Set API level for NDK --- examples/simple-android/WORKSPACE.bzlmod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple-android/WORKSPACE.bzlmod b/examples/simple-android/WORKSPACE.bzlmod index 11ea151..b83172e 100644 --- a/examples/simple-android/WORKSPACE.bzlmod +++ b/examples/simple-android/WORKSPACE.bzlmod @@ -1,2 +1,2 @@ android_sdk_repository(name = "androidsdk") -android_ndk_repository(name = "androidndk") +android_ndk_repository(name = "androidndk", api_level = 30) From 1d0c4f201e50aaeeffdefa55b95eaf120611fda7 Mon Sep 17 00:00:00 2001 From: Arunkumar Date: Fri, 22 Dec 2023 23:47:54 +0800 Subject: [PATCH 4/6] Fix buildifier --- examples/simple-android/WORKSPACE.bzlmod | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/simple-android/WORKSPACE.bzlmod b/examples/simple-android/WORKSPACE.bzlmod index b83172e..83430f9 100644 --- a/examples/simple-android/WORKSPACE.bzlmod +++ b/examples/simple-android/WORKSPACE.bzlmod @@ -1,2 +1,6 @@ android_sdk_repository(name = "androidsdk") -android_ndk_repository(name = "androidndk", api_level = 30) + +android_ndk_repository( + name = "androidndk", + api_level = 30, +) From 3b7b71641f5018809e5378de545ecc119e2c4503 Mon Sep 17 00:00:00 2001 From: Arunkumar Date: Tue, 16 Apr 2024 00:52:14 +0800 Subject: [PATCH 5/6] Update examples and fix tests --- examples/simple-android/AndroidManifest.xml | 6 ++---- examples/simple-android/BUILD.bazel | 2 +- examples/simple-android/TestActivity.java | 2 +- .../simple-android/bin_lint_test_lint_baseline.xml | 11 ++--------- .../simple-android/lib_lint_test_lint_baseline.xml | 13 +++---------- 5 files changed, 9 insertions(+), 25 deletions(-) diff --git a/examples/simple-android/AndroidManifest.xml b/examples/simple-android/AndroidManifest.xml index 91edeac..d695316 100644 --- a/examples/simple-android/AndroidManifest.xml +++ b/examples/simple-android/AndroidManifest.xml @@ -1,10 +1,8 @@ + package="com.rules.android.lint"> - - - + - + - +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 8e80cdd..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 @@ - + - + \ No newline at end of file From 7cb874a221ccc31b628bad9fcde1029fb7ab5c45 Mon Sep 17 00:00:00 2001 From: Arunkumar Date: Tue, 16 Apr 2024 00:52:55 +0800 Subject: [PATCH 6/6] Use manifest file as-is --- rules/impl.bzl | 3 --- 1 file changed, 3 deletions(-) diff --git a/rules/impl.bzl b/rules/impl.bzl index d1f80ef..689ea26 100644 --- a/rules/impl.bzl +++ b/rules/impl.bzl @@ -174,9 +174,6 @@ 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: