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 {
+