diff --git a/buildSrc/src/main/kotlin/GradleCommon.kt b/buildSrc/src/main/kotlin/GradleCommon.kt
index 7806b458703..628fb5d2d0e 100644
--- a/buildSrc/src/main/kotlin/GradleCommon.kt
+++ b/buildSrc/src/main/kotlin/GradleCommon.kt
@@ -124,7 +124,7 @@ fun Project.createGradleCommonSourceSet(): SourceSet {
dependencies {
compileOnlyConfigurationName(kotlinStdlib())
- "commonGradleApiCompileOnly"("dev.gradleplugins:gradle-api:8.0")
+ "commonGradleApiCompileOnly"("dev.gradleplugins:gradle-api:8.1")
if (this@createGradleCommonSourceSet.name !in testPlugins) {
compileOnlyConfigurationName(project(":kotlin-gradle-plugin-api")) {
capabilities {
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 1ccd07dc9be..60cc42ea903 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -16,6 +16,7 @@
+
@@ -44,6 +45,8 @@
+
+
@@ -62,8 +65,6 @@
-
-
@@ -5684,6 +5685,12 @@
+
+
+
+
+
+
@@ -5702,6 +5709,12 @@
+
+
+
+
+
+
@@ -5720,6 +5733,12 @@
+
+
+
+
+
+
@@ -5738,6 +5757,12 @@
+
+
+
+
+
+
@@ -5756,6 +5781,12 @@
+
+
+
+
+
+
@@ -5774,6 +5805,12 @@
+
+
+
+
+
+
@@ -5792,6 +5829,12 @@
+
+
+
+
+
+
@@ -5810,6 +5853,12 @@
+
+
+
+
+
+
@@ -5828,6 +5877,12 @@
+
+
+
+
+
+
@@ -5846,6 +5901,12 @@
+
+
+
+
+
+
@@ -5864,6 +5925,12 @@
+
+
+
+
+
+
@@ -5882,6 +5949,12 @@
+
+
+
+
+
+
@@ -5900,6 +5973,12 @@
+
+
+
+
+
+
@@ -5918,6 +5997,12 @@
+
+
+
+
+
+
@@ -5936,6 +6021,12 @@
+
+
+
+
+
+
@@ -5954,6 +6045,12 @@
+
+
+
+
+
+
@@ -5972,6 +6069,12 @@
+
+
+
+
+
+
@@ -5990,6 +6093,12 @@
+
+
+
+
+
+
@@ -6008,6 +6117,12 @@
+
+
+
+
+
+
@@ -6026,6 +6141,12 @@
+
+
+
+
+
+
@@ -6050,6 +6171,12 @@
+
+
+
+
+
+
@@ -6458,6 +6585,12 @@
+
+
+
+
+
+
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt
index a5e60418c56..0d4bffe6e3e 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt
@@ -15,8 +15,23 @@ import java.nio.file.Path
@DisplayName("FUS statistic")
//Tests for FUS statistics have to create new instance of KotlinBuildStatsService
class FusStatisticsIT : KGPDaemonsBaseTest() {
+ private val expectedMetrics = arrayOf(
+ "OS_TYPE",
+ "BUILD_FAILED=false",
+ "EXECUTED_FROM_IDEA=false",
+ "BUILD_FINISH_TIME",
+ "GRADLE_VERSION",
+ "KOTLIN_STDLIB_VERSION",
+ "KOTLIN_COMPILER_VERSION",
+ )
+
@DisplayName("for dokka")
@GradleTest
+ @GradleTestVersions(
+ minVersion = TestVersions.Gradle.MIN_SUPPORTED,
+ additionalVersions = [TestVersions.Gradle.G_7_6, TestVersions.Gradle.G_8_0],
+ maxVersion = TestVersions.Gradle.G_8_1
+ )
fun testDokka(gradleVersion: GradleVersion) {
project(
"simpleProject",
@@ -48,6 +63,11 @@ class FusStatisticsIT : KGPDaemonsBaseTest() {
@DisplayName("general fields")
@GradleTest
+ @GradleTestVersions(
+ minVersion = TestVersions.Gradle.MIN_SUPPORTED,
+ additionalVersions = [TestVersions.Gradle.G_7_6, TestVersions.Gradle.G_8_0],
+ maxVersion = TestVersions.Gradle.G_8_1
+ )
fun testFusStatistics(gradleVersion: GradleVersion) {
project(
"simpleProject",
@@ -57,13 +77,7 @@ class FusStatisticsIT : KGPDaemonsBaseTest() {
val fusStatisticsPath = fusStatisticsPath
assertFileContains(
fusStatisticsPath,
- "OS_TYPE",
- "BUILD_FAILED=false",
- "EXECUTED_FROM_IDEA=false",
- "BUILD_FINISH_TIME",
- "GRADLE_VERSION",
- "KOTLIN_STDLIB_VERSION",
- "KOTLIN_COMPILER_VERSION",
+ *expectedMetrics,
)
assertFileDoesNotContain(
fusStatisticsPath,
@@ -74,8 +88,65 @@ class FusStatisticsIT : KGPDaemonsBaseTest() {
}
}
+ @DisplayName("for project with buildSrc")
+ @GradleTest
+ @GradleTestVersions(
+ minVersion = TestVersions.Gradle.MIN_SUPPORTED,
+ additionalVersions = [TestVersions.Gradle.G_7_6, TestVersions.Gradle.G_8_0],
+ maxVersion = TestVersions.Gradle.G_8_1
+ )
+ fun testProjectWithBuildSrc(gradleVersion: GradleVersion) {
+ project(
+ "instantExecutionWithBuildSrc",
+ gradleVersion,
+ ) {
+ build("compileKotlin", "-Pkotlin.session.logger.root.path=$projectPath") {
+ val fusStatisticsPath = fusStatisticsPath
+ assertFileContains(
+ fusStatisticsPath,
+ *expectedMetrics,
+ "BUILD_SRC_EXISTS=true"
+ )
+ }
+ }
+ }
+
+ @DisplayName("for project with included build")
+ @GradleTest
+ @GradleTestVersions(
+ minVersion = TestVersions.Gradle.G_7_6,
+ maxVersion = TestVersions.Gradle.G_8_0
+ )
+ fun testProjectWithIncludedBuild(gradleVersion: GradleVersion) {
+ project(
+ "instantExecutionWithIncludedBuildPlugin",
+ gradleVersion,
+ buildOptions = defaultBuildOptions.copy(configurationCache = true)
+ ) {
+ build("compileKotlin", "-Pkotlin.session.logger.root.path=$projectPath") {
+ val fusStatisticsPath = fusStatisticsPath
+ assertFileContains(
+ fusStatisticsPath,
+ *expectedMetrics,
+ )
+ }
+ build("compileKotlin", "-Pkotlin.session.logger.root.path=$projectPath") {
+ val fusStatisticsPath = fusStatisticsPath
+ assertFileContains(
+ fusStatisticsPath,
+ *expectedMetrics,
+ )
+ }
+ }
+ }
+
@DisplayName("for failed build")
@GradleTest
+ @GradleTestVersions(
+ minVersion = TestVersions.Gradle.MIN_SUPPORTED,
+ additionalVersions = [TestVersions.Gradle.G_7_6, TestVersions.Gradle.G_8_0],
+ maxVersion = TestVersions.Gradle.G_8_1
+ )
fun testFusStatisticsForFailedBuild(gradleVersion: GradleVersion) {
project(
"simpleProject",
@@ -98,4 +169,33 @@ class FusStatisticsIT : KGPDaemonsBaseTest() {
}
}
}
+
+ @DisplayName("general fields with configuration cache")
+ @GradleTest
+ @GradleTestVersions(
+ minVersion = TestVersions.Gradle.MIN_SUPPORTED,
+ additionalVersions = [TestVersions.Gradle.G_7_6, TestVersions.Gradle.G_8_0],
+ maxVersion = TestVersions.Gradle.G_8_1
+ )
+ fun testFusStatisticsWithConfigurationCache(gradleVersion: GradleVersion) {
+ project(
+ "simpleProject",
+ gradleVersion,
+ buildOptions = defaultBuildOptions.copy(configurationCache = true),
+ ) {
+ build(
+ "compileKotlin",
+ "-Pkotlin.session.logger.root.path=$projectPath",
+ ) {
+ assertConfigurationCacheStored()
+ }
+
+ build(
+ "compileKotlin",
+ "-Pkotlin.session.logger.root.path=$projectPath",
+ ) {
+ assertConfigurationCacheReused()
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt
index 54b154ca816..d9f8c90b0ee 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/fileAssertions.kt
@@ -191,7 +191,7 @@ fun assertFileContains(
|${textNotInTheFile.joinToString(separator = "\n")}
|
|actual file content:
- |$text"
+ |"$text"
|
""".trimMargin()
}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt
index b77f49600e9..d601f1c2087 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSetFactory
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.report.BuildMetricsService
+import org.jetbrains.kotlin.gradle.plugin.statistics.BuildFlowService
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin
import org.jetbrains.kotlin.gradle.targets.js.npm.addNpmDependencyExtension
@@ -65,10 +66,11 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin {
override val pluginVersion: String = getKotlinPluginVersion(logger)
override fun apply(project: Project) {
- val kotlinPluginVersion = project.getKotlinPluginVersion()
- val statisticsReporter = KotlinBuildStatsService.getOrCreateInstance(project)
- statisticsReporter?.report(StringMetrics.KOTLIN_COMPILER_VERSION, kotlinPluginVersion)
+ KotlinBuildStatsService.getOrCreateInstance(project)?.apply {
+ report(StringMetrics.KOTLIN_COMPILER_VERSION, pluginVersion)
+ }
+ BuildFlowService.registerIfAbsent(project)
checkGradleCompatibility()
@@ -89,7 +91,7 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin {
val kotlinGradleBuildServices = KotlinGradleBuildServices.registerIfAbsent(project.gradle).get()
if (!project.isProjectIsolationEnabled) {
- kotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion)
+ kotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, pluginVersion)
}
BuildMetricsService.registerIfAbsent(project)
@@ -212,7 +214,6 @@ abstract class KotlinBasePluginWrapper : DefaultKotlinBasePlugin() {
override fun apply(project: Project) {
super.apply(project)
- val kotlinPluginVersion = project.getKotlinPluginVersion()
project.logger.info("Using Kotlin Gradle Plugin $pluginVariant variant")
@@ -225,7 +226,7 @@ abstract class KotlinBasePluginWrapper : DefaultKotlinBasePlugin() {
project.maybeCreateCommonizerClasspathConfiguration()
project.createKotlinExtension(projectExtensionClass).apply {
- coreLibrariesVersion = kotlinPluginVersion
+ coreLibrariesVersion = pluginVersion
fun kotlinSourceSetContainer(factory: NamedDomainObjectFactory) =
project.container(KotlinSourceSet::class.java, factory)
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/StatisticsBuildFlowManager.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/StatisticsBuildFlowManager.kt
new file mode 100644
index 00000000000..7bcaf476786
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/StatisticsBuildFlowManager.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.plugin
+
+import org.gradle.api.Project
+import org.gradle.api.flow.*
+import org.gradle.api.provider.Property
+import org.gradle.api.services.ServiceReference
+import org.gradle.api.tasks.Input
+import org.jetbrains.kotlin.gradle.plugin.statistics.BuildFlowService
+import org.jetbrains.kotlin.gradle.report.BuildMetricsService
+import org.jetbrains.kotlin.gradle.report.BuildScanExtensionHolder
+import javax.inject.Inject
+
+internal abstract class StatisticsBuildFlowManager @Inject constructor(
+ private val flowScope: FlowScope,
+ private val flowProviders: FlowProviders,
+) {
+ companion object {
+ fun getInstance(project: Project) =
+ project.objects.newInstance(StatisticsBuildFlowManager::class.java)
+ }
+
+ fun subscribeForBuildResult() {
+ flowScope.always(
+ BuildFinishFlowAction::class.java
+ ) { spec ->
+ spec.parameters.buildFailed.set(flowProviders.buildWorkResult.map { it.failure.isPresent })
+ }
+ }
+
+ fun subscribeForBuildScan(project: Project) {
+ val buildScanExtension = project.rootProject.extensions.findByName("buildScan")
+ val buildScanHolder = buildScanExtension?.let { BuildScanExtensionHolder(it) }
+
+ flowScope.always(
+ BuildScanFlowAction::class.java
+ ) { spec ->
+ spec.parameters.buildScanExtensionHolder.set(buildScanHolder)
+ }
+ }
+}
+
+internal class BuildScanFlowAction : FlowAction {
+ interface Parameters : FlowParameters {
+ @get:ServiceReference
+ val buildMetricService: Property
+
+ @get: Input
+ val buildScanExtensionHolder: Property
+ }
+
+ override fun execute(parameters: Parameters) {
+ parameters.buildMetricService.orNull?.addCollectedTagsToBuildScan(parameters.buildScanExtensionHolder.orNull)
+ }
+}
+
+internal class BuildFinishFlowAction : FlowAction {
+ interface Parameters : FlowParameters {
+ @get:ServiceReference
+ val buildFlowServiceProperty: Property
+
+ @get:Input
+ val action: Property
+
+ @get:Input
+ val buildFailed: Property
+
+ }
+
+ override fun execute(parameters: Parameters) {
+ parameters.buildFlowServiceProperty.get().recordBuildFinished(
+ parameters.action.orNull, parameters.buildFailed.get()
+ )
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFlowService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFlowService.kt
new file mode 100644
index 00000000000..229669d8ec9
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFlowService.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.plugin.statistics
+
+import org.gradle.api.Project
+import org.gradle.api.invocation.Gradle
+import org.gradle.api.provider.Property
+import org.gradle.api.provider.Provider
+import org.gradle.api.services.BuildService
+import org.gradle.api.services.BuildServiceParameters
+import org.gradle.tooling.events.FinishEvent
+import org.gradle.tooling.events.OperationCompletionListener
+import org.gradle.tooling.events.task.TaskFailureResult
+import org.gradle.tooling.events.task.TaskFinishEvent
+import org.gradle.util.GradleVersion
+import org.jetbrains.kotlin.gradle.plugin.BuildEventsListenerRegistryHolder
+import org.jetbrains.kotlin.gradle.plugin.StatisticsBuildFlowManager
+import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
+import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
+import org.jetbrains.kotlin.statistics.metrics.IStatisticsValuesConsumer
+import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics
+import org.jetbrains.kotlin.statistics.metrics.StringMetrics
+import java.io.Serializable
+
+internal abstract class BuildFlowService : BuildService, AutoCloseable, OperationCompletionListener {
+ private var buildFailed: Boolean = false
+
+ interface Parameters : BuildServiceParameters {
+ val configurationMetrics: Property
+ val fusStatisticsAvailable: Property
+ }
+
+ companion object {
+ private val serviceName = "${BuildFlowService::class.simpleName}_${BuildFlowService::class.java.classLoader.hashCode()}"
+
+ private fun fusStatisticsAvailable(gradle: Gradle): Boolean {
+ return when {
+ //known issue for Gradle with configurationCache: https://github.com/gradle/gradle/issues/20001
+ GradleVersion.current().baseVersion < GradleVersion.version("7.4") -> !isConfigurationCacheAvailable(gradle)
+ GradleVersion.current().baseVersion < GradleVersion.version("8.1") -> true
+ //known issue. Cant reuse cache if file is changed in gradle_user_home dir: KT-58768
+ else -> !isConfigurationCacheAvailable(gradle)
+ }
+ }
+ fun registerIfAbsent(
+ project: Project,
+ ): Provider {
+
+ project.gradle.sharedServices.registrations.findByName(serviceName)?.let {
+ @Suppress("UNCHECKED_CAST")
+ return it.service as Provider
+ }
+
+ val fusStatisticsAvailable = fusStatisticsAvailable(project.gradle)
+ return project.gradle.sharedServices.registerIfAbsent(serviceName, BuildFlowService::class.java) { spec ->
+ if (fusStatisticsAvailable) {
+ KotlinBuildStatsService.applyIfInitialised {
+ it.recordProjectsEvaluated(project.gradle)
+ }
+ }
+
+ spec.parameters.configurationMetrics.set(project.provider {
+ KotlinBuildStatsService.getInstance()?.collectStartMetrics(project)
+ })
+ spec.parameters.fusStatisticsAvailable.set(fusStatisticsAvailable)
+ }.also { buildService ->
+ if (fusStatisticsAvailable) {
+ when {
+ GradleVersion.current().baseVersion < GradleVersion.version("8.1") ->
+ BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(buildService)
+ else -> StatisticsBuildFlowManager.getInstance(project).subscribeForBuildResult()
+ }
+ }
+ if (GradleVersion.current().baseVersion >= GradleVersion.version("8.1")) {
+ StatisticsBuildFlowManager.getInstance(project).subscribeForBuildScan(project)
+ }
+ }
+ }
+ }
+
+ override fun onFinish(event: FinishEvent?) {
+ if ((event is TaskFinishEvent) && (event.result is TaskFailureResult)) {
+ buildFailed = true
+ }
+ }
+
+ override fun close() {
+ if (parameters.fusStatisticsAvailable.get()) {
+ recordBuildFinished(null, buildFailed)
+ }
+ KotlinBuildStatsService.applyIfInitialised {
+ it.close()
+ }
+ }
+
+ internal fun recordBuildFinished(action: String?, buildFailed: Boolean) {
+ KotlinBuildStatsService.applyIfInitialised {
+ it.recordBuildFinish(action, buildFailed, parameters.configurationMetrics.orElse(MetricContainer()).get())
+ }
+ }
+}
+
+internal class MetricContainer : Serializable {
+ private val numericalMetrics = HashMap()
+ private val booleanMetrics = HashMap()
+ private val stringMetrics = HashMap()
+
+ fun report(sessionLogger: IStatisticsValuesConsumer) {
+ for ((key, value) in numericalMetrics) {
+ sessionLogger.report(key, value)
+ }
+ for ((key, value) in booleanMetrics) {
+ sessionLogger.report(key, value)
+ }
+ for ((key, value) in stringMetrics) {
+ sessionLogger.report(key, value)
+ }
+ }
+
+ fun put(metric: StringMetrics, value: String) = stringMetrics.put(metric, value)
+ fun put(metric: BooleanMetrics, value: Boolean) = booleanMetrics.put(metric, value)
+ fun put(metric: NumericalMetrics, value: Long) = numericalMetrics.put(metric, value)
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatHandler.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatHandler.kt
index 927e5da77e0..bc2e5f6ad87 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatHandler.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatHandler.kt
@@ -7,12 +7,9 @@ package org.jetbrains.kotlin.gradle.plugin.statistics
import org.gradle.api.Project
import org.gradle.api.artifacts.DependencySet
-import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logging
-import org.jetbrains.kotlin.gradle.utils.API
-import org.jetbrains.kotlin.gradle.utils.COMPILE
-import org.jetbrains.kotlin.gradle.utils.IMPLEMENTATION
-import org.jetbrains.kotlin.gradle.utils.RUNTIME
+import org.jetbrains.kotlin.gradle.plugin.internal.isProjectIsolationEnabled
+import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.statistics.BuildSessionLogger
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics
@@ -61,92 +58,102 @@ class KotlinBuildStatHandler {
}
}
- fun reportGlobalMetricsAndBuildFinished(
- gradle: Gradle?,
- beanName: ObjectName,
+ fun reportGlobalMetrics(
sessionLogger: BuildSessionLogger,
- action: String?,
- failure: Throwable?
) {
runSafe("${KotlinBuildStatHandler::class.java}.reportGlobalMetrics") {
- try {
- try {
- if (gradle != null) reportGlobalMetrics(gradle, sessionLogger)
- } finally {
- sessionLogger.finishBuildSession(action, failure)
- }
- } finally {
- buildFinished(beanName)
- }
+ System.getProperty("os.name")?.also { sessionLogger.report(StringMetrics.OS_TYPE, System.getProperty("os.name")) }
+ sessionLogger.report(NumericalMetrics.CPU_NUMBER_OF_CORES, Runtime.getRuntime().availableProcessors().toLong())
+ sessionLogger.report(BooleanMetrics.EXECUTED_FROM_IDEA, System.getProperty("idea.active") != null)
+ sessionLogger.report(NumericalMetrics.GRADLE_DAEMON_HEAP_SIZE, Runtime.getRuntime().maxMemory())
}
}
- internal fun reportGlobalMetrics(gradle: Gradle, sessionLogger: BuildSessionLogger) {
- sessionLogger.report(StringMetrics.PROJECT_PATH, gradle.rootProject.projectDir.absolutePath)
- System.getProperty("os.name")?.also { sessionLogger.report(StringMetrics.OS_TYPE, System.getProperty("os.name")) }
- sessionLogger.report(NumericalMetrics.CPU_NUMBER_OF_CORES, Runtime.getRuntime().availableProcessors().toLong())
- sessionLogger.report(StringMetrics.GRADLE_VERSION, gradle.gradleVersion)
- sessionLogger.report(BooleanMetrics.EXECUTED_FROM_IDEA, System.getProperty("idea.active") != null)
- sessionLogger.report(NumericalMetrics.GRADLE_DAEMON_HEAP_SIZE, Runtime.getRuntime().maxMemory())
- sessionLogger.report(
- BooleanMetrics.KOTLIN_OFFICIAL_CODESTYLE,
- gradle.rootProject.providers.gradleProperty("kotlin.code.style").orNull == "official"
- ) // constants are saved in IDEA plugin and could not be accessed directly
+ internal fun reportBuildFinished(
+ sessionLogger: BuildSessionLogger,
+ action: String?,
+ buildFailed: Boolean,
+ configurationMetrics: MetricContainer,
+ ) {
+ runSafe("${KotlinBuildStatHandler::class.java}.reportBuildFinish") {
+ configurationMetrics.report(sessionLogger)
+ sessionLogger.finishBuildSession(action, buildFailed)
+ }
+ }
- gradle.taskGraph.whenReady() { taskExecutionGraph ->
- val executedTaskNames = taskExecutionGraph.allTasks.map { it.name }.distinct()
- report(sessionLogger, BooleanMetrics.MAVEN_PUBLISH_EXECUTED, executedTaskNames.contains("install"), null)
+ internal fun collectConfigurationTimeMetrics(
+ project: Project,
+ sessionLogger: BuildSessionLogger,
+ ): MetricContainer {
+ val gradle = project.gradle
+ val configurationTimeMetrics = MetricContainer()
+ configurationTimeMetrics.put(StringMetrics.PROJECT_PATH, gradle.rootProject.projectDir.absolutePath)
+ configurationTimeMetrics.put(StringMetrics.GRADLE_VERSION, gradle.gradleVersion)
+
+ if (project.isProjectIsolationEnabled) { //support project isolation - KT-58768
+ return configurationTimeMetrics
}
+ gradle.taskGraph.whenReady { taskExecutionGraph ->
+ val executedTaskNames = taskExecutionGraph.allTasks.map { it.name }.distinct()
+ configurationTimeMetrics.put(BooleanMetrics.MAVEN_PUBLISH_EXECUTED, executedTaskNames.contains("install"))
+ }// constants are saved in IDEA plugin and could not be accessed directly
fun buildSrcExists(project: Project) = File(project.projectDir, "buildSrc").exists()
- sessionLogger.report(BooleanMetrics.BUILD_SRC_EXISTS, buildSrcExists(gradle.rootProject))
+ configurationTimeMetrics.put(BooleanMetrics.BUILD_SRC_EXISTS, buildSrcExists(gradle.rootProject))
val statisticOverhead = measureTimeMillis {
gradle.allprojects { project ->
project.plugins.findPlugin(DOKKA_PLUGIN)?.also {
- sessionLogger.report(BooleanMetrics.ENABLED_DOKKA, true)
+ configurationTimeMetrics.put(BooleanMetrics.ENABLED_DOKKA, true)
}
for (configuration in project.configurations) {
- val configurationName = configuration.name
- val dependencies = configuration.dependencies
+ try {
+ val configurationName = configuration.name
+ val dependencies = configuration.dependencies
- when (configurationName) {
- "KoverEngineConfig" -> {
- sessionLogger.report(BooleanMetrics.ENABLED_KOVER, true)
- }
- "kapt" -> {
- sessionLogger.report(BooleanMetrics.ENABLED_KAPT, true)
- for (dependency in dependencies) {
- when (dependency.group) {
- "com.google.dagger" -> sessionLogger.report(BooleanMetrics.ENABLED_DAGGER, true)
- "com.android.databinding" -> sessionLogger.report(BooleanMetrics.ENABLED_DATABINDING, true)
+ when (configurationName) {
+ "KoverEngineConfig" -> {
+ configurationTimeMetrics.put(BooleanMetrics.ENABLED_KOVER, true)
+ }
+ "kapt" -> {
+ configurationTimeMetrics.put(BooleanMetrics.ENABLED_KAPT, true)
+ for (dependency in dependencies) {
+ when (dependency.group) {
+ "com.google.dagger" -> configurationTimeMetrics.put(BooleanMetrics.ENABLED_DAGGER, true)
+ "com.android.databinding" -> configurationTimeMetrics.put(BooleanMetrics.ENABLED_DATABINDING, true)
+ }
}
}
+ API -> {
+ configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_API_COUNT, 1)
+ reportLibrariesVersions(configurationTimeMetrics, dependencies)
+ }
+ IMPLEMENTATION -> {
+ configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_IMPLEMENTATION_COUNT, 1)
+ reportLibrariesVersions(configurationTimeMetrics, dependencies)
+ }
+ COMPILE -> {
+ configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_COMPILE_COUNT, 1)
+ reportLibrariesVersions(configurationTimeMetrics, dependencies)
+ }
+ RUNTIME -> {
+ configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_RUNTIME_COUNT, 1)
+ reportLibrariesVersions(configurationTimeMetrics, dependencies)
+ }
}
- API -> {
- sessionLogger.report(NumericalMetrics.CONFIGURATION_API_COUNT, 1)
- reportLibrariesVersions(sessionLogger, dependencies)
- }
- IMPLEMENTATION -> {
- sessionLogger.report(NumericalMetrics.CONFIGURATION_IMPLEMENTATION_COUNT, 1)
- reportLibrariesVersions(sessionLogger, dependencies)
- }
- COMPILE -> {
- sessionLogger.report(NumericalMetrics.CONFIGURATION_COMPILE_COUNT, 1)
- reportLibrariesVersions(sessionLogger, dependencies)
- }
- RUNTIME -> {
- sessionLogger.report(NumericalMetrics.CONFIGURATION_RUNTIME_COUNT, 1)
- reportLibrariesVersions(sessionLogger, dependencies)
- }
+ } catch (e: Throwable) {
+ // log?
}
}
val taskNames = project.tasks.names
- sessionLogger.report(NumericalMetrics.NUMBER_OF_SUBPROJECTS, 1)
- sessionLogger.report(BooleanMetrics.KOTLIN_KTS_USED, project.buildscript.sourceFile?.name?.endsWith(".kts") ?: false)
- sessionLogger.report(NumericalMetrics.GRADLE_NUMBER_OF_TASKS, taskNames.size.toLong())
- sessionLogger.report(
+ configurationTimeMetrics.put(NumericalMetrics.NUMBER_OF_SUBPROJECTS, 1)
+ configurationTimeMetrics.put(
+ BooleanMetrics.KOTLIN_KTS_USED,
+ project.buildscript.sourceFile?.name?.endsWith(".kts") ?: false
+ )
+ configurationTimeMetrics.put(NumericalMetrics.GRADLE_NUMBER_OF_TASKS, taskNames.size.toLong())
+ configurationTimeMetrics.put(
NumericalMetrics.GRADLE_NUMBER_OF_UNCONFIGURED_TASKS,
taskNames.count { name ->
try {
@@ -157,52 +164,54 @@ class KotlinBuildStatHandler {
}.toLong()
)
- if (buildSrcExists(project)) {
- sessionLogger.report(NumericalMetrics.BUILD_SRC_COUNT, 1)
- sessionLogger.report(BooleanMetrics.BUILD_SRC_EXISTS, true)
+ if (project.name == "buildSrc") {
+ configurationTimeMetrics.put(NumericalMetrics.BUILD_SRC_COUNT, 1)
+ configurationTimeMetrics.put(BooleanMetrics.BUILD_SRC_EXISTS, true)
}
}
}
sessionLogger.report(NumericalMetrics.STATISTICS_VISIT_ALL_PROJECTS_OVERHEAD, statisticOverhead)
+
+ return configurationTimeMetrics
}
- private fun reportLibrariesVersions(sessionLogger: BuildSessionLogger, dependencies: DependencySet?) {
+ private fun reportLibrariesVersions(configurationTimeMetrics: MetricContainer, dependencies: DependencySet?) {
dependencies?.forEach { dependency ->
when {
- dependency.group?.startsWith("org.springframework") ?: false -> sessionLogger.report(
+ dependency.group?.startsWith("org.springframework") ?: false -> configurationTimeMetrics.put(
StringMetrics.LIBRARY_SPRING_VERSION,
dependency.version ?: "0.0.0"
)
- dependency.group?.startsWith("com.vaadin") ?: false -> sessionLogger.report(
+ dependency.group?.startsWith("com.vaadin") ?: false -> configurationTimeMetrics.put(
StringMetrics.LIBRARY_VAADIN_VERSION,
dependency.version ?: "0.0.0"
)
- dependency.group?.startsWith("com.google.gwt") ?: false -> sessionLogger.report(
+ dependency.group?.startsWith("com.google.gwt") ?: false -> configurationTimeMetrics.put(
StringMetrics.LIBRARY_GWT_VERSION,
dependency.version ?: "0.0.0"
)
- dependency.group?.startsWith("org.hibernate") ?: false -> sessionLogger.report(
+ dependency.group?.startsWith("org.hibernate") ?: false -> configurationTimeMetrics.put(
StringMetrics.LIBRARY_HIBERNATE_VERSION,
dependency.version ?: "0.0.0"
)
- dependency.group == "org.jetbrains.kotlin" && dependency.name.startsWith("kotlin-stdlib") -> sessionLogger.report(
+ dependency.group == "org.jetbrains.kotlin" && dependency.name.startsWith("kotlin-stdlib") -> configurationTimeMetrics.put(
StringMetrics.KOTLIN_STDLIB_VERSION,
dependency.version ?: "0.0.0"
)
- dependency.group == "org.jetbrains.kotlinx" && dependency.name == "kotlinx-coroutines" -> sessionLogger.report(
+ dependency.group == "org.jetbrains.kotlinx" && dependency.name == "kotlinx-coroutines" -> configurationTimeMetrics.put(
StringMetrics.KOTLIN_COROUTINES_VERSION,
dependency.version ?: "0.0.0"
)
- dependency.group == "org.jetbrains.kotlin" && dependency.name == "kotlin-reflect" -> sessionLogger.report(
+ dependency.group == "org.jetbrains.kotlin" && dependency.name == "kotlin-reflect" -> configurationTimeMetrics.put(
StringMetrics.KOTLIN_REFLECT_VERSION,
dependency.version ?: "0.0.0"
)
dependency.group == "org.jetbrains.kotlinx" && dependency.name
- .startsWith("kotlinx-serialization-runtime") -> sessionLogger.report(
+ .startsWith("kotlinx-serialization-runtime") -> configurationTimeMetrics.put(
StringMetrics.KOTLIN_SERIALIZATION_VERSION,
dependency.version ?: "0.0.0"
)
- dependency.group == "com.android.tools.build" && dependency.name.startsWith("gradle") -> sessionLogger.report(
+ dependency.group == "com.android.tools.build" && dependency.name.startsWith("gradle") -> configurationTimeMetrics.put(
StringMetrics.ANDROID_GRADLE_PLUGIN_VERSION,
dependency.version ?: "0.0.0"
)
@@ -215,7 +224,7 @@ class KotlinBuildStatHandler {
metric: BooleanMetrics,
value: Boolean,
subprojectName: String?,
- weight: Long? = null
+ weight: Long? = null,
) = runSafe("report metric ${metric.name}") {
sessionLogger.report(metric, value, subprojectName, weight)
} ?: false
@@ -225,7 +234,7 @@ class KotlinBuildStatHandler {
metric: NumericalMetrics,
value: Long,
subprojectName: String?,
- weight: Long? = null
+ weight: Long? = null,
) = runSafe("report metric ${metric.name}") {
sessionLogger.report(metric, value, subprojectName, weight)
} ?: false
@@ -235,7 +244,7 @@ class KotlinBuildStatHandler {
metric: StringMetrics,
value: String,
subprojectName: String?,
- weight: Long? = null
+ weight: Long? = null,
) = runSafe("report metric ${metric.name}") {
sessionLogger.report(metric, value, subprojectName, weight)
} ?: false
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatsService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatsService.kt
index 466e87a509d..6e8abfff994 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatsService.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatsService.kt
@@ -5,8 +5,6 @@
package org.jetbrains.kotlin.gradle.plugin.statistics
-import org.gradle.BuildAdapter
-import org.gradle.BuildResult
import org.gradle.api.Project
import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logger
@@ -19,13 +17,13 @@ import org.jetbrains.kotlin.gradle.plugin.BuildEventsListenerRegistryHolder
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatHandler.Companion.runSafe
import org.jetbrains.kotlin.gradle.plugin.statistics.old.Pre232IdeaKotlinBuildStatsMXBean
import org.jetbrains.kotlin.gradle.plugin.statistics.old.Pre232IdeaKotlinBuildStatsService
-import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
import org.jetbrains.kotlin.statistics.BuildSessionLogger
import org.jetbrains.kotlin.statistics.BuildSessionLogger.Companion.STATISTICS_FOLDER_NAME
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.statistics.metrics.IStatisticsValuesConsumer
import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
+import java.io.Closeable
import java.io.File
import java.lang.management.ManagementFactory
import javax.management.MBeanServer
@@ -48,7 +46,7 @@ interface KotlinBuildStatsMXBean {
}
-internal abstract class KotlinBuildStatsService internal constructor() : BuildAdapter(), IStatisticsValuesConsumer {
+internal abstract class KotlinBuildStatsService internal constructor() : IStatisticsValuesConsumer, Closeable {
companion object {
// Do not rename this bean otherwise compatibility with the older Kotlin Gradle Plugins would be lost
private const val JMX_BEAN_NAME_BEFORE_232_IDEA = "org.jetbrains.kotlin.gradle.plugin.statistics:type=StatsService"
@@ -77,7 +75,7 @@ internal abstract class KotlinBuildStatsService internal constructor() : BuildAd
*/
@JvmStatic
@Synchronized
- fun getInstance(): IStatisticsValuesConsumer? {
+ fun getInstance(): KotlinBuildStatsService? {
if (statisticsIsEnabled != true) {
return null
}
@@ -101,7 +99,7 @@ internal abstract class KotlinBuildStatsService internal constructor() : BuildAd
*/
@JvmStatic
@Synchronized
- internal fun getOrCreateInstance(project: Project): IStatisticsValuesConsumer? {
+ internal fun getOrCreateInstance(project: Project): KotlinBuildStatsService? {
return runSafe("${KotlinBuildStatsService::class.java}.getOrCreateInstance") {
val gradle = project.gradle
@@ -131,11 +129,7 @@ internal abstract class KotlinBuildStatsService internal constructor() : BuildAd
registerPre232IdeaStatsBean(mbs, gradle, log)
}
- if (!isConfigurationCacheAvailable(gradle)) {
- gradle.addBuildListener(instance!!)
- }
-
- BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(project.provider {
+ BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(project.provider {
OperationCompletionListener { event ->
if (event is TaskFinishEvent) {
reportTaskIfNeed(event.descriptor.name)
@@ -181,7 +175,7 @@ internal abstract class KotlinBuildStatsService internal constructor() : BuildAd
* Invokes provided collector if the reporting service is initialised.
* The duration of collector's wall time is reported into overall overhead metric.
*/
- fun applyIfInitialised(collector: (IStatisticsValuesConsumer) -> Unit) {
+ fun applyIfInitialised(collector: (KotlinBuildStatsService) -> Unit) {
getInstance()?.apply {
try {
val duration = measureTimeMillis {
@@ -213,6 +207,22 @@ internal abstract class KotlinBuildStatsService internal constructor() : BuildAd
}
}
}
+
+ override fun close() {
+ instance = null
+ }
+
+ /**
+ * Collects metrics at the end of a build
+ */
+ open fun recordBuildFinish(action: String?, buildFailed: Boolean, configurationTimeMetrics: MetricContainer) {}
+
+ /**
+ * Collect project general and configuration metrics at the start of a build
+ */
+ open fun collectStartMetrics(project: Project): MetricContainer = MetricContainer()
+
+ open fun recordProjectsEvaluated(gradle: Gradle) {}
}
internal class JMXKotlinBuildStatsService(private val mbs: MBeanServer, private val beanName: ObjectName) :
@@ -242,14 +252,11 @@ internal class JMXKotlinBuildStatsService(private val mbs: MBeanServer, private
callJmx("reportString", "java.lang.String", metric.name, value, subprojectName, weight)
} as? Boolean ?: false
- override fun buildFinished(result: BuildResult) {
- instance = null
- }
}
internal abstract class AbstractKotlinBuildStatsService(
gradle: Gradle,
- protected val beanName: ObjectName,
+ private val beanName: ObjectName,
) : KotlinBuildStatsService() {
companion object {
//test only
@@ -275,13 +282,16 @@ internal abstract class AbstractKotlinBuildStatsService(
private val sessionLoggerRootPath =
customSessionLoggerRootPath?.let { File(it) } ?: gradle.gradleUserHomeDir
- protected val sessionLogger = BuildSessionLogger(sessionLoggerRootPath, forceValuesValidation = forcePropertiesValidation)
+ protected val sessionLogger = BuildSessionLogger(
+ sessionLoggerRootPath,
+ forceValuesValidation = forcePropertiesValidation,
+ )
private fun gradleBuildStartTime(gradle: Gradle): Long? {
return (gradle as? DefaultGradle)?.services?.get(BuildRequestMetaData::class.java)?.startTime
}
- override fun projectsEvaluated(gradle: Gradle) {
+ override fun recordProjectsEvaluated(gradle: Gradle) {
runSafe("${DefaultKotlinBuildStatsService::class.java}.projectEvaluated") {
if (!sessionLogger.isBuildSessionStarted()) {
sessionLogger.startBuildSession(
@@ -293,15 +303,15 @@ internal abstract class AbstractKotlinBuildStatsService(
}
@Synchronized
- override fun buildFinished(result: BuildResult) {
+ override fun close() {
KotlinBuildStatHandler().buildFinished(beanName)
- instance = null
+ super.close()
}
}
internal class DefaultKotlinBuildStatsService internal constructor(
gradle: Gradle,
- beanName: ObjectName
+ beanName: ObjectName,
) : AbstractKotlinBuildStatsService(gradle, beanName), KotlinBuildStatsMXBean {
override fun report(metric: BooleanMetrics, value: Boolean, subprojectName: String?, weight: Long?): Boolean =
@@ -323,9 +333,11 @@ internal class DefaultKotlinBuildStatsService internal constructor(
report(StringMetrics.valueOf(name), value, subprojectName, weight)
//only one jmx bean service should report global metrics
- @Synchronized
- override fun buildFinished(result: BuildResult) {
- KotlinBuildStatHandler().reportGlobalMetricsAndBuildFinished(result.gradle, beanName, sessionLogger, result.action, result.failure)
- instance = null
+ override fun recordBuildFinish(action: String?, buildFailed: Boolean, configurationTimeMetrics: MetricContainer) {
+ KotlinBuildStatHandler().reportGlobalMetrics(sessionLogger)
+ KotlinBuildStatHandler().reportBuildFinished(sessionLogger, action, buildFailed, configurationTimeMetrics)
}
+
+ override fun collectStartMetrics(project: Project) = KotlinBuildStatHandler().collectConfigurationTimeMetrics(project, sessionLogger)
+
}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsService.kt
index 7707f56b745..3348468ae5c 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsService.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsService.kt
@@ -22,6 +22,7 @@ import org.gradle.tooling.events.task.TaskExecutionResult
import org.gradle.tooling.events.task.TaskFailureResult
import org.gradle.tooling.events.task.TaskFinishEvent
import org.gradle.tooling.events.task.TaskSkippedResult
+import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.build.report.metrics.BuildMetrics
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
import org.jetbrains.kotlin.build.report.metrics.BuildPerformanceMetric
@@ -224,25 +225,27 @@ abstract class BuildMetricsService : BuildService
if (event is TaskFinishEvent) {
val buildOperation = buildMetricService.get().updateBuildOperationRecord(event)
val buildParameters = buildMetricService.get().parameters.toBuildReportParameters()
+ val buildReportService = buildMetricService.map { it.buildReportService }
buildReportService.get().onFinish(event, buildOperation, buildParameters, buildScan)
}
}
})
-
- val buildScanReportSettings = buildMetricService.get().parameters.reportingSettings.orNull?.buildScanReportSettings
if (buildScanReportSettings != null) {
buildScan?.also {
- buildReportService.get().initBuildScanTags(
+ buildMetricService.map { it.buildReportService }.get().initBuildScanTags(
it, buildMetricService.get().parameters.label.orNull
)
- it.buildScan.buildFinished {
- buildReportService.get().addCollectedTags(buildScan)
+ if (GradleVersion.current().baseVersion < GradleVersion.version("8.0")) {
+ it.buildScan.buildFinished {
+ buildMetricService.map { it.addCollectedTagsToBuildScan(buildScan) }
+ }
}
}
}
@@ -273,6 +276,11 @@ abstract class BuildMetricsService : BuildService
assertTrue(
@@ -69,21 +69,21 @@ class BuildSessionLoggerTest {
val maxFileSize = 10_000
val logger = BuildSessionLogger(rootFolder, 100, maxFileSize.toLong())
logger.startBuildSession(0, null)
- logger.finishBuildSession("", null)
+ logger.finishBuildSession("", false)
assertEquals(1, statFilesCount())
val file2edit = rootFolder.listFiles()?.first()?.listFiles()?.first() ?: fail("Could not find single stat file")
logger.startBuildSession(0, 0)
- logger.finishBuildSession("", null)
+ logger.finishBuildSession("", false)
//new file should not be created
assertEquals(1, statFilesCount())
file2edit.appendBytes(ByteArray(maxFileSize))
logger.startBuildSession(0, 0)
- logger.finishBuildSession("", null)
+ logger.finishBuildSession("", false)
// a new file should be created as maximal file size
assertEquals(2, statFilesCount())
@@ -94,7 +94,7 @@ class BuildSessionLoggerTest {
val maxFiles = 100
val logger = BuildSessionLogger(rootFolder, maxFiles)
logger.startBuildSession(0, null)
- logger.finishBuildSession("", null)
+ logger.finishBuildSession("", false)
assertEquals(1, statFilesCount())
val statsFolder = rootFolder.listFiles()?.single() ?: fail("${rootFolder.absolutePath} was not created")
@@ -107,7 +107,7 @@ class BuildSessionLoggerTest {
}
logger.startBuildSession(0, 0)
- logger.finishBuildSession("", null)
+ logger.finishBuildSession("", false)
assertTrue(
statsFolder.listFiles()?.count { it.name == singleStatFile.name } == 1,
@@ -139,7 +139,7 @@ class BuildSessionLoggerTest {
val startTime = System.currentTimeMillis() - 1001
logger.startBuildSession(1, startTime)
- logger.finishBuildSession("Build", null)
+ logger.finishBuildSession("Build", false)
assertEquals(1, statFilesCount())
val statFile = rootFolder.listFiles()?.single()?.listFiles()?.single() ?: fail("Could not find stat file")
@@ -158,7 +158,7 @@ class BuildSessionLoggerTest {
}
- logger.finishBuildSession("", null)
+ logger.finishBuildSession("", false)
val metrics = ArrayList()
MetricsContainer.readFromFile(statFile) {
@@ -194,7 +194,7 @@ class BuildSessionLoggerTest {
for (metric in NumericalMetrics.values()) {
logger.report(metric, System.currentTimeMillis())
}
- logger.finishBuildSession("Build", null)
+ logger.finishBuildSession("Build", false)
MetricsContainer.readFromFile(rootFolder.listFiles()?.single()?.listFiles()?.single() ?: fail("Could not find stat file")) {
for (metric in StringMetrics.values()) {
@@ -217,7 +217,7 @@ class BuildSessionLoggerTest {
logger.report(NumericalMetrics.ANALYSIS_LINES_PER_SECOND, 10, null, 9)
logger.report(NumericalMetrics.ANALYSIS_LINES_PER_SECOND, 100, null, 1)
- logger.finishBuildSession("Build", null)
+ logger.finishBuildSession("Build", false)
MetricsContainer.readFromFile(rootFolder.listFiles()?.single()?.listFiles()?.single() ?: fail("Could not find stat file")) {
assertEquals(19L, it.getMetric(NumericalMetrics.ANALYSIS_LINES_PER_SECOND)?.getValue())
}
diff --git a/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/BuildSessionLogger.kt b/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/BuildSessionLogger.kt
index f4a66f36e20..0c8c6c9edb0 100644
--- a/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/BuildSessionLogger.kt
+++ b/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/BuildSessionLogger.kt
@@ -20,7 +20,7 @@ class BuildSessionLogger(
private val maxProfileFiles: Int = DEFAULT_MAX_PROFILE_FILES,
private val maxFileSize: Long = DEFAULT_MAX_PROFILE_FILE_SIZE,
private val maxFileAge: Long = DEFAULT_MAX_FILE_AGE,
- private val forceValuesValidation: Boolean = false
+ private val forceValuesValidation: Boolean = false,
) : IStatisticsValuesConsumer {
companion object {
@@ -131,7 +131,10 @@ class BuildSessionLogger(
}
@Synchronized
- fun finishBuildSession(@Suppress("UNUSED_PARAMETER") action: String?, failure: Throwable?) {
+ fun finishBuildSession(
+ @Suppress("UNUSED_PARAMETER") action: String?,
+ buildFailed: Boolean,
+ ) {
try {
// nanotime could not be used as build start time in nanotime is unknown. As result, the measured duration
// could be affected by system clock correction
@@ -142,7 +145,7 @@ class BuildSessionLogger(
}
report(NumericalMetrics.GRADLE_EXECUTION_DURATION, finishTime - it.projectEvaluatedTime)
report(NumericalMetrics.BUILD_FINISH_TIME, finishTime)
- report(BooleanMetrics.BUILD_FAILED, failure != null)
+ report(BooleanMetrics.BUILD_FAILED, buildFailed)
}
buildSession = null
} finally {