mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 08:27:12 -07:00
Dynamic tasks can be incremental too.
This commit is contained in:
parent
ea8a812ed2
commit
fd21ec1162
10 changed files with 96 additions and 65 deletions
|
@ -1,13 +1,16 @@
|
||||||
package com.beust.kobalt.api
|
package com.beust.kobalt.api
|
||||||
|
|
||||||
|
import com.beust.kobalt.IncrementalTaskInfo
|
||||||
import com.beust.kobalt.TaskResult
|
import com.beust.kobalt.TaskResult
|
||||||
import com.beust.kobalt.Variant
|
import com.beust.kobalt.Variant
|
||||||
|
import com.beust.kobalt.internal.IncrementalManager
|
||||||
|
import com.google.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plug-ins that are ITaskContributor can use this class to manage their collection of tasks and
|
* Plug-ins that are ITaskContributor can use this class to manage their collection of tasks and
|
||||||
* implement the interface by delegating to an instance of this class (if injection permits).
|
* implement the interface by delegating to an instance of this class (if injection permits).
|
||||||
*/
|
*/
|
||||||
class TaskContributor : ITaskContributor {
|
class TaskContributor @Inject constructor(val incrementalManager: IncrementalManager) : ITaskContributor {
|
||||||
val dynamicTasks = arrayListOf<DynamicTask>()
|
val dynamicTasks = arrayListOf<DynamicTask>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,5 +39,20 @@ class TaskContributor : ITaskContributor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addIncrementalVariantTasks(plugin: IPlugin, project: Project, context: KobaltContext, taskName: String,
|
||||||
|
runBefore : List<String> = emptyList(),
|
||||||
|
runAfter : List<String> = emptyList(),
|
||||||
|
alwaysRunAfter : List<String> = emptyList(),
|
||||||
|
runTask: (Project) -> IncrementalTaskInfo) {
|
||||||
|
Variant.allVariants(project).forEach { variant ->
|
||||||
|
val variantTaskName = variant.toTask(taskName)
|
||||||
|
dynamicTasks.add(DynamicTask(plugin, variantTaskName, variantTaskName,
|
||||||
|
runBefore = runBefore.map { variant.toTask(it) },
|
||||||
|
runAfter = runAfter.map { variant.toTask(it) },
|
||||||
|
alwaysRunAfter = alwaysRunAfter.map { variant.toTask(it) },
|
||||||
|
closure = incrementalManager.toIncrementalTaskClosure(plugin, taskName, runTask)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun tasksFor(context: KobaltContext) : List<DynamicTask> = dynamicTasks
|
override fun tasksFor(context: KobaltContext) : List<DynamicTask> = dynamicTasks
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
package com.beust.kobalt.internal
|
package com.beust.kobalt.internal
|
||||||
|
|
||||||
|
import com.beust.kobalt.IncrementalTaskInfo
|
||||||
|
import com.beust.kobalt.TaskResult
|
||||||
|
import com.beust.kobalt.api.IPlugin
|
||||||
|
import com.beust.kobalt.api.Project
|
||||||
import com.beust.kobalt.misc.KFiles
|
import com.beust.kobalt.misc.KFiles
|
||||||
|
import com.beust.kobalt.misc.log
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -32,10 +37,10 @@ class IncrementalManager(val fileName: String = IncrementalManager.BUILD_INFO_FI
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun taskInfos() = hashMapOf<String, TaskInfo>().apply {
|
private fun taskInfos() = hashMapOf<String, TaskInfo>().apply {
|
||||||
buildInfo().tasks.forEach {
|
buildInfo().tasks.forEach {
|
||||||
put(it.taskName, it)
|
put(it.taskName, it)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun save(map: Map<String, TaskInfo>) {
|
private fun save(map: Map<String, TaskInfo>) {
|
||||||
val bi = BuildInfo(map.values.toList())
|
val bi = BuildInfo(map.values.toList())
|
||||||
|
@ -65,4 +70,53 @@ class IncrementalManager(val fileName: String = IncrementalManager.BUILD_INFO_FI
|
||||||
|
|
||||||
fun outputChecksumFor(taskName: String) : String? =
|
fun outputChecksumFor(taskName: String) : String? =
|
||||||
taskInfoFor(taskInfos(), taskName).outputChecksum
|
taskInfoFor(taskInfos(), taskName).outputChecksum
|
||||||
|
/**
|
||||||
|
* @param method is assumed to return an IncrementalTaskInfo.
|
||||||
|
* @return a closure that invokes that method and decide whether to run the task or not based
|
||||||
|
* on the content of that IncrementalTaskInfo
|
||||||
|
*/
|
||||||
|
fun toIncrementalTaskClosure(plugin: IPlugin, taskName: String, method: (Project) -> IncrementalTaskInfo)
|
||||||
|
: (Project) -> TaskResult {
|
||||||
|
return { project: Project ->
|
||||||
|
val iit = method(project)
|
||||||
|
// TODO: compare the checksums with the previous run
|
||||||
|
val taskName = project.name + ":" + taskName
|
||||||
|
var upToDate = false
|
||||||
|
inputChecksumFor(taskName)?.let { inputChecksum ->
|
||||||
|
if (inputChecksum == iit.inputChecksum) {
|
||||||
|
outputChecksumFor(taskName)?.let { outputChecksum ->
|
||||||
|
if (outputChecksum == iit.outputChecksum) {
|
||||||
|
upToDate = true
|
||||||
|
} else {
|
||||||
|
logIncremental(1, "Incremental task $taskName output is out of date, running it")
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logIncremental(1, "Incremental task $taskName input is out of date, running it"
|
||||||
|
+ " old: $inputChecksum new: ${iit.inputChecksum}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (! upToDate) {
|
||||||
|
val result = iit.task(project)
|
||||||
|
if (result.success) {
|
||||||
|
logIncremental(1, "Incremental task $taskName done running, saving checksums")
|
||||||
|
iit.inputChecksum?.let {
|
||||||
|
saveInputChecksum(taskName, it)
|
||||||
|
logIncremental(1, " input checksum \"$it\" saved")
|
||||||
|
}
|
||||||
|
iit.outputChecksum?.let {
|
||||||
|
saveOutputChecksum(taskName, it)
|
||||||
|
logIncremental(1, " output checksum \"$it\" saved")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
logIncremental(2, "Incremental task \"$taskName\" is up to date, not running it")
|
||||||
|
TaskResult()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logIncremental(level: Int, s: String) = log(level, " INC - $s")
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ abstract class JvmCompilerPlugin @Inject constructor(
|
||||||
open val dependencyManager: DependencyManager,
|
open val dependencyManager: DependencyManager,
|
||||||
open val executors: KobaltExecutors,
|
open val executors: KobaltExecutors,
|
||||||
open val jvmCompiler: JvmCompiler,
|
open val jvmCompiler: JvmCompiler,
|
||||||
val taskContributor : TaskContributor = TaskContributor())
|
open val taskContributor : TaskContributor)
|
||||||
: BasePlugin(), ISourceDirectoryContributor, IProjectContributor, ITaskContributor by taskContributor {
|
: BasePlugin(), ISourceDirectoryContributor, IProjectContributor, ITaskContributor by taskContributor {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -63,7 +63,8 @@ abstract class JvmCompilerPlugin @Inject constructor(
|
||||||
override fun apply(project: Project, context: KobaltContext) {
|
override fun apply(project: Project, context: KobaltContext) {
|
||||||
super.apply(project, context)
|
super.apply(project, context)
|
||||||
project.projectProperties.put(DEPENDENT_PROJECTS, projects())
|
project.projectProperties.put(DEPENDENT_PROJECTS, projects())
|
||||||
taskContributor.addVariantTasks(this, project, context, "compile", runTask = { doTaskCompile(project) })
|
taskContributor.addIncrementalVariantTasks(this, project, context, "compile",
|
||||||
|
runTask = { taskCompile(project) })
|
||||||
}
|
}
|
||||||
|
|
||||||
@Task(name = TASK_TEST, description = "Run the tests",
|
@Task(name = TASK_TEST, description = "Run the tests",
|
||||||
|
|
|
@ -236,7 +236,6 @@ public class TaskManager @Inject constructor(val args: Args, val incrementalMana
|
||||||
= TaskAnnotation(method, plugin, ta.name, ta.description, ta.runBefore, ta.runAfter, ta.alwaysRunAfter,
|
= TaskAnnotation(method, plugin, ta.name, ta.description, ta.runBefore, ta.runAfter, ta.alwaysRunAfter,
|
||||||
{ project ->
|
{ project ->
|
||||||
method.invoke(plugin, project) as TaskResult
|
method.invoke(plugin, project) as TaskResult
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -245,47 +244,10 @@ public class TaskManager @Inject constructor(val args: Args, val incrementalMana
|
||||||
*/
|
*/
|
||||||
fun toTaskAnnotation(method: Method, plugin: IPlugin, ta: IncrementalTask)
|
fun toTaskAnnotation(method: Method, plugin: IPlugin, ta: IncrementalTask)
|
||||||
= TaskAnnotation(method, plugin, ta.name, ta.description, ta.runBefore, ta.runAfter, ta.alwaysRunAfter,
|
= TaskAnnotation(method, plugin, ta.name, ta.description, ta.runBefore, ta.runAfter, ta.alwaysRunAfter,
|
||||||
{ project ->
|
incrementalManager.toIncrementalTaskClosure(plugin, ta.name,
|
||||||
val iit = method.invoke(plugin, project) as IncrementalTaskInfo
|
{ project ->
|
||||||
// TODO: compare the checksums with the previous run
|
method.invoke(plugin, project) as IncrementalTaskInfo
|
||||||
val taskName = project.name + ":" + ta.name
|
}))
|
||||||
var upToDate = false
|
|
||||||
incrementalManager.inputChecksumFor(taskName)?.let { inputChecksum ->
|
|
||||||
if (inputChecksum == iit.inputChecksum) {
|
|
||||||
incrementalManager.outputChecksumFor(taskName)?.let { outputChecksum ->
|
|
||||||
if (outputChecksum == iit.outputChecksum) {
|
|
||||||
upToDate = true
|
|
||||||
} else {
|
|
||||||
logIncremental(1, "Incremental task ${ta.name} output is out of date, running it")
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logIncremental(1, "Incremental task ${ta.name} input is out of date, running it"
|
|
||||||
+ " old: $inputChecksum new: ${iit.inputChecksum}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (! upToDate) {
|
|
||||||
val result = iit.task(project)
|
|
||||||
if (result.success) {
|
|
||||||
logIncremental(1, "Incremental task ${ta.name} done running, saving checksums")
|
|
||||||
iit.inputChecksum?.let {
|
|
||||||
incrementalManager.saveInputChecksum(taskName, it)
|
|
||||||
logIncremental(1, " input checksum \"$it\" saved")
|
|
||||||
}
|
|
||||||
iit.outputChecksum?.let {
|
|
||||||
incrementalManager.saveOutputChecksum(taskName, it)
|
|
||||||
logIncremental(1, " output checksum \"$it\" saved")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result
|
|
||||||
} else {
|
|
||||||
logIncremental(2, "Incremental task \"${ta.name}\" is up to date, not running it")
|
|
||||||
TaskResult()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
private fun logIncremental(level: Int, s: String) = log(level, " INC - $s")
|
|
||||||
|
|
||||||
class PluginDynamicTask(val plugin: IPlugin, val task: DynamicTask)
|
class PluginDynamicTask(val plugin: IPlugin, val task: DynamicTask)
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ import java.nio.file.Paths
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler,
|
public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler,
|
||||||
val executors: KobaltExecutors, val dependencyManager: DependencyManager)
|
val executors: KobaltExecutors, val dependencyManager: DependencyManager, val taskContributor : TaskContributor)
|
||||||
: ConfigPlugin<AndroidConfig>(), IClasspathContributor, IRepoContributor, ICompilerFlagContributor,
|
: ConfigPlugin<AndroidConfig>(), IClasspathContributor, IRepoContributor, ICompilerFlagContributor,
|
||||||
ICompilerInterceptor, IBuildDirectoryIncerceptor, IRunnerContributor, IClasspathInterceptor,
|
ICompilerInterceptor, IBuildDirectoryIncerceptor, IRunnerContributor, IClasspathInterceptor,
|
||||||
ISourceDirectoryContributor, IBuildConfigFieldContributor, ITaskContributor, IMavenIdInterceptor {
|
ISourceDirectoryContributor, IBuildConfigFieldContributor, ITaskContributor, IMavenIdInterceptor {
|
||||||
|
@ -52,8 +52,6 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler,
|
||||||
|
|
||||||
fun isAndroid(project: Project) = configurationFor(project) != null
|
fun isAndroid(project: Project) = configurationFor(project) != null
|
||||||
|
|
||||||
val taskContributor : TaskContributor = TaskContributor()
|
|
||||||
|
|
||||||
override fun apply(project: Project, context: KobaltContext) {
|
override fun apply(project: Project, context: KobaltContext) {
|
||||||
super.apply(project, context)
|
super.apply(project, context)
|
||||||
if (accept(project)) {
|
if (accept(project)) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ fun Project.application(init: ApplicationConfig.() -> Unit) {
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class ApplicationPlugin @Inject constructor(val executors: KobaltExecutors,
|
class ApplicationPlugin @Inject constructor(val executors: KobaltExecutors,
|
||||||
val dependencyManager: DependencyManager)
|
val dependencyManager: DependencyManager, val taskContributor : TaskContributor)
|
||||||
: ConfigPlugin<ApplicationConfig>(), IRunnerContributor, ITaskContributor {
|
: ConfigPlugin<ApplicationConfig>(), IRunnerContributor, ITaskContributor {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -43,8 +43,6 @@ class ApplicationPlugin @Inject constructor(val executors: KobaltExecutors,
|
||||||
|
|
||||||
override val name = PLUGIN_NAME
|
override val name = PLUGIN_NAME
|
||||||
|
|
||||||
val taskContributor : TaskContributor = TaskContributor()
|
|
||||||
|
|
||||||
override fun apply(project: Project, context: KobaltContext) {
|
override fun apply(project: Project, context: KobaltContext) {
|
||||||
super.apply(project, context)
|
super.apply(project, context)
|
||||||
taskContributor.addVariantTasks(this, project, context, "run", runAfter = listOf("install"),
|
taskContributor.addVariantTasks(this, project, context, "run", runAfter = listOf("install"),
|
||||||
|
|
|
@ -24,8 +24,9 @@ class JavaPlugin @Inject constructor(
|
||||||
override val dependencyManager: DependencyManager,
|
override val dependencyManager: DependencyManager,
|
||||||
override val executors: KobaltExecutors,
|
override val executors: KobaltExecutors,
|
||||||
val javaCompiler: JavaCompiler,
|
val javaCompiler: JavaCompiler,
|
||||||
override val jvmCompiler: JvmCompiler)
|
override val jvmCompiler: JvmCompiler,
|
||||||
: JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler),
|
override val taskContributor : TaskContributor)
|
||||||
|
: JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler, taskContributor),
|
||||||
ICompilerContributor, IDocContributor, ITestSourceDirectoryContributor {
|
ICompilerContributor, IDocContributor, ITestSourceDirectoryContributor {
|
||||||
companion object {
|
companion object {
|
||||||
const val PLUGIN_NAME = "Java"
|
const val PLUGIN_NAME = "Java"
|
||||||
|
|
|
@ -28,8 +28,9 @@ class KotlinPlugin @Inject constructor(
|
||||||
override val depFactory: DepFactory,
|
override val depFactory: DepFactory,
|
||||||
override val dependencyManager: DependencyManager,
|
override val dependencyManager: DependencyManager,
|
||||||
override val executors: KobaltExecutors,
|
override val executors: KobaltExecutors,
|
||||||
override val jvmCompiler: JvmCompiler)
|
override val jvmCompiler: JvmCompiler,
|
||||||
: JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler),
|
override val taskContributor : TaskContributor)
|
||||||
|
: JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler, taskContributor),
|
||||||
IClasspathContributor, ICompilerContributor, IDocContributor {
|
IClasspathContributor, ICompilerContributor, IDocContributor {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -24,7 +24,8 @@ import javax.inject.Singleton
|
||||||
@Singleton
|
@Singleton
|
||||||
class PackagingPlugin @Inject constructor(val dependencyManager : DependencyManager,
|
class PackagingPlugin @Inject constructor(val dependencyManager : DependencyManager,
|
||||||
val executors: KobaltExecutors, val jarGenerator: JarGenerator, val warGenerator: WarGenerator,
|
val executors: KobaltExecutors, val jarGenerator: JarGenerator, val warGenerator: WarGenerator,
|
||||||
val zipGenerator: ZipGenerator) : ConfigPlugin<InstallConfig>(), ITaskContributor {
|
val zipGenerator: ZipGenerator, val taskContributor: TaskContributor)
|
||||||
|
: ConfigPlugin<InstallConfig>(), ITaskContributor {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val PLUGIN_NAME = "Packaging"
|
const val PLUGIN_NAME = "Packaging"
|
||||||
|
@ -133,8 +134,6 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
|
||||||
|
|
||||||
private val packages = arrayListOf<PackageConfig>()
|
private val packages = arrayListOf<PackageConfig>()
|
||||||
|
|
||||||
val taskContributor : TaskContributor = TaskContributor()
|
|
||||||
|
|
||||||
override fun apply(project: Project, context: KobaltContext) {
|
override fun apply(project: Project, context: KobaltContext) {
|
||||||
super.apply(project, context)
|
super.apply(project, context)
|
||||||
project.projectProperties.put(LIBS_DIR, libsDir(project))
|
project.projectProperties.put(LIBS_DIR, libsDir(project))
|
||||||
|
|
|
@ -18,8 +18,9 @@ import java.io.File
|
||||||
* the most recent retrolambda.jar and it can be configured with the `retrolambda{}` directive.
|
* the most recent retrolambda.jar and it can be configured with the `retrolambda{}` directive.
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
class RetrolambdaPlugin @Inject constructor(val dependencyManager: DependencyManager)
|
class RetrolambdaPlugin @Inject constructor(val dependencyManager: DependencyManager,
|
||||||
: ConfigPlugin<RetrolambdaConfig>(), IClasspathContributor, ITaskContributor {
|
val taskContributor : TaskContributor)
|
||||||
|
: ConfigPlugin<RetrolambdaConfig>(), IClasspathContributor, ITaskContributor {
|
||||||
|
|
||||||
override val name = PLUGIN_NAME
|
override val name = PLUGIN_NAME
|
||||||
|
|
||||||
|
@ -73,8 +74,6 @@ class RetrolambdaPlugin @Inject constructor(val dependencyManager: DependencyMan
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
val taskContributor : TaskContributor = TaskContributor()
|
|
||||||
|
|
||||||
// ITaskContributor
|
// ITaskContributor
|
||||||
override fun tasksFor(context: KobaltContext) : List<DynamicTask> = taskContributor.dynamicTasks
|
override fun tasksFor(context: KobaltContext) : List<DynamicTask> = taskContributor.dynamicTasks
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue