Skip to content

Commit

Permalink
ScanCodeResultParser: Associate stand-alone exceptions to licenses
Browse files Browse the repository at this point in the history
ScanCode reports exceptions to licenses as individual license findings.
This is problematic as exceptions on their own are not valid SPDX
expressions, also see [1].

Introduce a new function that fixes up findings by associating
exceptions to their belonging licenses, for now at the example of
"LLVM-exception" which by definition [2] always belongs to "Apache-2.0".

[1]: aboutcode-org/scancode-toolkit#2873
[2]: https://spdx.org/licenses/LLVM-exception.html

Signed-off-by: Sebastian Schuberth <sebastian.schuberth@bosch.io>
  • Loading branch information
sschuberth committed Feb 20, 2022
1 parent 802d9b3 commit 1abab5b
Show file tree
Hide file tree
Showing 3 changed files with 835 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ import java.io.File
import java.time.Instant
import java.util.regex.Pattern

import kotlin.math.min
import kotlin.math.max

import org.ossreviewtoolkit.model.CopyrightFinding
import org.ossreviewtoolkit.model.LicenseFinding
import org.ossreviewtoolkit.model.OrtIssue
Expand All @@ -38,6 +41,7 @@ import org.ossreviewtoolkit.utils.common.textValueOrEmpty
import org.ossreviewtoolkit.utils.spdx.SpdxConstants
import org.ossreviewtoolkit.utils.spdx.SpdxConstants.LICENSE_REF_PREFIX
import org.ossreviewtoolkit.utils.spdx.calculatePackageVerificationCode
import org.ossreviewtoolkit.utils.spdx.toSpdx

private data class LicenseExpression(
val expression: String,
Expand Down Expand Up @@ -201,7 +205,7 @@ private fun getLicenseFindings(result: JsonNode, parseExpressions: Boolean): Lis
}
}

return licenseFindings
return associateLicensesWithExceptions(licenseFindings)
}

/**
Expand Down Expand Up @@ -245,6 +249,52 @@ internal fun replaceLicenseKeys(licenseExpression: String, replacements: Collect
result
}

private const val LICENSES_WITH_EXCEPTIONS_TOLERANCE_LINES = 5

internal fun associateLicensesWithExceptions(findings: List<LicenseFinding>): List<LicenseFinding> {
val otherFindings = mutableListOf<LicenseFinding>()

val apacheLicenses = mutableListOf<LicenseFinding>()
val llvmExceptions = mutableListOf<LicenseFinding>()

findings.forEach {
when (it.license.toString()) {
"Apache-2.0" -> apacheLicenses += it
"LLVM-exception" -> llvmExceptions += it
else -> otherFindings += it
}
}

val fixedApacheLicenses = apacheLicenses.map { apache ->
val llvm = llvmExceptions.filter { it.location.path == apache.location.path }
.map { it to it.location.distanceTo(apache.location) }
.sortedBy { it.second }
.firstOrNull { it.second <= LICENSES_WITH_EXCEPTIONS_TOLERANCE_LINES }

if (llvm != null) {
llvmExceptions.remove(llvm.first)

// Fixup an "Apache-2.0" license finding with a nearby "LLVM-exception".
apache.copy(
license = "Apache-2.0 WITH LLVM-exception".toSpdx(),
location = apache.location.copy(
startLine = min(apache.location.startLine, llvm.first.location.startLine),
endLine = max(apache.location.endLine, llvm.first.location.endLine)
)
)
} else {
apache
}
}

val fixedLlvmExceptions = llvmExceptions.map { llvm ->
// Fixup an "LLVM-exception" without a nearby "Apache-2.0" license.
llvm.copy(license = "Apache-2.0 WITH LLVM-exception".toSpdx())
}

return otherFindings + fixedApacheLicenses + fixedLlvmExceptions
}

/**
* Get the copyright findings from the given [result].
*/
Expand Down
Loading

0 comments on commit 1abab5b

Please sign in to comment.