diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt index a1c2f12302932..841075c3530b4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt @@ -22,10 +22,8 @@ import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidBaseSourceSetName import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidVariantType import org.jetbrains.kotlin.gradle.plugin.sources.android.androidSourceSetInfoOrNull -import org.jetbrains.kotlin.gradle.plugin.sources.internal import org.jetbrains.kotlin.gradle.plugin.sources.sourceSetDependencyConfigurationByScope -import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType -import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget +import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinStdlibConfigurationMetrics import org.jetbrains.kotlin.gradle.targets.js.npm.SemVer import org.jetbrains.kotlin.gradle.utils.forAllTargets import org.jetbrains.kotlin.gradle.utils.withType @@ -136,6 +134,8 @@ private fun KotlinTarget.addStdlibDependency( val stdlibModule = compilation.platformType.stdlibPlatformType(this, kotlinSourceSet, stdlibVersion >= kotlin1920Version) ?: return@withDependencies + KotlinStdlibConfigurationMetrics.collectMetrics(project, requestedStdlibVersion) + dependencySet.addLater( coreLibrariesVersion.map { dependencies.kotlinDependency(stdlibModule, it) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt index 7a9cb4981f7ee..3a898eaa96f6c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.resources.publication.SetUpMultipl import org.jetbrains.kotlin.gradle.plugin.mpp.resources.RegisterMultiplatformResourcesPublicationExtensionAction import org.jetbrains.kotlin.gradle.plugin.sources.KotlinMultiplatformSourceSetSetupAction import org.jetbrains.kotlin.gradle.plugin.sources.LanguageSettingsSetupAction +import org.jetbrains.kotlin.gradle.plugin.statistics.FinalizeConfigurationFusMetricAction import org.jetbrains.kotlin.gradle.plugin.statistics.MultiplatformBuildStatsReportSetupAction import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubpluginSetupAction import org.jetbrains.kotlin.gradle.targets.* @@ -55,6 +56,7 @@ internal fun Project.registerKotlinPluginExtensions() { register(project, CustomizeKotlinDependenciesSetupAction) register(project, AddKotlinPlatformIntegersSupportLibrary) register(project, SetupKotlinNativePlatformDependenciesForLegacyImport) + register(project, FinalizeConfigurationFusMetricAction) if (isJvm || isMultiplatform) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFusService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFusService.kt index 98f9d6f4aa8c8..c6defd3489802 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFusService.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFusService.kt @@ -56,6 +56,7 @@ abstract class BuildFusService : BuildService, AutoC } interface Parameters : BuildServiceParameters { + val generalConfigurationMetrics: Property val configurationMetrics: ListProperty val useBuildFinishFlowAction: Property val buildStatisticsConfiguration: Property @@ -94,13 +95,9 @@ abstract class BuildFusService : BuildService, AutoC val isConfigurationCacheRequested = project.isConfigurationCacheRequested val isProjectIsolationRequested = project.isProjectIsolationRequested - project.gradle.sharedServices.registrations.findByName(serviceName)?.let { - (it.parameters as Parameters).configurationMetrics.add( - project.provider { - KotlinProjectConfigurationMetrics.collectMetrics(project) - } + ProjectConfigurationFusService.registerIfAbsent(project) - ) + project.gradle.sharedServices.registrations.findByName(serviceName)?.let { @Suppress("UNCHECKED_CAST") return (it.service as Provider) } @@ -116,7 +113,7 @@ abstract class BuildFusService : BuildService, AutoC // when this OperationCompletionListener is called services can be already closed for Gradle 8, // so there is a change that no VariantImplementationFactory will be found return gradle.sharedServices.registerIfAbsent(serviceName, BuildFusService::class.java) { spec -> - spec.parameters.configurationMetrics.add(project.provider { + spec.parameters.generalConfigurationMetrics.set(project.provider { //isProjectIsolationEnabled isConfigurationCacheRequested and isProjectIsolationRequested should be calculated beforehand // because since Gradle 8.0 provider's calculation is made in BuildFinishFlowAction // and VariantImplementationFactories is not initialized at that moment @@ -131,11 +128,6 @@ abstract class BuildFusService : BuildService, AutoC isConfigurationCacheRequested ) }) - spec.parameters.configurationMetrics.add( - project.provider { - collectProjectConfigurationTimeMetrics(project) - } - ) spec.parameters.useBuildFinishFlowAction.set(GradleVersion.current().baseVersion >= GradleVersion.version("8.1")) spec.parameters.buildStatisticsConfiguration.set(KotlinBuildStatsConfiguration(project)) }.also { buildService -> @@ -182,6 +174,7 @@ abstract class BuildFusService : BuildService, AutoC internal fun recordBuildFinished(buildFailed: Boolean) { BuildFinishMetrics.collectMetrics(log, buildFailed, buildStartTime, projectEvaluatedTime, fusMetricsConsumer) parameters.configurationMetrics.orElse(emptyList()).get().forEach { it.addToConsumer(fusMetricsConsumer) } + parameters.generalConfigurationMetrics.orNull?.addToConsumer(fusMetricsConsumer) parameters.buildStatisticsConfiguration.orNull?.also { val loggerService = KotlinBuildStatsLoggerService(it) loggerService.initSessionLogger(buildId) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FinalizeConfigurationFusMetricAction.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FinalizeConfigurationFusMetricAction.kt new file mode 100644 index 0000000000000..239d866cfbb96 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FinalizeConfigurationFusMetricAction.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2024 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.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle +import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupCoroutine +import org.jetbrains.kotlin.gradle.plugin.await + + +internal val FinalizeConfigurationFusMetricAction = KotlinProjectSetupCoroutine { + KotlinPluginLifecycle.Stage.ReadyForExecution.await() + + val projectConfigurationService = + project.gradle.sharedServices.registrations.findByName(ProjectConfigurationFusService.getServiceName(project))?.also { + val parameters = it.parameters as ProjectConfigurationFusService.Parameters + parameters.configurationMetrics.finalizeValue() + } + + project.gradle.sharedServices.registrations.findByName(BuildFusService.serviceName)?.also { + val parameters = it.parameters as BuildFusService.Parameters + parameters.generalConfigurationMetrics.finalizeValue() + projectConfigurationService?.service?.orNull?.also { + parameters.configurationMetrics.add((it.parameters as ProjectConfigurationFusService.Parameters).configurationMetrics) + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FusMetrics.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FusMetrics.kt index 958c1dc336fba..741d7f10f8675 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FusMetrics.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FusMetrics.kt @@ -280,4 +280,12 @@ internal object NativeLinkTaskMetrics : FusMetrics { it.put(BooleanMetrics.KOTLIN_INCREMENTAL_NATIVE_ENABLED, project.isKonanIncrementalCompilationEnabled()) } } +} + +internal object KotlinStdlibConfigurationMetrics : FusMetrics { + internal fun collectMetrics(project: Project, requestedStdlibVersion: String, ) { + project.addConfigurationMetrics { + it.put(StringMetrics.KOTLIN_STDLIB_VERSION, requestedStdlibVersion) + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ProjectConfigurationFusService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ProjectConfigurationFusService.kt new file mode 100644 index 0000000000000..8517fcd55479f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ProjectConfigurationFusService.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2024 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.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters + +abstract class ProjectConfigurationFusService : BuildService, AutoCloseable { + interface Parameters : BuildServiceParameters { + val configurationMetrics: Property + } + + companion object { + fun getServiceName(project: Project): String = + "${project.path}_${ProjectConfigurationFusService::class.simpleName}_${ProjectConfigurationFusService::class.java.classLoader.hashCode()}" + + //register a new service for every project to collect configuration metrics + fun registerIfAbsent(project: Project): Provider { + return project.gradle.sharedServices.registerIfAbsent( + getServiceName(project), + ProjectConfigurationFusService::class.java + ) { spec -> + spec.parameters.configurationMetrics.set(project.provider { + KotlinProjectConfigurationMetrics.collectMetrics(project) + }) + } + } + } + + override fun close() { + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/kotlinBuildStatisticsUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/kotlinBuildStatisticsUtils.kt index 374d7cabea6f4..1d705c7deb211 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/kotlinBuildStatisticsUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/kotlinBuildStatisticsUtils.kt @@ -172,7 +172,7 @@ private fun collectAppliedPluginsStatistics( configurationTimeMetrics: MetricContainer, ) { for (plugin in ObservablePlugins.values()) { - project.plugins.withId(plugin.title) { + if (project.plugins.hasPlugin(plugin.title)) { configurationTimeMetrics.put(plugin.metric, true) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetPreset.kt index 13ddcdf2d302a..40ac769aa3f12 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetPreset.kt @@ -30,13 +30,11 @@ open class KotlinJsIrTargetPreset( override fun instantiateTarget(name: String): KotlinJsIrTarget { return project.objects.newInstance(KotlinJsIrTarget::class.java, project, platformType).apply { this.isMpp = this@KotlinJsIrTargetPreset.isMpp - project.runProjectConfigurationHealthCheckWhenEvaluated { - KotlinJsIrTargetMetrics.collectMetrics( - isBrowserConfigured = isBrowserConfigured, - isNodejsConfigured = isNodejsConfigured, - project - ) - } + KotlinJsIrTargetMetrics.collectMetrics( + isBrowserConfigured = isBrowserConfigured, + isNodejsConfigured = isNodejsConfigured, + project + ) } }