100 lines
3.7 KiB
Kotlin
100 lines
3.7 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 TAG = "DetektLinter"
|
|
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 diffsBranch = properties[ONLY_DIFFS_FLAG] as? String
|
|
source = getSources(extension.excludes, diffsBranch, project)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun getSources(excludes: String, diffsBranch: String?, project: Project): FileTree = when (diffsBranch) {
|
|
null -> project.getSources(excludes)
|
|
else -> getGitDiffFiles(excludes, diffsBranch, project)
|
|
}
|
|
|
|
private fun getGitDiffFiles(excludes: String, diffsBranch: String, project: Project): FileTree {
|
|
val getGitDiffsCommand = if (diffsBranch.isEmpty()) {
|
|
GET_GIT_DIFFS_COMMAND
|
|
} else {
|
|
GET_GIT_DIFFS_COMMAND.plus(" --merge-base $diffsBranch")
|
|
}
|
|
|
|
val gitDiffs = getGitDiffsCommand.runCommand()
|
|
|
|
if (gitDiffs.isNullOrEmpty()) {
|
|
project.logger.error("$TAG: Diffs are empty or specified branch or commit does not exists")
|
|
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")
|
|
|
|
}
|