diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/TaskContributor.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/TaskContributor.kt index b90926d9..41762a26 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/TaskContributor.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/TaskContributor.kt @@ -1,13 +1,16 @@ package com.beust.kobalt.api +import com.beust.kobalt.IncrementalTaskInfo import com.beust.kobalt.TaskResult 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 * 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() /** @@ -36,5 +39,20 @@ class TaskContributor : ITaskContributor { } } + fun addIncrementalVariantTasks(plugin: IPlugin, project: Project, context: KobaltContext, taskName: String, + runBefore : List = emptyList(), + runAfter : List = emptyList(), + alwaysRunAfter : List = 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 = dynamicTasks } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/IncrementalManager.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/IncrementalManager.kt index 3ff1536f..42fbedf5 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/IncrementalManager.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/IncrementalManager.kt @@ -1,6 +1,11 @@ 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.log import com.google.gson.Gson import com.google.gson.GsonBuilder import java.io.File @@ -32,10 +37,10 @@ class IncrementalManager(val fileName: String = IncrementalManager.BUILD_INFO_FI } private fun taskInfos() = hashMapOf().apply { - buildInfo().tasks.forEach { - put(it.taskName, it) - } + buildInfo().tasks.forEach { + put(it.taskName, it) } + } private fun save(map: Map) { val bi = BuildInfo(map.values.toList()) @@ -65,4 +70,53 @@ class IncrementalManager(val fileName: String = IncrementalManager.BUILD_INFO_FI fun outputChecksumFor(taskName: String) : String? = 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") } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt index 6820ec81..9474f8fc 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt @@ -33,7 +33,7 @@ abstract class JvmCompilerPlugin @Inject constructor( open val dependencyManager: DependencyManager, open val executors: KobaltExecutors, open val jvmCompiler: JvmCompiler, - val taskContributor : TaskContributor = TaskContributor()) + open val taskContributor : TaskContributor) : BasePlugin(), ISourceDirectoryContributor, IProjectContributor, ITaskContributor by taskContributor { companion object { @@ -63,7 +63,8 @@ abstract class JvmCompilerPlugin @Inject constructor( override fun apply(project: Project, context: KobaltContext) { super.apply(project, context) 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", diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt index 243ab169..6a7519b5 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt @@ -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, { project -> 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) = TaskAnnotation(method, plugin, ta.name, ta.description, ta.runBefore, ta.runAfter, ta.alwaysRunAfter, - { project -> - val iit = method.invoke(plugin, project) as IncrementalTaskInfo - // TODO: compare the checksums with the previous run - 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") + incrementalManager.toIncrementalTaskClosure(plugin, ta.name, + { project -> + method.invoke(plugin, project) as IncrementalTaskInfo + })) class PluginDynamicTask(val plugin: IPlugin, val task: DynamicTask) diff --git a/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt index e825a27c..0a64ae35 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt @@ -37,7 +37,7 @@ import java.nio.file.Paths */ @Singleton public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, - val executors: KobaltExecutors, val dependencyManager: DependencyManager) + val executors: KobaltExecutors, val dependencyManager: DependencyManager, val taskContributor : TaskContributor) : ConfigPlugin(), IClasspathContributor, IRepoContributor, ICompilerFlagContributor, ICompilerInterceptor, IBuildDirectoryIncerceptor, IRunnerContributor, IClasspathInterceptor, ISourceDirectoryContributor, IBuildConfigFieldContributor, ITaskContributor, IMavenIdInterceptor { @@ -52,8 +52,6 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, fun isAndroid(project: Project) = configurationFor(project) != null - val taskContributor : TaskContributor = TaskContributor() - override fun apply(project: Project, context: KobaltContext) { super.apply(project, context) if (accept(project)) { diff --git a/src/main/kotlin/com/beust/kobalt/plugin/application/ApplicationPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/application/ApplicationPlugin.kt index 4134aa87..9664f75f 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/application/ApplicationPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/application/ApplicationPlugin.kt @@ -34,7 +34,7 @@ fun Project.application(init: ApplicationConfig.() -> Unit) { @Singleton class ApplicationPlugin @Inject constructor(val executors: KobaltExecutors, - val dependencyManager: DependencyManager) + val dependencyManager: DependencyManager, val taskContributor : TaskContributor) : ConfigPlugin(), IRunnerContributor, ITaskContributor { companion object { @@ -43,8 +43,6 @@ class ApplicationPlugin @Inject constructor(val executors: KobaltExecutors, override val name = PLUGIN_NAME - val taskContributor : TaskContributor = TaskContributor() - override fun apply(project: Project, context: KobaltContext) { super.apply(project, context) taskContributor.addVariantTasks(this, project, context, "run", runAfter = listOf("install"), diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt index b612f18f..3f386372 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt @@ -24,8 +24,9 @@ class JavaPlugin @Inject constructor( override val dependencyManager: DependencyManager, override val executors: KobaltExecutors, val javaCompiler: JavaCompiler, - override val jvmCompiler: JvmCompiler) - : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler), + override val jvmCompiler: JvmCompiler, + override val taskContributor : TaskContributor) + : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler, taskContributor), ICompilerContributor, IDocContributor, ITestSourceDirectoryContributor { companion object { const val PLUGIN_NAME = "Java" diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt index 1c4e6151..37bc5b54 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt @@ -28,8 +28,9 @@ class KotlinPlugin @Inject constructor( override val depFactory: DepFactory, override val dependencyManager: DependencyManager, override val executors: KobaltExecutors, - override val jvmCompiler: JvmCompiler) - : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler), + override val jvmCompiler: JvmCompiler, + override val taskContributor : TaskContributor) + : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler, taskContributor), IClasspathContributor, ICompilerContributor, IDocContributor { companion object { diff --git a/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt index f90f8073..869a8866 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt @@ -24,7 +24,8 @@ import javax.inject.Singleton @Singleton class PackagingPlugin @Inject constructor(val dependencyManager : DependencyManager, val executors: KobaltExecutors, val jarGenerator: JarGenerator, val warGenerator: WarGenerator, - val zipGenerator: ZipGenerator) : ConfigPlugin(), ITaskContributor { + val zipGenerator: ZipGenerator, val taskContributor: TaskContributor) + : ConfigPlugin(), ITaskContributor { companion object { const val PLUGIN_NAME = "Packaging" @@ -133,8 +134,6 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana private val packages = arrayListOf() - val taskContributor : TaskContributor = TaskContributor() - override fun apply(project: Project, context: KobaltContext) { super.apply(project, context) project.projectProperties.put(LIBS_DIR, libsDir(project)) diff --git a/src/main/kotlin/com/beust/kobalt/plugin/retrolambda/RetrolambdaPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/retrolambda/RetrolambdaPlugin.kt index 037d44a2..0486cb72 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/retrolambda/RetrolambdaPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/retrolambda/RetrolambdaPlugin.kt @@ -18,8 +18,9 @@ import java.io.File * the most recent retrolambda.jar and it can be configured with the `retrolambda{}` directive. */ @Singleton -class RetrolambdaPlugin @Inject constructor(val dependencyManager: DependencyManager) - : ConfigPlugin(), IClasspathContributor, ITaskContributor { +class RetrolambdaPlugin @Inject constructor(val dependencyManager: DependencyManager, + val taskContributor : TaskContributor) + : ConfigPlugin(), IClasspathContributor, ITaskContributor { override val name = PLUGIN_NAME @@ -73,8 +74,6 @@ class RetrolambdaPlugin @Inject constructor(val dependencyManager: DependencyMan return result } - val taskContributor : TaskContributor = TaskContributor() - // ITaskContributor override fun tasksFor(context: KobaltContext) : List = taskContributor.dynamicTasks }