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

First pass at introducing ITaskContributor.

This commit is contained in:
Cedric Beust 2015-12-04 17:23:36 -08:00
parent 8a850c22ce
commit 6656c3f503
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.IPlugin
import com.beust.kobalt.api.PluginTask import com.beust.kobalt.api.PluginTask
import com.beust.kobalt.api.Project 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, public abstract class BasePluginTask(override val plugin: IPlugin,
override val name: String, override val name: String,

View file

@ -178,18 +178,14 @@ private class Main @Inject constructor(
// List of tasks // List of tasks
// //
val sb = StringBuffer("List of tasks\n") val sb = StringBuffer("List of tasks\n")
Plugins.plugins.forEach { plugin -> taskManager.tasks.distinctBy {
if (plugin.tasks.size > 0) { it.name
sb.append("\n " + AsciiArt.horizontalDoubleLine +" ${plugin.name} " }.forEach { task ->
+ AsciiArt.horizontalDoubleLine + "\n") sb.append("\n " + AsciiArt.horizontalDoubleLine +" ${task.plugin.name} "
plugin.tasks.distinctBy { + AsciiArt.horizontalDoubleLine + "\n")
it.name sb.append(" ${task.name}\t\t${task.doc}\n")
}.forEach { task -> println(sb.toString())
sb.append(" ${task.name}\t\t${task.doc}\n")
}
}
} }
println(sb.toString())
} else if (args.checkVersions) { } else if (args.checkVersions) {
checkVersions.run(allProjects) checkVersions.run(allProjects)
} else if (args.download) { } 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.PluginInfo
import com.beust.kobalt.internal.TaskManager import com.beust.kobalt.internal.TaskManager
import com.beust.kobalt.maven.DepFactory import com.beust.kobalt.maven.DepFactory
import com.beust.kobalt.api.IClasspathDependency
import com.beust.kobalt.maven.LocalRepo import com.beust.kobalt.maven.LocalRepo
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.KobaltExecutors import com.beust.kobalt.misc.KobaltExecutors
@ -26,7 +25,8 @@ public class Plugins @Inject constructor (val taskManagerProvider : Provider<Tas
val depFactory: DepFactory, val depFactory: DepFactory,
val localRepo: LocalRepo, val localRepo: LocalRepo,
val executors: KobaltExecutors, val executors: KobaltExecutors,
val pluginInfo: PluginInfo) { val pluginInfo: PluginInfo,
val taskManager: TaskManager) {
companion object { companion object {
private var pluginMap = hashMapOf<String, IPlugin>() private var pluginMap = hashMapOf<String, IPlugin>()
@ -84,33 +84,15 @@ public class Plugins @Inject constructor (val taskManagerProvider : Provider<Tas
} }
val annotation = it.second val annotation = it.second
plugin.methodTasks.add(IPlugin.MethodTask(it.first, annotation)) taskManager.staticTasks.add(TaskManager.StaticTask(plugin, it.first, annotation))
} }
currentClass = currentClass.superclass 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 dependencies = arrayListOf<IClasspathDependency>()
val allTasks : List<PluginTask>
get() = Plugins.plugins.flatMap { it.tasks }
fun installPlugins(dependencies: List<IClasspathDependency>, classLoader: ClassLoader) { fun installPlugins(dependencies: List<IClasspathDependency>, classLoader: ClassLoader) {
val executor = executors.newExecutor("Plugins", 5) val executor = executors.newExecutor("Plugins", 5)
dependencies.forEach { dependencies.forEach {

View file

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

View file

@ -1,43 +1,10 @@
package com.beust.kobalt.api 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.TaskManager
import com.beust.kobalt.internal.TaskResult2
import java.lang.reflect.Method
import java.util.*
public interface IPlugin : IPluginActor { public interface IPlugin : IPluginActor {
val name: String val name: String
val tasks : ArrayList<PluginTask>
fun accept(project: Project) : Boolean fun accept(project: Project) : Boolean
fun apply(project: Project, context: KobaltContext) {} 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 var taskManager : TaskManager
} }

View file

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

View file

@ -1,18 +1,21 @@
package com.beust.kobalt.internal package com.beust.kobalt.internal
import com.beust.kobalt.* import com.beust.kobalt.*
import com.beust.kobalt.api.IPlugin
import com.beust.kobalt.api.PluginTask import com.beust.kobalt.api.PluginTask
import com.beust.kobalt.api.Project import com.beust.kobalt.api.Project
import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import com.google.common.collect.ArrayListMultimap import com.google.common.collect.ArrayListMultimap
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.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@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 runBefore = TreeMultimap.create<String, String>()
private val alwaysRunAfter = 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 // 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 = ArrayListMultimap.create<String, PluginTask>()
plugins.allTasks.filter { tasks.filter {
it.project.name == project.name it.project.name == project.name
}.forEach { }.forEach {
tasksByNames.put(it.name, it) tasksByNames.put(it.name, it)
@ -211,6 +214,87 @@ public class TaskManager @Inject constructor(val plugins: Plugins, val args: Arg
return transitiveClosure 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> { 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.KobaltException
import com.beust.kobalt.Plugins import com.beust.kobalt.Plugins
import com.beust.kobalt.api.IPlugin
import com.beust.kobalt.api.KobaltContext import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project import com.beust.kobalt.api.Project
import com.beust.kobalt.api.annotation.Task 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.KFiles
import com.beust.kobalt.misc.Topological import com.beust.kobalt.misc.Topological
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
@ -20,7 +19,8 @@ import java.net.URLClassLoader
import java.util.* import java.util.*
import java.util.jar.JarInputStream 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>() val projects = arrayListOf<Project>()
/** /**
@ -82,7 +82,8 @@ class BuildScriptUtil @Inject constructor(val plugins: Plugins, val files: KFile
} else { } else {
val taskAnnotation = method.getAnnotation(Task::class.java) val taskAnnotation = method.getAnnotation(Task::class.java)
if (taskAnnotation != null) { if (taskAnnotation != null) {
Plugins.defaultPlugin.methodTasks.add(IPlugin.MethodTask(method, taskAnnotation)) taskManager.staticTasks.add(TaskManager.StaticTask(Plugins.defaultPlugin,
method, taskAnnotation))
} }
}} }}