1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 16:28:12 -07:00

Unify static and dynamic tasks under ITask.

This commit is contained in:
Cedric Beust 2016-04-21 21:52:16 -08:00
parent 851bc75ce6
commit a4f06702b7
5 changed files with 64 additions and 40 deletions

View file

@ -77,7 +77,7 @@ class Plugins @Inject constructor (val taskManagerProvider : Provider<TaskManage
// Collect all the tasks from the task contributors
context.pluginInfo.taskContributors.forEach {
taskManager.dynamicTasks.addAll(it.tasksFor(context).map { TaskManager.PluginDynamicTask(it.plugin, it) })
taskManager.dynamicTasks.addAll(it.tasksFor(context))
}
// Now that we have collected all static and dynamic tasks, turn them all into plug-in tasks

View file

@ -1,6 +1,7 @@
package com.beust.kobalt.api
import com.beust.kobalt.TaskResult
import com.beust.kobalt.internal.TaskResult2
/**
* Plug-ins that need to add dynamic tasks (tasks that are not methods annotated with @Task) need
@ -10,9 +11,18 @@ interface ITaskContributor : IContributor {
fun tasksFor(context: KobaltContext) : List<DynamicTask>
}
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<String> = listOf<String>(),
val reverseDependsOn: List<String> = listOf<String>(),
val runBefore: List<String> = listOf<String>(),
val runAfter: List<String> = listOf<String>(),
val closure: (Project) -> TaskResult)
val closure: (Project) -> TaskResult) : ITask {
override fun call(): TaskResult2<ITask> {
val taskResult = closure.invoke(project)
return TaskResult2(taskResult.success, taskResult.errorMessage, this)
}
}

View file

@ -3,13 +3,16 @@ package com.beust.kobalt.api
import com.beust.kobalt.internal.TaskResult2
import java.util.concurrent.Callable
abstract class PluginTask : Callable<TaskResult2<PluginTask>> {
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<TaskResult2<ITask>> {
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
}

View file

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

View file

@ -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<String>)
/**
* @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<String, out ITask> {
return ArrayListMultimap.create<String, ITask>().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<String>, projects: List<Project>) : RunTargetResult {
var result = 0
val failedProjects = hashSetOf<String>()
@ -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<String, PluginTask>()
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<PluginTask> {
override fun createWorkers(nodes: Collection<PluginTask>)
val factory = object : IThreadWorkerFactory<ITask> {
override fun createWorkers(nodes: Collection<ITask>)
= 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 <T> createGraph(projectName: String, taskNames: List<String>, nodeMap: Multimap<String, T>,
fun <T> createGraph(projectName: String, taskNames: List<String>, nodeMap: Multimap<String, out T>,
dependsOn: Multimap<String, String>,
reverseDependsOn: Multimap<String, String>,
runBefore: Multimap<String, String>,
@ -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<PluginTask>()
/** Tasks provided by ITaskContributors */
val dynamicTasks = arrayListOf<PluginDynamicTask>()
val dynamicTasks = arrayListOf<DynamicTask>()
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<Project>) {
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<PluginTask> {
override fun call(): TaskResult2<ITask> {
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<PluginTask>, val dryRun: Boolean, val messages: MutableList<String>)
: IWorker<PluginTask> {
class TaskWorker(val tasks: List<ITask>, val dryRun: Boolean, val messages: MutableList<String>)
: IWorker<ITask> {
override fun call() : TaskResult2<PluginTask> {
override fun call() : TaskResult2<ITask> {
if (tasks.size > 0) {
tasks[0].let {
log(1, AsciiArt.taskColor(AsciiArt.horizontalSingleLine + " ${it.project.name}:${it.name}"))