mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 08:27:12 -07:00
Move commands in their own class files.
This commit is contained in:
parent
5a5b56e442
commit
fae115ef91
7 changed files with 193 additions and 158 deletions
|
@ -5,6 +5,8 @@ import com.beust.kobalt.api.Kobalt
|
||||||
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.internal.*
|
import com.beust.kobalt.internal.*
|
||||||
|
import com.beust.kobalt.internal.remote.KobaltClient
|
||||||
|
import com.beust.kobalt.internal.remote.KobaltServer
|
||||||
import com.beust.kobalt.kotlin.BuildFile
|
import com.beust.kobalt.kotlin.BuildFile
|
||||||
import com.beust.kobalt.maven.*
|
import com.beust.kobalt.maven.*
|
||||||
import com.beust.kobalt.misc.*
|
import com.beust.kobalt.misc.*
|
||||||
|
|
|
@ -1,155 +0,0 @@
|
||||||
package com.beust.kobalt.internal
|
|
||||||
|
|
||||||
import com.beust.kobalt.Args
|
|
||||||
import com.beust.kobalt.kotlin.BuildFile
|
|
||||||
import com.beust.kobalt.kotlin.BuildFileCompiler
|
|
||||||
import com.beust.kobalt.maven.IClasspathDependency
|
|
||||||
import com.beust.kobalt.maven.MavenDependency
|
|
||||||
import com.beust.kobalt.misc.KobaltExecutors
|
|
||||||
import com.beust.kobalt.misc.log
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import com.google.gson.JsonParser
|
|
||||||
import com.google.inject.Inject
|
|
||||||
import java.io.BufferedReader
|
|
||||||
import java.io.InputStreamReader
|
|
||||||
import java.io.PrintWriter
|
|
||||||
import java.net.ServerSocket
|
|
||||||
import java.net.SocketException
|
|
||||||
import java.nio.file.Paths
|
|
||||||
|
|
||||||
public class KobaltServer @Inject constructor(val args: Args, val executors: KobaltExecutors,
|
|
||||||
val buildFileCompilerFactory: BuildFileCompiler.IFactory) : Runnable {
|
|
||||||
var outgoing: PrintWriter? = null
|
|
||||||
val pending = arrayListOf<String>()
|
|
||||||
|
|
||||||
override fun run() {
|
|
||||||
val portNumber = args.port
|
|
||||||
|
|
||||||
log1("Listening to port $portNumber")
|
|
||||||
var quit = false
|
|
||||||
val serverSocket = ServerSocket(portNumber)
|
|
||||||
while (! quit) {
|
|
||||||
val clientSocket = serverSocket.accept()
|
|
||||||
outgoing = PrintWriter(clientSocket.outputStream, true)
|
|
||||||
if (pending.size() > 0) {
|
|
||||||
log1("Emptying the queue, size $pending.size()")
|
|
||||||
synchronized(pending) {
|
|
||||||
pending.forEach { sendData(it) }
|
|
||||||
pending.clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val ins = BufferedReader(InputStreamReader(clientSocket.inputStream))
|
|
||||||
try {
|
|
||||||
var line = ins.readLine()
|
|
||||||
while (!quit && line != null) {
|
|
||||||
log1("Received from client $line")
|
|
||||||
val jo = JsonParser().parse(line) as JsonObject
|
|
||||||
if ("Quit" == jo.get("name").asString) {
|
|
||||||
log1("Quitting")
|
|
||||||
quit = true
|
|
||||||
} else {
|
|
||||||
runCommand(jo)
|
|
||||||
line = ins.readLine()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch(ex: SocketException) {
|
|
||||||
log1("Client disconnected, resetting")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Command {
|
|
||||||
fun run(jo: JsonObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
class CommandData(val commandName: String, val data: String)
|
|
||||||
|
|
||||||
inner class PingCommand() : Command {
|
|
||||||
override fun run(jo: JsonObject) = sendData("{ \"response\" : \"${jo.toString()}\" }")
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class GetDependenciesCommand() : Command {
|
|
||||||
override fun run(jo: JsonObject) {
|
|
||||||
val buildFile = BuildFile(Paths.get(jo.get("buildFile").asString), "GetDependenciesCommand")
|
|
||||||
val scriptCompiler = buildFileCompilerFactory.create(listOf(buildFile))
|
|
||||||
scriptCompiler.observable.subscribe {
|
|
||||||
buildScriptInfo -> if (buildScriptInfo.projects.size() > 0) {
|
|
||||||
sendData(toJson(buildScriptInfo))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scriptCompiler.compileBuildFiles(args)
|
|
||||||
sendData("{ \"name\": \"Quit\" }")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DependencyData(val id: String, val scope: String, val path: String)
|
|
||||||
|
|
||||||
class ProjectData( val name: String, val dependencies: List<DependencyData>)
|
|
||||||
|
|
||||||
class GetDependenciesData(val projects: List<ProjectData>) {
|
|
||||||
fun toData() : CommandData {
|
|
||||||
val data = Gson().toJson(this)
|
|
||||||
return CommandData("GetDependencies", data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toJson(info: BuildFileCompiler.BuildScriptInfo) : String {
|
|
||||||
val executor = executors.miscExecutor
|
|
||||||
val projects = arrayListOf<ProjectData>()
|
|
||||||
|
|
||||||
fun toDependencyData(d: IClasspathDependency, scope: String) : DependencyData {
|
|
||||||
val dep = MavenDependency.create(d.id, executor)
|
|
||||||
return DependencyData(d.id, scope, dep.jarFile.get().absolutePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
info.projects.forEach { project ->
|
|
||||||
val allDependencies =
|
|
||||||
project.compileDependencies.map { toDependencyData(it, "compile") } +
|
|
||||||
project.compileProvidedDependencies.map { toDependencyData(it, "provided") } +
|
|
||||||
project.compileRuntimeDependencies.map { toDependencyData(it, "runtime") } +
|
|
||||||
project.testDependencies.map { toDependencyData(it, "testCompile") } +
|
|
||||||
project.testProvidedDependencies.map { toDependencyData(it, "testProvided") }
|
|
||||||
|
|
||||||
projects.add(ProjectData(project.name!!, allDependencies))
|
|
||||||
}
|
|
||||||
log1("Returning BuildScriptInfo")
|
|
||||||
val result = Gson().toJson(GetDependenciesData(projects).toData())
|
|
||||||
log2(" $result")
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private val COMMANDS = hashMapOf<String, Command>(
|
|
||||||
Pair("GetDependencies", GetDependenciesCommand())
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun runCommand(jo: JsonObject) {
|
|
||||||
val command = jo.get("name").asString
|
|
||||||
if (command != null) {
|
|
||||||
COMMANDS.getOrElse(command, { PingCommand() }).run(jo)
|
|
||||||
} else {
|
|
||||||
error("Did not find a name in command: $jo")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun sendData(info: String) {
|
|
||||||
if (outgoing != null) {
|
|
||||||
outgoing!!.println(info)
|
|
||||||
} else {
|
|
||||||
log1("Queuing $info")
|
|
||||||
synchronized(pending) {
|
|
||||||
pending.add(info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun log1(s: String) {
|
|
||||||
log(1, "[KobaltServer] $s")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun log2(s: String) {
|
|
||||||
log(2, "[KobaltServer] $s")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.beust.kobalt.internal.remote
|
||||||
|
|
||||||
|
import com.beust.kobalt.Args
|
||||||
|
import com.beust.kobalt.kotlin.BuildFile
|
||||||
|
import com.beust.kobalt.kotlin.BuildFileCompiler
|
||||||
|
import com.beust.kobalt.maven.IClasspathDependency
|
||||||
|
import com.beust.kobalt.maven.MavenDependency
|
||||||
|
import com.beust.kobalt.misc.KobaltExecutors
|
||||||
|
import com.beust.kobalt.misc.log
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import com.google.inject.Inject
|
||||||
|
import java.nio.file.Paths
|
||||||
|
|
||||||
|
class GetDependenciesCommand @Inject constructor(val executors: KobaltExecutors,
|
||||||
|
val buildFileCompilerFactory: BuildFileCompiler.IFactory, val args: Args) : ICommand {
|
||||||
|
override val name = "getDependencies"
|
||||||
|
override fun run(sender: ICommandSender, received: JsonObject) {
|
||||||
|
val buildFile = BuildFile(Paths.get(received.get("buildFile").asString), "GetDependenciesCommand")
|
||||||
|
val scriptCompiler = buildFileCompilerFactory.create(listOf(buildFile))
|
||||||
|
scriptCompiler.observable.subscribe {
|
||||||
|
buildScriptInfo -> if (buildScriptInfo.projects.size() > 0) {
|
||||||
|
sender.sendData(toJson(buildScriptInfo))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scriptCompiler.compileBuildFiles(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toJson(info: BuildFileCompiler.BuildScriptInfo) : String {
|
||||||
|
val executor = executors.miscExecutor
|
||||||
|
val projects = arrayListOf<ProjectData>()
|
||||||
|
|
||||||
|
fun toDependencyData(d: IClasspathDependency, scope: String) : DependencyData {
|
||||||
|
val dep = MavenDependency.create(d.id, executor)
|
||||||
|
return DependencyData(d.id, scope, dep.jarFile.get().absolutePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
info.projects.forEach { project ->
|
||||||
|
val allDependencies =
|
||||||
|
project.compileDependencies.map { toDependencyData(it, "compile") } +
|
||||||
|
project.compileProvidedDependencies.map { toDependencyData(it, "provided") } +
|
||||||
|
project.compileRuntimeDependencies.map { toDependencyData(it, "runtime") } +
|
||||||
|
project.testDependencies.map { toDependencyData(it, "testCompile") } +
|
||||||
|
project.testProvidedDependencies.map { toDependencyData(it, "testProvided") }
|
||||||
|
|
||||||
|
projects.add(ProjectData(project.name!!, allDependencies))
|
||||||
|
}
|
||||||
|
log(1, "Returning BuildScriptInfo")
|
||||||
|
val result = Gson().toJson(GetDependenciesData(projects).toData())
|
||||||
|
log(2, " $result")
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DependencyData(val id: String, val scope: String, val path: String)
|
||||||
|
|
||||||
|
class ProjectData( val name: String, val dependencies: List<DependencyData>)
|
||||||
|
|
||||||
|
class GetDependenciesData(val projects: List<ProjectData>) {
|
||||||
|
fun toData() : CommandData {
|
||||||
|
val data = Gson().toJson(this)
|
||||||
|
return CommandData("getDependencies", data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.beust.kobalt.internal
|
package com.beust.kobalt.internal.remote
|
||||||
|
|
||||||
import com.beust.kobalt.Args
|
import com.beust.kobalt.Args
|
||||||
import com.beust.kobalt.SystemProperties
|
import com.beust.kobalt.SystemProperties
|
||||||
|
@ -47,7 +47,7 @@ public class KobaltClient @Inject constructor() : Runnable {
|
||||||
done = true
|
done = true
|
||||||
} else {
|
} else {
|
||||||
val data = jo.get("data").asString
|
val data = jo.get("data").asString
|
||||||
val dd = Gson().fromJson(data, KobaltServer.GetDependenciesData::class.java)
|
val dd = Gson().fromJson(data, GetDependenciesData::class.java)
|
||||||
println("Read GetDependencyData, project count: ${dd.projects.size()}")
|
println("Read GetDependencyData, project count: ${dd.projects.size()}")
|
||||||
line = ins.readLine()
|
line = ins.readLine()
|
||||||
}
|
}
|
112
src/main/kotlin/com/beust/kobalt/internal/remote/KobaltServer.kt
Normal file
112
src/main/kotlin/com/beust/kobalt/internal/remote/KobaltServer.kt
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
package com.beust.kobalt.internal.remote
|
||||||
|
|
||||||
|
import com.beust.kobalt.Args
|
||||||
|
import com.beust.kobalt.api.Kobalt
|
||||||
|
import com.beust.kobalt.misc.log
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import com.google.gson.JsonParser
|
||||||
|
import com.google.inject.Inject
|
||||||
|
import com.google.inject.Singleton
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.io.PrintWriter
|
||||||
|
import java.net.ServerSocket
|
||||||
|
import java.net.SocketException
|
||||||
|
|
||||||
|
interface ICommandSender {
|
||||||
|
fun sendData(content: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICommand {
|
||||||
|
val name: String
|
||||||
|
fun run(sender: ICommandSender, received: JsonObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
class CommandData(val commandName: String, val data: String)
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class KobaltServer @Inject constructor(val args: Args) : Runnable, ICommandSender {
|
||||||
|
var outgoing: PrintWriter? = null
|
||||||
|
val pending = arrayListOf<String>()
|
||||||
|
|
||||||
|
private val COMMAND_CLASSES = listOf(GetDependenciesCommand::class.java, PingCommand::class.java)
|
||||||
|
|
||||||
|
private val COMMANDS = hashMapOf<String, ICommand>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
COMMAND_CLASSES.forEach {
|
||||||
|
val c = Kobalt.INJECTOR.getInstance(it)
|
||||||
|
COMMANDS.put(c.name, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
val portNumber = args.port
|
||||||
|
|
||||||
|
log1("Listening to port $portNumber")
|
||||||
|
var quit = false
|
||||||
|
val serverSocket = ServerSocket(portNumber)
|
||||||
|
while (! quit) {
|
||||||
|
val clientSocket = serverSocket.accept()
|
||||||
|
outgoing = PrintWriter(clientSocket.outputStream, true)
|
||||||
|
if (pending.size() > 0) {
|
||||||
|
log1("Emptying the queue, size $pending.size()")
|
||||||
|
synchronized(pending) {
|
||||||
|
pending.forEach { sendData(it) }
|
||||||
|
pending.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val ins = BufferedReader(InputStreamReader(clientSocket.inputStream))
|
||||||
|
try {
|
||||||
|
var line = ins.readLine()
|
||||||
|
while (!quit && line != null) {
|
||||||
|
log1("Received from client $line")
|
||||||
|
val jo = JsonParser().parse(line) as JsonObject
|
||||||
|
if ("Quit" == jo.get("name").asString) {
|
||||||
|
log1("Quitting")
|
||||||
|
quit = true
|
||||||
|
} else {
|
||||||
|
runCommand(jo)
|
||||||
|
|
||||||
|
// Done, send a quit to the client
|
||||||
|
sendData("{ \"name\": \"Quit\" }")
|
||||||
|
|
||||||
|
line = ins.readLine()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(ex: SocketException) {
|
||||||
|
log1("Client disconnected, resetting")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runCommand(jo: JsonObject) {
|
||||||
|
val command = jo.get("name").asString
|
||||||
|
if (command != null) {
|
||||||
|
COMMANDS.getOrElse(command, { PingCommand() }).run(this, jo)
|
||||||
|
} else {
|
||||||
|
error("Did not find a name in command: $jo")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun sendData(info: String) {
|
||||||
|
if (outgoing != null) {
|
||||||
|
outgoing!!.println(info)
|
||||||
|
} else {
|
||||||
|
log1("Queuing $info")
|
||||||
|
synchronized(pending) {
|
||||||
|
pending.add(info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun log1(s: String) {
|
||||||
|
log(1, "[KobaltServer] $s")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun log2(s: String) {
|
||||||
|
log(2, "[KobaltServer] $s")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.beust.kobalt.internal.remote
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
|
||||||
|
class PingCommand() : ICommand {
|
||||||
|
override val name = "ping"
|
||||||
|
override fun run(sender: ICommandSender, received: JsonObject) =
|
||||||
|
sender.sendData("{ \"response\" : \"${received.toString()}\"" + " }")
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.beust.kobalt.api.KobaltContext
|
||||||
import com.beust.kobalt.api.Plugin
|
import com.beust.kobalt.api.Plugin
|
||||||
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.KobaltServer
|
import com.beust.kobalt.internal.remote.KobaltServer
|
||||||
import com.beust.kobalt.maven.KobaltException
|
import com.beust.kobalt.maven.KobaltException
|
||||||
import com.beust.kobalt.misc.*
|
import com.beust.kobalt.misc.*
|
||||||
import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate
|
import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue