Skip to content

Commit a462740

Browse files
committed
feat(model,scanner): extract NONE-padding logic into reusable helpers
Prep work for upcoming PR oss-review-toolkit#10502. * Add ScanResult.padNoneLicenseFindings(paths) Creates a copy whose summary contains a single LicenseFinding(SpdxConstants.NONE, UNKNOWN_LINE) for every path in *paths* that currently lacks a licence finding. * Add ScannerRun.padNoneLicenseFindings() Uses the run’s FileList map to obtain all paths per provenance and delegates to the ScanResult helper for every contained result. * Remove the ad-hoc padding code from Scanner.kt and replace it with a single call to scannerRun.padNoneLicenseFindings() when includeFilesWithoutFindings is enabled. * Introduce ScannerRunTest.padNoneLicenseFindings() Ensures a file without licence findings receives exactly one NONE entry. This refactor keeps behaviour unchanged while centralising the padding logic in the model layer, improving reuse and testability. Signed-off-by: Jonatan Männchen <jonatan@maennchen.ch>
1 parent a15d3fb commit a462740

File tree

4 files changed

+96
-28
lines changed

4 files changed

+96
-28
lines changed

model/src/main/kotlin/ScanResult.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package org.ossreviewtoolkit.model
2222
import com.fasterxml.jackson.annotation.JsonInclude
2323

2424
import org.ossreviewtoolkit.model.utils.PathLicenseMatcher
25+
import org.ossreviewtoolkit.utils.spdx.SpdxConstants
2526

2627
/**
2728
* The result of a single scan of a single package.
@@ -73,4 +74,23 @@ data class ScanResult(
7374
*/
7475
fun filterByIgnorePatterns(ignorePatterns: Collection<String>): ScanResult =
7576
copy(summary = summary.filterByIgnorePatterns(ignorePatterns))
77+
78+
/**
79+
* Return a [ScanResult] whose [summary] contains SpdxConstants.NONE findings for all [paths] that do not
80+
* already have a license finding.
81+
*/
82+
internal fun padNoneLicenseFindings(paths: Set<String>): ScanResult {
83+
val pathsWithFindings = summary.licenseFindings.mapTo(mutableSetOf()) { it.location.path }
84+
val pathsWithoutFindings = paths - pathsWithFindings
85+
86+
val findingsThatAreNone = pathsWithoutFindings.mapTo(mutableSetOf()) {
87+
LicenseFinding(SpdxConstants.NONE, TextLocation(it, TextLocation.UNKNOWN_LINE))
88+
}
89+
90+
return copy(
91+
summary = summary.copy(
92+
licenseFindings = summary.licenseFindings + findingsThatAreNone
93+
)
94+
)
95+
}
7696
}

model/src/main/kotlin/ScannerRun.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,22 @@ data class ScannerRun(
273273
scanResultsById.mapValues { (_, scanResults) ->
274274
scanResults.flatMapTo(mutableSetOf()) { it.summary.issues }
275275
}.zipWithSets(issues)
276+
277+
/**
278+
* Return a [ScannerRun] where all scan results have been padded with findings for files that do not have any
279+
* license findings.
280+
*/
281+
internal fun padNoneLicenseFindings(): ScannerRun {
282+
val paddedScanResults = scanResults.mapTo(mutableSetOf()) { scanResult ->
283+
val allPaths = fileListByProvenance[scanResult.provenance]?.files?.mapTo(mutableSetOf()) {
284+
it.path
285+
}.orEmpty()
286+
287+
scanResult.padNoneLicenseFindings(allPaths)
288+
}
289+
290+
return copy(scanResults = paddedScanResults)
291+
}
276292
}
277293

278294
private fun scanResultForProvenanceResolutionIssues(packageProvenance: KnownProvenance?, issues: List<Issue>) =

model/src/test/kotlin/ScannerRunTest.kt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import io.kotest.matchers.should
2828
import org.ossreviewtoolkit.model.FileList.Entry
2929
import org.ossreviewtoolkit.model.utils.alignRevisions
3030
import org.ossreviewtoolkit.model.utils.clearVcsPath
31+
import org.ossreviewtoolkit.utils.spdx.SpdxConstants
3132

3233
class ScannerRunTest : WordSpec({
3334
"getFileList()" should {
@@ -145,4 +146,55 @@ class ScannerRunTest : WordSpec({
145146
)
146147
}
147148
}
149+
150+
"padNoneLicenseFindings()" should {
151+
"add NONE license findings for files without findings" {
152+
val provenance = RepositoryProvenance(
153+
VcsInfo(type = VcsType.GIT, url = "https://github.com/example.git", revision = "revision"),
154+
"revision"
155+
)
156+
157+
val run = ScannerRun.EMPTY.copy(
158+
provenances = setOf(
159+
ProvenanceResolutionResult(
160+
id = Identifier("maven::example:1.0"),
161+
packageProvenance = provenance
162+
)
163+
),
164+
scanResults = setOf(
165+
ScanResult(
166+
provenance = provenance,
167+
scanner = ScannerDetails.EMPTY,
168+
summary = ScanSummary.EMPTY.copy(
169+
licenseFindings = setOf(
170+
LicenseFinding("MIT", TextLocation("file1.txt", 1, 1))
171+
)
172+
)
173+
)
174+
),
175+
files = setOf(
176+
FileList(
177+
provenance = provenance,
178+
files = setOf(
179+
Entry(
180+
path = "file1.txt",
181+
sha1 = "1111111111111111111111111111111111111111"
182+
),
183+
Entry(
184+
path = "file2.txt",
185+
sha1 = "2222222222222222222222222222222222222222"
186+
)
187+
)
188+
)
189+
)
190+
)
191+
192+
val paddedRun = run.padNoneLicenseFindings()
193+
194+
paddedRun.scanResults.single().summary.licenseFindings should containExactlyInAnyOrder(
195+
LicenseFinding("MIT", TextLocation("file1.txt", 1, 1)),
196+
LicenseFinding(SpdxConstants.NONE, TextLocation("file2.txt", TextLocation.UNKNOWN_LINE))
197+
)
198+
}
199+
}
148200
})

scanner/src/main/kotlin/Scanner.kt

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,12 @@ import org.ossreviewtoolkit.model.FileList
3636
import org.ossreviewtoolkit.model.Identifier
3737
import org.ossreviewtoolkit.model.Issue
3838
import org.ossreviewtoolkit.model.KnownProvenance
39-
import org.ossreviewtoolkit.model.LicenseFinding
4039
import org.ossreviewtoolkit.model.OrtResult
4140
import org.ossreviewtoolkit.model.Package
4241
import org.ossreviewtoolkit.model.PackageType
4342
import org.ossreviewtoolkit.model.ProvenanceResolutionResult
4443
import org.ossreviewtoolkit.model.ScanResult
4544
import org.ossreviewtoolkit.model.ScannerRun
46-
import org.ossreviewtoolkit.model.TextLocation
4745
import org.ossreviewtoolkit.model.VcsInfo
4846
import org.ossreviewtoolkit.model.config.DownloaderConfiguration
4947
import org.ossreviewtoolkit.model.config.ScannerConfiguration
@@ -68,7 +66,6 @@ import org.ossreviewtoolkit.utils.common.collectMessages
6866
import org.ossreviewtoolkit.utils.common.safeDeleteRecursively
6967
import org.ossreviewtoolkit.utils.ort.Environment
7068
import org.ossreviewtoolkit.utils.ort.showStackTrace
71-
import org.ossreviewtoolkit.utils.spdx.SpdxConstants
7269
import org.ossreviewtoolkit.utils.spdx.toSpdx
7370

7471
class Scanner(
@@ -193,7 +190,7 @@ class Scanner(
193190

194191
val vcsPathsForProvenances = getVcsPathsForProvenances(provenances)
195192

196-
val filteredScanResults = filterScanResultsByVcsPaths(controller.getAllScanResults(), vcsPathsForProvenances)
193+
val scanResults = filterScanResultsByVcsPaths(controller.getAllScanResults(), vcsPathsForProvenances)
197194

198195
val files = controller.getAllFileLists().mapTo(mutableSetOf()) { (provenance, fileList) ->
199196
FileList(
@@ -208,42 +205,25 @@ class Scanner(
208205
}
209206
}
210207

211-
val scanResults = if (scannerConfig.includeFilesWithoutFindings) {
212-
filteredScanResults.mapTo(mutableSetOf()) { scanResult ->
213-
val allPaths = controller.getAllFileLists()[scanResult.provenance]?.files?.mapTo(mutableSetOf()) {
214-
it.path
215-
}.orEmpty()
216-
217-
val pathsWithFindings = scanResult.summary.licenseFindings.mapTo(mutableSetOf()) { it.location.path }
218-
val pathsWithoutFindings = allPaths - pathsWithFindings
219-
220-
val findingsThatAreNone = pathsWithoutFindings.mapTo(mutableSetOf()) {
221-
LicenseFinding(SpdxConstants.NONE, TextLocation(it, TextLocation.UNKNOWN_LINE))
222-
}
223-
224-
scanResult.copy(
225-
summary = scanResult.summary.copy(
226-
licenseFindings = scanResult.summary.licenseFindings + findingsThatAreNone
227-
)
228-
)
229-
}
230-
} else {
231-
filteredScanResults
232-
}
233-
234208
val scannerIds = scannerWrappers.mapTo(mutableSetOf()) { it.descriptor.id }
235209
val scanners = packages.associateBy({ it.id }) { scannerIds }
236210

237211
val issues = controller.getIssues()
238212

239-
return ScannerRun.EMPTY.copy(
213+
val scannerRun = ScannerRun.EMPTY.copy(
240214
config = scannerConfig,
241215
provenances = provenances,
242216
scanResults = scanResults,
243217
files = files,
244218
scanners = scanners,
245219
issues = issues
246220
)
221+
222+
if (scannerConfig.includeFilesWithoutFindings) {
223+
return scannerRun.padNoneLicenseFindings()
224+
}
225+
226+
return scannerRun
247227
}
248228

249229
private suspend fun resolvePackageProvenances(controller: ScanController) {

0 commit comments

Comments
 (0)