Skip to content

Commit

Permalink
refactor(ctrlx-reporter): Migrate from Jackson to kotlinx-serialization
Browse files Browse the repository at this point in the history
To avoid both Jackson and kotlinx-serialization annotations on the
`SpdxExpression` (sealed) class, simply change the `spdx` property to be
a `String`.

This is part of #3904.

Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
  • Loading branch information
sschuberth committed May 24, 2023
1 parent b6186fe commit dc9118b
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 20 deletions.
19 changes: 16 additions & 3 deletions plugins/reporters/ctrlx/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

/*
* Copyright (C) 2023 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
*
Expand All @@ -20,18 +22,29 @@
plugins {
// Apply core plugins.
`java-library`

// Apply third-party plugins.
alias(libs.plugins.kotlinSerialization)
}

dependencies {
api(project(":reporter"))
api(project(":utils:spdx-utils"))

api(libs.jacksonAnnotations)

implementation(project(":model"))
implementation(project(":utils:common-utils"))

implementation(libs.jacksonDatabind)
implementation(libs.bundles.kotlinxSerialization)

funTestImplementation(testFixtures(project(":reporter")))
}

tasks.withType<KotlinCompile>().configureEach {
val customCompilerArgs = listOf(
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi"
)

kotlinOptions {
freeCompilerArgs = freeCompilerArgs + customCompilerArgs
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import io.kotest.matchers.collections.containExactly
import io.kotest.matchers.collections.haveSize
import io.kotest.matchers.should

import org.ossreviewtoolkit.model.readValue
import kotlinx.serialization.json.decodeFromStream

import org.ossreviewtoolkit.plugins.reporters.ctrlx.CtrlXAutomationReporter.Companion.REPORT_FILENAME
import org.ossreviewtoolkit.reporter.ORT_RESULT
import org.ossreviewtoolkit.reporter.ReporterInput
Expand All @@ -35,7 +36,7 @@ import org.ossreviewtoolkit.utils.test.shouldNotBeNull
class CtrlXAutomationReporterFunTest : StringSpec({
"The official sample file can be deserialized" {
val fossInfoFile = getAssetFile("sample.fossinfo.json")
val fossInfo = fossInfoFile.readValue<FossInfo>()
val fossInfo = fossInfoFile.inputStream().use { CtrlXAutomationReporter.JSON.decodeFromStream<FossInfo>(it) }

fossInfo.components shouldNotBeNull {
this should haveSize(8)
Expand Down
21 changes: 11 additions & 10 deletions plugins/reporters/ctrlx/src/main/kotlin/CtrlXAutomationModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,21 @@

package org.ossreviewtoolkit.plugins.reporters.ctrlx

import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonProperty
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

import org.ossreviewtoolkit.utils.spdx.SpdxExpression
import org.ossreviewtoolkit.utils.spdx.SpdxExpression.Strictness

/**
* The root element of "fossinfo.json" files, see https://github.com/boschrexroth/json-schema.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@Serializable
data class FossInfo(
/**
* The reference to the JSON schema in use.
*/
@JsonProperty("\$schema")
@SerialName("\$schema")
val schema: String? = "https://github.com/boschrexroth/json-schema/blob/a84eab6/ctrlx-automation/ctrlx-core/apps/" +
"fossinfo/fossinfo.v1.schema.json",

Expand All @@ -56,7 +57,7 @@ data class FossInfo(
/**
* An OSS component.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@Serializable
data class Component(
/**
* The OSS component name.
Expand Down Expand Up @@ -97,7 +98,7 @@ data class Component(
/**
* A single OSS component integration.
*/
@JsonProperty("integrationMechanism")
@SerialName("integrationMechanism")
val integrationMechanism: IntegrationMechanism? = null
) {
init {
Expand All @@ -122,7 +123,7 @@ data class Component(
/**
* An OSS component's copyright information.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@Serializable
data class CopyrightInformation(
/**
* The copyright text.
Expand All @@ -138,7 +139,7 @@ data class CopyrightInformation(
/**
* An OSS component's license.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@Serializable
data class License(
/**
* The license name.
Expand All @@ -148,7 +149,7 @@ data class License(
/**
* The official identifier of the license, also see https://spdx.org/licenses.
*/
val spdx: SpdxExpression? = null,
val spdx: String? = null,

/**
* OSS component license text. Use "\n" as line separator.
Expand All @@ -165,7 +166,7 @@ data class License(
"The '$name' value of the 'name' field must not contain any leading or trailing whitespaces."
}

require(spdx?.isValid(SpdxExpression.Strictness.ALLOW_LICENSEREF_EXCEPTIONS) != false) {
require(spdx == null || SpdxExpression.parse(spdx, Strictness.ALLOW_LICENSEREF_EXCEPTIONS).isValid()) {
"The '$spdx' value of the 'spdx' field must be a valid SPDX identifier."
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,23 @@ package org.ossreviewtoolkit.plugins.reporters.ctrlx

import java.io.File

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.encodeToStream

import org.ossreviewtoolkit.model.licenses.LicenseView
import org.ossreviewtoolkit.model.writeValue
import org.ossreviewtoolkit.reporter.Reporter
import org.ossreviewtoolkit.reporter.ReporterInput
import org.ossreviewtoolkit.utils.spdx.SpdxConstants
import org.ossreviewtoolkit.utils.spdx.toSpdx

class CtrlXAutomationReporter : Reporter {
companion object {
const val REPORT_FILENAME = "fossinfo.json"

val JSON = Json { encodeDefaults = false }

private val LICENSE_NOASSERTION = License(
name = SpdxConstants.NOASSERTION,
spdx = SpdxConstants.NOASSERTION.toSpdx(),
spdx = SpdxConstants.NOASSERTION,
text = ""
)
}
Expand Down Expand Up @@ -67,7 +70,7 @@ class CtrlXAutomationReporter : Reporter {
val licenses = effectiveLicense?.decompose()?.map {
val id = it.toString()
val text = input.licenseTextProvider.getLicenseText(id)
License(name = id, spdx = it, text = text.orEmpty())
License(name = id, spdx = id, text = text.orEmpty())
}

// The specification requires at least one license.
Expand All @@ -85,7 +88,7 @@ class CtrlXAutomationReporter : Reporter {
}

val info = FossInfo(components = components)
reportFile.writeValue(info)
reportFile.outputStream().use { JSON.encodeToStream(info, it) }

return listOf(reportFile)
}
Expand Down

0 comments on commit dc9118b

Please sign in to comment.