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

89 lines
3.4 KiB
Kotlin

package static_analysis.linters
import io.gitlab.arturbosch.detekt.Detekt
import org.gradle.api.Project
import org.gradle.api.file.FileTree
import static_analysis.errors.DetektError
import static_analysis.errors.StaticAnalysisError
import static_analysis.plugins.StaticAnalysisExtension
import static_analysis.utils.getSources
import static_analysis.utils.runCommand
import static_analysis.utils.typedChildren
import static_analysis.utils.xmlParser
import java.io.File
class DetektLinter : Linter {
private companion object {
const val ONLY_DIFFS_FLAG = "only-diffs"
const val GET_GIT_DIFFS_COMMAND = "git diff --name-only --ignore-submodules"
}
override val name: String = "Detekt"
override fun getErrors(project: Project): List<StaticAnalysisError> = xmlParser(project.getDetektReportFile())
.typedChildren()
.filter { fileNode -> fileNode.name() == "file" }
.map { fileNode ->
fileNode
.typedChildren()
.filter { it.name() == "error" }
.map { errorNode ->
DetektError(
filePath = fileNode.attribute("name") as String,
fileLine = errorNode.attribute("line") as String,
errorId = errorNode.attribute("source") as String,
description = errorNode.attribute("message") as String
)
}
}
.flatten()
override fun setupForProject(project: Project, extension: StaticAnalysisExtension) {
project.afterEvaluate {
tasks.withType(Detekt::class.java) {
exclude("**/test/**")
exclude("resources/")
exclude("build/")
exclude("tmp/")
jvmTarget = "1.8"
config.setFrom(files("${extension.buildScriptDir!!}/static_analysis_configs/detekt-config.yml"))
reports {
txt.enabled = false
html.enabled = false
xml {
enabled = true
destination = getDetektReportFile()
}
}
val isOnlyDiffs = properties["args"] == ONLY_DIFFS_FLAG // example: ./gradlew detektAnalysis -Pargs="only-diffs"
source = getSources(extension.excludes, isOnlyDiffs, project)
}
}
}
private fun getSources(excludes: String, isOnlyDiffs: Boolean, project: Project): FileTree = when {
isOnlyDiffs -> getGitDiffFiles(excludes, project)
else -> project.getSources(excludes)
}
private fun getGitDiffFiles(excludes: String, project: Project): FileTree {
val gitDiffs = GET_GIT_DIFFS_COMMAND.runCommand() ?: return project.files().asFileTree
val diffFiles = gitDiffs.lines()
.map { File(it) }
.filter { (it.extension == "kt" || it.extension == "java") && !excludes.contains(it.path) }
.toList()
return project.files(diffFiles).asFileTree
}
override fun getTaskNames(project: Project, buildType: String?): List<String> = listOf(":detekt")
private fun Project.getDetektReportFile() = file("${rootProject.buildDir}/reports/detekt.xml")
}