feature add detektAnalysis task

This commit is contained in:
Sergey Vlasenko 2024-03-19 10:46:12 +03:00
parent 5c46386ebf
commit b183a4f5f4
3 changed files with 80 additions and 1 deletions

View File

@ -2,15 +2,24 @@ 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())
@ -50,11 +59,39 @@ class DetektLinter : Linter {
}
}
source = getSources(extension.excludes)
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")

View File

@ -27,6 +27,23 @@ class StaticAnalysisAndroidPlugin : StaticAnalysisPlugin() {
buildVariant = applicationVariants.first { it.name.contains("Debug") }.name
)
}
/**
* Task to run detekt checks.
*
* @param --only-diffs <branch or commit> if specified, only files modified
* relative to this branch or commit will be checked. If specified without value
* then current uncommited changes will be checked. If not specified all source files will be checked.
* @see DetektLinter.getGitDiffFiles, 'git diff' for more info.
* */
project.tasks.register("detektAnalysis") {
val detektLinter = linters.find { it is DetektLinter }
?: throw IllegalStateException("DetektLinter not found")
setupStaticAnalysisTask(
linters = listOf(detektLinter),
buildVariant = applicationVariants.first { it.name.contains("Debug") }.name
)
}
}
}
}

View File

@ -0,0 +1,25 @@
package static_analysis.utils
import java.io.File
import java.io.IOException
import java.util.concurrent.TimeUnit
fun String.runCommand(
directoryToExecute: File? = null,
timeoutSec: Long = 30,
): String? {
return try {
val parts = this.split("\\s".toRegex())
val process = ProcessBuilder(*parts.toTypedArray())
.directory(directoryToExecute)
.redirectOutput(ProcessBuilder.Redirect.PIPE)
.redirectError(ProcessBuilder.Redirect.PIPE)
.start()
process.waitFor(timeoutSec, TimeUnit.SECONDS)
process.inputStream.bufferedReader().readText()
} catch(e: IOException) {
e.printStackTrace()
null
}
}