Skip to content

Commit 1bbe4ed

Browse files
committed
feat(evaluated-model): Add path includes properties to the evaluated model
Signed-off-by: Nicolas Nobelis <[email protected]>
1 parent 4c6743a commit 1bbe4ed

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

plugins/reporters/evaluated-model/src/main/kotlin/EvaluatedFinding.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,9 @@ data class EvaluatedFinding(
3838
val endLine: Int,
3939
val scanResult: EvaluatedScanResult,
4040
@JsonInclude(JsonInclude.Include.NON_EMPTY)
41-
val pathExcludes: List<PathExclude>
41+
val pathExcludes: List<PathExclude>,
42+
43+
// If the finding is excluded by the presence of a [PathInclude], this property is true.
44+
@JsonInclude(JsonInclude.Include.NON_EMPTY)
45+
val isExcludedByPathIncludes: Boolean
4246
)

plugins/reporters/evaluated-model/src/main/kotlin/EvaluatedModel.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import org.ossreviewtoolkit.model.config.RepositoryConfiguration
4343
import org.ossreviewtoolkit.model.config.RuleViolationResolution
4444
import org.ossreviewtoolkit.model.config.ScopeExclude
4545
import org.ossreviewtoolkit.model.config.VulnerabilityResolution
46+
import org.ossreviewtoolkit.model.config.PathInclude
4647
import org.ossreviewtoolkit.model.mapperConfig
4748
import org.ossreviewtoolkit.reporter.Reporter
4849
import org.ossreviewtoolkit.reporter.ReporterInput
@@ -91,6 +92,7 @@ import org.ossreviewtoolkit.reporter.Statistics
9192
*/
9293
data class EvaluatedModel(
9394
val pathExcludes: List<PathExclude>,
95+
val pathIncludes: List<PathInclude>,
9496
val scopeExcludes: List<ScopeExclude>,
9597
val copyrights: List<CopyrightStatement>,
9698
val licenses: List<LicenseId>,

plugins/reporters/evaluated-model/src/main/kotlin/EvaluatedModelMapper.kt

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import org.ossreviewtoolkit.model.config.Resolutions
4444
import org.ossreviewtoolkit.model.config.RuleViolationResolution
4545
import org.ossreviewtoolkit.model.config.ScopeExclude
4646
import org.ossreviewtoolkit.model.config.VulnerabilityResolution
47+
import org.ossreviewtoolkit.model.config.PathInclude
4748
import org.ossreviewtoolkit.model.licenses.LicenseView
4849
import org.ossreviewtoolkit.model.toYaml
4950
import org.ossreviewtoolkit.model.utils.FindingCurationMatcher
@@ -59,7 +60,7 @@ import org.ossreviewtoolkit.utils.spdx.calculatePackageVerificationCode
5960
/**
6061
* Maps the [reporter input][input] to an [EvaluatedModel].
6162
*/
62-
@Suppress("TooManyFunctions")
63+
@Suppress("LargeClass", "TooManyFunctions")
6364
internal class EvaluatedModelMapper(private val input: ReporterInput) {
6465
private val packages = mutableMapOf<Identifier, EvaluatedPackage>()
6566
private val paths = mutableListOf<EvaluatedPackagePath>()
@@ -71,6 +72,7 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
7172
private val issues = mutableListOf<EvaluatedIssue>()
7273
private val issueResolutions = mutableListOf<IssueResolution>()
7374
private val pathExcludes = mutableListOf<PathExclude>()
75+
private val pathIncludes = mutableListOf<PathInclude>()
7476
private val scopeExcludes = mutableListOf<ScopeExclude>()
7577
private val ruleViolations = mutableListOf<EvaluatedRuleViolation>()
7678
private val ruleViolationResolutions = mutableListOf<RuleViolationResolution>()
@@ -84,6 +86,7 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
8486
var id: Identifier,
8587
var isExcluded: Boolean,
8688
val pathExcludes: MutableList<PathExclude> = mutableListOf(),
89+
val pathIncludes: MutableList<PathInclude> = mutableListOf(),
8790
val scopeExcludes: MutableList<ScopeExclude> = mutableListOf()
8891
)
8992

@@ -134,6 +137,7 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
134137

135138
return EvaluatedModel(
136139
pathExcludes = pathExcludes,
140+
pathIncludes = pathIncludes,
137141
scopeExcludes = scopeExcludes,
138142
issueResolutions = issueResolutions,
139143
issues = issues,
@@ -169,21 +173,26 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
169173

170174
input.ortResult.getProjects().forEach { project ->
171175
val pathExcludes = input.ortResult.getExcludes().findPathExcludes(project, input.ortResult)
176+
val pathIncludes = input.ortResult.getIncludes().findPathIncludes(project, input.ortResult)
172177
val dependencies = input.ortResult.dependencyNavigator.projectDependencies(project)
173-
if (pathExcludes.isEmpty()) {
178+
if (pathExcludes.isEmpty() && pathIncludes.isEmpty()) {
174179
val info = packageExcludeInfo.getValue(project.id)
175180
if (info.isExcluded) {
176181
info.isExcluded = false
177182
info.pathExcludes.clear()
178183
info.scopeExcludes.clear()
179184
}
185+
186+
info.pathIncludes.clear()
180187
} else {
181188
dependencies.forEach { id ->
182189
val info = packageExcludeInfo.getOrPut(id) { PackageExcludeInfo(id, true) }
183190

184191
if (info.isExcluded) {
185192
info.pathExcludes += pathExcludes
186193
}
194+
195+
info.pathIncludes += pathIncludes
187196
}
188197
}
189198

@@ -238,6 +247,14 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
238247
.flatMap { it.pathExcludes }
239248
}
240249

250+
private fun getPathIncludes(id: Identifier, provenance: Provenance): List<PathInclude> =
251+
if (input.ortResult.isProject(id)) {
252+
input.ortResult.getIncludes().paths
253+
} else {
254+
input.ortResult.getPackageConfigurations(id, provenance)
255+
.flatMap { it.pathIncludes }
256+
}
257+
241258
private fun addProject(project: Project) {
242259
val scanResults = mutableListOf<EvaluatedScanResult>()
243260
val detectedLicenses = mutableSetOf<LicenseId>()
@@ -246,7 +263,9 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
246263
val issues = mutableListOf<EvaluatedIssue>()
247264

248265
val applicablePathExcludes = input.ortResult.getExcludes().findPathExcludes(project, input.ortResult)
266+
val applicablePathIncludes = input.ortResult.getIncludes().findPathIncludes(project, input.ortResult)
249267
val evaluatedPathExcludes = pathExcludes.addIfRequired(applicablePathExcludes)
268+
pathIncludes.addIfRequired(applicablePathIncludes)
250269

251270
val evaluatedPackage = EvaluatedPackage(
252271
id = project.id,
@@ -287,7 +306,8 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
287306
findings.filter { it.type == EvaluatedFindingType.LICENSE }.mapNotNullTo(detectedLicenses) { it.license }
288307

289308
val includedDetectedLicenses = findings.filter {
290-
it.type == EvaluatedFindingType.LICENSE && it.pathExcludes.isEmpty()
309+
val isIncluded = pathIncludes.isEmpty() || pathIncludes.any { include -> include.matches(it.path) }
310+
it.type == EvaluatedFindingType.LICENSE && it.pathExcludes.isEmpty() && isIncluded
291311
}.mapNotNullTo(mutableSetOf()) { it.license }
292312

293313
detectedExcludedLicenses += detectedLicenses - includedDetectedLicenses
@@ -660,6 +680,7 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
660680
findings: MutableList<EvaluatedFinding>
661681
) {
662682
val pathExcludes = getPathExcludes(id, scanResult.provenance)
683+
val pathIncludes = getPathIncludes(id, scanResult.provenance)
663684
val licenseFindingCurations = getLicenseFindingCurations(id, scanResult.provenance)
664685
// Sort the curated findings here to avoid the need to sort in the web-app each time it is loaded.
665686
val curatedFindings = curationsMatcher.applyAll(scanResult.summary.licenseFindings, licenseFindingCurations)
@@ -679,6 +700,16 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
679700
val evaluatedPathExcludes = pathExcludes
680701
.filter { it.matches(copyrightFinding.location.getRelativePathToRoot(id)) }
681702
.let { this@EvaluatedModelMapper.pathExcludes.addIfRequired(it) }
703+
pathIncludes.let { this@EvaluatedModelMapper.pathIncludes.addIfRequired(it) }
704+
705+
val evaluatedPathIncludes = if (pathIncludes.isEmpty() || pathIncludes.any { include ->
706+
include.matches(copyrightFinding.location.getRelativePathToRoot(id))
707+
}
708+
) {
709+
emptyList()
710+
} else {
711+
pathIncludes
712+
}
682713

683714
findings += EvaluatedFinding(
684715
type = EvaluatedFindingType.COPYRIGHT,
@@ -688,7 +719,8 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
688719
startLine = copyrightFinding.location.startLine,
689720
endLine = copyrightFinding.location.endLine,
690721
scanResult = evaluatedScanResult,
691-
pathExcludes = evaluatedPathExcludes
722+
pathExcludes = evaluatedPathExcludes,
723+
isExcludedByPathIncludes = evaluatedPathExcludes.isEmpty() && evaluatedPathIncludes.isNotEmpty()
692724
)
693725
}
694726

@@ -699,6 +731,18 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
699731
.filter { it.matches(licenseFinding.location.getRelativePathToRoot(id)) }
700732
.let { this@EvaluatedModelMapper.pathExcludes.addIfRequired(it) }
701733

734+
pathIncludes.let { this@EvaluatedModelMapper.pathIncludes.addIfRequired(it) }
735+
736+
val evaluatedPathIncludes = if (pathIncludes.isEmpty() || pathIncludes.any {
737+
include ->
738+
include.matches(licenseFinding.location.getRelativePathToRoot(id))
739+
}
740+
) {
741+
emptyList()
742+
} else {
743+
pathIncludes
744+
}
745+
702746
findings += EvaluatedFinding(
703747
type = EvaluatedFindingType.LICENSE,
704748
license = actualLicense,
@@ -707,7 +751,8 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
707751
startLine = licenseFinding.location.startLine,
708752
endLine = licenseFinding.location.endLine,
709753
scanResult = evaluatedScanResult,
710-
pathExcludes = evaluatedPathExcludes
754+
pathExcludes = evaluatedPathExcludes,
755+
isExcludedByPathIncludes = evaluatedPathExcludes.isEmpty() && evaluatedPathIncludes.isNotEmpty()
711756
)
712757
}
713758
}
@@ -772,6 +817,12 @@ internal class EvaluatedModelMapper(private val input: ReporterInput) {
772817
)
773818
}
774819

775-
return copy(config = config.copy(excludes = excludes, resolutions = resolutions))
820+
val includes = with(config.includes) {
821+
copy(
822+
paths = paths.map { pathIncludes.addIfRequired(it) }
823+
)
824+
}
825+
826+
return copy(config = config.copy(excludes = excludes, includes = includes, resolutions = resolutions))
776827
}
777828
}

0 commit comments

Comments
 (0)