@@ -42,19 +42,24 @@ import org.ossreviewtoolkit.model.config.AnalyzerConfiguration
4242import org.ossreviewtoolkit.model.config.Excludes
4343import org.ossreviewtoolkit.model.config.Includes
4444import org.ossreviewtoolkit.model.createAndLogIssue
45+ import org.ossreviewtoolkit.model.utils.toIdentifier
46+ import org.ossreviewtoolkit.model.utils.toPackageUrl
4547import org.ossreviewtoolkit.plugins.api.OrtPlugin
48+ import org.ossreviewtoolkit.plugins.api.OrtPluginOption
4649import org.ossreviewtoolkit.plugins.api.PluginConfig
4750import org.ossreviewtoolkit.plugins.api.PluginDescriptor
4851import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.SpdxDocumentCache
4952import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.SpdxResolvedDocument
5053import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.extractScopeFromExternalReferences
5154import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.isExternalDocumentReferenceId
5255import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.locateCpe
56+ import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.locateExternalReference
5357import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.mapNotPresentToEmpty
5458import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.projectPackage
5559import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.toIdentifier
5660import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.toPackage
5761import org.ossreviewtoolkit.plugins.packagemanagers.spdx.utils.wrapPresentInSet
62+ import org.ossreviewtoolkit.utils.spdxdocument.model.SpdxExternalReference
5863import org.ossreviewtoolkit.utils.spdxdocument.model.SpdxPackage
5964import org.ossreviewtoolkit.utils.spdxdocument.model.SpdxRelationship
6065
@@ -70,6 +75,11 @@ private val SPDX_LINKAGE_RELATIONSHIPS = mapOf(
7075
7176private val SPDX_SCOPE_RELATIONSHIPS = SpdxRelationship .Type .entries.filter { it.name.endsWith(" _DEPENDENCY_OF" ) }
7277
78+ data class SpdxDocumentFileConfig (
79+ @OrtPluginOption(defaultValue = " false" )
80+ val deduceOrtIdFromPurl : Boolean
81+ )
82+
7383/* *
7484 * A "fake" package manager implementation that uses SPDX documents as definition files to declare projects and describe
7585 * packages. See https://github.com/spdx/spdx-spec/issues/439 for details.
@@ -79,7 +89,10 @@ private val SPDX_SCOPE_RELATIONSHIPS = SpdxRelationship.Type.entries.filter { it
7989 description = " A package manager that uses SPDX documents as definition files." ,
8090 factory = PackageManagerFactory ::class
8191)
82- class SpdxDocumentFile (override val descriptor : PluginDescriptor = SpdxDocumentFileFactory .descriptor) :
92+ class SpdxDocumentFile (
93+ override val descriptor : PluginDescriptor = SpdxDocumentFileFactory .descriptor,
94+ private val config : SpdxDocumentFileConfig
95+ ) :
8396 PackageManager (PROJECT_TYPE ) {
8497 override val globsForDefinitionFiles = listOf (" *.spdx.yml" , " *.spdx.yaml" , " *.spdx.json" )
8598
@@ -116,7 +129,8 @@ class SpdxDocumentFile(override val descriptor: PluginDescriptor = SpdxDocumentF
116129 val issues = mutableListOf<Issue >()
117130 getPackageManagerDependency(target, doc, analyzerConfig) ? : doc.getSpdxPackageForId(target, issues)
118131 ?.let { dependency ->
119- val ortPackage = dependency.toPackage(doc.getDefinitionFile(target), doc)
132+ val targetFile = doc.getDefinitionFile(target)
133+ val ortPackage = dependency.toPackage(targetFile, doc, config.deduceOrtIdFromPurl)
120134 packages + = ortPackage
121135
122136 PackageReference (
@@ -160,7 +174,8 @@ class SpdxDocumentFile(override val descriptor: PluginDescriptor = SpdxDocumentF
160174
161175 getPackageManagerDependency(source, doc, analyzerConfig) ? : doc.getSpdxPackageForId(source, issues)
162176 ?.let { dependency ->
163- val ortPackage = dependency.toPackage(doc.getDefinitionFile(source), doc)
177+ val sourceFile = doc.getDefinitionFile(source)
178+ val ortPackage = dependency.toPackage(sourceFile, doc, config.deduceOrtIdFromPurl)
164179 packages + = ortPackage
165180
166181 PackageReference (
@@ -269,8 +284,12 @@ class SpdxDocumentFile(override val descriptor: PluginDescriptor = SpdxDocumentF
269284 )
270285 )
271286
287+ val purlReference = projectPackage.locateExternalReference(SpdxExternalReference .Type .Purl )
288+ val id = purlReference?.takeIf { config.deduceOrtIdFromPurl }?.run { toPackageUrl()?.toIdentifier() }
289+ ? : projectPackage.toIdentifier(projectType)
290+
272291 val project = Project (
273- id = projectPackage.toIdentifier(projectType) ,
292+ id = id ,
274293 cpe = projectPackage.locateCpe(),
275294 definitionFilePath = VersionControlSystem .getPathInfo(definitionFile).path,
276295 authors = projectPackage.originator.wrapPresentInSet(),
0 commit comments