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

First pass at introducing ITaskContributor.

This commit is contained in:
Cedric Beust 2015-12-04 17:23:36 -08:00
parent baf06a9fb7
commit 235ff7337f
8 changed files with 109 additions and 87 deletions

View file

@ -3,8 +3,6 @@ package com.beust.kobalt
import com.beust.kobalt.api.IPlugin
import com.beust.kobalt.api.PluginTask
import com.beust.kobalt.api.Project
import com.beust.kobalt.TaskResult
import com.beust.kobalt.internal.TaskResult2
public abstract class BasePluginTask(override val plugin: IPlugin,
override val name: String,

View file

@ -178,18 +178,14 @@ private class Main @Inject constructor(
// List of tasks
//
val sb = StringBuffer("List of tasks\n")
Plugins.plugins.forEach { plugin ->
if (plugin.tasks.size > 0) {
sb.append("\n " + AsciiArt.horizontalDoubleLine +" ${plugin.name} "
+ AsciiArt.horizontalDoubleLine + "\n")
plugin.tasks.distinctBy {
it.name
}.forEach { task ->
sb.append(" ${task.name}\t\t${task.doc}\n")
}
}
taskManager.tasks.distinctBy {
it.name
}.forEach { task ->
sb.append("\n " + AsciiArt.horizontalDoubleLine +" ${task.plugin.name} "
+ AsciiArt.horizontalDoubleLine + "\n")
sb.append(" ${task.name}\t\t${task.doc}\n")
println(sb.toString())
}
println(sb.toString())
} else if (args.checkVersions) {
checkVersions.run(allProjects)
} else if (args.download) {

View file

@ -5,7 +5,6 @@ import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.internal.TaskManager
import com.beust.kobalt.maven.DepFactory
import com.beust.kobalt.api.IClasspathDependency
import com.beust.kobalt.maven.LocalRepo
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.KobaltExecutors
@ -26,7 +25,8 @@ public class Plugins @Inject constructor (val taskManagerProvider : Provider<Tas
val depFactory: DepFactory,
val localRepo: LocalRepo,
val executors: KobaltExecutors,
val pluginInfo: PluginInfo) {
val pluginInfo: PluginInfo,
val taskManager: TaskManager) {
companion object {
private var pluginMap = hashMapOf<String, IPlugin>()
@ -84,33 +84,15 @@ public class Plugins @Inject constructor (val taskManagerProvider : Provider<Tas
}
val annotation = it.second
plugin.methodTasks.add(IPlugin.MethodTask(it.first, annotation))
taskManager.staticTasks.add(TaskManager.StaticTask(plugin, it.first, annotation))
}
currentClass = currentClass.superclass
}
// Now plugin.methodTasks contains both tasks from the build file and the plug-ins, we
// can create the whole set of tasks and set up their dependencies
plugin.methodTasks.forEach { methodTask ->
val method = methodTask.method
val annotation = methodTask.taskAnnotation
val methodName = method.declaringClass.toString() + "." + method.name
log(3, " Found task:${annotation.name} method: $methodName")
fun toTask(m: Method, project: Project, plugin: IPlugin): (Project) -> TaskResult {
val result: (Project) -> TaskResult = {
m.invoke(plugin, project) as TaskResult
}
return result
}
projects.filter { plugin.accept(it) }.forEach { project ->
plugin.addStaticTask(annotation, project, toTask(method, project, plugin))
}
}
}
// Now that we have collected all static and dynamic tasks, turn them all into plug-in tasks
taskManager.computePluginTasks(plugins, projects)
}
/**
@ -136,9 +118,6 @@ public class Plugins @Inject constructor (val taskManagerProvider : Provider<Tas
val dependencies = arrayListOf<IClasspathDependency>()
val allTasks : List<PluginTask>
get() = Plugins.plugins.flatMap { it.tasks }
fun installPlugins(dependencies: List<IClasspathDependency>, classLoader: ClassLoader) {
val executor = executors.newExecutor("Plugins", 5)
dependencies.forEach {

View file

@ -4,13 +4,10 @@ import com.beust.kobalt.Plugins
import com.beust.kobalt.TaskResult
import com.beust.kobalt.Variant
import com.beust.kobalt.internal.TaskManager
import java.util.*
import kotlin.properties.Delegates
abstract public class BasePlugin : IPlugin {
override val tasks: ArrayList<PluginTask> = arrayListOf()
override var taskManager: TaskManager by Delegates.notNull()
override var methodTasks = arrayListOf<IPlugin.MethodTask>()
override fun accept(project: Project) = true
var plugins: Plugins by Delegates.notNull()
@ -36,7 +33,7 @@ abstract public class BasePlugin : IPlugin {
runTask: (Project) -> TaskResult) {
Variant.allVariants(project).forEach { variant ->
val variantTaskName = variant.toTask(taskName)
addTask(project, variantTaskName, variantTaskName,
taskManager.addTask(this, project, variantTaskName, variantTaskName,
runBefore = runBefore.map { variant.toTask(it) },
runAfter = runAfter.map { variant.toTask(it) },
task = { p: Project ->

View file

@ -1,43 +1,10 @@
package com.beust.kobalt.api
import com.beust.kobalt.BasePluginTask
import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.internal.TaskManager
import com.beust.kobalt.internal.TaskResult2
import java.lang.reflect.Method
import java.util.*
public interface IPlugin : IPluginActor {
val name: String
val tasks : ArrayList<PluginTask>
fun accept(project: Project) : Boolean
fun apply(project: Project, context: KobaltContext) {}
class MethodTask(val method: Method, val taskAnnotation: Task)
val methodTasks : ArrayList<MethodTask>
fun addStaticTask(annotation: Task, project: Project, task: (Project) -> TaskResult) {
addTask(project, annotation.name, annotation.description, annotation.runBefore.toList(),
annotation.runAfter.toList(), annotation.alwaysRunAfter.toList(), task)
}
fun addTask(project: Project, name: String, description: String = "",
runBefore: List<String> = listOf<String>(),
runAfter: List<String> = listOf<String>(),
alwaysRunAfter: List<String> = listOf<String>(),
task: (Project) -> TaskResult) {
tasks.add(
object : BasePluginTask(this, name, description, project) {
override fun call(): TaskResult2<PluginTask> {
val taskResult = task(project)
return TaskResult2(taskResult.success, this)
}
})
runBefore.forEach { taskManager.runBefore(it, name) }
runAfter.forEach { taskManager.runBefore(name, it) }
alwaysRunAfter.forEach { taskManager.alwaysRunAfter(it, name)}
}
var taskManager : TaskManager
}

View file

@ -26,7 +26,7 @@ open public class Project(
@Directive open var packageName: String? = group,
val projectInfo: IProjectInfo) : IBuildConfig {
override var buildConfig = BuildConfig()
override var buildConfig : BuildConfig? = null //BuildConfig()
val testArgs = arrayListOf<String>()
val testJvmArgs = arrayListOf<String>()
@ -171,7 +171,7 @@ class BuildConfig {
}
interface IBuildConfig {
var buildConfig: BuildConfig
var buildConfig: BuildConfig?
fun buildConfig(init: BuildConfig.() -> Unit) {
buildConfig = BuildConfig().apply {
@ -181,7 +181,7 @@ interface IBuildConfig {
}
class ProductFlavorConfig(val name: String) : IBuildConfig {
override var buildConfig = BuildConfig()
override var buildConfig : BuildConfig? = BuildConfig()
}
@Directive
@ -199,7 +199,7 @@ class BuildTypeConfig(val project: Project?, val name: String) : IBuildConfig {
return Proguard(androidPlugin.androidHome(project)).getDefaultProguardFile(name)
}
override var buildConfig = BuildConfig()
override var buildConfig : BuildConfig? = BuildConfig()
}
@Directive

View file

@ -1,18 +1,21 @@
package com.beust.kobalt.internal
import com.beust.kobalt.*
import com.beust.kobalt.api.IPlugin
import com.beust.kobalt.api.PluginTask
import com.beust.kobalt.api.Project
import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.misc.log
import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.Multimap
import com.google.common.collect.TreeMultimap
import java.lang.reflect.Method
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
public class TaskManager @Inject constructor(val plugins: Plugins, val args: Args) {
public class TaskManager @Inject constructor(val args: Args) {
private val runBefore = TreeMultimap.create<String, String>()
private val alwaysRunAfter = TreeMultimap.create<String, String>()
@ -48,7 +51,7 @@ public class TaskManager @Inject constructor(val plugins: Plugins, val args: Arg
// 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>()
plugins.allTasks.filter {
tasks.filter {
it.project.name == project.name
}.forEach {
tasksByNames.put(it.name, it)
@ -211,6 +214,87 @@ public class TaskManager @Inject constructor(val plugins: Plugins, val args: Arg
return transitiveClosure
}
/////
// Manage the tasks
//
class StaticTask(val plugin: IPlugin, val method: Method, val taskAnnotation: Task)
class DynamicTask(val plugin: IPlugin, val name: String, val description: String,
val runBefore: List<String> = listOf<String>(),
val runAfter: List<String> = listOf<String>(),
val alwaysRunAfter: List<String> = listOf<String>(),
val closure: (Project) -> TaskResult)
val tasks = arrayListOf<PluginTask>()
val staticTasks = arrayListOf<StaticTask>()
val dynamicTasks = arrayListOf<DynamicTask>()
/**
* Turn all the static and dynamic tasks into plug-in tasks, which are then suitable to be executed.
*/
fun computePluginTasks(plugins: List<IPlugin>, projects: List<Project>) {
addStaticTasks(projects)
addDynamicTasks(projects)
}
private fun addDynamicTasks(projects: List<Project>) {
dynamicTasks.forEach { task ->
projects.filter { task.plugin.accept(it) }.forEach { project ->
addTask(task.plugin, project, task.name, task.description, task.runBefore, task.runAfter,
task.alwaysRunAfter, task.closure)
}
}
}
private fun addStaticTasks(projects: List<Project>) {
staticTasks.forEach { staticTask ->
val method = staticTask.method
val annotation = staticTask.taskAnnotation
val methodName = method.declaringClass.toString() + "." + method.name
log(3, " Found task:${annotation.name} method: $methodName")
fun toTask(m: Method, project: Project, plugin: IPlugin): (Project) -> TaskResult {
val result: (Project) -> TaskResult = {
m.invoke(plugin, project) as TaskResult
}
return result
}
val plugin = staticTask.plugin
projects.filter { plugin.accept(it) }.forEach { project ->
addStaticTask(plugin, project, staticTask.taskAnnotation, toTask(method, project, plugin))
}
}
}
private fun addStaticTask(plugin: IPlugin, project: Project, annotation: Task, task: (Project) -> TaskResult) {
addTask(plugin, project, annotation.name, annotation.description, annotation.runBefore.toList(),
annotation.runAfter.toList(), annotation.alwaysRunAfter.toList(), task)
}
fun addTask(plugin: IPlugin, project: Project, name: String, description: String = "",
runBefore: List<String> = listOf<String>(),
runAfter: List<String> = listOf<String>(),
alwaysRunAfter: List<String> = listOf<String>(),
task: (Project) -> TaskResult) {
tasks.add(
object : BasePluginTask(plugin, name, description, project) {
override fun call(): TaskResult2<PluginTask> {
val taskResult = task(project)
return TaskResult2(taskResult.success, this)
}
})
runBefore.forEach { runBefore(it, name) }
runAfter.forEach { runBefore(name, it) }
alwaysRunAfter.forEach { alwaysRunAfter(it, name)}
}
//
//
/////
}
class TaskWorker(val tasks: List<PluginTask>, val dryRun: Boolean) : IWorker<PluginTask> {

View file

@ -2,11 +2,10 @@ package com.beust.kobalt.internal.build
import com.beust.kobalt.KobaltException
import com.beust.kobalt.Plugins
import com.beust.kobalt.api.IPlugin
import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project
import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.internal.build.BuildFile
import com.beust.kobalt.internal.TaskManager
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.Topological
import com.beust.kobalt.misc.log
@ -20,7 +19,8 @@ import java.net.URLClassLoader
import java.util.*
import java.util.jar.JarInputStream
class BuildScriptUtil @Inject constructor(val plugins: Plugins, val files: KFiles){
class BuildScriptUtil @Inject constructor(val plugins: Plugins, val files: KFiles,
val taskManager: TaskManager) {
val projects = arrayListOf<Project>()
/**
@ -82,7 +82,8 @@ class BuildScriptUtil @Inject constructor(val plugins: Plugins, val files: KFile
} else {
val taskAnnotation = method.getAnnotation(Task::class.java)
if (taskAnnotation != null) {
Plugins.defaultPlugin.methodTasks.add(IPlugin.MethodTask(method, taskAnnotation))
taskManager.staticTasks.add(TaskManager.StaticTask(Plugins.defaultPlugin,
method, taskAnnotation))
}
}}