mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
Gradle Service refactor
This commit is contained in:
@@ -10,7 +10,6 @@ import kotlin.time.TimeSource
|
||||
|
||||
class Debugger {
|
||||
companion object {
|
||||
// TODO: Stop if build has failed
|
||||
suspend fun connect(port: Int?): VirtualMachine? {
|
||||
try {
|
||||
Messages.log("Attaching to VM $port")
|
||||
|
||||
@@ -17,14 +17,29 @@ import org.gradle.tooling.events.problems.internal.DefaultSingleProblemEvent
|
||||
import org.gradle.tooling.events.task.TaskFinishEvent
|
||||
import org.gradle.tooling.events.task.TaskStartEvent
|
||||
import org.gradle.tooling.events.task.TaskSuccessResult
|
||||
import processing.app.Base
|
||||
import processing.app.Base.DEBUG
|
||||
import processing.app.Base.getSketchbookFolder
|
||||
import processing.app.Base.getVersionName
|
||||
import processing.app.Language.text
|
||||
import processing.app.Messages
|
||||
import processing.app.Platform
|
||||
import processing.app.Platform.getContentFile
|
||||
import processing.app.Platform.getSettingsFolder
|
||||
import processing.app.Sketch
|
||||
import processing.app.gradle.Log.Companion.startLogServer
|
||||
import processing.app.ui.Editor
|
||||
import processing.app.ui.EditorStatus
|
||||
import java.io.PrintStream
|
||||
import java.net.ServerSocket
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.deleteIfExists
|
||||
import kotlin.io.path.writeText
|
||||
|
||||
class GradleJob{
|
||||
// Starts a gradle job to run the sketch
|
||||
class GradleJob(
|
||||
vararg val tasks: String,
|
||||
val workingDir: Path,
|
||||
val sketch: Sketch,
|
||||
val editor: Editor? = null,
|
||||
){
|
||||
enum class State{
|
||||
NONE,
|
||||
BUILDING,
|
||||
@@ -33,8 +48,9 @@ class GradleJob{
|
||||
DONE
|
||||
}
|
||||
|
||||
var service: GradleService? = null
|
||||
var configure: BuildLauncher.() -> Unit = {}
|
||||
val debugPort = (30_000..60_000).random()
|
||||
val logPort = debugPort + 1
|
||||
val errPort = logPort + 1
|
||||
|
||||
val state = mutableStateOf(State.NONE)
|
||||
val vm = mutableStateOf<VirtualMachine?>(null)
|
||||
@@ -44,70 +60,177 @@ class GradleJob{
|
||||
private val scope = CoroutineScope(Dispatchers.IO)
|
||||
private val cancel = GradleConnector.newCancellationTokenSource()
|
||||
|
||||
fun start() {
|
||||
val folder = service?.sketch?.folder ?: throw IllegalStateException("Sketch folder is not set")
|
||||
launchJob {
|
||||
try {
|
||||
state.value = State.BUILDING
|
||||
service?.editor?.statusMessage("Connecting to Gradle", EditorStatus.NOTICE)
|
||||
|
||||
// All the configuration for the gradle build
|
||||
private fun BuildLauncher.setupGradle(extraArguments: List<String> = listOf()) {
|
||||
val copy = sketch.isReadOnly || sketch.isUntitled
|
||||
|
||||
val sketchFolder = if(copy) workingDir.resolve("sketch").toFile() else sketch.folder
|
||||
|
||||
if(copy){
|
||||
// If the sketch is read-only, we copy it to the working directory
|
||||
// This allows us to run the sketch without modifying the original files
|
||||
sketch.folder.copyRecursively(sketchFolder, overwrite = true)
|
||||
}
|
||||
// Save the unsaved code into the working directory for gradle to compile
|
||||
val unsaved = sketch.code
|
||||
.map { code ->
|
||||
val file = workingDir.resolve("unsaved/${code.fileName}")
|
||||
file.parent.toFile().mkdirs()
|
||||
// If tab is marked modified save it to the working directory
|
||||
// Otherwise delete the file so we don't compile with old code
|
||||
if(code.isModified){
|
||||
file.writeText(code.documentText)
|
||||
}else{
|
||||
file.deleteIfExists()
|
||||
}
|
||||
return@map code.fileName
|
||||
}
|
||||
// Collect the variables to pass to gradle
|
||||
val variables = mapOf(
|
||||
"group" to System.getProperty("processing.group", "org.processing"),
|
||||
"version" to getVersionName(),
|
||||
"sketchFolder" to sketchFolder,
|
||||
"sketchbook" to getSketchbookFolder(),
|
||||
"workingDir" to workingDir.toAbsolutePath().toString(),
|
||||
"settings" to getSettingsFolder().absolutePath.toString(),
|
||||
"unsaved" to unsaved.joinToString(","),
|
||||
"debugPort" to debugPort.toString(),
|
||||
"logPort" to logPort.toString(),
|
||||
"errPort" to errPort.toString(),
|
||||
"fullscreen" to System.getProperty("processing.fullscreen", "false").equals("true"),
|
||||
"display" to 1, // TODO: Implement
|
||||
"external" to true,
|
||||
"location" to null, // TODO: Implement
|
||||
"editor.location" to editor?.location?.let { "${it.x},${it.y}" },
|
||||
//"awt.disable" to false,
|
||||
//"window.color" to "0xFF000000", // TODO: Implement
|
||||
//"stop.color" to "0xFF000000", // TODO: Implement
|
||||
"stop.hide" to false, // TODO: Implement
|
||||
)
|
||||
val repository = getContentFile("repository").absolutePath.replace("""\""", """\\""")
|
||||
// Create the init.gradle.kts file in the working directory
|
||||
// This allows us to run the gradle plugin that has been bundled with the editor
|
||||
val initGradle = workingDir.resolve("init.gradle.kts").apply {
|
||||
val content = """
|
||||
beforeSettings{
|
||||
pluginManagement {
|
||||
repositories {
|
||||
maven("$repository")
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
}
|
||||
allprojects{
|
||||
repositories {
|
||||
maven("$repository")
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
writeText(content)
|
||||
}
|
||||
// Create the build.gradle.kts file in the sketch folder
|
||||
val buildGradle = sketchFolder.resolve("build.gradle.kts")
|
||||
val generate = buildGradle.let {
|
||||
if(!it.exists()) return@let true
|
||||
|
||||
val contents = it.readText()
|
||||
if(!contents.contains("@processing-auto-generated")) return@let false
|
||||
|
||||
val version = contents.substringAfter("version=").substringBefore("\n")
|
||||
if(version != getVersionName()) return@let true
|
||||
|
||||
val modeTitle = contents.substringAfter("mode=").substringBefore(" ")
|
||||
if(sketch.mode.title != modeTitle) return@let true
|
||||
|
||||
return@let DEBUG
|
||||
}
|
||||
if (generate) {
|
||||
Messages.log("build.gradle.kts outdated or not found in ${sketch.folder}, creating one")
|
||||
val header = """
|
||||
// @processing-auto-generated mode=${sketch.mode.title} version=${getVersionName()}
|
||||
//
|
||||
""".trimIndent()
|
||||
|
||||
val instructions = text("gradle.instructions")
|
||||
.split("\n")
|
||||
.joinToString("\n") { "// $it" }
|
||||
|
||||
val configuration = """
|
||||
plugins{
|
||||
id("org.processing.java") version "${getVersionName()}"
|
||||
}
|
||||
""".trimIndent()
|
||||
val content = "${header}\n${instructions}\n\n${configuration}"
|
||||
buildGradle.writeText(content)
|
||||
}
|
||||
// Create and empty settings.gradle.kts file in the sketch folder
|
||||
val settingsGradle = sketchFolder.resolve("settings.gradle.kts")
|
||||
if (!settingsGradle.exists()) {
|
||||
settingsGradle.createNewFile()
|
||||
}
|
||||
// Collect the arguments to pass to gradle
|
||||
val arguments = mutableListOf("--init-script", initGradle.toAbsolutePath().toString())
|
||||
// Hide Gradle output from the console if not in debug mode
|
||||
if(!DEBUG) arguments += "--quiet"
|
||||
|
||||
if(copy) arguments += listOf("--project-dir", sketchFolder.absolutePath)
|
||||
|
||||
arguments += variables.entries
|
||||
.filter { it.value != null }
|
||||
.map { "-Pprocessing.${it.key}=${it.value}" }
|
||||
|
||||
arguments += extraArguments
|
||||
|
||||
withArguments(*arguments.toTypedArray())
|
||||
|
||||
forTasks(*tasks)
|
||||
|
||||
// TODO: Instead of shipping Processing with a build-in JDK we should download the JDK through Gradle
|
||||
setJavaHome(Platform.getJavaHome())
|
||||
withCancellationToken(cancel.token())
|
||||
}
|
||||
|
||||
fun start() {
|
||||
launchJob {
|
||||
handleExceptions {
|
||||
state.value = State.BUILDING
|
||||
|
||||
// Connect Gradle, configure the build and run it
|
||||
GradleConnector.newConnector()
|
||||
.forProjectDirectory(folder)
|
||||
.forProjectDirectory(sketch.folder)
|
||||
.apply {
|
||||
editor?.statusMessage("Connecting to Gradle", EditorStatus.NOTICE)
|
||||
// TODO: Remove when switched to classic confinement within Snap
|
||||
if(System.getenv("SNAP_USER_COMMON") != null){
|
||||
useGradleUserHomeDir(Platform.getSettingsFolder().resolve("gradle"))
|
||||
if (System.getenv("SNAP_USER_COMMON") != null) {
|
||||
useGradleUserHomeDir(getSettingsFolder().resolve("gradle"))
|
||||
}
|
||||
}
|
||||
.connect()
|
||||
.apply {
|
||||
service?.editor?.statusMessage("Building sketch", EditorStatus.NOTICE)
|
||||
editor?.statusMessage("Building sketch", EditorStatus.NOTICE)
|
||||
}
|
||||
.newBuild()
|
||||
.apply {
|
||||
configure()
|
||||
withCancellationToken(cancel.token())
|
||||
addStateListener()
|
||||
addDebugging()
|
||||
addLogserver()
|
||||
if(Base.DEBUG) {
|
||||
if (DEBUG) {
|
||||
setStandardOutput(System.out)
|
||||
setStandardError(System.err)
|
||||
}
|
||||
run()
|
||||
|
||||
setupGradle()
|
||||
|
||||
addStateListener()
|
||||
addLogserver()
|
||||
addDebugging()
|
||||
|
||||
}
|
||||
}catch (e: Exception){
|
||||
val causesList = mutableListOf<Throwable>()
|
||||
var cause: Throwable? = e
|
||||
while (cause != null && cause.cause != cause) {
|
||||
causesList.add(cause)
|
||||
cause = cause.cause
|
||||
}
|
||||
|
||||
val errors = causesList.joinToString("\n") { it.message ?: "Unknown error" }
|
||||
|
||||
val skip = listOf(BuildCancelledException::class)
|
||||
|
||||
if (skip.any { it.isInstance(e) }) {
|
||||
Messages.log("Gradle job error: $errors")
|
||||
return@launchJob
|
||||
}
|
||||
|
||||
if(state.value == State.RUNNING){
|
||||
Messages.log("Gradle job error: $errors")
|
||||
return@launchJob
|
||||
}
|
||||
|
||||
// An error occurred during the build process
|
||||
|
||||
System.err.println(errors)
|
||||
service?.editor?.statusError(causesList.last().message)
|
||||
}finally {
|
||||
state.value = State.DONE
|
||||
vm.value = null
|
||||
.run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun launchJob(block: suspend CoroutineScope.() -> Unit){
|
||||
val job = scope.launch { block() }
|
||||
jobs.add(job)
|
||||
@@ -118,29 +241,66 @@ class GradleJob{
|
||||
jobs.forEach(Job::cancel)
|
||||
}
|
||||
|
||||
// Handle exception thrown by Gradle
|
||||
private fun handleExceptions(action: () -> Unit){
|
||||
try{
|
||||
action()
|
||||
}catch (e: Exception){
|
||||
val causesList = mutableListOf<Throwable>()
|
||||
var cause: Throwable? = e
|
||||
|
||||
while (cause != null && cause.cause != cause) {
|
||||
causesList.add(cause)
|
||||
cause = cause.cause
|
||||
}
|
||||
|
||||
val errors = causesList.joinToString("\n") { it.message ?: "Unknown error" }
|
||||
|
||||
val skip = listOf(BuildCancelledException::class)
|
||||
|
||||
if (skip.any { it.isInstance(e) }) {
|
||||
Messages.log("Gradle job error: $errors")
|
||||
return
|
||||
}
|
||||
|
||||
if(state.value == State.RUNNING){
|
||||
Messages.log("Gradle job error: $errors")
|
||||
return
|
||||
}
|
||||
|
||||
// An error occurred during the build process
|
||||
|
||||
System.err.println(errors)
|
||||
editor?.statusError(causesList.last().message)
|
||||
}finally {
|
||||
state.value = State.DONE
|
||||
vm.value = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun BuildLauncher.addStateListener(){
|
||||
addProgressListener(ProgressListener { event ->
|
||||
if(event is TaskStartEvent) {
|
||||
service?.editor?.statusMessage("Running task: ${event.descriptor.name}", EditorStatus.NOTICE)
|
||||
editor?.statusMessage("Running task: ${event.descriptor.name}", EditorStatus.NOTICE)
|
||||
when(event.descriptor.name) {
|
||||
":run" -> {
|
||||
state.value = State.RUNNING
|
||||
Messages.log("Start run")
|
||||
service?.editor?.toolbar?.activateRun()
|
||||
editor?.toolbar?.activateRun()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(event is TaskFinishEvent) {
|
||||
if(event.result is TaskSuccessResult){
|
||||
service?.editor?.statusMessage("Finished task ${event.descriptor.name}", EditorStatus.NOTICE)
|
||||
editor?.statusMessage("Finished task ${event.descriptor.name}", EditorStatus.NOTICE)
|
||||
}
|
||||
|
||||
when(event.descriptor.name){
|
||||
":run"->{
|
||||
state.value = State.DONE
|
||||
service?.editor?.toolbar?.deactivateRun()
|
||||
service?.editor?.toolbar?.deactivateStop()
|
||||
editor?.toolbar?.deactivateRun()
|
||||
editor?.toolbar?.deactivateStop()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,7 +328,7 @@ class GradleJob{
|
||||
*/
|
||||
|
||||
val error = event.definition.id.displayName
|
||||
service?.editor?.statusError(error)
|
||||
editor?.statusError(error)
|
||||
System.err.println("Problem: $error")
|
||||
state.value = State.ERROR
|
||||
|
||||
@@ -183,32 +343,12 @@ class GradleJob{
|
||||
})
|
||||
}
|
||||
|
||||
fun addLogserver(){
|
||||
fun BuildLauncher.addLogserver(){
|
||||
launchJob {
|
||||
startLogServer(service?.logPort ?: 5006, System.out)
|
||||
startLogServer(logPort, System.out)
|
||||
}
|
||||
launchJob{
|
||||
startLogServer(service?.errPort ?: 5007, System.err)
|
||||
}
|
||||
}
|
||||
fun startLogServer(port: Int, target: PrintStream){
|
||||
val server = ServerSocket(port)
|
||||
Messages.log("Log server started on port $port")
|
||||
val client = server.accept()
|
||||
Messages.log("Log server client connected")
|
||||
|
||||
val reader = client.getInputStream().bufferedReader()
|
||||
try {
|
||||
reader.forEachLine { line ->
|
||||
if (line.isNotBlank()) {
|
||||
target.println(line)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Messages.log("Error while reading from log server: ${e.message}")
|
||||
} finally {
|
||||
client.close()
|
||||
server.close()
|
||||
startLogServer(errPort, System.err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,9 +358,9 @@ class GradleJob{
|
||||
if (event.descriptor.name != ":run") return@ProgressListener
|
||||
|
||||
launchJob {
|
||||
val debugger = Debugger.connect(service?.debugPort) ?: return@launchJob
|
||||
val debugger = Debugger.connect(debugPort) ?: return@launchJob
|
||||
vm.value = debugger
|
||||
val exceptions = Exceptions(debugger, service?.editor)
|
||||
val exceptions = Exceptions(debugger, editor)
|
||||
exceptions.listen()
|
||||
}
|
||||
|
||||
|
||||
@@ -2,22 +2,12 @@ package processing.app.gradle
|
||||
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import org.gradle.tooling.BuildLauncher
|
||||
import processing.app.Base.DEBUG
|
||||
import processing.app.Base.getSketchbookFolder
|
||||
import processing.app.Base.getVersionName
|
||||
import processing.app.Language.text
|
||||
import processing.app.Messages
|
||||
import processing.app.Mode
|
||||
import processing.app.Platform
|
||||
import processing.app.Platform.getContentFile
|
||||
import processing.app.Platform.getSettingsFolder
|
||||
import processing.app.Preferences
|
||||
import processing.app.Sketch
|
||||
import processing.app.ui.Editor
|
||||
import kotlin.io.path.createTempDirectory
|
||||
import kotlin.io.path.deleteIfExists
|
||||
import kotlin.io.path.writeText
|
||||
|
||||
// TODO: Test offline mode, gradle seems to be included as not needed to be downloaded.
|
||||
// TODO: Test running examples
|
||||
@@ -48,10 +38,6 @@ class GradleService(
|
||||
val jobs = mutableStateListOf<GradleJob>()
|
||||
val workingDir = createTempDirectory()
|
||||
|
||||
val debugPort = (30_000..60_000).random()
|
||||
val logPort = debugPort + 1
|
||||
val errPort = logPort + 1
|
||||
|
||||
fun run(){
|
||||
startJob("run")
|
||||
}
|
||||
@@ -68,12 +54,12 @@ class GradleService(
|
||||
if(!active.value) return
|
||||
editor?.let { println(text("gradle.using_gradle")) }
|
||||
|
||||
val job = GradleJob()
|
||||
job.service = this
|
||||
job.configure = {
|
||||
setupGradle()
|
||||
forTasks(tasks.joinToString(" "))
|
||||
}
|
||||
val job = GradleJob(
|
||||
tasks = tasks,
|
||||
workingDir = workingDir,
|
||||
sketch = sketch ?: throw IllegalStateException("Sketch is not set"),
|
||||
editor = editor
|
||||
)
|
||||
jobs.add(job)
|
||||
job.start()
|
||||
}
|
||||
@@ -82,133 +68,6 @@ class GradleService(
|
||||
jobs.forEach(GradleJob::cancel)
|
||||
}
|
||||
|
||||
private fun BuildLauncher.setupGradle(extraArguments: List<String> = listOf()) {
|
||||
val sketch = sketch ?: throw IllegalStateException("Sketch is not set")
|
||||
val copy = sketch.isReadOnly || sketch.isUntitled
|
||||
val sketchFolder = if(copy) workingDir.resolve("sketch").toFile() else sketch.folder
|
||||
if(copy){
|
||||
// If the sketch is read-only, we copy it to the working directory
|
||||
// This allows us to run the sketch without modifying the original files
|
||||
sketch.folder.copyRecursively(sketchFolder, overwrite = true)
|
||||
}
|
||||
// Save the unsaved code into the working directory for gradle to compile
|
||||
val unsaved = sketch.code
|
||||
.map { code ->
|
||||
val file = workingDir.resolve("unsaved/${code.fileName}")
|
||||
file.parent.toFile().mkdirs()
|
||||
// If tab is marked modified save it to the working directory
|
||||
// Otherwise delete the file so we don't compile with old code
|
||||
if(code.isModified){
|
||||
file.writeText(code.documentText)
|
||||
}else{
|
||||
file.deleteIfExists()
|
||||
}
|
||||
return@map code.fileName
|
||||
}
|
||||
// Collect the variables to pass to gradle
|
||||
val variables = mapOf(
|
||||
"group" to System.getProperty("processing.group", "org.processing"),
|
||||
"version" to getVersionName(),
|
||||
"sketchFolder" to sketchFolder,
|
||||
"sketchbook" to getSketchbookFolder(),
|
||||
"workingDir" to workingDir.toAbsolutePath().toString(),
|
||||
"settings" to getSettingsFolder().absolutePath.toString(),
|
||||
"unsaved" to unsaved.joinToString(","),
|
||||
"debugPort" to debugPort.toString(),
|
||||
"logPort" to logPort.toString(),
|
||||
"errPort" to errPort.toString(),
|
||||
"fullscreen" to System.getProperty("processing.fullscreen", "false").equals("true"),
|
||||
"display" to 1, // TODO: Implement
|
||||
"external" to true,
|
||||
"location" to null, // TODO: Implement
|
||||
"editor.location" to editor?.location?.let { "${it.x},${it.y}" },
|
||||
//"awt.disable" to false,
|
||||
//"window.color" to "0xFF000000", // TODO: Implement
|
||||
//"stop.color" to "0xFF000000", // TODO: Implement
|
||||
"stop.hide" to false, // TODO: Implement
|
||||
)
|
||||
val repository = getContentFile("repository").absolutePath.replace("""\""", """\\""")
|
||||
// Create the init.gradle.kts file in the working directory
|
||||
val initGradle = workingDir.resolve("init.gradle.kts").apply {
|
||||
val content = """
|
||||
beforeSettings{
|
||||
pluginManagement {
|
||||
repositories {
|
||||
maven { url = uri("$repository") }
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
}
|
||||
allprojects{
|
||||
repositories {
|
||||
maven { url = uri("$repository") }
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
writeText(content)
|
||||
}
|
||||
// Create the build.gradle.kts file in the sketch folder
|
||||
val buildGradle = sketchFolder.resolve("build.gradle.kts")
|
||||
val generate = buildGradle.let {
|
||||
if(!it.exists()) return@let true
|
||||
|
||||
val contents = it.readText()
|
||||
if(!contents.contains("@processing-auto-generated")) return@let false
|
||||
|
||||
val version = contents.substringAfter("version=").substringBefore("\n")
|
||||
if(version != getVersionName()) return@let true
|
||||
|
||||
val modeTitle = contents.substringAfter("mode=").substringBefore(" ")
|
||||
if(mode.title != modeTitle) return@let true
|
||||
|
||||
return@let DEBUG
|
||||
}
|
||||
if (generate) {
|
||||
Messages.log("build.gradle.kts outdated or not found in ${sketch.folder}, creating one")
|
||||
val header = """
|
||||
// @processing-auto-generated mode=${mode.title} version=${getVersionName()}
|
||||
//
|
||||
""".trimIndent()
|
||||
|
||||
val instructions = text("gradle.instructions")
|
||||
.split("\n")
|
||||
.joinToString("\n") { "// $it" }
|
||||
|
||||
val configuration = """
|
||||
|
||||
plugins{
|
||||
id("org.processing.java") version "${getVersionName()}"
|
||||
}
|
||||
""".trimIndent()
|
||||
val content = "${header}\n${instructions}\n${configuration}"
|
||||
buildGradle.writeText(content)
|
||||
}
|
||||
// Create the settings.gradle.kts file in the sketch folder
|
||||
val settingsGradle = sketchFolder.resolve("settings.gradle.kts")
|
||||
if (!settingsGradle.exists()) {
|
||||
settingsGradle.createNewFile()
|
||||
}
|
||||
// Collect the arguments to pass to gradle
|
||||
val arguments = mutableListOf("--init-script", initGradle.toAbsolutePath().toString())
|
||||
if (!DEBUG) arguments.add("--quiet")
|
||||
if(copy){
|
||||
arguments += listOf("--project-dir", sketchFolder.absolutePath)
|
||||
}
|
||||
|
||||
arguments.addAll(variables.entries
|
||||
.filter { it.value != null }
|
||||
.map { "-Pprocessing.${it.key}=${it.value}" }
|
||||
)
|
||||
arguments.addAll(extraArguments)
|
||||
|
||||
withArguments(*arguments.toTypedArray())
|
||||
|
||||
// TODO: Instead of shipping Processing with a build-in JDK we should download the JDK through Gradle
|
||||
setJavaHome(Platform.getJavaHome())
|
||||
}
|
||||
|
||||
// Hooks for java to check if the Gradle service is running since mutableStateOf is not accessible in java
|
||||
fun getEnabled(): Boolean {
|
||||
return active.value
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package processing.app.gradle
|
||||
|
||||
import processing.app.Messages
|
||||
import java.io.PrintStream
|
||||
import java.net.ServerSocket
|
||||
|
||||
class Log{
|
||||
companion object{
|
||||
fun startLogServer(port: Int, target: PrintStream){
|
||||
val server = ServerSocket(port)
|
||||
Messages.Companion.log("Log server started on port $port")
|
||||
val client = server.accept()
|
||||
Messages.Companion.log("Log server client connected")
|
||||
|
||||
val reader = client.getInputStream().bufferedReader()
|
||||
try {
|
||||
reader.forEachLine { line ->
|
||||
if (line.isNotBlank()) {
|
||||
target.println(line)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Messages.Companion.log("Error while reading from log server: ${e.message}")
|
||||
} finally {
|
||||
client.close()
|
||||
server.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user