Don't get BuildScanExtension when buildScan report is disabled

#KT-59589: Fixed
This commit is contained in:
Nataliya.Valtman
2023-06-29 12:03:01 +02:00
committed by Space Team
parent 5e7e1e6c92
commit ea8b482f4f
3 changed files with 62 additions and 30 deletions
@@ -19,6 +19,8 @@ import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.plugin.BuildEventsListenerRegistryHolder
import org.jetbrains.kotlin.gradle.plugin.StatisticsBuildFlowManager
import org.jetbrains.kotlin.gradle.plugin.internal.isProjectIsolationEnabled
import org.jetbrains.kotlin.gradle.report.BuildReportType
import org.jetbrains.kotlin.gradle.report.reportingSettings
import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.statistics.metrics.IStatisticsValuesConsumer
@@ -56,6 +58,7 @@ internal abstract class BuildFlowService : BuildService<BuildFlowService.Paramet
}
val fusStatisticsAvailable = fusStatisticsAvailable(project.gradle)
val buildScanReportEnabled = reportingSettings(project).buildReportOutputs.contains(BuildReportType.BUILD_SCAN)
//Workaround for known issues for Gradle 8+: https://github.com/gradle/gradle/issues/24887:
// when this OperationCompletionListener is called services can be already closed for Gradle 8,
@@ -80,7 +83,7 @@ internal abstract class BuildFlowService : BuildService<BuildFlowService.Paramet
else -> StatisticsBuildFlowManager.getInstance(project).subscribeForBuildResult()
}
}
if (GradleVersion.current().baseVersion >= GradleVersion.version("8.1")) {
if (buildScanReportEnabled && GradleVersion.current().baseVersion >= GradleVersion.version("8.1")) {
StatisticsBuildFlowManager.getInstance(project).subscribeForBuildScan(project)
}
}
@@ -231,44 +231,60 @@ abstract class BuildMetricsService : BuildService<BuildMetricsService.Parameters
}
private fun subscribeForTaskEvents(project: Project, buildMetricServiceProvider: Provider<BuildMetricsService>) {
// BuildScanExtension cant be parameter nor BuildService's field
val buildScanExtension = project.rootProject.extensions.findByName("buildScan")
val buildScan = buildScanExtension?.let { BuildScanExtensionHolder(it) }
val buildMetricService = buildMetricServiceProvider.get()
val buildScanReportSettings = buildMetricService.parameters.reportingSettings.orNull?.buildScanReportSettings
val buildScanHolder = initBuildScanExtensionHolder(project, buildMetricServiceProvider)
if (buildScanHolder != null) {
subscribeForTaskEventsForBuildScan(project, buildMetricServiceProvider, buildScanHolder)
}
val gradle80withBuildScanReport =
GradleVersion.current().baseVersion == GradleVersion.version("8.0") && buildScanReportSettings != null && buildScan != null
GradleVersion.current().baseVersion == GradleVersion.version("8.0") && buildScanHolder != null
if (!gradle80withBuildScanReport) {
BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(buildMetricServiceProvider)
}
}
private fun initBuildScanExtensionHolder(
project: Project,
buildMetricServiceProvider: Provider<BuildMetricsService>,
): BuildScanExtensionHolder? {
val buildScanReportSettings = buildMetricServiceProvider.get().parameters.reportingSettings.orNull?.buildScanReportSettings
if (buildScanReportSettings != null) {
buildScan?.also { buildScanHolder ->
when {
GradleVersion.current().baseVersion < GradleVersion.version("8.0") -> {
buildScanHolder.buildScan.buildFinished {
buildMetricServiceProvider.map {it.addBuildScanReport(buildScan)}.get()
}
}
GradleVersion.current().baseVersion < GradleVersion.version("8.1") -> {
buildMetricService.buildReportService.initBuildScanTags(buildScan, buildMetricService.parameters.label.orNull)
BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(project.provider {
OperationCompletionListener { event ->
if (event is TaskFinishEvent) {
val buildOperation = buildMetricService.updateBuildOperationRecord(event)
val buildParameters = buildMetricService.parameters.toBuildReportParameters()
val buildReportService = buildMetricServiceProvider.map { it.buildReportService }.get()
buildReportService.addBuildScanReport(event, buildOperation, buildParameters, buildScanHolder)
buildReportService.onFinish(event, buildOperation, buildParameters)
}
}
// BuildScanExtension cant be parameter nor BuildService's field
val buildScanExtension = project.rootProject.extensions.findByName("buildScan")
return buildScanExtension?.let { BuildScanExtensionHolder(it) }
}
return null
}
})
}
else -> {}//do nothing, BuildScanFlowAction is used
private fun subscribeForTaskEventsForBuildScan(
project: Project,
buildMetricServiceProvider: Provider<BuildMetricsService>,
buildScanHolder: BuildScanExtensionHolder
) {
when {
GradleVersion.current().baseVersion < GradleVersion.version("8.0") -> {
buildScanHolder.buildScan.buildFinished {
buildMetricServiceProvider.map { it.addBuildScanReport(buildScanHolder) }.get()
}
}
GradleVersion.current().baseVersion < GradleVersion.version("8.1") -> {
val buildMetricService = buildMetricServiceProvider.get()
buildMetricService.buildReportService.initBuildScanTags(buildScanHolder, buildMetricService.parameters.label.orNull)
BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(project.provider {
OperationCompletionListener { event ->
if (event is TaskFinishEvent) {
val buildOperation = buildMetricService.updateBuildOperationRecord(event)
val buildParameters = buildMetricService.parameters.toBuildReportParameters()
val buildReportService = buildMetricServiceProvider.map { it.buildReportService }.get()
buildReportService.addBuildScanReport(event, buildOperation, buildParameters, buildScanHolder)
buildReportService.onFinish(event, buildOperation, buildParameters)
}
}
})
}
else -> {}//do nothing, BuildScanFlowAction is used
}
}
@@ -8,5 +8,18 @@ package org.jetbrains.kotlin.gradle.report
import com.gradle.scan.plugin.BuildScanExtension
class BuildScanExtensionHolder(val buildScan: BuildScanExtension) : java.io.Serializable {
constructor(extension: Any) : this(extension as BuildScanExtension)
companion object {
internal operator fun invoke(extension: Any): BuildScanExtensionHolder? {
val buildScanExtension = try {
extension as BuildScanExtension
} catch (e: ClassNotFoundException) {
// Build scan plugin is applied, but BuildScanExtension class is not available due to Gradle classpath isolation
// Could be reproduced by applying Gradle enterprise plugin via init script: KT-59589
null
}
return buildScanExtension?.let { BuildScanExtensionHolder(it) }
}
}
}