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

Support tasks in the IDEA plug-in.

This commit is contained in:
Cedric Beust 2016-04-25 22:09:11 -08:00
parent 1eeb34ca2a
commit a6cb4c3314
7 changed files with 81 additions and 41 deletions

View file

@ -340,6 +340,15 @@ class TaskManager @Inject constructor(val args: Args,
runAfter.forEach { runAfter(it, name) }
}
/**
* Invoked by the server whenever it's done processing a command so the state can be reset for the next command.
*/
private fun cleanUp() {
annotationTasks.clear()
dynamicTasks.clear()
taskAnnotations.clear()
}
//
// Manage the tasks
/////

View file

@ -1,5 +1,6 @@
package com.beust.kobalt.internal.remote
import com.beust.kobalt.api.Project
import com.google.gson.JsonObject
/**
@ -14,15 +15,16 @@ interface ICommand {
/**
* Run this command based on the information received from the client. When done, use
* the sender object to send back a response.
* @param initCallback The string is a path to the build file
*/
fun run(sender: ICommandSender, received: JsonObject)
fun run(sender: ICommandSender, received: JsonObject, initCallback: (String) -> List<Project>)
fun toCommandData(data: String, error: String? = null) = CommandData(name, data, error)
}
/**
* Passed to a command in its `run` method so it can send information back to the caller.
* @param The string content that will be sent in the "data" field.
* @param commandData The string content that will be sent in the "data" field.
*/
interface ICommandSender {
fun sendData(commandData: CommandData)

View file

@ -1,5 +1,6 @@
package com.beust.kobalt.internal.remote
import com.beust.kobalt.api.Project
import com.google.gson.Gson
import com.google.gson.JsonObject
@ -14,7 +15,7 @@ import com.google.gson.JsonObject
class PingCommand() : ICommand {
override val name = "ping"
override fun run(sender: ICommandSender, received: JsonObject) {
override fun run(sender: ICommandSender, received: JsonObject, initCallback: (String) -> List<Project>) {
sender.sendData(toCommandData(Gson().toJson(PingData(received.toString()))))
}

View file

@ -157,7 +157,11 @@ private class Main @Inject constructor(
} else if (args.usage) {
jc.usage()
} else if (args.serverMode) {
val port = KobaltServer(args.force, { pluginInfo.shutdown()}).call()
// --server
val port = KobaltServer(args.force,
{ buildFile -> initForBuildFile(BuildFile(Paths.get(buildFile), buildFile), args)},
{ cleanUp() })
.call()
} else {
// Options that don't need Build.kt to be parsed first
if (args.gc) {
@ -172,37 +176,8 @@ private class Main @Inject constructor(
if (!buildFile.exists()) {
error(buildFile.path.toFile().path + " does not exist")
} else {
val findProjectResult = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo)
.compileBuildFiles(args)
if (! findProjectResult.taskResult.success) {
throw KobaltException("Couldn't compile build file: "
+ findProjectResult.taskResult.errorMessage)
}
val allProjects = findProjectResult.projects
//
// Now that we have projects, add all the repos from repo contributors that need a Project
//
allProjects.forEach { project ->
pluginInfo.repoContributors.forEach {
it.reposFor(project).forEach {
Kobalt.addRepo(it)
}
}
}
//
// Run all the dependencies through the IDependencyInterceptors
//
runClasspathInterceptors(allProjects)
log(2, "Final list of repos:\n " + Kobalt.repos.joinToString("\n "))
//
// Call apply() on all plug-ins now that the repos are set up
//
plugins.applyPlugins(Kobalt.context!!, allProjects)
val allProjects = initForBuildFile(buildFile, args)
// DONOTCOMMIT
// val data = dependencyData.dependenciesDataFor(homeDir("kotlin/klaxon/kobalt/src/Build.kt"), Args())
@ -245,6 +220,47 @@ private class Main @Inject constructor(
return result
}
private fun cleanUp() {
pluginInfo.shutdown()
taskManager.shutdown()
}
private fun initForBuildFile(buildFile: BuildFile, args: Args): List<Project> {
val findProjectResult = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo)
.compileBuildFiles(args)
if (! findProjectResult.taskResult.success) {
throw KobaltException("Couldn't compile build file: "
+ findProjectResult.taskResult.errorMessage)
}
val allProjects = findProjectResult.projects
//
// Now that we have projects, add all the repos from repo contributors that need a Project
//
allProjects.forEach { project ->
pluginInfo.repoContributors.forEach {
it.reposFor(project).forEach {
Kobalt.addRepo(it)
}
}
}
//
// Run all the dependencies through the IDependencyInterceptors
//
runClasspathInterceptors(allProjects)
log(2, "Final list of repos:\n " + Kobalt.repos.joinToString("\n "))
//
// Call apply() on all plug-ins now that the repos are set up
//
plugins.applyPlugins(Kobalt.context!!, allProjects)
return allProjects
}
private fun displayTasks() {
//
// List of tasks, --tasks

View file

@ -1,6 +1,7 @@
package com.beust.kobalt.app.remote
import com.beust.kobalt.Args
import com.beust.kobalt.api.Project
import com.beust.kobalt.internal.remote.ICommand
import com.beust.kobalt.internal.remote.ICommandSender
import com.google.gson.Gson
@ -17,8 +18,9 @@ class GetDependenciesCommand @Inject constructor(val args: Args, val dependencyD
override val name = "getDependencies"
override fun run(sender: ICommandSender, received: JsonObject) {
override fun run(sender: ICommandSender, received: JsonObject, initCallback: (String) -> List<Project>) {
val buildFile = received.get("buildFile").asString
val projects = initCallback(buildFile)
val dd = dependencyData.dependenciesDataFor(buildFile, args)
val data = toCommandData(Gson().toJson(dd), dd.errorMessage)
sender.sendData(data)

View file

@ -36,7 +36,7 @@ class ServerProcess {
var port = launchPrivate()
while (port == 0) {
executor.submit {
KobaltServer(force = true, shutdownCallback = {}).call()
KobaltServer(force = true, initCallback = { buildFile -> emptyList()}, cleanUpCallback = {}).call()
}
// launchServer(ProcessUtil.findAvailablePort())
port = launchPrivate()

View file

@ -1,6 +1,7 @@
package com.beust.kobalt.app.remote
import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.Project
import com.beust.kobalt.homeDir
import com.beust.kobalt.internal.remote.CommandData
import com.beust.kobalt.internal.remote.ICommandSender
@ -17,7 +18,16 @@ import java.net.SocketException
import java.util.*
import java.util.concurrent.Callable
class KobaltServer(val force: Boolean, val shutdownCallback: () -> Unit) : Callable<Int>, ICommandSender {
/**
* Launch a Kobalt server. If @param{force} is specified, a new server will be launched even if one was detected
* to be already running (from the ~/.kobalt/kobaltServer.properties file).
*
* The callbacks are used to initialize and clean up the state before and after each command, so that Kobalt's state
* can be properly reset, making the server reentrant.
*/
class KobaltServer(val force: Boolean,
val initCallback: (String) -> List<Project>,
val cleanUpCallback: () -> Unit) : Callable<Int>, ICommandSender {
// var outgoing: PrintWriter? = null
val pending = arrayListOf<CommandData>()
@ -110,13 +120,13 @@ class KobaltServer(val force: Boolean, val shutdownCallback: () -> Unit) : Calla
log(1, "Quitting")
quit = true
} else {
runCommand(jo)
runCommand(jo, initCallback)
// Done, send a quit to the client
sendData(CommandData("quit", ""))
// Clean up all the plug-in actors
shutdownCallback()
cleanUpCallback()
line = serverInfo.reader.readLine()
}
}
@ -137,10 +147,10 @@ class KobaltServer(val force: Boolean, val shutdownCallback: () -> Unit) : Calla
}
}
private fun runCommand(jo: JsonObject) {
private fun runCommand(jo: JsonObject, initCallback: (String) -> List<Project>) {
val command = jo.get("name").asString
if (command != null) {
(COMMANDS[command] ?: COMMANDS["ping"])!!.run(this, jo)
(COMMANDS[command] ?: COMMANDS["ping"])!!.run(this, jo, initCallback)
} else {
error("Did not find a name in command: $jo")
}