Skip to content

Commit 701f9f5

Browse files
committed
Gradle Runner PoC Refactor
1 parent 947a90e commit 701f9f5

8 files changed

Lines changed: 327 additions & 234 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package processing.app.gradle
2+
3+
class ActionGradleJob : GradleJob()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package processing.app.gradle
2+
3+
class BackgroundGradleJob : GradleJob()
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package processing.app.gradle
2+
3+
import androidx.compose.runtime.mutableStateListOf
4+
import androidx.compose.runtime.mutableStateOf
5+
import com.sun.jdi.Bootstrap
6+
import com.sun.jdi.VirtualMachine
7+
import com.sun.jdi.connect.AttachingConnector
8+
import kotlinx.coroutines.CoroutineScope
9+
import kotlinx.coroutines.Dispatchers
10+
import kotlinx.coroutines.launch
11+
import org.gradle.tooling.BuildLauncher
12+
import org.gradle.tooling.GradleConnector
13+
import org.gradle.tooling.events.ProgressListener
14+
import org.gradle.tooling.events.problems.ProblemEvent
15+
import org.gradle.tooling.events.task.TaskFinishEvent
16+
import org.gradle.tooling.events.task.TaskStartEvent
17+
import processing.app.Messages
18+
19+
// TODO: Capture and filter gradle output
20+
open abstract class GradleJob{
21+
enum class State{
22+
NONE,
23+
BUILDING,
24+
RUNNING,
25+
DONE
26+
}
27+
28+
var service: GradleService? = null
29+
var configure: BuildLauncher.() -> Unit = {}
30+
31+
val state = mutableStateOf(State.NONE)
32+
val vm = mutableStateOf<VirtualMachine?>(null)
33+
val problems = mutableStateListOf<ProblemEvent>()
34+
35+
private val scope = CoroutineScope(Dispatchers.IO)
36+
private val cancel = GradleConnector.newCancellationTokenSource()
37+
38+
fun start() {
39+
service?.jobs?.add(this)
40+
val connection = service?.connection ?: return
41+
scope.launch {
42+
try {
43+
state.value = State.BUILDING
44+
45+
connection.newBuild()
46+
.apply {
47+
configure()
48+
}
49+
.withCancellationToken(cancel.token())
50+
.addStateListener()
51+
.addDebugging()
52+
.run()
53+
54+
}catch (e: Exception){
55+
if(state.value == State.RUNNING){
56+
Messages.log("Error while running: ${e.message}")
57+
}else{
58+
throw e
59+
}
60+
}finally {
61+
state.value = State.DONE
62+
vm.value = null
63+
}
64+
65+
}
66+
}
67+
68+
fun cancel(){
69+
cancel.cancel()
70+
}
71+
72+
private fun BuildLauncher.addStateListener(): BuildLauncher{
73+
this.addProgressListener(ProgressListener { event ->
74+
if(event is TaskStartEvent) {
75+
when(event.descriptor.name) {
76+
":run" -> {
77+
state.value = State.RUNNING
78+
}
79+
}
80+
81+
}
82+
if(event is TaskFinishEvent) {
83+
when(event.descriptor.name){
84+
":jar"->{
85+
state.value = State.NONE
86+
Messages.log("Jar finished")
87+
}
88+
":run"->{
89+
state.value = State.NONE
90+
}
91+
}
92+
}
93+
if(event is ProblemEvent) {
94+
problems.add(event)
95+
}
96+
})
97+
return this
98+
}
99+
100+
private fun BuildLauncher.addDebugging(): BuildLauncher{
101+
this.addProgressListener(ProgressListener { event ->
102+
if(event !is TaskStartEvent) return@ProgressListener
103+
if(event.descriptor.name != ":run") return@ProgressListener
104+
105+
Messages.log("Attaching to VM")
106+
val connector = Bootstrap.virtualMachineManager().allConnectors()
107+
.firstOrNull { it.name() == "com.sun.jdi.SocketAttach" }
108+
as AttachingConnector?
109+
?: return@ProgressListener
110+
val args = connector.defaultArguments()
111+
args["port"]?.setValue(service?.debugPort.toString())
112+
val sketch = connector.attach(args)
113+
vm.value = sketch
114+
Messages.log("Attached to VM: ${sketch.name()}")
115+
})
116+
return this
117+
}
118+
}

0 commit comments

Comments
 (0)