Compare commits

..

2 Commits

Author SHA1 Message Date
fd54489747 update README 2025-12-14 00:08:23 +01:00
c1cbd96558 small refactor 2025-12-14 00:07:46 +01:00
5 changed files with 22 additions and 24 deletions

View File

@@ -1,14 +1,15 @@
# Kotlin Shell # shell-kt
This library enables the execution of shell commands in Kotlin Multiplatform. `shell-kt` is a Kotlin Multiplatform library that enables the execution of shell commands.
## Features ## Targets
* Execute commands on the shell. | Target | Status |
* Multiplatform support |------------------|---------------|
* JVM | JVM | Supported |
* JavaScript | JavaScript | Supported |
* Native (Linux) | Native (Linux) | Supported |
| Native (Windows) | Not Supported |
## Installation ## Installation
@@ -29,7 +30,7 @@ dependencies {
```kotlin ```kotlin
import com.infendro.shell.Shell import com.infendro.shell.Shell
fun main() { suspend fun main() {
// the command to execute // the command to execute
val command = arrayOf("echo", "Hello World!") val command = arrayOf("echo", "Hello World!")

View File

@@ -26,6 +26,10 @@ kotlin {
implementation(libs.node) implementation(libs.node)
} }
} }
compilerOptions {
freeCompilerArgs.add("-opt-in=kotlinx.cinterop.ExperimentalForeignApi")
}
} }
publishing.repositories { publishing.repositories {

View File

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

View File

@@ -6,16 +6,12 @@ internal actual suspend fun execute(
command: Array<String>, command: Array<String>,
directory: String?, directory: String?,
): Shell.Result { ): Shell.Result {
val process = ProcessBuilder(*command) val process = ProcessBuilder(*command).also {
.also {
if (directory != null) { if (directory != null) {
it.directory(File(directory)) it.directory(File(directory))
} }
} }.start()
.start()
val code = process.waitFor() val code = process.waitFor()
val value = process val value = (if (code == 0) process.inputReader() else process.errorReader()).readText()
.let { if (code == 0) it.inputReader() else it.errorReader() }
.readText()
return Shell.Result(code, value) return Shell.Result(code, value)
} }

View File

@@ -1,12 +1,10 @@
package com.infendro.shell package com.infendro.shell
import kotlinx.cinterop.CPointer import kotlinx.cinterop.CPointer
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.refTo import kotlinx.cinterop.refTo
import kotlinx.cinterop.toKString import kotlinx.cinterop.toKString
import platform.posix.* import platform.posix.*
@ExperimentalForeignApi
internal actual suspend fun execute( internal actual suspend fun execute(
command: Array<String>, command: Array<String>,
directory: String?, directory: String?,
@@ -21,7 +19,6 @@ internal actual suspend fun execute(
return Shell.Result(code, value) return Shell.Result(code, value)
} }
@ExperimentalForeignApi
private fun CPointer<FILE>.readLines(): List<String> { private fun CPointer<FILE>.readLines(): List<String> {
val lines = mutableListOf<String>() val lines = mutableListOf<String>()
val buffer = ByteArray(4096) val buffer = ByteArray(4096)