initial commit
Some checks failed
/ publish (push) Failing after 53s

This commit is contained in:
2025-07-12 20:23:00 +02:00
commit 3565632465
14 changed files with 717 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
package com.infendro.shell
object Shell {
suspend fun run(
command: Array<String>,
directory: String? = null,
): Result {
return execute(command, directory)
}
class Result(
val code: Int,
val value: String,
)
}
internal expect suspend fun execute(
command: Array<String>,
directory: String?,
): Shell.Result

View File

@@ -0,0 +1,19 @@
package com.infendro.shell
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import node.childProcess.ExecOptions
import node.childProcess.exec
internal actual suspend fun execute(
command: Array<String>,
directory: String?,
): Shell.Result = suspendCoroutine { continuation ->
val command = command.joinToString(" ") { "\"$it\"" }
val options = ExecOptions.invoke(cwd = directory)
exec(command, options) { error, stdout, stderr ->
val code = if (error == null) 0 else error.code!!.toInt()
val value = if (error == null) stdout else stderr
continuation.resume(Shell.Result(code, value))
}
}

View File

@@ -0,0 +1,21 @@
package com.infendro.shell
import java.io.File
internal actual suspend fun execute(
command: Array<String>,
directory: String?,
): Shell.Result {
val process = ProcessBuilder(*command)
.also {
if (directory != null) {
it.directory(File(directory))
}
}
.start()
val code = process.waitFor()
val value = process
.let { if (code == 0) it.inputReader() else it.errorReader() }
.readText()
return Shell.Result(code, value)
}

View File

@@ -0,0 +1,34 @@
package com.infendro.shell
import kotlinx.cinterop.CPointer
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.refTo
import kotlinx.cinterop.toKString
import platform.posix.*
@ExperimentalForeignApi
internal actual suspend fun execute(
command: Array<String>,
directory: String?,
): Shell.Result {
val command = command.joinToString(" ") { "\"$it\"" }
if (directory != null) {
chdir(directory)
}
val stream = popen(command, "r")!!
val value = stream.readLines().joinToString("")
val code = pclose(stream)
return Shell.Result(code, value)
}
@ExperimentalForeignApi
private fun CPointer<FILE>.readLines(): List<String> {
val lines = mutableListOf<String>()
val buffer = ByteArray(4096)
while (true) {
val line = fgets(buffer.refTo(0), buffer.size, this)
if (line == null) break
lines.add(line.toKString())
}
return lines
}