Skip to content

Commit

Permalink
fix(reporter): Fix the creation of first level dependency relationships
Browse files Browse the repository at this point in the history
As of [1] the SPDX reporter intends to associate any first level
dependency with all root projects it corresponds to. The implementation
introduced by [1] has the following issues:

1. Relationships to excluded packages are added, even though excluded
   packages are not contained in the report. For proof see [2] which
   adds such relationship.
2. Dependencies which are direct depdendencies of a sub-project, but not
   of any root project are not considered a first level dependency. Such
   dependencies may not be linked into the dependency tree of resulting
   SPDX document at all.

Rewrite the algorithm in order to fix both of the above mentioned
issues.

Fixes #7487.

[1] b471544
[2] b471544#diff-6de35dd2aff1f92b7f5ea558d3f77e02d0d596dd4ce2a8199056cfb31b47fcabR181-R184

Signed-off-by: Frank Viernau <[email protected]>
  • Loading branch information
fviernau committed Sep 19, 2023
1 parent 023390a commit 91cd08a
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,6 @@
"spdxElementId" : "SPDXRef-Package-Maven-seventh-package-group-seventh-package-0.0.1",
"relationshipType" : "GENERATED_FROM",
"relatedSpdxElement" : "SPDXRef-Package-Maven-seventh-package-group-seventh-package-0.0.1-source-artifact"
}, {
"spdxElementId" : "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1",
"relationshipType" : "DEPENDS_ON",
"relatedSpdxElement" : "SPDXRef-Package-Maven-fifth-package-group-fifth-package-0.0.1"
}, {
"spdxElementId" : "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1",
"relationshipType" : "DEPENDS_ON",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,6 @@ relationships:
- spdxElementId: "SPDXRef-Package-Maven-seventh-package-group-seventh-package-0.0.1"
relationshipType: "GENERATED_FROM"
relatedSpdxElement: "SPDXRef-Package-Maven-seventh-package-group-seventh-package-0.0.1-source-artifact"
- spdxElementId: "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
relationshipType: "DEPENDS_ON"
relatedSpdxElement: "SPDXRef-Package-Maven-fifth-package-group-fifth-package-0.0.1"
- spdxElementId: "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
relationshipType: "DEPENDS_ON"
relatedSpdxElement: "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1"
Expand Down
37 changes: 30 additions & 7 deletions plugins/reporters/spdx/src/main/kotlin/SpdxDocumentModelMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicInteger

import org.apache.logging.log4j.kotlin.Logging

import org.ossreviewtoolkit.model.Identifier
import org.ossreviewtoolkit.model.OrtResult
import org.ossreviewtoolkit.model.SourceCodeOrigin.ARTIFACT
import org.ossreviewtoolkit.model.SourceCodeOrigin.VCS
Expand Down Expand Up @@ -64,21 +65,21 @@ internal object SpdxDocumentModelMapper : Logging {

val projects = ortResult.getProjects(omitExcluded = true, includeSubProjects = false).sortedBy { it.id }
val projectPackages = projects.map { project ->
val spdxProjectPackage = project.toPackage().toSpdxPackage(
project.toPackage().toSpdxPackage(
SpdxPackageType.PROJECT,
licenseInfoResolver,
ortResult
)
}

ortResult.getDependencies(project.id, 1).mapTo(relationships) { dependency ->
SpdxRelationship(
spdxElementId = spdxProjectPackage.spdxId,
ortResult.getRootProjectsForFirstLevelDependencies().forEach { (pkgId, rootProjectIds) ->
rootProjectIds.forEach { rootProjectId ->
relationships += SpdxRelationship(
spdxElementId = rootProjectId.toSpdxId(SpdxPackageType.PROJECT),
relationshipType = SpdxRelationship.Type.DEPENDS_ON,
relatedSpdxElement = dependency.toSpdxId()
relatedSpdxElement = pkgId.toSpdxId(SpdxPackageType.BINARY_PACKAGE)
)
}

spdxProjectPackage
}

val files = mutableListOf<SpdxFile>()
Expand Down Expand Up @@ -169,3 +170,25 @@ internal object SpdxDocumentModelMapper : Logging {
).addExtractedLicenseInfo(licenseTextProvider)
}
}

/**
* Return a mapping from the identifiers of all non-excluded first level dependencies to the identifiers of the
* non-excluded root projects they correspond to.
*/
private fun OrtResult.getRootProjectsForFirstLevelDependencies(): Map<Identifier, Set<Identifier>> {
val result = mutableMapOf<Identifier, MutableSet<Identifier>>()

getProjects(omitExcluded = true).map { it.id }.forEach { rootProjectId ->
val subProjectIds = getDependencies(rootProjectId).filter { isProject(it) && !isExcluded(it) }

val firstLevelDependencies = (subProjectIds + rootProjectId).flatMapTo(mutableSetOf()) { projectId ->
getDependencies(projectId, maxLevel = 1).filter { isPackage(it) && !isExcluded(it) }
}

firstLevelDependencies.forEach { pkgId ->
result.getOrPut(pkgId) { mutableSetOf() } += rootProjectId
}
}

return result
}

0 comments on commit 91cd08a

Please sign in to comment.