Skip to content

Commit 3b38131

Browse files
committed
Move ProcessUtil to buildSrc
1 parent a5654c7 commit 3b38131

File tree

3 files changed

+81
-76
lines changed

3 files changed

+81
-76
lines changed

buildSrc/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ plugins {
55
repositories {
66
mavenCentral()
77
}
8+
9+
dependencies {
10+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
11+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import kotlinx.coroutines.CoroutineScope
2+
import kotlinx.coroutines.Dispatchers
3+
import kotlinx.coroutines.joinAll
4+
import kotlinx.coroutines.launch
5+
import kotlinx.coroutines.runBlocking
6+
import java.io.Reader
7+
import java.util.concurrent.TimeUnit
8+
import kotlin.time.Duration
9+
10+
object ProcessUtil {
11+
data class Result(
12+
val exitCode: Int,
13+
val stdout: String,
14+
val stderr: String,
15+
val isTimeout: Boolean, // true if the process was terminated due to timeout
16+
)
17+
18+
fun run(
19+
command: List<String>,
20+
input: Reader = "".reader(),
21+
timeout: Duration? = null,
22+
builder: ProcessBuilder.() -> Unit = {},
23+
): Result {
24+
val process = ProcessBuilder(command).apply(builder).start()
25+
return communicate(process, input, timeout)
26+
}
27+
28+
private fun communicate(
29+
process: Process,
30+
input: Reader,
31+
timeout: Duration? = null,
32+
): Result {
33+
val stdout = StringBuilder()
34+
val stderr = StringBuilder()
35+
36+
val scope = CoroutineScope(Dispatchers.IO)
37+
38+
// Handle process input
39+
val stdinJob = scope.launch {
40+
process.outputStream.bufferedWriter().use { writer ->
41+
input.copyTo(writer)
42+
}
43+
}
44+
45+
// Launch output capture coroutines
46+
val stdoutJob = scope.launch {
47+
process.inputStream.bufferedReader().useLines { lines ->
48+
lines.forEach { stdout.appendLine(it) }
49+
}
50+
}
51+
val stderrJob = scope.launch {
52+
process.errorStream.bufferedReader().useLines { lines ->
53+
lines.forEach { stderr.appendLine(it) }
54+
}
55+
}
56+
57+
// Wait for completion
58+
val isTimeout = if (timeout != null) {
59+
!process.waitFor(timeout.inWholeNanoseconds, TimeUnit.NANOSECONDS)
60+
} else {
61+
process.waitFor()
62+
false
63+
}
64+
65+
// Wait for all coroutines to finish
66+
runBlocking {
67+
joinAll(stdinJob, stdoutJob, stderrJob)
68+
}
69+
70+
return Result(
71+
exitCode = process.exitValue(),
72+
stdout = stdout.toString(),
73+
stderr = stderr.toString(),
74+
isTimeout = isTimeout,
75+
)
76+
}
77+
}

jacodb-ets/build.gradle.kts

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
import com.github.gradle.node.npm.task.NpmTask
2-
import kotlinx.coroutines.CoroutineScope
3-
import kotlinx.coroutines.Dispatchers
4-
import kotlinx.coroutines.joinAll
5-
import kotlinx.coroutines.launch
6-
import kotlinx.coroutines.runBlocking
72
import java.io.FileNotFoundException
8-
import java.io.Reader
9-
import kotlin.time.Duration
103
import kotlin.time.Duration.Companion.minutes
114

125
plugins {
@@ -117,72 +110,3 @@ tasks.register("generateTestResources") {
117110
)
118111
}
119112
}
120-
121-
object ProcessUtil {
122-
data class Result(
123-
val exitCode: Int,
124-
val stdout: String,
125-
val stderr: String,
126-
val isTimeout: Boolean, // true if the process was terminated due to timeout
127-
)
128-
129-
fun run(
130-
command: List<String>,
131-
input: Reader = "".reader(),
132-
timeout: Duration? = null,
133-
builder: ProcessBuilder.() -> Unit = {},
134-
): Result {
135-
val process = ProcessBuilder(command).apply(builder).start()
136-
return communicate(process, input, timeout)
137-
}
138-
139-
private fun communicate(
140-
process: Process,
141-
input: Reader,
142-
timeout: Duration? = null,
143-
): Result {
144-
val stdout = StringBuilder()
145-
val stderr = StringBuilder()
146-
147-
val scope = CoroutineScope(Dispatchers.IO)
148-
149-
// Handle process input
150-
val stdinJob = scope.launch {
151-
process.outputStream.bufferedWriter().use { writer ->
152-
input.copyTo(writer)
153-
}
154-
}
155-
156-
// Launch output capture coroutines
157-
val stdoutJob = scope.launch {
158-
process.inputStream.bufferedReader().useLines { lines ->
159-
lines.forEach { stdout.appendLine(it) }
160-
}
161-
}
162-
val stderrJob = scope.launch {
163-
process.errorStream.bufferedReader().useLines { lines ->
164-
lines.forEach { stderr.appendLine(it) }
165-
}
166-
}
167-
168-
// Wait for completion
169-
val isTimeout = if (timeout != null) {
170-
!process.waitFor(timeout.inWholeNanoseconds, TimeUnit.NANOSECONDS)
171-
} else {
172-
process.waitFor()
173-
false
174-
}
175-
176-
// Wait for all coroutines to finish
177-
runBlocking {
178-
joinAll(stdinJob, stdoutJob, stderrJob)
179-
}
180-
181-
return Result(
182-
exitCode = process.exitValue(),
183-
stdout = stdout.toString(),
184-
stderr = stderr.toString(),
185-
isTimeout = isTimeout,
186-
)
187-
}
188-
}

0 commit comments

Comments
 (0)