ca2051e1d4
Custom input normalizations currently isn't supported by Gracle configuration cache #KT-44611 In Progress
110 lines
3.9 KiB
Kotlin
110 lines
3.9 KiB
Kotlin
/*
|
|
* Copyright 2010-2018 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.
|
|
*/
|
|
|
|
import org.gradle.api.Task
|
|
import org.gradle.api.execution.TaskExecutionListener
|
|
import org.gradle.api.invocation.Gradle
|
|
import org.gradle.api.logging.Logger
|
|
import org.gradle.api.tasks.TaskState
|
|
import java.util.HashMap
|
|
|
|
if (isConfigurationCacheDisabled) {
|
|
BuildTimeReporter.configure(gradle)
|
|
}
|
|
|
|
private class BuildTimeReporter(
|
|
private val kotlinCompileClass: Class<*>,
|
|
private val javaCompileClass: Class<*>,
|
|
private val jarClass: Class<*>,
|
|
private val proguardClass: Class<*>
|
|
) : TaskExecutionListener {
|
|
companion object {
|
|
fun configure(gradle: Gradle) {
|
|
val rootProject = gradle.rootProject
|
|
val logger = rootProject.logger
|
|
val classloader = rootProject.buildscript.classLoader
|
|
|
|
fun findClass(name: String): Class<*>? =
|
|
try {
|
|
Class.forName(name, false, classloader)
|
|
} catch (e: ClassNotFoundException) {
|
|
logger.warn("Could not find class '$name'. Build times won't be reported")
|
|
null
|
|
}
|
|
|
|
val reporter = BuildTimeReporter(
|
|
kotlinCompileClass = findClass("org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile") ?: return,
|
|
javaCompileClass = findClass("org.gradle.api.tasks.compile.JavaCompile") ?: return,
|
|
jarClass = findClass("org.gradle.jvm.tasks.Jar") ?: return,
|
|
proguardClass = findClass("proguard.gradle.ProGuardTask") ?: return
|
|
)
|
|
gradle.taskGraph.addTaskExecutionListener(reporter)
|
|
gradle.buildFinished {
|
|
reporter.report(logger)
|
|
}
|
|
}
|
|
}
|
|
|
|
private enum class TaskCategory {
|
|
COMPILING_KOTLIN,
|
|
COMPILING_JAVA,
|
|
PROCESSING_JARS,
|
|
UNCATEGORIZED;
|
|
|
|
private fun String.toTitleCase() =
|
|
if (length <= 1) capitalize() else { get(0).toUpperCase() + substring(1).toLowerCase() }
|
|
|
|
fun description(): String =
|
|
name.replace("_", " ").toTitleCase()
|
|
}
|
|
|
|
private val taskStartTime = HashMap<Task, Long>()
|
|
private val categoryTimeNs = HashMap<TaskCategory, Long>()
|
|
private var totalTimeNs = 0L
|
|
|
|
@Synchronized
|
|
override fun beforeExecute(task: Task) {
|
|
taskStartTime[task] = System.nanoTime()
|
|
}
|
|
|
|
@Synchronized
|
|
override fun afterExecute(task: Task, state: TaskState) {
|
|
val startTimeNs = taskStartTime.remove(task) ?: return
|
|
val endTimeNs = System.nanoTime()
|
|
val timeNs = endTimeNs - startTimeNs
|
|
totalTimeNs += timeNs
|
|
val category = taskCategory(task)
|
|
categoryTimeNs[category] = (categoryTimeNs[category] ?: 0L) + timeNs
|
|
}
|
|
|
|
private fun taskCategory(task: Task): TaskCategory = when {
|
|
kotlinCompileClass.isInstance(task) -> TaskCategory.COMPILING_KOTLIN
|
|
javaCompileClass.isInstance(task) -> TaskCategory.COMPILING_JAVA
|
|
jarClass.isInstance(task) ||
|
|
proguardClass.isInstance(task) -> TaskCategory.PROCESSING_JARS
|
|
else -> TaskCategory.UNCATEGORIZED
|
|
}
|
|
|
|
private fun Double.asShortString() =
|
|
String.format("%.2f", this)
|
|
|
|
@Synchronized
|
|
private fun report(log: Logger) {
|
|
val secondInNs = 1000_000_000
|
|
val totalTimeSec = totalTimeNs.toDouble() / secondInNs
|
|
if (totalTimeSec < 1) return
|
|
|
|
log.info("Build time for tasks:")
|
|
for (category in TaskCategory.values()) {
|
|
val timeNs = categoryTimeNs[category] ?: 0L
|
|
val timeSec = timeNs.toDouble() / secondInNs
|
|
if (timeSec < 1) continue
|
|
|
|
val percent = timeSec / totalTimeSec * 100
|
|
log.info("${category.description()}: ${timeSec.asShortString()}s (${percent.asShortString()}% of total time)")
|
|
}
|
|
}
|
|
}
|