Skip to content

Commit

Permalink
Basic android lint implementation (#119)
Browse files Browse the repository at this point in the history
Fixes #119
  • Loading branch information
arunkumar9t2 committed Oct 24, 2023
1 parent a20492f commit a6960f8
Show file tree
Hide file tree
Showing 10 changed files with 10,136 additions and 3,341 deletions.
13,285 changes: 9,947 additions & 3,338 deletions bazel_common_maven_install.json

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions rules/android/android_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ load("@grab_bazel_common//tools/res_value:res_value.bzl", "res_value")
load("@grab_bazel_common//tools/kotlin:android.bzl", "kt_android_library")
load("@grab_bazel_common//rules/android/databinding:databinding.bzl", "kt_db_android_library")
load(":resources.bzl", "build_resources")
load(":lint.bzl", "lint")

"""Enhanced android_library rule with support for build configs, res values, Kotlin compilation and databinding support"""

Expand Down Expand Up @@ -80,3 +81,13 @@ def android_library(
deps = android_library_deps,
plugins = attrs.get("plugins", default = None),
)

lint(
name = name + ".lint",
srcs = srcs,
resources = resource_files,
manifest = attrs.get("manifest"),
deps = android_library_deps,
android = False,
library = True,
)
4 changes: 2 additions & 2 deletions rules/android/compose/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@grab_bazel_common//rules:defs.bzl", "kt_compiler_plugin", "kt_jvm_library")
load("@grab_bazel_common//rules:defs.bzl", "kotlin_library", "kt_compiler_plugin")

kt_compiler_plugin(
name = "compose-compiler-plugin",
Expand All @@ -9,7 +9,7 @@ kt_compiler_plugin(
],
)

kt_jvm_library(
kotlin_library(
name = "compose-plugin",
exported_compiler_plugins = [":compose-compiler-plugin"],
visibility = ["//visibility:public"],
Expand Down
78 changes: 78 additions & 0 deletions rules/android/lint.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
def _lint_test_impl(ctx):
classpath = depset()
for dep in ctx.attr.deps:
if JavaInfo in dep:
classpath = depset(transitive = [classpath, dep[JavaInfo].transitive_runtime_jars, dep[JavaInfo].transitive_compile_time_jars])

# TODO Extract dependent modules via a custom provider

project_xml_file = ctx.actions.declare_file(ctx.label.name + "_project.xml")

# Create project XML:
project_xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
project_xml += "<project>\n"
project_xml += "<module name=\"{0}\" android=\"false\" library=\"true\">\n".format(ctx.label.name)
for file in ctx.files.srcs:
project_xml += " <src file=\"{0}\" ".format(file.path)
if ctx.attr.is_test_sources:
project_xml += "test=\"true\" "
project_xml += "/>\n"
for file in ctx.files.resources:
project_xml += " <resource file=\"{0}\"/>\n".format(file.path)
for file in classpath.to_list():
project_xml += " <classpath jar=\"{0}\" />\n".format(file.path)
if ctx.file.manifest != None:
project_xml += " <manifest file=\"{0}\"/>\n".format(ctx.file.manifest.path)
if ctx.file.merged_manifest != None:
project_xml += " <merged-manifest file=\"{0}\"/>\n".format(ctx.file.merged_manifest.path)

project_xml += "</module>\n"
project_xml += "</project>\n"

ctx.actions.write(output = project_xml_file, content = project_xml)

args = ctx.actions.args()
args.set_param_file_format("multiline")
args.use_param_file("--flagfile=%s", use_always = True)

args.add("--project-xml", project_xml_file.path)
args.add("--output-xml", ctx.outputs.lint_result)

mnemonic = "AndroidLint"
ctx.actions.run(
mnemonic = mnemonic,
inputs = depset(ctx.files.srcs + ctx.files.resources + [project_xml_file], transitive = [classpath]),
outputs = [ctx.outputs.lint_result],
executable = ctx.executable._lint_cli,
arguments = [args],
progress_message = "%s %s" % (mnemonic, ctx.label),
execution_requirements = {
"supports-workers": "1",
"supports-multiplex-workers": "1",
"requires-worker-protocol": "json",
},
)

return [DefaultInfo(files = depset([ctx.outputs.lint_result]))]

lint = rule(
attrs = {
"srcs": attr.label_list(allow_files = True),
"resources": attr.label_list(allow_files = True),
"deps": attr.label_list(allow_files = True),
"merged_manifest": attr.label(allow_single_file = True),
"manifest": attr.label(allow_single_file = True),
"android": attr.bool(),
"library": attr.bool(),
"is_test_sources": attr.bool(),
"_lint_cli": attr.label(
executable = True,
cfg = "target",
default = Label("//tools/lint:lint_cli"),
),
},
outputs = {
"lint_result": "%{name}_result.xml",
},
implementation = _lint_test_impl,
)
2 changes: 1 addition & 1 deletion rules/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ android_instrumentation_binary = _android_instrumentation_binary
android_unit_test = _android_unit_test

# Kotlin
kt_jvm_library = _kt_jvm_library
kotlin_library = _kt_jvm_library
kt_compiler_plugin = _kt_compiler_plugin
kotlin_test = _kotlin_test
2 changes: 2 additions & 0 deletions rules/setup.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def bazel_common_setup(
maven_install(
name = repo_name,
artifacts = DAGGER_ARTIFACTS + [
"com.android.tools.lint:lint:31.0.2",
"com.google.guava:guava:29.0-jre",
"com.google.auto:auto-common:0.10",
"com.google.auto.service:auto-service:1.0-rc6",
Expand Down Expand Up @@ -89,6 +90,7 @@ def bazel_common_setup(
],
strict_visibility = True,
maven_install_json = maven_install_json,
fetch_sources = True,
)

_android(patched_android_tools)
Expand Down
10 changes: 10 additions & 0 deletions tools/lint/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
java_binary(
name = "lint_cli",
main_class = "com.grab.lint.MainKt",
visibility = [
"//visibility:public",
],
runtime_deps = [
"//tools/lint/src/main/java/com/grab/lint",
],
)
17 changes: 17 additions & 0 deletions tools/lint/src/main/java/com/grab/lint/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
load("@grab_bazel_common//rules:defs.bzl", "kotlin_library")

kotlin_library(
name = "lint",
srcs = glob([
"*.kt",
]),
visibility = [
"//visibility:public",
],
deps = [
"//:dagger",
"//tools/worker:worker_lib",
"@bazel_common_maven//:com_android_tools_lint_lint",
"@bazel_common_maven//:com_github_ajalt_clikt",
],
)
59 changes: 59 additions & 0 deletions tools/lint/src/main/java/com/grab/lint/LintCommand.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.grab.lint

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.convert
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.required
import java.io.File
import kotlin.io.path.writeLines
import com.android.tools.lint.Main as LintCli

class LintCommand : CliktCommand() {

private val projectXml by option(
"-p",
"--project-xml",
help = "Project descriptor XML"
).convert { File(it) }.required()

private val lintConfig by option(
"-l",
"--lint-config",
help = "Path to lint config"
).convert { File(it) }

private val outputXml by option(
"-o",
"--output-xml",
help = "Lint output xml"
).convert { File(it) }.required()

override fun run() {
val outputDir = File(".").toPath()
val baselineFile = outputDir.resolve("baseline.xml")

// TODO: Get this from rule itself
val lintConfig = outputDir.resolve("lint.xml").writeLines(
listOf(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<lint checkTestSources=\"true\">",
" <issue id=\"all\" severity=\"error\" />",
" <issue id=\"MissingSuperCall\" severity=\"error\" />",
"</lint>"
)
)

outputXml.createNewFile()

val lintCli = LintCli()
lintCli.run(
arrayOf(
"--project", projectXml.toString(),
"--xml", outputXml.toString(),
"--baseline", baselineFile.toString(),
"--config", lintConfig.toString(),
"--client-id", "test"
)
)
}
}
9 changes: 9 additions & 0 deletions tools/lint/src/main/java/com/grab/lint/Main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.grab.lint

import io.bazel.Worker

fun main(args: Array<String>) {
Worker.create(args) { cliArgs ->
LintCommand().main(cliArgs)
}.run()
}

0 comments on commit a6960f8

Please sign in to comment.