BuildScripts/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt

80 lines
3.3 KiB
Kotlin

package static_analysis.linters
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.gradle.AppPlugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.findByType
import static_analysis.errors.AndroidLintError
import static_analysis.errors.StaticAnalysisError
import static_analysis.plugins.StaticAnalysisExtension
import static_analysis.utils.typedChildren
import static_analysis.utils.xmlParser
class AndroidLinter : Linter {
override val name: String = "Android lint"
override fun getErrors(project: Project): List<StaticAnalysisError> = xmlParser(project.getLintReportFile())
.typedChildren()
.filter { it.name() == "issue" && (it.attribute("severity") as String) == "Error" }
.map { errorNode ->
errorNode
.typedChildren()
.filter { it.name() == "location" }
.map { locationNode ->
AndroidLintError(
filePath = locationNode.attribute("file") as String,
fileLine = locationNode.attribute("line") as String?,
errorId = errorNode.attribute("id") as String,
description = errorNode.attribute("message") as String
)
}
}
.flatten()
@Suppress("UnstableApiUsage")
override fun setupForProject(project: Project, extension: StaticAnalysisExtension) {
// Make sure to set lint options manually in app module gradle file
// Otherwise you will get java.io.FileNotFoundException
project.beforeEvaluate {
subprojects
.mapNotNull { it.extensions.findByType(AndroidComponentsExtension::class) }
.first()
.finalizeDsl { ext ->
ext.lint {
abortOnError = false
checkAllWarnings = true
warningsAsErrors = false
checkDependencies = true
htmlReport = false
textReport = false
xmlReport = true
disable.addAll(listOf("MissingConstraints", "VectorRaster"))
xmlOutput = project.getLintReportFile()
lintConfig = file("${extension.buildScriptDir}/static_analysis_configs/lint.xml")
}
}
}
}
override fun getTaskNames(project: Project, buildType: String?): List<String> {
if (buildType == null) {
throw IllegalStateException("Build type must not be null in android linter")
}
return project
.subprojects
.filter { it.plugins.hasPlugin(AppPlugin::class.java) }
.mapNotNull { subproject: Project ->
subproject
.tasks
.find { task -> task.name.equals("lint$buildType") }
?.path
}
}
private fun Project.getLintReportFile() = file("${rootProject.buildDir}/reports/lint-report.xml")
}