Build on save

This commit is contained in:
Stef Tervelde
2025-07-18 10:43:33 +02:00
parent fdc43dc7d2
commit 578c287606
4 changed files with 60 additions and 6 deletions
+2
View File
@@ -122,3 +122,5 @@ processing-examples
/java/gradle/example/gradlew
/java/gradle/example/gradlew.bat
/java/gradle/example/.kotlin/errors
/java/gradle/hotreload/build
*.iml
@@ -72,6 +72,7 @@ class GradleJob(
Create the necessary build files if they do not exist.
*/
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
@@ -218,6 +219,8 @@ class GradleJob(
val arguments = mutableListOf("--init-script", initGradle.toAbsolutePath().toString())
// Hide Gradle output from the console if not in debug mode
if(!DEBUG) arguments += "--quiet"
// TODO: Fix continuous mode for the hot reload
arguments += "-t"
if(copy) arguments += listOf("--project-dir", sketchFolder.absolutePath)
+45 -3
View File
@@ -2,7 +2,12 @@ package processing.app.gradle
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.neverEqualPolicy
import androidx.compose.ui.awt.ComposePanel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import processing.app.Language.text
import processing.app.Mode
import processing.app.Preferences
@@ -30,7 +35,7 @@ class GradleService(
val editor: Editor?,
) {
val active = mutableStateOf(Preferences.getBoolean("run.use_gradle"))
var sketch = mutableStateOf<Sketch?>(null)
var sketch = mutableStateOf<Sketch?>(null, neverEqualPolicy())
val jobs = mutableStateListOf<GradleJob>()
val workingDir = createTempDirectory()
@@ -52,7 +57,7 @@ class GradleService(
val job = GradleJob(
tasks = tasks,
workingDir = workingDir,
workingDir = workingDir,
sketch = sketch.value ?: throw IllegalStateException("Sketch is not set"),
editor = editor
)
@@ -64,10 +69,47 @@ class GradleService(
jobs.forEach(GradleJob::cancel)
}
private val scope = CoroutineScope(Dispatchers.IO)
/*
Watch the sketch folder for changes and start a build job when the sketch is modified
This need to be done properly to use hooks in the future but right now this is the simplest way to do it
*/
init{
scope.launch {
var path = ""
var modified = false
var sketched: Sketch? = null
while(true){
sketch.value?.let { sketch ->
if(sketch.folder.absolutePath != path){
path = sketch.folder.absolutePath
if(sketched == sketch){
// The same sketch has its folder changed, trigger updates downstream from the service
this@GradleService.sketch.value = sketch
}else {
sketched = sketch
}
startJob("build")
}
if(sketch.isModified != modified){
modified = sketch.isModified
if(!modified){
// If the sketch is no longer modified, start the build job, aka build on save
startJob("build")
}
}
}
delay(100)
}
}
}
// Hooks for java to interact with the Gradle service since mutableStateOf is not accessible in java
fun setSketch(sketch: Sketch){
this.sketch.value = sketch
startJob("build")
}
fun getEnabled(): Boolean {
return active.value
@@ -2,7 +2,10 @@ package org.processing.java.gradle
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.GradleBuild
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.jvm.toolchain.JvmVendorSpec
import org.jetbrains.compose.reload.gradle.ComposeHotReloadPlugin
import org.jetbrains.compose.reload.gradle.ComposeHotRun
@@ -11,10 +14,14 @@ class ProcessingHotReloadPlugin: Plugin<Project> {
project.plugins.apply(ComposeHotReloadPlugin::class.java)
project.repositories.google()
project.extensions.getByType(JavaPluginExtension::class.java).toolchain {
it.languageVersion.set(JavaLanguageVersion.of(21))
it.vendor.set(JvmVendorSpec.JETBRAINS)
}
project.afterEvaluate {
project.tasks.named("hotRun", ComposeHotRun::class.java){ task ->
task.isAutoReloadEnabled.set(true)
project.tasks.named("build").configure { task ->
task.finalizedBy("reload")
}
project.tasks.named("run").configure { task ->
task.dependsOn("hotRun")