From 1e089a44e384796f1713020f88fc9cd39ab98b0b Mon Sep 17 00:00:00 2001 From: Marcin Simonides Date: Thu, 24 Feb 2022 10:45:50 +0100 Subject: [PATCH] Detekt: use code snippet as fingerprint instead of position. The signature for some formatting warnings is just file name and line number. In this case use the surrounding code to build issue fingerprint. --- .../outputreport/GitlabQualityOutputReport.kt | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/detekt-gitlab-output-plugin/src/main/kotlin/outputreport/GitlabQualityOutputReport.kt b/detekt-gitlab-output-plugin/src/main/kotlin/outputreport/GitlabQualityOutputReport.kt index 755c0aece..5c986b092 100644 --- a/detekt-gitlab-output-plugin/src/main/kotlin/outputreport/GitlabQualityOutputReport.kt +++ b/detekt-gitlab-output-plugin/src/main/kotlin/outputreport/GitlabQualityOutputReport.kt @@ -20,9 +20,13 @@ package outputreport import io.gitlab.arturbosch.detekt.api.Detektion +import io.gitlab.arturbosch.detekt.api.Location import io.gitlab.arturbosch.detekt.api.OutputReport import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json +import java.io.File + +private const val CONTEXT_SIZE = 10 class GitlabQualityOutputReport : OutputReport() { @@ -33,17 +37,36 @@ class GitlabQualityOutputReport : OutputReport() { override fun render(detektion: Detektion): String { val findings = detektion.findings.values.flatten() val reports = findings.map { - val location = with(it.entity.location) { + val location = with(it.location) { GitlabQualityReport.Location( GitlabQualityReport.Location.Lines(source.line, source.line), (filePath.relativePath ?: filePath.absolutePath).toString() ) } - val fingerprint = it.issue.id + " - " + it.signature + val fingerprintSignature = if (isFilePosition(it.signature, it.location)) + with(it.location) { getTextContext(filePath.absolutePath.toString(), text.start, text.end) } + else + it.signature + + val fingerprint = it.issue.id + " - " + fingerprintSignature // Detekt severity doesn't map well to GitLab severity. val severity = "info" GitlabQualityReport(it.messageOrDescription(), fingerprint, location, severity) } return json.encodeToString(reports) } + + private fun isFilePosition(signature: String, location: Location): Boolean = with(location) { + signature.endsWith("${filePath.absolutePath.fileName}:${source.line}") + } + + private fun getTextContext(filePath: String, startOffset: Int, endOffset: Int): String { + val contents = File(filePath).readText().replace("\r\n", "\n") + val selection = contents.slice(startOffset until endOffset) + return selection.ifBlank { + val preceding = contents.slice((startOffset - CONTEXT_SIZE).coerceAtLeast(0) until startOffset) + val following = contents.slice(endOffset until (endOffset + CONTEXT_SIZE).coerceAtMost(contents.length)) + preceding + following + } + } }