1
0
Fork 0
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:
Cedric Beust 2015-10-22 02:08:19 -07:00
parent 5a5b56e442
commit fae115ef91
7 changed files with 193 additions and 158 deletions

View file

@ -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.*

View file

@ -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")
}
}

View file

@ -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)
}
}

View file

@ -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()
} }

View 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")
}
}

View file

@ -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()}\"" + " }")
}

View file

@ -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