From a4f06702b73b74fd273ccdb02424316e8cbb97cd Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 21 Apr 2016 21:52:16 -0800 Subject: [PATCH] Unify static and dynamic tasks under ITask. --- .../main/kotlin/com/beust/kobalt/Plugins.kt | 2 +- .../com/beust/kobalt/api/ITaskContributor.kt | 14 ++++- .../kotlin/com/beust/kobalt/api/PluginTask.kt | 21 ++++--- .../com/beust/kobalt/api/TaskContributor.kt | 4 +- .../com/beust/kobalt/internal/TaskManager.kt | 63 +++++++++++-------- 5 files changed, 64 insertions(+), 40 deletions(-) diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Plugins.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Plugins.kt index d2646a04..1c1d9dd1 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Plugins.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Plugins.kt @@ -77,7 +77,7 @@ class Plugins @Inject constructor (val taskManagerProvider : Provider } -class DynamicTask(val plugin: IPlugin, val name: String, val description: String = "", +class DynamicTask(override val plugin: IPlugin, override val name: String, override val doc: String, + override val project: Project, val dependsOn: List = listOf(), val reverseDependsOn: List = listOf(), val runBefore: List = listOf(), val runAfter: List = listOf(), - val closure: (Project) -> TaskResult) + val closure: (Project) -> TaskResult) : ITask { + + override fun call(): TaskResult2 { + val taskResult = closure.invoke(project) + return TaskResult2(taskResult.success, taskResult.errorMessage, this) + } + +} + diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/PluginTask.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/PluginTask.kt index 194f6200..a2d2b7b7 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/PluginTask.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/PluginTask.kt @@ -3,13 +3,16 @@ package com.beust.kobalt.api import com.beust.kobalt.internal.TaskResult2 import java.util.concurrent.Callable -abstract class PluginTask : Callable> { - abstract val plugin: IPlugin - open val name: String = "" - open val doc: String = "" - abstract val project: Project - - override fun toString() : String { - return project.name + ":" + name - } +interface ITask : Callable> { + val plugin: IPlugin + val project: Project + val name: String + val doc: String +} + +abstract class PluginTask : ITask { + override val name: String = "" + override open val doc: String = "" + + override fun toString() = project.name + ":" + name } 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 4d901040..0d1c1333 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 @@ -30,7 +30,7 @@ class TaskContributor @Inject constructor(val incrementalManagerFactory: Increme runTask: (Project) -> TaskResult) { Variant.allVariants(project).forEach { variant -> val variantTaskName = variant.toTask(taskName) - dynamicTasks.add(DynamicTask(plugin, variantTaskName, variantTaskName, + dynamicTasks.add(DynamicTask(plugin, variantTaskName, variantTaskName, project, dependsOn = dependsOn.map { variant.toTask(it) }, reverseDependsOn = reverseDependsOn.map { variant.toTask(it) }, runBefore = runBefore.map { variant.toTask(it) }, @@ -50,7 +50,7 @@ class TaskContributor @Inject constructor(val incrementalManagerFactory: Increme runTask: (Project) -> IncrementalTaskInfo) { Variant.allVariants(project).forEach { variant -> val variantTaskName = variant.toTask(taskName) - dynamicTasks.add(DynamicTask(plugin, variantTaskName, variantTaskName, + dynamicTasks.add(DynamicTask(plugin, variantTaskName, variantTaskName, project, dependsOn = dependsOn.map { variant.toTask(it) }, reverseDependsOn = reverseDependsOn.map { variant.toTask(it) }, runBefore = runBefore.map { variant.toTask(it) }, 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 76b4cdbc..ea800e5d 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 @@ -1,10 +1,7 @@ package com.beust.kobalt.internal import com.beust.kobalt.* -import com.beust.kobalt.api.DynamicTask -import com.beust.kobalt.api.IPlugin -import com.beust.kobalt.api.PluginTask -import com.beust.kobalt.api.Project +import com.beust.kobalt.api.* import com.beust.kobalt.api.annotation.IncrementalTask import com.beust.kobalt.api.annotation.Task import com.beust.kobalt.misc.Strings @@ -13,6 +10,7 @@ import com.beust.kobalt.misc.kobaltError import com.beust.kobalt.misc.log import com.google.common.annotations.VisibleForTesting import com.google.common.collect.ArrayListMultimap +import com.google.common.collect.ListMultimap import com.google.common.collect.Multimap import com.google.common.collect.TreeMultimap import java.lang.reflect.Method @@ -60,6 +58,27 @@ class TaskManager @Inject constructor(val args: Args, class RunTargetResult(val exitCode: Int, val messages: List) + /** + * @return the list of tasks available for the given project. + * + * There can be multiple tasks by the same name (e.g. PackagingPlugin and AndroidPlugin both + * define "install"), so return a multimap. + */ + fun tasksByNames(project: Project): ListMultimap { + return ArrayListMultimap.create().apply { + annotationTasks.filter { + it.project.name == project.name + }.forEach { + put(it.name, it) + } + dynamicTasks.filter { + it.plugin.accept(project) + }.forEach { + put(it.name, it) + } + } + } + fun runTargets(taskNames: List, projects: List) : RunTargetResult { var result = 0 val failedProjects = hashSetOf() @@ -83,12 +102,7 @@ class TaskManager @Inject constructor(val args: Args, } else { // There can be multiple tasks by the same name (e.g. PackagingPlugin and AndroidPlugin both // define "install"), so use a multimap - val tasksByNames = ArrayListMultimap.create() - annotationTasks.filter { - it.project.name == project.name - }.forEach { - tasksByNames.put(it.name, it) - } + val tasksByNames = tasksByNames(project) log(3, "Tasks:") tasksByNames.keys().forEach { @@ -97,16 +111,16 @@ class TaskManager @Inject constructor(val args: Args, val graph = createGraph(project.name, taskNames, tasksByNames, dependsOn, reverseDependsOn, runBefore, runAfter, - { task: PluginTask -> task.name }, - { task: PluginTask -> task.plugin.accept(project) }) + { task: ITask -> task.name }, + { task: ITask -> task.plugin.accept(project) }) // // Now that we have a full graph, run it // log(2, "About to run graph:\n ${graph.dump()} ") - val factory = object : IThreadWorkerFactory { - override fun createWorkers(nodes: Collection) + val factory = object : IThreadWorkerFactory { + override fun createWorkers(nodes: Collection) = nodes.map { TaskWorker(listOf(it), args.dryRun, messages) } } @@ -128,7 +142,7 @@ class TaskManager @Inject constructor(val args: Args, * Create a dynamic graph representing all the tasks that need to be run. */ @VisibleForTesting - fun createGraph(projectName: String, taskNames: List, nodeMap: Multimap, + fun createGraph(projectName: String, taskNames: List, nodeMap: Multimap, dependsOn: Multimap, reverseDependsOn: Multimap, runBefore: Multimap, @@ -255,13 +269,11 @@ class TaskManager @Inject constructor(val args: Args, method.invoke(plugin, project) as IncrementalTaskInfo })) - class PluginDynamicTask(val plugin: IPlugin, val task: DynamicTask) - /** Tasks annotated with @Task or @IncrementalTask */ val annotationTasks = arrayListOf() /** Tasks provided by ITaskContributors */ - val dynamicTasks = arrayListOf() + val dynamicTasks = arrayListOf() fun addAnnotationTask(plugin: IPlugin, method: Method, annotation: Task) = taskAnnotations.add(toTaskAnnotation(method, plugin, annotation)) @@ -278,10 +290,9 @@ class TaskManager @Inject constructor(val args: Args, } private fun installDynamicTasks(projects: List) { - dynamicTasks.forEach { dynamicTask -> - val task = dynamicTask.task - projects.filter { dynamicTask.plugin.accept(it) }.forEach { project -> - addTask(dynamicTask.plugin, project, task.name, task.description, + dynamicTasks.forEach { task -> + projects.filter { task.plugin.accept(it) }.forEach { project -> + addTask(task.plugin, project, task.name, task.doc, task.dependsOn, task.reverseDependsOn, task.runBefore, task.runAfter, task.closure) } @@ -318,7 +329,7 @@ class TaskManager @Inject constructor(val args: Args, task: (Project) -> TaskResult) { annotationTasks.add( object : BasePluginTask(plugin, name, description, project) { - override fun call(): TaskResult2 { + override fun call(): TaskResult2 { val taskResult = task(project) return TaskResult2(taskResult.success, taskResult.errorMessage, this) } @@ -334,10 +345,10 @@ class TaskManager @Inject constructor(val args: Args, ///// } -class TaskWorker(val tasks: List, val dryRun: Boolean, val messages: MutableList) - : IWorker { +class TaskWorker(val tasks: List, val dryRun: Boolean, val messages: MutableList) + : IWorker { - override fun call() : TaskResult2 { + override fun call() : TaskResult2 { if (tasks.size > 0) { tasks[0].let { log(1, AsciiArt.taskColor(AsciiArt.horizontalSingleLine + " ${it.project.name}:${it.name}"))