Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SpdxDocumentModelMapper: Make SPDX "idstring" generation predictable #5225

Merged
merged 1 commit into from
Apr 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
"licenseId" : "LicenseRef-scancode-srgb"
} ],
"documentNamespace" : "<REPLACE_DOCUMENT_NAMESPACE>",
"documentDescribes" : [ "SPDXRef-Package-0-root-package" ],
"documentDescribes" : [ "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1" ],
"packages" : [ {
"SPDXID" : "SPDXRef-Package-0-root-package",
"SPDXID" : "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1",
"copyrightText" : "NOASSERTION",
"downloadLocation" : "NOASSERTION",
"filesAnalyzed" : false,
Expand All @@ -29,7 +29,7 @@
"licenseDeclared" : "NOASSERTION",
"name" : "Root package"
}, {
"SPDXID" : "SPDXRef-Package-1-first-package",
"SPDXID" : "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1",
"copyrightText" : "Copyright 2020 Some copyright holder in VCS\nCopyright 2020 Some copyright holder in source artifact\nCopyright 2020 Some other copyright holder in source artifact",
"downloadLocation" : "https://some-host/first-package.jar",
"externalRefs" : [ {
Expand All @@ -45,7 +45,7 @@
"summary" : "A package with all supported attributes set, with a VCS URL containing a user name, and with a scan result containing two copyright finding matched to a license finding.",
"versionInfo" : "0.0.1"
}, {
"SPDXID" : "SPDXRef-Package-2-first-package-vcs",
"SPDXID" : "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1-vcs",
"copyrightText" : "Copyright 2020 Some copyright holder in VCS\nCopyright 2020 Some copyright holder in source artifact\nCopyright 2020 Some other copyright holder in source artifact",
"downloadLocation" : "git+ssh://github.com/path/first-package-repo.git@deadbeef#project-path",
"externalRefs" : [ {
Expand All @@ -64,7 +64,7 @@
"summary" : "A package with all supported attributes set, with a VCS URL containing a user name, and with a scan result containing two copyright finding matched to a license finding.",
"versionInfo" : "0.0.1"
}, {
"SPDXID" : "SPDXRef-Package-3-first-package-source-artifact",
"SPDXID" : "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1-source-artifact",
"copyrightText" : "Copyright 2020 Some copyright holder in VCS\nCopyright 2020 Some copyright holder in source artifact\nCopyright 2020 Some other copyright holder in source artifact",
"downloadLocation" : "https://some-host/first-package-sources.jar",
"externalRefs" : [ {
Expand All @@ -83,7 +83,7 @@
"summary" : "A package with all supported attributes set, with a VCS URL containing a user name, and with a scan result containing two copyright finding matched to a license finding.",
"versionInfo" : "0.0.1"
}, {
"SPDXID" : "SPDXRef-Package-4-fourth-package",
"SPDXID" : "SPDXRef-Package-Maven-fourth-package-group-fourth-package-0.0.1",
"copyrightText" : "NONE",
"downloadLocation" : "NONE",
"externalRefs" : [ {
Expand All @@ -99,7 +99,7 @@
"summary" : "A package with partially mapped declared license.",
"versionInfo" : "0.0.1"
}, {
"SPDXID" : "SPDXRef-Package-5-second-package",
"SPDXID" : "SPDXRef-Package-Maven-second-package-group-second-package-0.0.1",
"copyrightText" : "NONE",
"downloadLocation" : "NONE",
"externalRefs" : [ {
Expand All @@ -115,7 +115,7 @@
"summary" : "A package with minimal attributes set.",
"versionInfo" : "0.0.1"
}, {
"SPDXID" : "SPDXRef-Package-6-sixth-package",
"SPDXID" : "SPDXRef-Package-Maven-sixth-package-group-sixth-package-0.0.1",
"copyrightText" : "NONE",
"downloadLocation" : "NONE",
"externalRefs" : [ {
Expand All @@ -131,7 +131,7 @@
"summary" : "A package with non-SPDX license IDs in the declared and concluded license.",
"versionInfo" : "0.0.1"
}, {
"SPDXID" : "SPDXRef-Package-7-third-package",
"SPDXID" : "SPDXRef-Package-Maven-third-package-group-third-package-0.0.1",
"copyrightText" : "NONE",
"downloadLocation" : "NONE",
"externalRefs" : [ {
Expand All @@ -148,32 +148,32 @@
"versionInfo" : "0.0.1"
} ],
"relationships" : [ {
"spdxElementId" : "SPDXRef-Package-1-first-package",
"spdxElementId" : "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1",
"relationshipType" : "DEPENDENCY_OF",
"relatedSpdxElement" : "SPDXRef-Package-0-root-package"
"relatedSpdxElement" : "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
}, {
"spdxElementId" : "SPDXRef-Package-1-first-package",
"spdxElementId" : "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1",
"relationshipType" : "GENERATED_FROM",
"relatedSpdxElement" : "SPDXRef-Package-2-first-package-vcs"
"relatedSpdxElement" : "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1-vcs"
}, {
"spdxElementId" : "SPDXRef-Package-1-first-package",
"spdxElementId" : "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1",
"relationshipType" : "GENERATED_FROM",
"relatedSpdxElement" : "SPDXRef-Package-3-first-package-source-artifact"
"relatedSpdxElement" : "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1-source-artifact"
}, {
"spdxElementId" : "SPDXRef-Package-4-fourth-package",
"spdxElementId" : "SPDXRef-Package-Maven-fourth-package-group-fourth-package-0.0.1",
"relationshipType" : "DEPENDENCY_OF",
"relatedSpdxElement" : "SPDXRef-Package-0-root-package"
"relatedSpdxElement" : "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
}, {
"spdxElementId" : "SPDXRef-Package-5-second-package",
"spdxElementId" : "SPDXRef-Package-Maven-second-package-group-second-package-0.0.1",
"relationshipType" : "DEPENDENCY_OF",
"relatedSpdxElement" : "SPDXRef-Package-0-root-package"
"relatedSpdxElement" : "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
}, {
"spdxElementId" : "SPDXRef-Package-6-sixth-package",
"spdxElementId" : "SPDXRef-Package-Maven-sixth-package-group-sixth-package-0.0.1",
"relationshipType" : "DEPENDENCY_OF",
"relatedSpdxElement" : "SPDXRef-Package-0-root-package"
"relatedSpdxElement" : "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
}, {
"spdxElementId" : "SPDXRef-Package-7-third-package",
"spdxElementId" : "SPDXRef-Package-Maven-third-package-group-third-package-0.0.1",
"relationshipType" : "DEPENDENCY_OF",
"relatedSpdxElement" : "SPDXRef-Package-0-root-package"
"relatedSpdxElement" : "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
} ]
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ hasExtractedLicensingInfos:
licenseId: "LicenseRef-scancode-srgb"
documentNamespace: "<REPLACE_DOCUMENT_NAMESPACE>"
documentDescribes:
- "SPDXRef-Package-0-root-package"
- "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
packages:
- SPDXID: "SPDXRef-Package-0-root-package"
- SPDXID: "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
copyrightText: "NOASSERTION"
downloadLocation: "NOASSERTION"
filesAnalyzed: false
homepage: "NOASSERTION"
licenseConcluded: "NOASSERTION"
licenseDeclared: "NOASSERTION"
name: "Root package"
- SPDXID: "SPDXRef-Package-1-first-package"
- SPDXID: "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1"
copyrightText: "Copyright 2020 Some copyright holder in VCS\nCopyright 2020 Some\
\ copyright holder in source artifact\nCopyright 2020 Some other copyright holder\
\ in source artifact"
Expand All @@ -56,7 +56,7 @@ packages:
\ a user name, and with a scan result containing two copyright finding matched\
\ to a license finding."
versionInfo: "0.0.1"
- SPDXID: "SPDXRef-Package-2-first-package-vcs"
- SPDXID: "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1-vcs"
copyrightText: "Copyright 2020 Some copyright holder in VCS\nCopyright 2020 Some\
\ copyright holder in source artifact\nCopyright 2020 Some other copyright holder\
\ in source artifact"
Expand All @@ -76,7 +76,7 @@ packages:
\ a user name, and with a scan result containing two copyright finding matched\
\ to a license finding."
versionInfo: "0.0.1"
- SPDXID: "SPDXRef-Package-3-first-package-source-artifact"
- SPDXID: "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1-source-artifact"
copyrightText: "Copyright 2020 Some copyright holder in VCS\nCopyright 2020 Some\
\ copyright holder in source artifact\nCopyright 2020 Some other copyright holder\
\ in source artifact"
Expand All @@ -96,7 +96,7 @@ packages:
\ a user name, and with a scan result containing two copyright finding matched\
\ to a license finding."
versionInfo: "0.0.1"
- SPDXID: "SPDXRef-Package-4-fourth-package"
- SPDXID: "SPDXRef-Package-Maven-fourth-package-group-fourth-package-0.0.1"
copyrightText: "NONE"
downloadLocation: "NONE"
externalRefs:
Expand All @@ -110,7 +110,7 @@ packages:
name: "fourth-package"
summary: "A package with partially mapped declared license."
versionInfo: "0.0.1"
- SPDXID: "SPDXRef-Package-5-second-package"
- SPDXID: "SPDXRef-Package-Maven-second-package-group-second-package-0.0.1"
copyrightText: "NONE"
downloadLocation: "NONE"
externalRefs:
Expand All @@ -124,7 +124,7 @@ packages:
name: "second-package"
summary: "A package with minimal attributes set."
versionInfo: "0.0.1"
- SPDXID: "SPDXRef-Package-6-sixth-package"
- SPDXID: "SPDXRef-Package-Maven-sixth-package-group-sixth-package-0.0.1"
copyrightText: "NONE"
downloadLocation: "NONE"
externalRefs:
Expand All @@ -138,7 +138,7 @@ packages:
name: "sixth-package"
summary: "A package with non-SPDX license IDs in the declared and concluded license."
versionInfo: "0.0.1"
- SPDXID: "SPDXRef-Package-7-third-package"
- SPDXID: "SPDXRef-Package-Maven-third-package-group-third-package-0.0.1"
copyrightText: "NONE"
downloadLocation: "NONE"
externalRefs:
Expand All @@ -153,24 +153,24 @@ packages:
summary: "A package with only unmapped declared license."
versionInfo: "0.0.1"
relationships:
- spdxElementId: "SPDXRef-Package-1-first-package"
- spdxElementId: "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1"
relationshipType: "DEPENDENCY_OF"
relatedSpdxElement: "SPDXRef-Package-0-root-package"
- spdxElementId: "SPDXRef-Package-1-first-package"
relatedSpdxElement: "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
- spdxElementId: "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1"
relationshipType: "GENERATED_FROM"
relatedSpdxElement: "SPDXRef-Package-2-first-package-vcs"
- spdxElementId: "SPDXRef-Package-1-first-package"
relatedSpdxElement: "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1-vcs"
- spdxElementId: "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1"
relationshipType: "GENERATED_FROM"
relatedSpdxElement: "SPDXRef-Package-3-first-package-source-artifact"
- spdxElementId: "SPDXRef-Package-4-fourth-package"
relatedSpdxElement: "SPDXRef-Package-Maven-first-package-group-first-package-0.0.1-source-artifact"
- spdxElementId: "SPDXRef-Package-Maven-fourth-package-group-fourth-package-0.0.1"
relationshipType: "DEPENDENCY_OF"
relatedSpdxElement: "SPDXRef-Package-0-root-package"
- spdxElementId: "SPDXRef-Package-5-second-package"
relatedSpdxElement: "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
- spdxElementId: "SPDXRef-Package-Maven-second-package-group-second-package-0.0.1"
relationshipType: "DEPENDENCY_OF"
relatedSpdxElement: "SPDXRef-Package-0-root-package"
- spdxElementId: "SPDXRef-Package-6-sixth-package"
relatedSpdxElement: "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
- spdxElementId: "SPDXRef-Package-Maven-sixth-package-group-sixth-package-0.0.1"
relationshipType: "DEPENDENCY_OF"
relatedSpdxElement: "SPDXRef-Package-0-root-package"
- spdxElementId: "SPDXRef-Package-7-third-package"
relatedSpdxElement: "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
- spdxElementId: "SPDXRef-Package-Maven-third-package-group-third-package-0.0.1"
relationshipType: "DEPENDENCY_OF"
relatedSpdxElement: "SPDXRef-Package-0-root-package"
relatedSpdxElement: "SPDXRef-Project-Maven-first-project-group-first-project-name-0.0.1"
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import org.ossreviewtoolkit.utils.spdx.model.SpdxExtractedLicenseInfo
import org.ossreviewtoolkit.utils.spdx.model.SpdxPackage
import org.ossreviewtoolkit.utils.spdx.model.SpdxPackageVerificationCode
import org.ossreviewtoolkit.utils.spdx.model.SpdxRelationship
import org.ossreviewtoolkit.utils.spdx.toSpdxId

/**
* A class for mapping [OrtResult]s to [SpdxDocument]s.
Expand All @@ -66,12 +67,12 @@ object SpdxDocumentModelMapper {
licenseTextProvider: LicenseTextProvider,
params: SpdxDocumentParams
): SpdxDocument {
val spdxPackageIdGenerator = SpdxPackageIdGenerator()
val packages = mutableListOf<SpdxPackage>()
val relationships = mutableListOf<SpdxRelationship>()

val rootPackages = ortResult.getProjects(omitExcluded = true, includeSubProjects = false)
val rootPackage = SpdxPackage(
spdxId = spdxPackageIdGenerator.nextId("root-package"),
spdxId = rootPackages.first().id.toSpdxId("Project"),
mnonnenmacher marked this conversation as resolved.
Show resolved Hide resolved
copyrightText = SpdxConstants.NOASSERTION,
downloadLocation = SpdxConstants.NOASSERTION,
filesAnalyzed = false,
Expand All @@ -87,7 +88,7 @@ object SpdxDocumentModelMapper {
val pkg = curatedPackage.pkg

val binaryPackage = SpdxPackage(
spdxId = spdxPackageIdGenerator.nextId(pkg.id.name),
spdxId = pkg.id.toSpdxId("Package"),
copyrightText = getSpdxCopyrightText(licenseInfoResolver, pkg.id),
downloadLocation = pkg.binaryArtifact.url.nullOrBlankToSpdxNone(),
externalRefs = pkg.toSpdxExternalReferences(),
Expand Down Expand Up @@ -123,7 +124,7 @@ object SpdxDocumentModelMapper {

// TODO: The copyright text contains copyrights from all scan results.
val vcsPackage = binaryPackage.copy(
spdxId = spdxPackageIdGenerator.nextId("${pkg.id.name}-vcs"),
spdxId = "${binaryPackage.spdxId}-vcs",
filesAnalyzed = filesAnalyzed,
downloadLocation = pkg.vcsProcessed.toSpdxDownloadLocation(provenance?.resolvedRevision),
licenseConcluded = SpdxConstants.NOASSERTION,
Expand Down Expand Up @@ -154,7 +155,7 @@ object SpdxDocumentModelMapper {

// TODO: The copyright text contains copyrights from all scan results.
val sourceArtifactPackage = binaryPackage.copy(
spdxId = spdxPackageIdGenerator.nextId("${curatedPackage.pkg.id.name}-source-artifact"),
spdxId = "${binaryPackage.spdxId}-source-artifact",
filesAnalyzed = filesAnalyzed,
downloadLocation = curatedPackage.pkg.sourceArtifact.url.nullOrBlankToSpdxNone(),
licenseConcluded = SpdxConstants.NOASSERTION,
Expand Down Expand Up @@ -190,18 +191,6 @@ object SpdxDocumentModelMapper {
}
}

private class SpdxPackageIdGenerator {
var nextPackageIndex = 0

fun nextId(name: String): String =
buildString {
append("${REF_PREFIX}Package-${nextPackageIndex++}")
if (name.isNotBlank()) {
append("-$name")
}
}
}

private fun getSpdxCopyrightText(
licenseInfoResolver: LicenseInfoResolver,
id: Identifier
Expand All @@ -215,6 +204,11 @@ private fun getSpdxCopyrightText(
}
}

/**
* Convert an [Identifier]'s coordinates to an SPDX reference ID with the specified [infix].
*/
private fun Identifier.toSpdxId(infix: String) = "$REF_PREFIX$infix-${toCoordinates()}".toSpdxId()

private fun Package.toSpdxExternalReferences(): List<SpdxExternalReference> {
val externalRefs = mutableListOf<SpdxExternalReference>()

Expand Down