diff --git a/src/main/kotlin/com/beust/kobalt/BasePluginTask.kt b/src/main/kotlin/com/beust/kobalt/BasePluginTask.kt index 1c4285b3..077093bf 100644 --- a/src/main/kotlin/com/beust/kobalt/BasePluginTask.kt +++ b/src/main/kotlin/com/beust/kobalt/BasePluginTask.kt @@ -3,11 +3,11 @@ package com.beust.kobalt import com.beust.kobalt.api.Plugin import com.beust.kobalt.api.PluginTask import com.beust.kobalt.api.Project +import com.beust.kobalt.internal.TaskResult +import com.beust.kobalt.internal.TaskResult2 public abstract class BasePluginTask(override val plugin: Plugin, override val name: String, override val doc: String, override val project: Project) - : PluginTask { - override val dependsOn = arrayListOf() -} + : PluginTask() diff --git a/src/main/kotlin/com/beust/kobalt/Plugins.kt b/src/main/kotlin/com/beust/kobalt/Plugins.kt index a2aa7d4a..cb2918d3 100644 --- a/src/main/kotlin/com/beust/kobalt/Plugins.kt +++ b/src/main/kotlin/com/beust/kobalt/Plugins.kt @@ -105,7 +105,13 @@ public class Plugins @Inject constructor (val taskManagerProvider : Provider + plugin.apply(project, context) + } + var currentClass : Class = plugin.javaClass @@ -147,11 +153,9 @@ public class Plugins @Inject constructor (val taskManagerProvider : Provider - plugin.addTask(annotation, project, toTask(method, project, plugin)) + plugin.addStaticTask(annotation, project, toTask(method, project, plugin)) annotation.runBefore.forEach { plugin.dependsOn(it, annotation.name) } annotation.runAfter.forEach { plugin.dependsOn(annotation.name, it) } - - plugin.apply(project, context) } } } diff --git a/src/main/kotlin/com/beust/kobalt/api/BasePlugin.kt b/src/main/kotlin/com/beust/kobalt/api/BasePlugin.kt index 0f2d9247..5aa68e55 100644 --- a/src/main/kotlin/com/beust/kobalt/api/BasePlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/api/BasePlugin.kt @@ -4,6 +4,7 @@ import com.beust.kobalt.BasePluginTask import com.beust.kobalt.Plugins import com.beust.kobalt.internal.TaskManager import com.beust.kobalt.internal.TaskResult +import com.beust.kobalt.internal.TaskResult2 import java.util.ArrayList import java.util.concurrent.Callable import kotlin.properties.Delegates @@ -12,9 +13,22 @@ abstract public class BasePlugin : Plugin { override val tasks: ArrayList = arrayListOf() override var taskManager : TaskManager by Delegates.notNull() override var methodTasks = arrayListOf() - override fun accept(project: Project) = true - var plugins : Plugins by Delegates.notNull() + fun addSyntheticTask(name: String, project: Project, task: (Project) -> TaskResult) { + val task = object: PluginTask() { + override val doc = "A synthetic task" + override val name = name + override val plugin = this@BasePlugin + override val project = project + + override fun call(): TaskResult2? { + val taskResult = task(project) + return TaskResult2(taskResult.success, this) + } + } + tasks.add(task) + } + } diff --git a/src/main/kotlin/com/beust/kobalt/api/Plugin.kt b/src/main/kotlin/com/beust/kobalt/api/Plugin.kt index 961f7292..aacebc39 100644 --- a/src/main/kotlin/com/beust/kobalt/api/Plugin.kt +++ b/src/main/kotlin/com/beust/kobalt/api/Plugin.kt @@ -17,7 +17,7 @@ public interface Plugin { class MethodTask(val method: Method, val taskAnnotation: Task) val methodTasks : ArrayList - fun addTask(annotation: Task, project: Project, task: (Project) -> TaskResult) { + fun addStaticTask(annotation: Task, project: Project, task: (Project) -> TaskResult) { tasks.add(object : BasePluginTask(this, annotation.name, annotation.description, project) { override fun call(): TaskResult2 { val taskResult = task(project) diff --git a/src/main/kotlin/com/beust/kobalt/api/PluginTask.kt b/src/main/kotlin/com/beust/kobalt/api/PluginTask.kt index 8f1b7378..779854de 100644 --- a/src/main/kotlin/com/beust/kobalt/api/PluginTask.kt +++ b/src/main/kotlin/com/beust/kobalt/api/PluginTask.kt @@ -4,12 +4,12 @@ import com.beust.kobalt.internal.TaskResult2 import com.beust.kobalt.misc.ToString import java.util.concurrent.Callable -public interface PluginTask : Callable> { - val plugin: Plugin - val name: String - val doc: String - val project: Project - val dependsOn : List +abstract public class PluginTask : Callable> { + abstract val plugin: Plugin + open val name: String = "" + open val doc: String = "" + abstract val project: Project + val dependsOn = arrayListOf() override public fun toString() : String { return ToString("PluginTask", "id", project.name + ":" + name).s diff --git a/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt b/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt index b1adfec3..f080f803 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/TaskManager.kt @@ -4,15 +4,11 @@ import com.beust.kobalt.Args import com.beust.kobalt.Plugins import com.beust.kobalt.api.PluginTask import com.beust.kobalt.api.Project -import com.beust.kobalt.api.Task import com.beust.kobalt.misc.KobaltLogger import com.beust.kobalt.maven.KobaltException -import com.google.common.collect.ArrayListMultimap import com.google.common.collect.HashMultimap import com.google.common.collect.TreeMultimap import java.util.HashSet -import java.util.concurrent.LinkedBlockingQueue -import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Singleton @@ -28,6 +24,13 @@ public class TaskManager @Inject constructor(val plugins: Plugins, val args: Arg dependentTaskMap.put(task1, task2) } + class TaskInfo(val id: String) { + val project: String? + get() = if (id.contains(":")) id.split(":").get(0) else null + val task: String + get() = if (id.contains(":")) id.split(":").get(1) else id + } + public fun runTargets(targets: List, projects: List) { val tasksByNames = HashMultimap.create() @@ -36,6 +39,9 @@ public class TaskManager @Inject constructor(val plugins: Plugins, val args: Arg log(1, " Building project ${project.name}") log(1, "") + val allTasksByNames = hashMapOf() + plugins.allTasks.forEach { allTasksByNames.put(TaskInfo(it.name).task, it)} + // // Locate all the tasks // @@ -70,38 +76,45 @@ public class TaskManager @Inject constructor(val plugins: Plugins, val args: Arg val newToProcess = hashSetOf() log(3, "toProcess size: " + toProcess.size()) toProcess.forEach { target -> - log(3, "Processing ${target}") - val actualTarget = - if (target.contains(":")) { - // The target specifies a project explicitly - target.split(":").let { - val projectName = it[0] - if (projectName == project.name) { - it[1] + val pluginTask = allTasksByNames.get(target) + // Only calculate the transitive closure for this target if its plug-in accepts the + // current project + if (pluginTask != null && pluginTask.plugin.accept(project)) { + log(3, "Processing ${target}") + val actualTarget = + if (target.contains(":")) { + // The target specifies a project explicitly + target.split(":").let { + val projectName = it[0] + if (projectName == project.name) { + it[1] + } else { + null + } + } } else { - null + target + } + if (actualTarget != null) { + transitiveClosure.add(actualTarget) + val tasks = tasksByNames.get(actualTarget) + if (tasks.isEmpty()) { + throw KobaltException("Unknown task: ${target}") + } + tasks.forEach { task -> + val dependencyNames = dependentTaskMap.get(task.name) + dependencyNames.forEach { dependencyName -> + if (!seen.contains(dependencyName)) { + newToProcess.add(dependencyName) + seen.add(dependencyName) + } } } } else { - target + log(2, "Target ${target} specified so not running it for project ${project.name}") } - if (actualTarget != null) { - transitiveClosure.add(actualTarget) - val tasks = tasksByNames.get(actualTarget) - if (tasks.isEmpty()) { - throw KobaltException("Unknown task: ${target}") - } - tasks.forEach { task -> - val dependencyNames = dependentTaskMap.get(task.name) - dependencyNames.forEach { dependencyName -> - if (!seen.contains(dependencyName)) { - newToProcess.add(dependencyName) - seen.add(dependencyName) - } - } - } - } else { - log(2, "Target ${target} specified so not running it for project ${project.name}") + } else if (pluginTask == null) { + throw AssertionError("Should have found the task for $target") } } done = newToProcess.isEmpty()