From 6e2202ad5a0f8ad0af34ae4d95a28c90d4fe93ad Mon Sep 17 00:00:00 2001 From: "nataliya.valtman" Date: Tue, 26 Jul 2022 16:21:47 +0200 Subject: [PATCH] Fix repeating custom values in build scan. Refactor build statistic --- .../ClasspathEntrySnapshotTransform.kt | 6 +- .../gradle/plugin/KotlinPluginWrapper.kt | 11 +- ...orterService.kt => BuildMetricsService.kt} | 59 +--- .../gradle/report/BuildReportsService.kt | 273 ++++++++++++++++++ .../kotlin/gradle/report/HttpReportService.kt | 194 ------------- .../kotlin/gradle/report/MetricsWriter.kt | 5 +- .../report/PlainTextBuildReportWriter.kt | 17 -- .../data/BuildExecutionDataProcessor.kt | 12 - .../gradle/targets/js/ir/KotlinBrowserJsIr.kt | 6 +- .../targets/js/subtargets/KotlinBrowserJs.kt | 6 +- .../targets/js/webpack/KotlinWebpack.kt | 6 +- .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 18 +- .../AbstractKotlinCompileConfig.kt | 10 +- .../configuration/KotlinCompileConfig.kt | 8 +- 14 files changed, 322 insertions(+), 309 deletions(-) rename libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/{BuildMetricsReporterService.kt => BuildMetricsService.kt} (67%) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildReportsService.kt delete mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/HttpReportService.kt delete mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/data/BuildExecutionDataProcessor.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/transforms/ClasspathEntrySnapshotTransform.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/transforms/ClasspathEntrySnapshotTransform.kt index 2df5bea4f31..32073f20f8e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/transforms/ClasspathEntrySnapshotTransform.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/transforms/ClasspathEntrySnapshotTransform.kt @@ -13,7 +13,7 @@ import org.gradle.api.provider.Provider import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Internal import org.jetbrains.kotlin.build.report.metrics.* -import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService +import org.jetbrains.kotlin.gradle.report.BuildMetricsService import org.jetbrains.kotlin.incremental.classpathDiff.ClassSnapshotGranularity import org.jetbrains.kotlin.incremental.classpathDiff.ClassSnapshotGranularity.CLASS_LEVEL import org.jetbrains.kotlin.incremental.classpathDiff.ClassSnapshotGranularity.CLASS_MEMBER_LEVEL @@ -31,7 +31,7 @@ abstract class ClasspathEntrySnapshotTransform : TransformAction + abstract val buildMetricsService: Property } @get:Classpath @@ -44,7 +44,7 @@ abstract class ClasspathEntrySnapshotTransform : TransformAction, - OperationCompletionListener, AutoCloseable { - - interface Parameters : BuildServiceParameters { - var buildDataProcessors: List - var startParameters: GradleBuildStartParameters - var reportingSettings: ReportingSettings - } +abstract class BuildMetricsService : BuildService, OperationCompletionListener { private val log = Logging.getLogger(this.javaClass) // Tasks and transforms' records - private val buildOperationRecords = ConcurrentLinkedQueue() - private val failureMessages = ConcurrentLinkedQueue() + internal val buildOperationRecords = ConcurrentLinkedQueue() + internal val failureMessages = ConcurrentLinkedQueue() // Info for tasks only private val taskPathToMetricsReporter = ConcurrentHashMap() @@ -102,55 +92,24 @@ abstract class BuildMetricsReporterService : BuildService "$key: $value"}, - systemProperties = it.systemPropertiesArgs.map {(key, value) -> "$key: $value"}, - ) - } - - fun registerIfAbsent(project: Project): Provider? { - val serviceClass = BuildMetricsReporterService::class.java - val serviceName = "${serviceClass.name}_${serviceClass.classLoader.hashCode()}" - + fun registerIfAbsent(project: Project): Provider? { // Return early if the service was already registered to avoid the overhead of reading the reporting settings below project.gradle.sharedServices.registrations.findByName(serviceName)?.let { @Suppress("UNCHECKED_CAST") - return it.service as Provider + return it.service as Provider } + //do not need to collect metrics if there aren't consumers for this data val reportingSettings = reportingSettings(project.rootProject) if (reportingSettings.buildReportOutputs.isEmpty()) { return null } - return project.gradle.sharedServices.registerIfAbsent(serviceName, serviceClass) { - val buildDataProcessors = mutableListOf() - reportingSettings.fileReportSettings?.let { fileReportSettings -> - buildDataProcessors.add(PlainTextBuildReportWriterDataProcessor(fileReportSettings, project.rootProject.name)) - } - reportingSettings.singleOutputFile?.let { singleOutputFile -> - buildDataProcessors.add(MetricsWriter(singleOutputFile.absoluteFile)) - } - - it.parameters.startParameters = getStartParameters(project) - it.parameters.buildDataProcessors = buildDataProcessors - it.parameters.reportingSettings = reportingSettings - }!! + return project.gradle.sharedServices.registerIfAbsent(serviceName, serviceClass) {}!! } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildReportsService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildReportsService.kt new file mode 100644 index 00000000000..7c11bbb94e7 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildReportsService.kt @@ -0,0 +1,273 @@ +/* + * Copyright 2010-2022 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.report + +import com.google.gson.Gson +import com.gradle.scan.plugin.BuildScanExtension +import org.gradle.api.Project +import org.gradle.api.invocation.Gradle +import org.gradle.api.logging.Logging +import org.gradle.api.provider.ListProperty +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.TaskFinishEvent +import org.jetbrains.kotlin.gradle.plugin.BuildEventsListenerRegistryHolder +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion +import org.jetbrains.kotlin.gradle.plugin.stat.BuildFinishStatisticsData +import org.jetbrains.kotlin.gradle.plugin.stat.GradleBuildStartParameters +import org.jetbrains.kotlin.gradle.plugin.stat.StatTag +import org.jetbrains.kotlin.gradle.plugin.statistics.BuildScanStatisticsListener +import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatListener +import org.jetbrains.kotlin.gradle.report.data.BuildExecutionData +import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable +import java.io.IOException +import java.net.HttpURLConnection +import java.net.URL +import java.text.SimpleDateFormat +import java.util.* +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit +import kotlin.system.measureTimeMillis + +abstract class BuildReportsService : BuildService, AutoCloseable, OperationCompletionListener { + + private val log = Logging.getLogger(this.javaClass) + + private val startTime = System.nanoTime() + private val buildUuid = UUID.randomUUID().toString() + private var executorService: ExecutorService = Executors.newSingleThreadExecutor() + + + init { + log.info("Build report service is registered. Unique build id: $buildUuid") + } + + interface Parameters : BuildServiceParameters { + val startParameters: Property + val reportingSettings: Property + var buildMetricsService: Provider + + val label: Property + val projectName: Property + val kotlinVersion: Property + val additionalTags: ListProperty + } + + override fun close() { + val buildData = BuildExecutionData( + startParameters = parameters.startParameters.get(), + failureMessages = parameters.buildMetricsService.orNull?.failureMessages?.toList() ?: emptyList(), + buildOperationRecord = parameters.buildMetricsService.orNull?.buildOperationRecords?.sortedBy { it.startTimeMs } ?: emptyList() + ) + + val reportingSettings = parameters.reportingSettings.get() + + reportingSettings.httpReportSettings?.also { + executorService.submit { reportBuildFinish() } // + } + reportingSettings.fileReportSettings?.also { + reportBuildStatInFile(it, buildData) + } + + reportingSettings.singleOutputFile?.also { singleOutputFile -> + MetricsWriter(singleOutputFile.absoluteFile).process(buildData, log) + } + + //It's expected that bad internet connection can cause a significant delay for big project + executorService.shutdownNow() + } + + override fun onFinish(event: FinishEvent?) { + addHttpReport(event) + } + + private fun reportBuildStatInFile(fileReportSettings: FileReportSettings, buildData: BuildExecutionData) { + val ts = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(Calendar.getInstance().time) + val reportFile = fileReportSettings.buildReportDir.resolve("${parameters.projectName.get()}-build-$ts.txt") + + PlainTextBuildReportWriter( + outputFile = reportFile, + printMetrics = fileReportSettings.includeMetricsInReport + ).process(buildData, log) + } + + private fun reportBuildFinish() { + val buildFinishData = BuildFinishStatisticsData( + projectName = parameters.projectName.get(), + startParameters = parameters.startParameters.get(), + buildUuid = buildUuid, + label = parameters.label.orNull, + totalTime = (System.nanoTime() - startTime) / 1_000_000 + ) + sendDataViaHttp(buildFinishData) + } + + private fun initService(project: Project) { + addListeners(project) + } + + private fun addBuildScanReport(project: Project) { + if (parameters.reportingSettings.get().buildReportOutputs.contains(BuildReportType.BUILD_SCAN)) { + val listenerRegistryHolder = BuildEventsListenerRegistryHolder.getInstance(project) + project.rootProject.extensions.findByName("buildScan") + ?.also { + listenerRegistryHolder.listenerRegistry.onTaskCompletion( + project.provider { + BuildScanStatisticsListener( + it as BuildScanExtension, + parameters.projectName.get(), + parameters.label.orNull, + parameters.kotlinVersion.get(), + buildUuid + ) + } + ) + } + } + } + + private fun addHttpReport(event: FinishEvent?) { + if (parameters.reportingSettings.get().httpReportSettings != null) { + if (event is TaskFinishEvent) { + val data = + KotlinBuildStatListener.prepareData( + event, + parameters.projectName.get(), + buildUuid, + parameters.label.orNull, + parameters.kotlinVersion.get(), + parameters.additionalTags.get() + ) + data?.also { executorService.submit { sendDataViaHttp(data) } } + } + } + + } + + private fun addListeners(project: Project) { + addBuildScanReport(project) + } + + private var invalidUrl = false + private var requestPreviousFailed = false + private fun sendDataViaHttp(data: Any) { + val httpSettings = parameters.reportingSettings.get().httpReportSettings ?: return + + val elapsedTime = measureTimeMillis { + if (invalidUrl) { + return + } + val connection = try { + URL(httpSettings.url).openConnection() as HttpURLConnection + } catch (e: IOException) { + log.warn("Unable to open connection to ${httpSettings.url}: ${e.message}") + invalidUrl = true + return + } + + try { + if (httpSettings.user != null && httpSettings.password != null) { + val auth = Base64.getEncoder() + .encode("${httpSettings.user}:${httpSettings.password}".toByteArray()) + .toString(Charsets.UTF_8) + connection.addRequestProperty("Authorization", "Basic $auth") + } + connection.addRequestProperty("Content-Type", "application/json") + connection.requestMethod = "POST" + connection.doOutput = true + connection.outputStream.use { + it.write(Gson().toJson(data).toByteArray()) + } + connection.connect() + checkResponseAndLog(connection) + } catch (e: Exception) { + log.debug("Unexpected exception happened ${e.message}: ${e.stackTrace}") + checkResponseAndLog(connection) + } finally { + connection.disconnect() + } + } + log.debug("Report statistic by http takes $elapsedTime ms") + } + + private fun checkResponseAndLog(connection: HttpURLConnection) { + val isResponseBad = connection.responseCode !in 200..299 + if (isResponseBad) { + val message = "Failed to send statistic to ${connection.url} with ${connection.responseCode}: ${connection.responseMessage}" + if (!requestPreviousFailed) { + log.warn(message) + } else { + log.debug(message) + } + requestPreviousFailed = true + } + } + + companion object { + + fun getStartParameters(project: Project) = project.gradle.startParameter.let { + GradleBuildStartParameters( + tasks = it.taskRequests.flatMap { it.args }, + excludedTasks = it.excludedTaskNames, + currentDir = it.currentDir.path, + projectProperties = it.projectProperties.map { (key, value) -> "$key: $value" }, + systemProperties = it.systemPropertiesArgs.map { (key, value) -> "$key: $value" }, + ) + } + + fun registerIfAbsent(project: Project, buildMetricsService: Provider): Provider? { + val serviceClass = BuildReportsService::class.java + val serviceName = "${serviceClass.name}_${serviceClass.classLoader.hashCode()}" + + val reportingSettings = reportingSettings(project.rootProject) + if (reportingSettings.buildReportOutputs.isEmpty()) { + return null //no need to collect data + } + + val kotlinVersion = project.getKotlinPluginVersion() + val gradle = project.gradle + project.gradle.sharedServices.registrations.findByName(serviceName)?.let { + @Suppress("UNCHECKED_CAST") + return it.service as Provider + } + + return gradle.sharedServices.registerIfAbsent(serviceName, serviceClass) { + it.parameters.label.set(reportingSettings.buildReportLabel) + it.parameters.projectName.set(project.rootProject.name) + it.parameters.kotlinVersion.set(kotlinVersion) + it.parameters.startParameters.set(getStartParameters(project)) + it.parameters.reportingSettings.set(reportingSettings) + it.parameters.buildMetricsService = buildMetricsService + + //init gradle tags for build scan and http reports + it.parameters.additionalTags.value(setupTags(gradle)) + }!!.also { + val buildReportsService = it.get() + buildReportsService.initService(project) + if (buildReportsService.parameters.reportingSettings.get().buildReportOutputs.contains(BuildReportType.HTTP)) { + BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(it) + } + } + } + + private fun setupTags(gradle: Gradle): ArrayList { + val additionalTags = ArrayList() + if (isConfigurationCacheAvailable(gradle)) { + additionalTags.add(StatTag.CONFIGURATION_CACHE) + } + if (gradle.startParameter.isBuildCacheEnabled) { + additionalTags.add(StatTag.BUILD_CACHE) + } + return additionalTags + } + } + +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/HttpReportService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/HttpReportService.kt deleted file mode 100644 index 09f28c836e9..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/HttpReportService.kt +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2010-2022 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.report - -import com.google.gson.Gson -import com.gradle.scan.plugin.BuildScanExtension -import org.gradle.api.Project -import org.gradle.api.logging.Logging -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.TaskFinishEvent -import org.jetbrains.kotlin.gradle.plugin.stat.BuildFinishStatisticsData -import org.jetbrains.kotlin.gradle.plugin.BuildEventsListenerRegistryHolder -import org.jetbrains.kotlin.gradle.plugin.stat.GradleBuildStartParameters -import org.jetbrains.kotlin.gradle.plugin.stat.StatTag -import org.jetbrains.kotlin.gradle.plugin.statistics.BuildScanStatisticsListener -import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatListener.Companion.prepareData -import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService.Companion.getStartParameters -import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable -import java.io.IOException -import java.net.HttpURLConnection -import java.net.URL -import java.util.* -import java.util.concurrent.ExecutorService -import java.util.concurrent.Executors -import kotlin.system.measureTimeMillis - -abstract class HttpReportService : BuildService, - OperationCompletionListener, AutoCloseable { - - var executorService: ExecutorService = Executors.newSingleThreadExecutor() - - val startTime = System.nanoTime() - - interface Parameters : BuildServiceParameters { - var label: String? - var projectName: String - var httpSettings: HttpReportSettings - var kotlinVersion: String - var additionalTags: List - var startParameters: GradleBuildStartParameters - } - - val log = Logging.getLogger(this.javaClass) - - init { - log.info("Http report service is registered. Unique build id: $buildUuid") - } - - // @Volatile for one thread executor it does not need - private var requestPreviousFailed = false - private var invalidUrl = false - - override fun onFinish(event: FinishEvent?) { - if (event is TaskFinishEvent) { - val data = - prepareData(event, parameters.projectName, buildUuid, parameters.label, parameters.kotlinVersion, parameters.additionalTags) - data?.also { executorService.submit { report(data) } } - } - } - - override fun close() { - executorService.submit { reportBuildFinish() } - executorService.shutdown() - } - - companion object { - - val buildUuid = UUID.randomUUID().toString() - - fun registerIfAbsent(project: Project, kotlinVersion: String): Provider? { - val gradle = project.gradle - val rootProject = gradle.rootProject - val reportingSettings = reportingSettings(rootProject) - - addListeners(project, reportingSettings, kotlinVersion) - - return reportingSettings.httpReportSettings?.let { httpSettings -> - gradle.sharedServices.registerIfAbsent( - "build_http_metric_service_${HttpReportService::class.java.classLoader.hashCode()}", - HttpReportService::class.java - ) { - it.parameters.label = reportingSettings.buildReportLabel - it.parameters.projectName = rootProject.name - it.parameters.httpSettings = httpSettings - it.parameters.kotlinVersion = kotlinVersion - it.parameters.startParameters = getStartParameters(project) - - //init gradle tags, that present in build scan - val additionalTags = ArrayList() - if (isConfigurationCacheAvailable(gradle)) { - additionalTags.add(StatTag.CONFIGURATION_CACHE) - } - if (gradle.startParameter.isBuildCacheEnabled) { - additionalTags.add(StatTag.BUILD_CACHE) - } - it.parameters.additionalTags = additionalTags - }!! - } - - } - - fun addListeners(project: Project, reportingSettings: ReportingSettings, kotlinVersion: String) { - if (reportingSettings.buildReportOutputs.contains(BuildReportType.BUILD_SCAN)) { - project.rootProject.extensions.findByName("buildScan") - ?.also { - val listenerRegistryHolder = BuildEventsListenerRegistryHolder.getInstance(project) - listenerRegistryHolder.listenerRegistry.onTaskCompletion( - project.provider { - BuildScanStatisticsListener( - it as BuildScanExtension, - project.rootProject.name, - reportingSettings.buildReportLabel, - kotlinVersion, - buildUuid - ) - } - ) - } - } - } - - } - - fun report(data: Any) { - val elapsedTime = measureTimeMillis { - if (invalidUrl) { - return - } - val connection = try { - URL(parameters.httpSettings.url).openConnection() as HttpURLConnection - } catch (e: IOException) { - log.warn("Unable to open connection to ${parameters.httpSettings.url}: ${e.message}") - invalidUrl = true - return - } - - try { - if (parameters.httpSettings.user != null && parameters.httpSettings.password != null) { - val auth = Base64.getEncoder() - .encode("${parameters.httpSettings.user}:${parameters.httpSettings.password}".toByteArray()) - .toString(Charsets.UTF_8) - connection.addRequestProperty("Authorization", "Basic $auth") - } - connection.addRequestProperty("Content-Type", "application/json") - connection.requestMethod = "POST" - connection.doOutput = true - connection.outputStream.use { - it.write(Gson().toJson(data).toByteArray()) - } - connection.connect() - checkResponseAndLog(connection) - connection.inputStream.use { it.reader().use { reader -> reader.readText() } } - } catch (e: Exception) { - log.debug("Unexpected exception happened ${e.message}: ${e.stackTrace}") - checkResponseAndLog(connection) - } finally { - connection.disconnect() - } - } - log.debug("Report statistic by http takes $elapsedTime ms") - } - - private fun reportBuildFinish() { - val buildFinishData = BuildFinishStatisticsData( - projectName = parameters.projectName, - startParameters = parameters.startParameters, - buildUuid = buildUuid, - label = parameters.label, - totalTime = (System.nanoTime() - startTime) / 1_000_000 - ) - report(buildFinishData) - } - - private fun checkResponseAndLog(connection: HttpURLConnection) { - val isResponseBad = connection.responseCode !in 200..299 - if (isResponseBad) { - val message = "Failed to send statistic to ${connection.url} with ${connection.responseCode}: ${connection.responseMessage}" - if (!requestPreviousFailed) { - log.warn(message) - } else { - log.debug(message) - } - requestPreviousFailed = true - } - } - -} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/MetricsWriter.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/MetricsWriter.kt index 04b83d60513..392154676dd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/MetricsWriter.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/MetricsWriter.kt @@ -12,15 +12,14 @@ import org.jetbrains.kotlin.gradle.internal.build.metrics.GradleBuildMetricsData import org.jetbrains.kotlin.gradle.internal.build.metrics.BuildOperationData import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.report.data.BuildExecutionData -import org.jetbrains.kotlin.gradle.report.data.BuildExecutionDataProcessor import java.io.File import java.io.ObjectOutputStream import java.io.Serializable internal class MetricsWriter( private val outputFile: File, -) : BuildExecutionDataProcessor, Serializable { - override fun process(build: BuildExecutionData, log: Logger) { +): Serializable { + fun process(build: BuildExecutionData, log: Logger) { if (build.failureMessages.isNotEmpty()) return try { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/PlainTextBuildReportWriter.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/PlainTextBuildReportWriter.kt index 9d1a8ccfc54..848c83201d0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/PlainTextBuildReportWriter.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/PlainTextBuildReportWriter.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.report import org.gradle.api.logging.Logger import org.jetbrains.kotlin.build.report.metrics.* import org.jetbrains.kotlin.gradle.report.data.BuildExecutionData -import org.jetbrains.kotlin.gradle.report.data.BuildExecutionDataProcessor import org.jetbrains.kotlin.gradle.report.data.BuildOperationRecord import org.jetbrains.kotlin.gradle.utils.Printer import org.jetbrains.kotlin.gradle.utils.asString @@ -16,25 +15,9 @@ import org.jetbrains.kotlin.gradle.utils.formatSize import org.jetbrains.kotlin.gradle.utils.formatTime import java.io.File import java.io.Serializable -import java.text.SimpleDateFormat import java.util.* import kotlin.math.max -internal class PlainTextBuildReportWriterDataProcessor( - val reportingSettings: FileReportSettings, - val rootProjectName: String -) : BuildExecutionDataProcessor, Serializable { - override fun process(build: BuildExecutionData, log: Logger) { - val ts = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(Calendar.getInstance().time) - val reportFile = reportingSettings.buildReportDir.resolve("${rootProjectName}-build-$ts.txt") - - PlainTextBuildReportWriter( - outputFile = reportFile, - printMetrics = reportingSettings.includeMetricsInReport - ).process(build, log) - } -} - internal class PlainTextBuildReportWriter( private val outputFile: File, private val printMetrics: Boolean diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/data/BuildExecutionDataProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/data/BuildExecutionDataProcessor.kt deleted file mode 100644 index c7f24521508..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/data/BuildExecutionDataProcessor.kt +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2010-2020 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.report.data - -import org.gradle.api.logging.Logger - -interface BuildExecutionDataProcessor { - fun process(build: BuildExecutionData, log: Logger) -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinBrowserJsIr.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinBrowserJsIr.kt index 83782e3772e..d1ee7cebb59 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinBrowserJsIr.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinBrowserJsIr.kt @@ -12,7 +12,7 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin import org.jetbrains.kotlin.gradle.dsl.KotlinJsDce import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation -import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService +import org.jetbrains.kotlin.gradle.report.BuildMetricsService import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalDceDsl import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBrowserDsl @@ -211,8 +211,8 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) : task.description = "build webpack ${mode.name.toLowerCase()} bundle" task._destinationDirectory = binary.distribution.directory - BuildMetricsReporterService.registerIfAbsent(project)?.let { - task.buildMetricsReporterService.value(it) + BuildMetricsService.registerIfAbsent(project)?.let { + task.buildMetricsService.value(it) } task.dependsOn( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt index b75b8473eed..33c64c85697 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.isMain import org.jetbrains.kotlin.gradle.plugin.mpp.isTest -import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService +import org.jetbrains.kotlin.gradle.report.BuildMetricsService import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget import org.jetbrains.kotlin.gradle.targets.js.dsl.* import org.jetbrains.kotlin.gradle.targets.js.ir.executeTaskBaseName @@ -237,8 +237,8 @@ abstract class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) : task.description = "build webpack ${type.name.toLowerCase()} bundle" task._destinationDirectory = distribution.directory - BuildMetricsReporterService.registerIfAbsent(project)?.let { - task.buildMetricsReporterService.value(it) + BuildMetricsService.registerIfAbsent(project)?.let { + task.buildMetricsService.value(it) } task.commonConfigure( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt index c300e02c4c9..9cca9194d63 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.distsDirectory -import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService +import org.jetbrains.kotlin.gradle.report.BuildMetricsService import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWebpackRulesContainer import org.jetbrains.kotlin.gradle.targets.js.dsl.WebpackRulesDsl @@ -73,7 +73,7 @@ constructor( get() = injected @get:Internal - internal abstract val buildMetricsReporterService: Property + internal abstract val buildMetricsService: Property @get:Internal val metrics: Property = project.objects @@ -330,7 +330,7 @@ constructor( buildMetrics.addMetric(BuildPerformanceMetric.BUNDLE_SIZE, it) } - buildMetricsReporterService.orNull?.also { it.addTask(path, this.javaClass, buildMetrics) } + buildMetricsService.orNull?.also { it.addTask(path, this.javaClass, buildMetrics) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 04ec5fe4715..a75052e8add 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -51,8 +51,9 @@ import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService -import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService +import org.jetbrains.kotlin.gradle.report.BuildMetricsService import org.jetbrains.kotlin.gradle.report.BuildReportMode +import org.jetbrains.kotlin.gradle.report.BuildReportsService import org.jetbrains.kotlin.gradle.report.ReportingSettings import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.incremental.* @@ -270,16 +271,19 @@ abstract class AbstractKotlinCompile @Inject constr internal open fun isIncrementalCompilationEnabled(): Boolean = incremental - @get:Internal - val startParameters = BuildMetricsReporterService.getStartParameters(project) - @get:Input abstract val ownModuleName: Property @get:Internal - internal abstract val buildMetricsReporterService: Property + internal abstract val buildMetricsService: Property - internal fun reportingSettings() = buildMetricsReporterService.orNull?.parameters?.reportingSettings ?: ReportingSettings() + @get:Internal + internal abstract val buildReportsService: Property + + @get:Internal + val startParameters = BuildReportsService.getStartParameters(project) + + internal fun reportingSettings() = buildReportsService.orNull?.parameters?.reportingSettings?.orNull ?: ReportingSettings() @get:Internal protected val multiModuleICSettings: MultiModuleICSettings @@ -403,7 +407,7 @@ abstract class AbstractKotlinCompile @Inject constr executeImpl(inputChanges, outputsBackup) } - buildMetricsReporterService.orNull?.also { it.addTask(path, this.javaClass, buildMetrics) } + buildMetricsService.orNull?.also { it.addTask(path, this.javaClass, buildMetrics) } } protected open fun skipCondition(): Boolean = sources.isEmpty diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt index 98eb1198ee8..84f9639ed94 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt @@ -19,7 +19,8 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPro import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithClosure import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinOptions -import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService +import org.jetbrains.kotlin.gradle.report.BuildMetricsService +import org.jetbrains.kotlin.gradle.report.BuildReportsService import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.KOTLIN_BUILD_DIR_NAME import org.jetbrains.kotlin.project.model.LanguageSettings @@ -58,10 +59,13 @@ internal abstract class AbstractKotlinCompileConfig task.kotlinDaemonJvmArguments.set(providers.provider { kotlinDaemonJvmArgs.split("\\s+".toRegex()) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt index e4e5b00f7a6..c6b34e9965c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder -import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService +import org.jetbrains.kotlin.gradle.report.BuildMetricsService import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.project.model.LanguageSettings @@ -111,18 +111,18 @@ internal open class BaseKotlinCompileConfig : AbstractKotl } project.extensions.extraProperties[TRANSFORMS_REGISTERED] = true - val buildMetricsReporterService = BuildMetricsReporterService.registerIfAbsent(project) + val buildMetricsService = BuildMetricsService.registerIfAbsent(project) project.dependencies.registerTransform(ClasspathEntrySnapshotTransform::class.java) { it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_ARTIFACT_TYPE) it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) it.parameters.gradleUserHomeDir.set(project.gradle.gradleUserHomeDir) - buildMetricsReporterService?.apply { it.parameters.buildMetricsReporterService.set(this) } + buildMetricsService?.apply { it.parameters.buildMetricsService.set(this) } } project.dependencies.registerTransform(ClasspathEntrySnapshotTransform::class.java) { it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_ARTIFACT_TYPE) it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) it.parameters.gradleUserHomeDir.set(project.gradle.gradleUserHomeDir) - buildMetricsReporterService?.apply { it.parameters.buildMetricsReporterService.set(this) } + buildMetricsService?.apply { it.parameters.buildMetricsService.set(this) } } }