Skip to content

Commit 6830e6a

Browse files
committed
feat(spdx): Report detected root licenses for packages
The SPDX `licenseDeclared` field for a package [1] is not a declared license in the ORT sense (which means that it must originate from package metadata only), but should list any "licenses that have been declared by the authors of the package" in any way, including as part of a `LICENSE` file, which in the ORT sense would be a detected license. To account for that, also use licenses detected in root license files as licenses "declared" for the package. This solves the concrete case for Go packages that so far did not have any `licenseDeclared` set, as they are just pointers to Git repositories which have no metadata associated. [1]: https://spdx.github.io/spdx-spec/v2.2.2/package-information/#715-declared-license-field Signed-off-by: Sebastian Schuberth <[email protected]>
1 parent 486f79b commit 6830e6a

File tree

1 file changed

+17
-22
lines changed

1 file changed

+17
-22
lines changed

plugins/reporters/spdx/src/main/kotlin/Extensions.kt

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,16 @@ import org.ossreviewtoolkit.model.ScanResult
3535
import org.ossreviewtoolkit.model.SourceCodeOrigin
3636
import org.ossreviewtoolkit.model.VcsInfo
3737
import org.ossreviewtoolkit.model.VcsType
38+
import org.ossreviewtoolkit.model.config.LicenseFilePatterns
3839
import org.ossreviewtoolkit.model.licenses.Findings
3940
import org.ossreviewtoolkit.model.licenses.LicenseInfoResolver
4041
import org.ossreviewtoolkit.model.licenses.LicenseView
4142
import org.ossreviewtoolkit.model.licenses.ResolvedLicenseInfo
4243
import org.ossreviewtoolkit.model.utils.FindingCurationMatcher
4344
import org.ossreviewtoolkit.model.utils.prependedPath
4445
import org.ossreviewtoolkit.reporter.LicenseTextProvider
46+
import org.ossreviewtoolkit.utils.common.FileMatcher
4547
import org.ossreviewtoolkit.utils.common.replaceCredentialsInUri
46-
import org.ossreviewtoolkit.utils.ort.ProcessedDeclaredLicense
4748
import org.ossreviewtoolkit.utils.spdx.SpdxConstants
4849
import org.ossreviewtoolkit.utils.spdx.SpdxExpression
4950
import org.ossreviewtoolkit.utils.spdx.SpdxExpression.Strictness
@@ -56,7 +57,6 @@ import org.ossreviewtoolkit.utils.spdx.model.SpdxExtractedLicenseInfo
5657
import org.ossreviewtoolkit.utils.spdx.model.SpdxFile
5758
import org.ossreviewtoolkit.utils.spdx.model.SpdxPackage
5859
import org.ossreviewtoolkit.utils.spdx.model.SpdxPackageVerificationCode
59-
import org.ossreviewtoolkit.utils.spdx.toSpdx
6060
import org.ossreviewtoolkit.utils.spdx.toSpdxId
6161

6262
/**
@@ -155,6 +155,20 @@ internal fun Package.toSpdxPackage(
155155
.filterExcluded()
156156
.filterValid(Strictness.ALLOW_DEPRECATED)
157157

158+
val declaredPackageLicenses = resolvedLicenseExpressions.filter(LicenseView.ONLY_DECLARED)
159+
160+
val patterns = LicenseFilePatterns.getInstance()
161+
val detectedPackageLicenses = resolvedLicenseExpressions.filter { licenseInfo ->
162+
licenseInfo.locations.any {
163+
FileMatcher.match(patterns.allLicenseFilenames, it.location.path, ignoreCase = true)
164+
}
165+
}
166+
167+
val foundPackageLicenses = (declaredPackageLicenses + detectedPackageLicenses)
168+
.map { it.license }
169+
.reduceOrNull(SpdxExpression::and)
170+
.nullOrBlankToSpdxNoassertionOrNone()
171+
158172
return SpdxPackage(
159173
spdxId = id.toSpdxId(type),
160174
checksums = when (type) {
@@ -179,7 +193,7 @@ internal fun Package.toSpdxPackage(
179193
SpdxPackageType.VCS_PACKAGE -> SpdxConstants.NOASSERTION
180194
else -> concludedLicense.nullOrBlankToSpdxNoassertionOrNone()
181195
},
182-
licenseDeclared = declaredLicensesProcessed.toSpdxDeclaredLicense(),
196+
licenseDeclared = foundPackageLicenses,
183197
licenseInfoFromFiles = if (packageVerificationCode == null) {
184198
emptyList()
185199
} else {
@@ -210,25 +224,6 @@ private fun OrtResult.getPackageVerificationCode(id: Identifier, type: SpdxPacka
210224
calculatePackageVerificationCode(fileList.files.map { it.sha1 }.asSequence())
211225
}
212226

213-
/**
214-
* Convert processed declared licenses to SPDX. Unmapped licenses are represented as `NOASSERTION`.
215-
*/
216-
private fun ProcessedDeclaredLicense.toSpdxDeclaredLicense(): String =
217-
when {
218-
// If there are unmapped licenses, represent this by adding NOASSERTION.
219-
unmapped.isNotEmpty() -> {
220-
spdxExpression?.let {
221-
if (SpdxConstants.NOASSERTION !in it.licenses()) {
222-
(it and SpdxConstants.NOASSERTION.toSpdx()).toString()
223-
} else {
224-
it.toString()
225-
}
226-
} ?: SpdxConstants.NOASSERTION
227-
}
228-
229-
else -> spdxExpression.nullOrBlankToSpdxNoassertionOrNone()
230-
}
231-
232227
/**
233228
* Use [licenseTextProvider] to add the license texts for all packages to the [SpdxDocument].
234229
*/

0 commit comments

Comments
 (0)