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

First pass for GroovyPlugin.

This commit is contained in:
Cedric Beust 2016-06-24 00:53:25 -08:00
parent 218fc5b292
commit a8b693b238
6 changed files with 119 additions and 19 deletions

View file

@ -0,0 +1,14 @@
package com.beust.kobalt.internal
fun <T> Collection<T>.doWhile(condition: (T) -> Boolean, action: (T) -> Unit) {
var i = 0
var done = false
while (i < size && ! done) {
elementAt(i).let { element ->
if (! condition(element)) done = true
else action(element)
}
i++
}
}

View file

@ -129,7 +129,7 @@ class DynamicGraphExecutor<T>(val graph : DynamicGraph<T>, val factory: IThreadW
val executor = Executors.newFixedThreadPool(5, NamedThreadFactory("DynamicGraphExecutor"))
val completion = ExecutorCompletionService<TaskResult2<T>>(executor)
fun run() : Int {
fun run() : TaskResult {
try {
return run2()
} finally {
@ -137,12 +137,12 @@ class DynamicGraphExecutor<T>(val graph : DynamicGraph<T>, val factory: IThreadW
}
}
private fun run2() : Int {
private fun run2() : TaskResult {
var running = 0
var gotError = false
val nodesRun = hashSetOf<T>()
var newFreeNodes = HashSet<T>(graph.freeNodes)
while (! gotError && (running > 0 || newFreeNodes.size > 0)) {
var failedResult: TaskResult? = null
val newFreeNodes = HashSet<T>(graph.freeNodes)
while (failedResult == null && (running > 0 || newFreeNodes.size > 0)) {
nodesRun.addAll(newFreeNodes)
val callables : List<IWorker<T>> = factory.createWorkers(newFreeNodes)
callables.forEach { completion.submit(it) }
@ -161,7 +161,9 @@ class DynamicGraphExecutor<T>(val graph : DynamicGraph<T>, val factory: IThreadW
} else {
log(2, "Task failed: $taskResult")
newFreeNodes.clear()
gotError = true
if (failedResult == null) {
failedResult = taskResult
}
}
} catch(ex: TimeoutException) {
log(2, "Time out")
@ -172,15 +174,15 @@ class DynamicGraphExecutor<T>(val graph : DynamicGraph<T>, val factory: IThreadW
throw (ex.cause as InvocationTargetException).targetException
} else {
error("Error: ${ite.cause?.message}", ite.cause)
gotError = true
failedResult = TaskResult(success = false, errorMessage = ite.cause?.message)
}
} else {
error("Error: ${ex.message}", ex)
gotError = true
failedResult = TaskResult(success = false, errorMessage = ex.message)
}
}
}
return if (gotError) 1 else 0
return if (failedResult != null) failedResult else TaskResult()
}
}

View file

@ -11,10 +11,7 @@ import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.maven.LocalRepo
import com.beust.kobalt.maven.Md5
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.KobaltExecutors
import com.beust.kobalt.misc.log
import com.beust.kobalt.misc.warn
import com.beust.kobalt.misc.*
import java.io.File
import java.util.*
import javax.inject.Inject
@ -180,12 +177,19 @@ open class JvmCompilerPlugin @Inject constructor(
// If this project has a kapt{} directive, we want to run the Java compiler first
val hasKapt = project.projectProperties.get("kaptConfig") != null
val finalAllCompilers = if (hasKapt) swapJavaAndKotlin(allCompilers) else allCompilers
finalAllCompilers.forEach { compiler ->
val allCompilersSorted = if (hasKapt) swapJavaAndKotlin(allCompilers) else allCompilers
var done = false
allCompilersSorted.doWhile({ ! done }) { compiler ->
val compilerResults = compilerUtils.invokeCompiler(project, context, compiler,
sourceDirectories(project, context), isTest)
results.addAll(compilerResults.successResults)
if (failedResult == null) failedResult = compilerResults.failedResult
compilerResults.failedResult?.let { failedResult ->
done = true
failedResult.errorMessage?.let { errorMessage ->
error(text = errorMessage)
}
}
}
return if (failedResult != null) failedResult!!

View file

@ -60,7 +60,7 @@ class TaskManager @Inject constructor(val args: Args,
fun matches(projectName: String) = project == null || project == projectName
}
class RunTargetResult(val exitCode: Int, val messages: List<String>)
class RunTargetResult(val taskResult: TaskResult, val messages: List<String>)
/**
* @return the list of tasks available for the given project.
@ -113,7 +113,7 @@ class TaskManager @Inject constructor(val args: Args,
}
private fun runProjects(taskInfos: List<TaskInfo>, projects: List<Project>) : RunTargetResult {
var result = 0
var result = TaskResult()
val failedProjects = hashSetOf<String>()
val messages = Collections.synchronizedList(arrayListOf<String>())
projects.forEach { project ->
@ -159,11 +159,11 @@ class TaskManager @Inject constructor(val args: Args,
val executor = DynamicGraphExecutor(graph, factory)
val thisResult = executor.run()
if (thisResult != 0) {
if (! thisResult.success) {
log(2, "Marking project ${project.name} as failed")
failedProjects.add(project.name)
}
if (result == 0) {
if (result.success) {
result = thisResult
}
}

View file

@ -0,0 +1,79 @@
package com.beust.kobalt.plugin.groovy
import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.*
import com.beust.kobalt.homeDir
import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.Strings
import com.beust.kobalt.misc.log
import com.beust.kobalt.misc.warn
import com.google.inject.Inject
import com.google.inject.Singleton
import java.io.File
import java.net.URLClassLoader
@Singleton
class GroovyPlugin @Inject constructor(val groovyCompiler: GroovyCompiler) : ICompilerContributor {
override fun affinity(project: Project, context: KobaltContext) =
if (hasSourceFiles(project)) 1 else 0
// ICompilerContributor
val compiler = object: ICompiler {
override val sourceSuffixes = GroovyCompiler.SUFFIXES
override val sourceDirectory = "groovy"
override val priority = 1
override fun compile(project: Project, context: KobaltContext, info: CompilerActionInfo): TaskResult {
val result =
if (info.sourceFiles.size > 0) {
groovyCompiler.compile(project, context, info)
} else {
warn("Couldn't find any source files to compile")
TaskResult()
}
return result
}
}
override fun compilersFor(project: Project, context: KobaltContext) = listOf(compiler)
private fun hasSourceFiles(project: Project)
= KFiles.findSourceFiles(project.directory, project.sourceDirectories, GroovyCompiler.SUFFIXES).size > 0
}
class GroovyCompiler @Inject constructor(dependencyManager: DependencyManager){
companion object {
val SUFFIXES = listOf("groovy")
val GROOVY_HOME = homeDir("java/groovy-2.4.7")
val GROOVYC = KFiles.joinDir(GROOVY_HOME, "bin/groovyc")
}
private val groovyCompilerClass: Class<*> by lazy {
val jarFile = dependencyManager.create("org.codehaus.groovy:groovy:2.4.7").jarFile.get()
val classLoader = URLClassLoader(arrayOf(jarFile.toURI().toURL()))
classLoader.loadClass("org.codehaus.groovy.tools.FileSystemCompiler")
}
private fun invokeGroovyCompiler(info: CompilerActionInfo) : TaskResult {
val cls = groovyCompilerClass
val main = cls.getMethod("commandLineCompile", Array<String>::class.java)
val classpath = info.dependencies.map { it.jarFile.get() }.joinToString(File.pathSeparator)
try {
main.invoke(null, arrayOf("-classpath", classpath, "-d", info.outputDir.path,
*info.sourceFiles.toTypedArray()))
return TaskResult()
} catch(ex: Exception) {
return TaskResult(success = false, errorMessage = ex.cause.toString())
}
}
fun compile(project: Project, context: KobaltContext, info: CompilerActionInfo): TaskResult {
val size = info.sourceFiles.size
log(1, "Groovy compiling " + size + " " + Strings.pluralize(size, "file"))
val result = invokeGroovyCompiler(info)
return result
}
}

View file

@ -13,6 +13,7 @@
<class-name>com.beust.kobalt.plugin.publish.PublishPlugin</class-name>
<class-name>com.beust.kobalt.plugin.apt.AptPlugin</class-name>
<class-name>com.beust.kobalt.internal.JvmCompilerPlugin</class-name>
<class-name>com.beust.kobalt.plugin.groovy.GroovyPlugin</class-name>
<!-- These classes manage -init for Java and Kotlin -->
<class-name>com.beust.kobalt.app.Templates</class-name>