From 4d532d862022df5921d21be19f8862e1409e1fce Mon Sep 17 00:00:00 2001 From: Frank Viernau Date: Tue, 5 Dec 2023 09:28:35 +0100 Subject: [PATCH] feat(model): Enable `Issue.affectedPath` also for older scan results Set the affected path during deserialization. Scan results which have been created before `affectedPath` got introduced now still have the value set properly. Signed-off-by: Frank Viernau --- model/src/main/kotlin/ScanSummary.kt | 19 +++++++++++++++++++ model/src/test/kotlin/ScanSummaryTest.kt | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/model/src/main/kotlin/ScanSummary.kt b/model/src/main/kotlin/ScanSummary.kt index cda072a73102b..19eaaf18dcf13 100644 --- a/model/src/main/kotlin/ScanSummary.kt +++ b/model/src/main/kotlin/ScanSummary.kt @@ -23,7 +23,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.databind.util.StdConverter import java.time.Instant @@ -79,6 +81,7 @@ data class ScanSummary( * the size of the result file. */ @JsonInclude(JsonInclude.Include.NON_EMPTY) + @JsonDeserialize(converter = IssueListConverter::class) val issues: List = emptyList() ) { companion object { @@ -144,3 +147,19 @@ data class ScanSummary( ) } } + +/** + * Set the `affectedPath` for scan timeout errors if otherwise it would have been unset. This way scan results which + * have been created before `affectedPath` was introduced will still have that property set. + */ + +internal class IssueListConverter : StdConverter, List>() { + override fun convert(issues: List): List = + issues.map { issue -> + if (issue.affectedPath != null) return@map issue + val match = TIMEOUT_ERROR_REGEX.matchEntire(issue.message) ?: return@map issue + issue.copy(affectedPath = match.groups["file"]!!.value) + } +} + +private val TIMEOUT_ERROR_REGEX = Regex("ERROR: Timeout after (\\d+) seconds while scanning file '(?.+)'.") diff --git a/model/src/test/kotlin/ScanSummaryTest.kt b/model/src/test/kotlin/ScanSummaryTest.kt index e4bedd1ef1673..5161d108dbd1b 100644 --- a/model/src/test/kotlin/ScanSummaryTest.kt +++ b/model/src/test/kotlin/ScanSummaryTest.kt @@ -22,6 +22,7 @@ package org.ossreviewtoolkit.model import io.kotest.core.spec.style.WordSpec import io.kotest.matchers.collections.containExactly import io.kotest.matchers.should +import io.kotest.matchers.shouldBe import org.ossreviewtoolkit.utils.spdx.SpdxExpression @@ -55,6 +56,18 @@ class ScanSummaryTest : WordSpec({ containExactly("a/file.txt", "b/c/file.txt") } } + + "deserializing an old scan result()" should { + "set the affected path of issues which represent a scan timeout error" { + val summary = createSummaryWithIssue( + "ERROR: Timeout after 300 seconds while scanning file 'some-path/some-file.txt'." + ) + + val deserializedSummary = summary.toYaml().fromYaml() + + deserializedSummary.issues.single().affectedPath shouldBe "some-path/some-file.txt" + } + } }) private fun createSummaryWithFindingAndIssuePaths(vararg paths: String): ScanSummary { @@ -88,3 +101,12 @@ private fun createSummaryWithFindingAndIssuePaths(vararg paths: String): ScanSum } ) } + +private fun createSummaryWithIssue(message: String): ScanSummary { + val issue = Issue( + source = "some source", + message = message + ) + + return ScanSummary.EMPTY.copy(issues = listOf(issue)) +}