diff --git a/build-tools/build.gradle.kts b/build-tools/build.gradle.kts index f8df91799d4..407082eb186 100644 --- a/build-tools/build.gradle.kts +++ b/build-tools/build.gradle.kts @@ -11,11 +11,16 @@ plugins { // We explicitly configure versions of plugins in settings.gradle.kts. // due to https://github.com/gradle/gradle/issues/1697. id("kotlin") - id("kotlinx-serialization") groovy `java-gradle-plugin` } +buildscript { + dependencies { + classpath("com.google.code.gson:gson:2.8.6") + } +} + val rootProperties = Properties().apply { rootDir.resolve("../gradle.properties").reader().use(::load) } diff --git a/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExecutorService.kt b/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExecutorService.kt index 9b650d7662b..4145953766d 100644 --- a/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExecutorService.kt +++ b/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExecutorService.kt @@ -16,10 +16,8 @@ package org.jetbrains.kotlin +import com.google.gson.annotations.Expose import groovy.lang.Closure -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration import org.gradle.api.Action import org.gradle.api.Project import org.gradle.process.ExecResult @@ -320,6 +318,8 @@ private fun sshExecutor(project: Project): ExecutorService = object : ExecutorSe } } +internal data class DeviceTarget(@Expose val name: String, @Expose val udid: String, @Expose val state: String, @Expose val type: String) + private fun deviceLauncher(project: Project) = object : ExecutorService { private val xcProject = Paths.get(project.testOutputRoot, "launcher") @@ -421,12 +421,10 @@ private fun deviceLauncher(project: Project) = object : ExecutorService { } return out.toString().run { check(isNotEmpty()) - @Serializable - data class DeviceTarget(val name: String, val udid: String, val state: String, val type: String) split("\n") .filter { it.isNotEmpty() } - .map { Json(JsonConfiguration.Stable.copy(ignoreUnknownKeys = true)) - .parse(DeviceTarget.serializer(), it) + .map { + gson.fromJson(it, DeviceTarget::class.java) } .first { it.type == "device" && deviceName?.run { this == it.name } ?: true diff --git a/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExternalReportUtils.kt b/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExternalReportUtils.kt index 6cc32de0299..8fe4a5669d1 100644 --- a/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExternalReportUtils.kt +++ b/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExternalReportUtils.kt @@ -1,29 +1,26 @@ package org.jetbrains.kotlin -import kotlinx.serialization.ImplicitReflectionSerializer -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json -import kotlinx.serialization.parse -import kotlinx.serialization.stringify + +import com.google.gson.annotations.* +import com.google.gson.* +import com.google.gson.stream.JsonReader import java.io.File import java.io.FileReader import java.io.PrintWriter -@Serializable -data class ExternalTestReport(val statistics: Statistics, val groups: List) +data class ExternalTestReport(@Expose val statistics: Statistics, @Expose val groups: List) -@ImplicitReflectionSerializer fun saveReport(reportFileName: String, statistics: Statistics, groups:List){ File(reportFileName).apply { parentFile.mkdirs() PrintWriter(this).use { - it.append(Json.stringify(ExternalTestReport(statistics, groups))) + it.append(gson.toJson(ExternalTestReport(statistics, groups))) } } } -@ImplicitReflectionSerializer -fun loadReport(reportFileName: String) : ExternalTestReport = FileReader(reportFileName).use { - return@use Json.parse(it.readText()) - } +internal val gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()!! +fun loadReport(reportFileName: String) : ExternalTestReport = JsonReader(FileReader(reportFileName)).use { + gson.fromJson(it, ExternalTestReport::class.java) +} diff --git a/build-tools/src/main/kotlin/org/jetbrains/kotlin/KonanTestSuiteReport.kt b/build-tools/src/main/kotlin/org/jetbrains/kotlin/KonanTestSuiteReport.kt index 3534825ba54..b6923007498 100644 --- a/build-tools/src/main/kotlin/org/jetbrains/kotlin/KonanTestSuiteReport.kt +++ b/build-tools/src/main/kotlin/org/jetbrains/kotlin/KonanTestSuiteReport.kt @@ -1,8 +1,8 @@ package org.jetbrains.kotlin +import com.google.gson.annotations.Expose import java.io.PrintWriter import java.io.StringWriter -import kotlinx.serialization.Serializable import org.gradle.api.Project enum class TestStatus { @@ -12,12 +12,11 @@ enum class TestStatus { SKIPPED } -@Serializable data class Statistics( - var passed: Int = 0, - var failed: Int = 0, - var error: Int = 0, - var skipped: Int = 0) { + @Expose var passed: Int = 0, + @Expose var failed: Int = 0, + @Expose var error: Int = 0, + @Expose var skipped: Int = 0) { fun pass(count: Int = 1) { passed += count } @@ -41,14 +40,12 @@ val Statistics.total: Int class TestFailedException(msg:String) : RuntimeException(msg) -@Serializable -data class KonanTestGroupReport(val name: String, val suites: List) -@Serializable -data class KonanTestSuiteReport(val name: String, val tests: List) +data class KonanTestGroupReport(@Expose val name: String, val suites: List) -@Serializable -data class KonanTestCaseReport(val name: String, val status: TestStatus, val comment: String? = null) +data class KonanTestSuiteReport(@Expose val name: String, val tests: List) + +data class KonanTestCaseReport(@Expose val name: String, @Expose val status: TestStatus, @Expose val comment: String? = null) class KonanTestSuiteReportEnvironment(val name: String, val project: Project, val statistics: Statistics) { private val tc = if (Tc.enabled) TeamCityTestPrinter(project) else null diff --git a/build-tools/src/main/kotlin/org/jetbrains/kotlin/LlvmCovReport.kt b/build-tools/src/main/kotlin/org/jetbrains/kotlin/LlvmCovReport.kt index 0c8b0da7648..15f11652c0a 100644 --- a/build-tools/src/main/kotlin/org/jetbrains/kotlin/LlvmCovReport.kt +++ b/build-tools/src/main/kotlin/org/jetbrains/kotlin/LlvmCovReport.kt @@ -1,11 +1,9 @@ package org.jetbrains.kotlin -import kotlinx.serialization.* -import kotlinx.serialization.internal.StringDescriptor -import kotlinx.serialization.json.Json +import com.google.gson.* +import com.google.gson.annotations.* -@Serializable data class LlvmCovReportFunction( val name: String, val count: Int, @@ -13,7 +11,6 @@ data class LlvmCovReportFunction( val filenames: List ) -@Serializable data class LlvmCovReportSummary( val lines: LlvmCovReportStatistics, val functions: LlvmCovReportStatistics, @@ -27,35 +24,30 @@ data class LlvmCovReportSummary( * It's a bit complicated since every segment * is encoded not as dictionary, but as array of ints and bools. */ -@Serializable data class LlvmCovReportFile( - val filename: String, - val summary: LlvmCovReportSummary + @Expose val filename: String, + @Expose val summary: LlvmCovReportSummary ) -@Serializable data class LlvmCovReportStatistics( - val count: Int, - val covered: Int, - val percent: Double + @Expose val count: Int, + @Expose val covered: Int, + @Expose val percent: Double ) -@Serializable data class LlvmCovReportData( - val files: List, - val functions: List, - val totals: LlvmCovReportSummary + @Expose val files: List, + @Expose val functions: List, + @Expose val totals: LlvmCovReportSummary ) -@Serializable data class LlvmCovReport( - val version: String, - val type: String, - val data: List + @Expose val version: String, + @Expose val type: String, + @Expose val data: List ) -fun parseLlvmCovReport(llvmCovReport: String): LlvmCovReport = - Json.nonstrict.parse(LlvmCovReport.serializer(), llvmCovReport) +fun parseLlvmCovReport(llvmCovReport: String): LlvmCovReport = gson.fromJson(llvmCovReport, LlvmCovReport::class.java) val LlvmCovReport.isValid get() = type == "llvm.coverage.json.export" diff --git a/build-tools/src/main/kotlin/org/jetbrains/kotlin/Reporter.kt b/build-tools/src/main/kotlin/org/jetbrains/kotlin/Reporter.kt index dccf2c40e6d..a133be2de56 100644 --- a/build-tools/src/main/kotlin/org/jetbrains/kotlin/Reporter.kt +++ b/build-tools/src/main/kotlin/org/jetbrains/kotlin/Reporter.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin import com.ullink.slack.simpleslackapi.impl.SlackSessionFactory -import kotlinx.serialization.ImplicitReflectionSerializer import org.gradle.api.DefaultTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction @@ -64,7 +63,6 @@ open class Reporter : DefaultTask() { @Input lateinit var reportHome: String - @ImplicitReflectionSerializer @TaskAction fun report() { @@ -74,12 +72,14 @@ open class Reporter : DefaultTask() { "${reportJson.statistics.report}\n ${reportEpilogue()}" project.logger.info(report) - sendTextToSlack(report) + if (doSlackSending()) + sendTextToSlack(report) } - - } +private fun DefaultTask.doSlackSending() = !project.hasProperty("build.reporter.noSlack") + || !project.property("build.reporter.noSlack").toString().toBoolean() + open class NightlyReporter: DefaultTask() { @Input lateinit var externalMacosReport:String @@ -88,7 +88,6 @@ open class NightlyReporter: DefaultTask() { @Input lateinit var externalWindowsReport:String - @ImplicitReflectionSerializer @TaskAction fun report() { val externalMacosJsonReport = loadReport("${project.rootDir.absolutePath}/$externalMacosReport") @@ -104,6 +103,7 @@ open class NightlyReporter: DefaultTask() { appendln(reportEpilogue()) } project.logger.info(report) - sendTextToSlack(report) + if (doSlackSending()) + sendTextToSlack(report) } } \ No newline at end of file diff --git a/build-tools/src/main/kotlin/org/jetbrains/kotlin/XcRunRuntimeUtils.kt b/build-tools/src/main/kotlin/org/jetbrains/kotlin/XcRunRuntimeUtils.kt index 6eb3dd9067c..84828a6723b 100644 --- a/build-tools/src/main/kotlin/org/jetbrains/kotlin/XcRunRuntimeUtils.kt +++ b/build-tools/src/main/kotlin/org/jetbrains/kotlin/XcRunRuntimeUtils.kt @@ -1,8 +1,6 @@ package org.jetbrains.kotlin -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration +import com.google.gson.annotations.Expose import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.Xcode import kotlin.math.min @@ -25,9 +23,7 @@ private fun compareStringsAsVersions(version1: String, version2: String): Int { /** * Returns parsed output of `xcrun simctl list runtimes -j`. */ -private fun Xcode.getSimulatorRuntimeDescriptors(): List = - Json(JsonConfiguration.Stable.copy(ignoreUnknownKeys = true, useArrayPolymorphism = true)) - .parse(ListRuntimesReport.serializer(), this.simulatorRuntimes).runtimes +private fun Xcode.getSimulatorRuntimeDescriptors(): List = gson.fromJson(simulatorRuntimes, ListRuntimesReport::class.java).runtimes /** * Returns first available simulator runtime for [target] with at least [osMinVersion] OS version. @@ -45,21 +41,19 @@ fun Xcode.getLatestSimulatorRuntimeFor(target: KonanTarget, osMinVersion: String } // Result of `xcrun simctl list runtimes -j`. -@Serializable data class ListRuntimesReport( - val runtimes: List + @Expose val runtimes: List ) -@Serializable data class SimulatorRuntimeDescriptor( - val version: String, + @Expose val version: String, // bundlePath field may not exist in the old Xcode (prior to 10.3). - val bundlePath: String? = null, - val isAvailable: Boolean? = null, - val availability: String? = null, - val name: String, - val identifier: String, - val buildversion: String + @Expose val bundlePath: String? = null, + @Expose val isAvailable: Boolean? = null, + @Expose val availability: String? = null, + @Expose val name: String, + @Expose val identifier: String, + @Expose val buildversion: String ) { /** * Different Xcode/macOS combinations give different fields that checks