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 // Collect all the tasks from the task contributors
context.pluginInfo.taskContributors.forEach { 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 // 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 package com.beust.kobalt.api
import com.beust.kobalt.TaskResult 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 * 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> 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 dependsOn: List<String> = listOf<String>(),
val reverseDependsOn: List<String> = listOf<String>(), val reverseDependsOn: List<String> = listOf<String>(),
val runBefore: List<String> = listOf<String>(), val runBefore: List<String> = listOf<String>(),
val runAfter: 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 com.beust.kobalt.internal.TaskResult2
import java.util.concurrent.Callable import java.util.concurrent.Callable
abstract class PluginTask : Callable<TaskResult2<PluginTask>> { interface ITask : Callable<TaskResult2<ITask>> {
abstract val plugin: IPlugin val plugin: IPlugin
open val name: String = "" val project: Project
open val doc: String = "" val name: String
abstract val project: Project val doc: String
}
override fun toString() : String {
return project.name + ":" + name 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) { runTask: (Project) -> TaskResult) {
Variant.allVariants(project).forEach { variant -> Variant.allVariants(project).forEach { variant ->
val variantTaskName = variant.toTask(taskName) val variantTaskName = variant.toTask(taskName)
dynamicTasks.add(DynamicTask(plugin, variantTaskName, variantTaskName, dynamicTasks.add(DynamicTask(plugin, variantTaskName, variantTaskName, project,
dependsOn = dependsOn.map { variant.toTask(it) }, dependsOn = dependsOn.map { variant.toTask(it) },
reverseDependsOn = reverseDependsOn.map { variant.toTask(it) }, reverseDependsOn = reverseDependsOn.map { variant.toTask(it) },
runBefore = runBefore.map { variant.toTask(it) }, runBefore = runBefore.map { variant.toTask(it) },
@ -50,7 +50,7 @@ class TaskContributor @Inject constructor(val incrementalManagerFactory: Increme
runTask: (Project) -> IncrementalTaskInfo) { runTask: (Project) -> IncrementalTaskInfo) {
Variant.allVariants(project).forEach { variant -> Variant.allVariants(project).forEach { variant ->
val variantTaskName = variant.toTask(taskName) val variantTaskName = variant.toTask(taskName)
dynamicTasks.add(DynamicTask(plugin, variantTaskName, variantTaskName, dynamicTasks.add(DynamicTask(plugin, variantTaskName, variantTaskName, project,
dependsOn = dependsOn.map { variant.toTask(it) }, dependsOn = dependsOn.map { variant.toTask(it) },
reverseDependsOn = reverseDependsOn.map { variant.toTask(it) }, reverseDependsOn = reverseDependsOn.map { variant.toTask(it) },
runBefore = runBefore.map { variant.toTask(it) }, runBefore = runBefore.map { variant.toTask(it) },

View file

@ -1,10 +1,7 @@
package com.beust.kobalt.internal package com.beust.kobalt.internal
import com.beust.kobalt.* import com.beust.kobalt.*
import com.beust.kobalt.api.DynamicTask import com.beust.kobalt.api.*
import com.beust.kobalt.api.IPlugin
import com.beust.kobalt.api.PluginTask
import com.beust.kobalt.api.Project
import com.beust.kobalt.api.annotation.IncrementalTask import com.beust.kobalt.api.annotation.IncrementalTask
import com.beust.kobalt.api.annotation.Task import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.misc.Strings import com.beust.kobalt.misc.Strings
@ -13,6 +10,7 @@ import com.beust.kobalt.misc.kobaltError
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import com.google.common.annotations.VisibleForTesting import com.google.common.annotations.VisibleForTesting
import com.google.common.collect.ArrayListMultimap import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.ListMultimap
import com.google.common.collect.Multimap import com.google.common.collect.Multimap
import com.google.common.collect.TreeMultimap import com.google.common.collect.TreeMultimap
import java.lang.reflect.Method 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>) 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 { fun runTargets(taskNames: List<String>, projects: List<Project>) : RunTargetResult {
var result = 0 var result = 0
val failedProjects = hashSetOf<String>() val failedProjects = hashSetOf<String>()
@ -83,12 +102,7 @@ class TaskManager @Inject constructor(val args: Args,
} else { } else {
// There can be multiple tasks by the same name (e.g. PackagingPlugin and AndroidPlugin both // There can be multiple tasks by the same name (e.g. PackagingPlugin and AndroidPlugin both
// define "install"), so use a multimap // define "install"), so use a multimap
val tasksByNames = ArrayListMultimap.create<String, PluginTask>() val tasksByNames = tasksByNames(project)
annotationTasks.filter {
it.project.name == project.name
}.forEach {
tasksByNames.put(it.name, it)
}
log(3, "Tasks:") log(3, "Tasks:")
tasksByNames.keys().forEach { tasksByNames.keys().forEach {
@ -97,16 +111,16 @@ class TaskManager @Inject constructor(val args: Args,
val graph = createGraph(project.name, taskNames, tasksByNames, val graph = createGraph(project.name, taskNames, tasksByNames,
dependsOn, reverseDependsOn, runBefore, runAfter, dependsOn, reverseDependsOn, runBefore, runAfter,
{ task: PluginTask -> task.name }, { task: ITask -> task.name },
{ task: PluginTask -> task.plugin.accept(project) }) { task: ITask -> task.plugin.accept(project) })
// //
// Now that we have a full graph, run it // Now that we have a full graph, run it
// //
log(2, "About to run graph:\n ${graph.dump()} ") log(2, "About to run graph:\n ${graph.dump()} ")
val factory = object : IThreadWorkerFactory<PluginTask> { val factory = object : IThreadWorkerFactory<ITask> {
override fun createWorkers(nodes: Collection<PluginTask>) override fun createWorkers(nodes: Collection<ITask>)
= nodes.map { TaskWorker(listOf(it), args.dryRun, messages) } = 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. * Create a dynamic graph representing all the tasks that need to be run.
*/ */
@VisibleForTesting @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>, dependsOn: Multimap<String, String>,
reverseDependsOn: Multimap<String, String>, reverseDependsOn: Multimap<String, String>,
runBefore: Multimap<String, String>, runBefore: Multimap<String, String>,
@ -255,13 +269,11 @@ class TaskManager @Inject constructor(val args: Args,
method.invoke(plugin, project) as IncrementalTaskInfo method.invoke(plugin, project) as IncrementalTaskInfo
})) }))
class PluginDynamicTask(val plugin: IPlugin, val task: DynamicTask)
/** Tasks annotated with @Task or @IncrementalTask */ /** Tasks annotated with @Task or @IncrementalTask */
val annotationTasks = arrayListOf<PluginTask>() val annotationTasks = arrayListOf<PluginTask>()
/** Tasks provided by ITaskContributors */ /** Tasks provided by ITaskContributors */
val dynamicTasks = arrayListOf<PluginDynamicTask>() val dynamicTasks = arrayListOf<DynamicTask>()
fun addAnnotationTask(plugin: IPlugin, method: Method, annotation: Task) = fun addAnnotationTask(plugin: IPlugin, method: Method, annotation: Task) =
taskAnnotations.add(toTaskAnnotation(method, plugin, annotation)) taskAnnotations.add(toTaskAnnotation(method, plugin, annotation))
@ -278,10 +290,9 @@ class TaskManager @Inject constructor(val args: Args,
} }
private fun installDynamicTasks(projects: List<Project>) { private fun installDynamicTasks(projects: List<Project>) {
dynamicTasks.forEach { dynamicTask -> dynamicTasks.forEach { task ->
val task = dynamicTask.task projects.filter { task.plugin.accept(it) }.forEach { project ->
projects.filter { dynamicTask.plugin.accept(it) }.forEach { project -> addTask(task.plugin, project, task.name, task.doc,
addTask(dynamicTask.plugin, project, task.name, task.description,
task.dependsOn, task.reverseDependsOn, task.runBefore, task.runAfter, task.dependsOn, task.reverseDependsOn, task.runBefore, task.runAfter,
task.closure) task.closure)
} }
@ -318,7 +329,7 @@ class TaskManager @Inject constructor(val args: Args,
task: (Project) -> TaskResult) { task: (Project) -> TaskResult) {
annotationTasks.add( annotationTasks.add(
object : BasePluginTask(plugin, name, description, project) { object : BasePluginTask(plugin, name, description, project) {
override fun call(): TaskResult2<PluginTask> { override fun call(): TaskResult2<ITask> {
val taskResult = task(project) val taskResult = task(project)
return TaskResult2(taskResult.success, taskResult.errorMessage, this) 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>) class TaskWorker(val tasks: List<ITask>, val dryRun: Boolean, val messages: MutableList<String>)
: IWorker<PluginTask> { : IWorker<ITask> {
override fun call() : TaskResult2<PluginTask> { override fun call() : TaskResult2<ITask> {
if (tasks.size > 0) { if (tasks.size > 0) {
tasks[0].let { tasks[0].let {
log(1, AsciiArt.taskColor(AsciiArt.horizontalSingleLine + " ${it.project.name}:${it.name}")) log(1, AsciiArt.taskColor(AsciiArt.horizontalSingleLine + " ${it.project.name}:${it.name}"))