mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 08:27:12 -07:00
Support tasks in the IDEA plug-in.
This commit is contained in:
parent
1eeb34ca2a
commit
a6cb4c3314
7 changed files with 81 additions and 41 deletions
|
@ -340,6 +340,15 @@ class TaskManager @Inject constructor(val args: Args,
|
||||||
runAfter.forEach { runAfter(it, name) }
|
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
|
// Manage the tasks
|
||||||
/////
|
/////
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.beust.kobalt.internal.remote
|
package com.beust.kobalt.internal.remote
|
||||||
|
|
||||||
|
import com.beust.kobalt.api.Project
|
||||||
import com.google.gson.JsonObject
|
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
|
* Run this command based on the information received from the client. When done, use
|
||||||
* the sender object to send back a response.
|
* 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)
|
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.
|
* 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 {
|
interface ICommandSender {
|
||||||
fun sendData(commandData: CommandData)
|
fun sendData(commandData: CommandData)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.beust.kobalt.internal.remote
|
package com.beust.kobalt.internal.remote
|
||||||
|
|
||||||
|
import com.beust.kobalt.api.Project
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ import com.google.gson.JsonObject
|
||||||
class PingCommand() : ICommand {
|
class PingCommand() : ICommand {
|
||||||
override val name = "ping"
|
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()))))
|
sender.sendData(toCommandData(Gson().toJson(PingData(received.toString()))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,11 @@ private class Main @Inject constructor(
|
||||||
} else if (args.usage) {
|
} else if (args.usage) {
|
||||||
jc.usage()
|
jc.usage()
|
||||||
} else if (args.serverMode) {
|
} 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 {
|
} else {
|
||||||
// Options that don't need Build.kt to be parsed first
|
// Options that don't need Build.kt to be parsed first
|
||||||
if (args.gc) {
|
if (args.gc) {
|
||||||
|
@ -172,37 +176,8 @@ private class Main @Inject constructor(
|
||||||
if (!buildFile.exists()) {
|
if (!buildFile.exists()) {
|
||||||
error(buildFile.path.toFile().path + " does not exist")
|
error(buildFile.path.toFile().path + " does not exist")
|
||||||
} else {
|
} 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
|
val allProjects = initForBuildFile(buildFile, args)
|
||||||
|
|
||||||
//
|
|
||||||
// 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)
|
|
||||||
|
|
||||||
// DONOTCOMMIT
|
// DONOTCOMMIT
|
||||||
// val data = dependencyData.dependenciesDataFor(homeDir("kotlin/klaxon/kobalt/src/Build.kt"), Args())
|
// val data = dependencyData.dependenciesDataFor(homeDir("kotlin/klaxon/kobalt/src/Build.kt"), Args())
|
||||||
|
@ -245,6 +220,47 @@ private class Main @Inject constructor(
|
||||||
return result
|
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() {
|
private fun displayTasks() {
|
||||||
//
|
//
|
||||||
// List of tasks, --tasks
|
// List of tasks, --tasks
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.beust.kobalt.app.remote
|
package com.beust.kobalt.app.remote
|
||||||
|
|
||||||
import com.beust.kobalt.Args
|
import com.beust.kobalt.Args
|
||||||
|
import com.beust.kobalt.api.Project
|
||||||
import com.beust.kobalt.internal.remote.ICommand
|
import com.beust.kobalt.internal.remote.ICommand
|
||||||
import com.beust.kobalt.internal.remote.ICommandSender
|
import com.beust.kobalt.internal.remote.ICommandSender
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
@ -17,8 +18,9 @@ class GetDependenciesCommand @Inject constructor(val args: Args, val dependencyD
|
||||||
|
|
||||||
override val name = "getDependencies"
|
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 buildFile = received.get("buildFile").asString
|
||||||
|
val projects = initCallback(buildFile)
|
||||||
val dd = dependencyData.dependenciesDataFor(buildFile, args)
|
val dd = dependencyData.dependenciesDataFor(buildFile, args)
|
||||||
val data = toCommandData(Gson().toJson(dd), dd.errorMessage)
|
val data = toCommandData(Gson().toJson(dd), dd.errorMessage)
|
||||||
sender.sendData(data)
|
sender.sendData(data)
|
||||||
|
|
|
@ -36,7 +36,7 @@ class ServerProcess {
|
||||||
var port = launchPrivate()
|
var port = launchPrivate()
|
||||||
while (port == 0) {
|
while (port == 0) {
|
||||||
executor.submit {
|
executor.submit {
|
||||||
KobaltServer(force = true, shutdownCallback = {}).call()
|
KobaltServer(force = true, initCallback = { buildFile -> emptyList()}, cleanUpCallback = {}).call()
|
||||||
}
|
}
|
||||||
// launchServer(ProcessUtil.findAvailablePort())
|
// launchServer(ProcessUtil.findAvailablePort())
|
||||||
port = launchPrivate()
|
port = launchPrivate()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.beust.kobalt.app.remote
|
package com.beust.kobalt.app.remote
|
||||||
|
|
||||||
import com.beust.kobalt.api.Kobalt
|
import com.beust.kobalt.api.Kobalt
|
||||||
|
import com.beust.kobalt.api.Project
|
||||||
import com.beust.kobalt.homeDir
|
import com.beust.kobalt.homeDir
|
||||||
import com.beust.kobalt.internal.remote.CommandData
|
import com.beust.kobalt.internal.remote.CommandData
|
||||||
import com.beust.kobalt.internal.remote.ICommandSender
|
import com.beust.kobalt.internal.remote.ICommandSender
|
||||||
|
@ -17,7 +18,16 @@ import java.net.SocketException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.Callable
|
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
|
// var outgoing: PrintWriter? = null
|
||||||
val pending = arrayListOf<CommandData>()
|
val pending = arrayListOf<CommandData>()
|
||||||
|
|
||||||
|
@ -110,13 +120,13 @@ class KobaltServer(val force: Boolean, val shutdownCallback: () -> Unit) : Calla
|
||||||
log(1, "Quitting")
|
log(1, "Quitting")
|
||||||
quit = true
|
quit = true
|
||||||
} else {
|
} else {
|
||||||
runCommand(jo)
|
runCommand(jo, initCallback)
|
||||||
|
|
||||||
// Done, send a quit to the client
|
// Done, send a quit to the client
|
||||||
sendData(CommandData("quit", ""))
|
sendData(CommandData("quit", ""))
|
||||||
|
|
||||||
// Clean up all the plug-in actors
|
// Clean up all the plug-in actors
|
||||||
shutdownCallback()
|
cleanUpCallback()
|
||||||
line = serverInfo.reader.readLine()
|
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
|
val command = jo.get("name").asString
|
||||||
if (command != null) {
|
if (command != null) {
|
||||||
(COMMANDS[command] ?: COMMANDS["ping"])!!.run(this, jo)
|
(COMMANDS[command] ?: COMMANDS["ping"])!!.run(this, jo, initCallback)
|
||||||
} else {
|
} else {
|
||||||
error("Did not find a name in command: $jo")
|
error("Did not find a name in command: $jo")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue