mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 08:27:12 -07:00
Introduce build listeners and build report contributors.
This commit is contained in:
parent
f629b76658
commit
007bb31ee3
7 changed files with 86 additions and 19 deletions
|
@ -0,0 +1,9 @@
|
||||||
|
package com.beust.kobalt.api
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plug-ins that listen to build events.
|
||||||
|
*/
|
||||||
|
interface IBuildListener : IListener {
|
||||||
|
fun taskStart(project: Project, context: KobaltContext, taskName: String)
|
||||||
|
fun taskEnd(project: Project, context: KobaltContext, taskName: String)
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.beust.kobalt.api
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plug-ins that produce build reports.
|
||||||
|
*/
|
||||||
|
interface IBuildReportContributor : IContributor {
|
||||||
|
fun generateReport(context: KobaltContext)
|
||||||
|
}
|
|
@ -10,3 +10,6 @@ interface IPluginActor {
|
||||||
interface IContributor : IPluginActor
|
interface IContributor : IPluginActor
|
||||||
|
|
||||||
interface IInterceptor : IPluginActor
|
interface IInterceptor : IPluginActor
|
||||||
|
|
||||||
|
interface IListener : IPluginActor
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.beust.kobalt.internal
|
||||||
|
|
||||||
|
import com.beust.kobalt.Args
|
||||||
|
import com.beust.kobalt.AsciiArt
|
||||||
|
import com.beust.kobalt.api.*
|
||||||
|
import com.beust.kobalt.misc.log
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record timings and display them at the end of the build.
|
||||||
|
*/
|
||||||
|
class BuildListeners : IBuildListener, IBuildReportContributor {
|
||||||
|
class ProfilerInfo(val taskName: String, val durationMillis: Long)
|
||||||
|
|
||||||
|
private val startTimes = ConcurrentHashMap<String, Long>()
|
||||||
|
private val timings = arrayListOf<ProfilerInfo>()
|
||||||
|
|
||||||
|
override fun taskStart(project: Project, context: KobaltContext, taskName: String) {
|
||||||
|
startTimes.put(taskName, System.currentTimeMillis())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun taskEnd(project: Project, context: KobaltContext, taskName: String) {
|
||||||
|
startTimes[taskName]?.let {
|
||||||
|
timings.add(ProfilerInfo(taskName, System.currentTimeMillis() - it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun generateReport(context: KobaltContext) {
|
||||||
|
val profiling = Kobalt.INJECTOR.getInstance(Args::class.java).profiling
|
||||||
|
if (profiling) {
|
||||||
|
log(1, "\n" + AsciiArt.horizontalSingleLine + " Timings (in seconds)")
|
||||||
|
timings.sortedByDescending { it.durationMillis }.forEach {
|
||||||
|
log(1, String.format("%1$10.2f", it.durationMillis.toDouble() / 1000)
|
||||||
|
+ " " + it.taskName)
|
||||||
|
}
|
||||||
|
log(1, "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -96,6 +96,8 @@ class PluginInfo(val xml: KobaltPluginXml, val pluginClassLoader: ClassLoader?,
|
||||||
val mavenIdInterceptors = arrayListOf<IMavenIdInterceptor>()
|
val mavenIdInterceptors = arrayListOf<IMavenIdInterceptor>()
|
||||||
val jvmFlagContributors = arrayListOf<IJvmFlagContributor>()
|
val jvmFlagContributors = arrayListOf<IJvmFlagContributor>()
|
||||||
val localMavenRepoPathInterceptors = arrayListOf<ILocalMavenRepoPathInterceptor>()
|
val localMavenRepoPathInterceptors = arrayListOf<ILocalMavenRepoPathInterceptor>()
|
||||||
|
val buildListeners = arrayListOf<IBuildListener>()
|
||||||
|
val buildReportContributors = arrayListOf<IBuildReportContributor>()
|
||||||
|
|
||||||
// Note: intentionally repeating them here even though they are defined by our base class so
|
// Note: intentionally repeating them here even though they are defined by our base class so
|
||||||
// that this class always contains the full list of contributors and interceptors
|
// that this class always contains the full list of contributors and interceptors
|
||||||
|
@ -212,6 +214,8 @@ class PluginInfo(val xml: KobaltPluginXml, val pluginClassLoader: ClassLoader?,
|
||||||
if (this is ITestJvmFlagInterceptor) testJvmFlagInterceptors.add(this)
|
if (this is ITestJvmFlagInterceptor) testJvmFlagInterceptors.add(this)
|
||||||
if (this is IJvmFlagContributor) jvmFlagContributors.add(this)
|
if (this is IJvmFlagContributor) jvmFlagContributors.add(this)
|
||||||
if (this is ILocalMavenRepoPathInterceptor) localMavenRepoPathInterceptors.add(this)
|
if (this is ILocalMavenRepoPathInterceptor) localMavenRepoPathInterceptors.add(this)
|
||||||
|
if (this is IBuildListener) buildListeners.add(this)
|
||||||
|
if (this is IBuildReportContributor) buildReportContributors.add(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +229,8 @@ class PluginInfo(val xml: KobaltPluginXml, val pluginClassLoader: ClassLoader?,
|
||||||
testSourceDirContributors, buildConfigFieldContributors,
|
testSourceDirContributors, buildConfigFieldContributors,
|
||||||
taskContributors, incrementalTaskContributors, assemblyContributors,
|
taskContributors, incrementalTaskContributors, assemblyContributors,
|
||||||
incrementalAssemblyContributors, testJvmFlagInterceptors,
|
incrementalAssemblyContributors, testJvmFlagInterceptors,
|
||||||
jvmFlagContributors, localMavenRepoPathInterceptors
|
jvmFlagContributors, localMavenRepoPathInterceptors, buildListeners,
|
||||||
|
buildReportContributors
|
||||||
).forEach {
|
).forEach {
|
||||||
it.forEach {
|
it.forEach {
|
||||||
it.cleanUpActors()
|
it.cleanUpActors()
|
||||||
|
@ -266,6 +271,8 @@ class PluginInfo(val xml: KobaltPluginXml, val pluginClassLoader: ClassLoader?,
|
||||||
testJvmFlagInterceptors.addAll(pluginInfo.testJvmFlagInterceptors)
|
testJvmFlagInterceptors.addAll(pluginInfo.testJvmFlagInterceptors)
|
||||||
jvmFlagContributors.addAll(pluginInfo.jvmFlagContributors)
|
jvmFlagContributors.addAll(pluginInfo.jvmFlagContributors)
|
||||||
localMavenRepoPathInterceptors.addAll(pluginInfo.localMavenRepoPathInterceptors)
|
localMavenRepoPathInterceptors.addAll(pluginInfo.localMavenRepoPathInterceptors)
|
||||||
|
buildListeners.addAll(pluginInfo.buildListeners)
|
||||||
|
buildReportContributors.addAll(pluginInfo.buildReportContributors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@ import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class TaskManager @Inject constructor(val args: Args,
|
class TaskManager @Inject constructor(val args: Args,
|
||||||
val incrementalManagerFactory: IncrementalManager.IFactory) {
|
val incrementalManagerFactory: IncrementalManager.IFactory,
|
||||||
|
val pluginInfo: PluginInfo) {
|
||||||
private val dependsOn = TreeMultimap.create<String, String>()
|
private val dependsOn = TreeMultimap.create<String, String>()
|
||||||
private val reverseDependsOn = TreeMultimap.create<String, String>()
|
private val reverseDependsOn = TreeMultimap.create<String, String>()
|
||||||
private val runBefore = TreeMultimap.create<String, String>()
|
private val runBefore = TreeMultimap.create<String, String>()
|
||||||
|
@ -168,7 +169,7 @@ class TaskManager @Inject constructor(val args: Args,
|
||||||
|
|
||||||
val factory = object : IThreadWorkerFactory<ITask> {
|
val factory = object : IThreadWorkerFactory<ITask> {
|
||||||
override fun createWorkers(nodes: Collection<ITask>)
|
override fun createWorkers(nodes: Collection<ITask>)
|
||||||
= nodes.map { TaskWorker(listOf(it), args.dryRun, messages) }
|
= nodes.map { TaskWorker(listOf(it), args.dryRun, messages, pluginInfo) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val executor = DynamicGraphExecutor(graph, factory)
|
val executor = DynamicGraphExecutor(graph, factory)
|
||||||
|
@ -534,8 +535,13 @@ class TaskManager @Inject constructor(val args: Args,
|
||||||
/////
|
/////
|
||||||
}
|
}
|
||||||
|
|
||||||
class TaskWorker(val tasks: List<ITask>, val dryRun: Boolean, val timings: MutableList<TaskManager.ProfilerInfo>)
|
class TaskWorker(val tasks: List<ITask>, val dryRun: Boolean, val pluginInfo: PluginInfo) : IWorker<ITask> {
|
||||||
: IWorker<ITask> {
|
|
||||||
|
private fun runBuildListeners(project: Project, context: KobaltContext, taskName: String, start: Boolean) {
|
||||||
|
context.pluginInfo.buildListeners.forEach {
|
||||||
|
if (start) it.taskStart(project, context, taskName) else it.taskEnd(project, context, taskName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun call() : TaskResult2<ITask> {
|
override fun call() : TaskResult2<ITask> {
|
||||||
if (tasks.size > 0) {
|
if (tasks.size > 0) {
|
||||||
|
@ -545,14 +551,14 @@ class TaskWorker(val tasks: List<ITask>, val dryRun: Boolean, val timings: Mutab
|
||||||
}
|
}
|
||||||
var success = true
|
var success = true
|
||||||
val errorMessages = arrayListOf<String>()
|
val errorMessages = arrayListOf<String>()
|
||||||
|
val context = Kobalt.context!!
|
||||||
tasks.forEach {
|
tasks.forEach {
|
||||||
val name = it.project.name + ":" + it.name
|
val name = it.project.name + ":" + it.name
|
||||||
val time = benchmarkMillis {
|
runBuildListeners(it.project, context, name, start = true)
|
||||||
val tr = if (dryRun) TaskResult() else it.call()
|
val tr = if (dryRun) TaskResult() else it.call()
|
||||||
success = success and tr.success
|
runBuildListeners(it.project, context, name, start = false)
|
||||||
if (tr.errorMessage != null) errorMessages.add(tr.errorMessage)
|
success = success and tr.success
|
||||||
}
|
if (tr.errorMessage != null) errorMessages.add(tr.errorMessage)
|
||||||
timings.add(TaskManager.ProfilerInfo(name, time.first))
|
|
||||||
}
|
}
|
||||||
return TaskResult2(success, errorMessages.joinToString("\n"), tasks[0])
|
return TaskResult2(success, errorMessages.joinToString("\n"), tasks[0])
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,14 +213,9 @@ private class Main @Inject constructor(
|
||||||
// Shutdown all plug-ins
|
// Shutdown all plug-ins
|
||||||
plugins.shutdownPlugins()
|
plugins.shutdownPlugins()
|
||||||
|
|
||||||
// Display timings if requested
|
// Run the build report contributors
|
||||||
if (args.profiling) {
|
pluginInfo.buildReportContributors.forEach {
|
||||||
log(1, "\n" + AsciiArt.horizontalSingleLine + " Timings (in seconds)")
|
it.generateReport(Kobalt.context!!)
|
||||||
runTargetResult.timings.sortedByDescending { it.durationMillis }.forEach {
|
|
||||||
log(1, String.format("%1$10.2f", it.durationMillis.toDouble() / 1000)
|
|
||||||
+ " " + it.taskName)
|
|
||||||
}
|
|
||||||
log(1, "\n")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue