1
0
Fork 0
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:
Cedric Beust 2016-07-30 07:36:03 -07:00
parent f629b76658
commit 007bb31ee3
7 changed files with 86 additions and 19 deletions

View file

@ -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)
}

View file

@ -0,0 +1,8 @@
package com.beust.kobalt.api
/**
* Plug-ins that produce build reports.
*/
interface IBuildReportContributor : IContributor {
fun generateReport(context: KobaltContext)
}

View file

@ -10,3 +10,6 @@ interface IPluginActor {
interface IContributor : IPluginActor interface IContributor : IPluginActor
interface IInterceptor : IPluginActor interface IInterceptor : IPluginActor
interface IListener : IPluginActor

View file

@ -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")
}
}
}

View file

@ -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)
} }
} }

View file

@ -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])
} }

View file

@ -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")
} }
} }
} }