Add JSON output type for build reports

#KT-65792 Fixed
This commit is contained in:
Nataliya.Valtman
2024-01-24 11:47:36 +01:00
committed by Space Team
parent f493df42a9
commit 5885514c3d
21 changed files with 515 additions and 330 deletions
@@ -5,9 +5,16 @@
package org.jetbrains.kotlin.gradle
import com.google.gson.*
import com.google.gson.stream.JsonReader
import org.gradle.api.logging.LogLevel
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.build.report.metrics.BuildMetrics
import org.jetbrains.kotlin.build.report.metrics.GradleBuildPerformanceMetric
import org.jetbrains.kotlin.build.report.metrics.GradleBuildTime
import org.jetbrains.kotlin.build.report.statistics.StatTag
import org.jetbrains.kotlin.build.report.statistics.formatSize
import org.jetbrains.kotlin.buildtools.api.SourcesChanges
import org.jetbrains.kotlin.gradle.internal.build.metrics.GradleBuildMetricsData
import org.jetbrains.kotlin.gradle.report.BuildReportType
import org.jetbrains.kotlin.gradle.testbase.*
@@ -17,10 +24,14 @@ import java.nio.file.Path
import kotlin.io.path.*
import kotlin.test.assertTrue
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.report.data.BuildExecutionData
import org.jetbrains.kotlin.gradle.report.data.BuildOperationRecord
import org.jetbrains.kotlin.gradle.testbase.TestVersions.ThirdPartyDependencies.GRADLE_ENTERPRISE_PLUGIN_VERSION
import java.lang.reflect.Type
import java.nio.file.Files
import kotlin.streams.asSequence
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
@DisplayName("Build reports")
@JvmGradlePluginTests
@@ -507,4 +518,79 @@ class BuildReportsIT : KGPBaseTest() {
}
}
@DisplayName("json validation")
@GradleTestVersions(
additionalVersions = [TestVersions.Gradle.G_7_6, TestVersions.Gradle.G_8_0],
)
@GradleTest
fun testJsonBuildMetricsFileValidation(gradleVersion: GradleVersion) {
project("simpleProject", gradleVersion) {
buildAndFail(
"compileKotlin", "-Pkotlin.build.report.output=JSON",
) {
assertOutputContains("Can't configure json report: 'kotlin.build.report.json.directory' property is mandatory")
}
}
}
@DisplayName("json report")
@GradleTestVersions(
additionalVersions = [TestVersions.Gradle.G_7_6, TestVersions.Gradle.G_8_0],
)
@GradleTest
fun testJsonBuildReport(gradleVersion: GradleVersion) {
project("simpleProject", gradleVersion) {
build(
"compileKotlin",
"-Pkotlin.build.report.output=JSON",
"-Pkotlin.build.report.json.directory=${projectPath.resolve("report").pathString}"
) {
//TODO: KT-66071 update deserialization
val gsonBuilder = GsonBuilder()
.registerTypeAdapter(BuildOperationRecord::class.java, object : JsonDeserializer<BuildOperationRecord> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?,
): BuildOperationRecord? {
//workaround to read both TaskRecord and TransformRecord
return context?.deserialize(json, BuildOperationRecordImpl::class.java)
}
}).registerTypeAdapter(SourcesChanges::class.java, object : JsonDeserializer<SourcesChanges> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext,
): SourcesChanges? {
return null //ignore source changes right now
}
})
val jsonReport = projectPath.getSingleFileInDir("report")
val buildExecutionData = jsonReport.bufferedReader().use {
gsonBuilder.create().fromJson(JsonReader(it), BuildExecutionData::class.java) as BuildExecutionData
}
val buildOperationRecords = buildExecutionData.buildOperationRecord.first { it.path == ":compileKotlin" } as BuildOperationRecordImpl
assertEquals(KotlinVersion.DEFAULT, buildOperationRecords.kotlinLanguageVersion)
}
}
}
}
data class BuildOperationRecordImpl(
override val path: String,
override val classFqName: String,
override val isFromKotlinPlugin: Boolean,
override val startTimeMs: Long, // Measured by System.currentTimeMillis(),
override val totalTimeMs: Long,
override val buildMetrics: BuildMetrics<GradleBuildTime, GradleBuildPerformanceMetric>,
override val didWork: Boolean,
override val skipMessage: String?,
override val icLogLines: List<String>,
//taskRecords
val kotlinLanguageVersion: KotlinVersion?,
val changedFiles: SourcesChanges? = null,
val compilerArguments: Array<String> = emptyArray(),
val statTags: Set<StatTag> = emptySet(),
): BuildOperationRecord