Skip to content

Commit 707c281

Browse files
committed
feat(scanoss): Map ScanOSS snippets to the ScanSummary
This commits maps the snippets in a ScanOSS response using the newly-created snippet data model. Please note that the snippet's license in the test data file has been manipulated to be a license not present in the other identifications of this file. This allows to demonstrate that license findings and snippet findings are disjoint in ORT, even if they are returned together by ScanOSS. Signed-off-by: Nicolas Nobelis <[email protected]>
1 parent 3c61670 commit 707c281

File tree

4 files changed

+533
-10
lines changed

4 files changed

+533
-10
lines changed

scanner/src/main/kotlin/scanners/scanoss/ScanOssResultParser.kt

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ import java.io.File
2323
import java.time.Instant
2424

2525
import org.ossreviewtoolkit.clients.scanoss.FullScanResponse
26+
import org.ossreviewtoolkit.clients.scanoss.model.IdentificationType
2627
import org.ossreviewtoolkit.clients.scanoss.model.ScanResponse
2728
import org.ossreviewtoolkit.model.CopyrightFinding
2829
import org.ossreviewtoolkit.model.LicenseFinding
2930
import org.ossreviewtoolkit.model.ScanSummary
3031
import org.ossreviewtoolkit.model.TextLocation
32+
import org.ossreviewtoolkit.model.utils.SnippetFinding
3133
import org.ossreviewtoolkit.utils.spdx.SpdxConstants
3234
import org.ossreviewtoolkit.utils.spdx.SpdxExpression
3335
import org.ossreviewtoolkit.utils.spdx.calculatePackageVerificationCode
@@ -64,11 +66,19 @@ internal fun generateSummary(
6466
): ScanSummary {
6567
val licenseFindings = mutableListOf<LicenseFinding>()
6668
val copyrightFindings = mutableListOf<CopyrightFinding>()
69+
val snippetFindings = mutableMapOf<String, MutableSet<SnippetFinding>>()
6770

6871
result.forEach { (_, scanResponses) ->
6972
scanResponses.forEach { scanResponse ->
70-
licenseFindings += getLicenseFindings(scanResponse, detectedLicenseMapping)
71-
copyrightFindings += getCopyrightFindings(scanResponse)
73+
if (scanResponse.id == IdentificationType.FILE) {
74+
licenseFindings += getLicenseFindings(scanResponse, detectedLicenseMapping)
75+
copyrightFindings += getCopyrightFindings(scanResponse)
76+
}
77+
if (scanResponse.id == IdentificationType.SNIPPET) {
78+
val path = requireNotNull(scanResponse.file)
79+
val findings = snippetFindings.getOrPut(path) { mutableSetOf() }
80+
findings += getSnippetFindings(scanResponse)
81+
}
7282
}
7383
}
7484

@@ -78,6 +88,7 @@ internal fun generateSummary(
7888
packageVerificationCode = verificationCode,
7989
licenseFindings = licenseFindings.toSortedSet(),
8090
copyrightFindings = copyrightFindings.toSortedSet(),
91+
snippetFindings = snippetFindings,
8192
issues = emptyList()
8293
)
8394
}
@@ -131,3 +142,39 @@ private fun getCopyrightFindings(scanResponse: ScanResponse): List<CopyrightFind
131142
)
132143
}
133144
}
145+
146+
/**
147+
* Get the snippet findings from the given [scanResponse].
148+
*/
149+
private fun getSnippetFindings(scanResponse: ScanResponse): Set<SnippetFinding> {
150+
val vendor = requireNotNull(scanResponse.vendor)
151+
val component = requireNotNull(scanResponse.component)
152+
val version = requireNotNull(scanResponse.version)
153+
val matched = requireNotNull(scanResponse.matched)
154+
val file = requireNotNull(scanResponse.file)
155+
val lines = requireNotNull(scanResponse.lines)
156+
val fileUrl = requireNotNull(scanResponse.fileUrl)
157+
val ossLines = requireNotNull(scanResponse.ossLines)
158+
159+
val licenses = scanResponse.licenses.map { license ->
160+
SpdxExpression.parse(license.name)
161+
}.toSet()
162+
163+
val score = matched.substringBeforeLast("%").toFloat()
164+
val sourceLocation = convertLines(file, lines)
165+
val snippetLocation = convertLines(fileUrl, ossLines)
166+
167+
return setOf(SnippetFinding(vendor, component, version, licenses, score, sourceLocation, snippetLocation))
168+
}
169+
170+
/**
171+
* Split a [lineRange] returned by ScanOSS such as 1-321 into a [TextLocation] for the given [file].
172+
*/
173+
private fun convertLines(file: String, lineRange: String): TextLocation {
174+
val splitLines = lineRange.split("-")
175+
return if (splitLines.size == 2) {
176+
TextLocation(file, splitLines.first().toInt(), splitLines.last().toInt())
177+
} else {
178+
TextLocation(file, splitLines.first().toInt())
179+
}
180+
}

0 commit comments

Comments
 (0)