-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathShell.kt
76 lines (72 loc) · 2.89 KB
/
Shell.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
@file:Suppress("NOTHING_TO_INLINE","unused","MemberVisibilityCanBePrivate","FunctionName",)
package me.heizi.kotlinx.shell
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import java.io.File
import java.nio.charset.Charset
import kotlin.coroutines.CoroutineContext
/**
* ## Shell - Process的封装类
* Create and run a [Process] by command line , that's Shell no matter is Windows call it or not .
* This class implemented [Deferred] asynchronous coroutine and [SharedFlow] ,
* That means you can use await to wait for [CommandResult] or collect [ProcessingResults].
*
* I recommend the fake constructor if you just want to **run a simple command**
* @see Shell
*
* @property prefix how to start a process.
* @property env event args
* @property isMixingMessage stderr redirect to stdout when true
* @property isEcho echo command line before run the command line.
* @property onRun you can delay or something to using [RunScope.run] run some fancy line.
* @param coroutineContext I don't know what's it So I'm just added it.
* @param charset make sure you won't see some fancy line you have never seen before
* @param startWithCreate don't you can read the name ? idiot
*/
@OptIn(ExperimentalApiReShell::class)
inline fun Shell(
coroutineContext: CoroutineContext = Dispatchers.IO,
prefix: Array<String> = defaultPrefix,
env: Map<String, String>? = null,
isMixingMessage: Boolean = false,
startWithCreate: Boolean = true,
workdir: File? = null,
charset: Charset = defaultCharset,
noinline onRun: (suspend WriteScope.() -> Unit)?=null,
) = ReShell(
coroutineContext = coroutineContext,
charset = charset,
environment = env,
isRedirect = isMixingMessage,
coroutineStart = if (startWithCreate) CoroutineStart.DEFAULT else CoroutineStart.LAZY,
stdin = onRun,
forest = prefix,
workdir = workdir,
flow = MutableSharedFlow(1024,1024)
)
/**
* 假构造器
*
* @see Shell
* @param isKeepCLIAndWrite ture means launch the Non-Close-CLI first and write command lines after. it'll exit
* while read the exit command on your [commandLines]. run on Prefix that joined commands by && sign if false
*/
inline fun Shell(
vararg commandLines:String,
globalArg:Map<String,String>?=null,
isMixingMessage: Boolean = false,
isKeepCLIAndWrite: Boolean = false,// keep cmd maybe (
startWithCreate: Boolean = true,
charset: Charset = defaultCharset,
prefix: Array<String> = defaultPrefix
) = Shell(env = globalArg, isMixingMessage=isMixingMessage, startWithCreate = startWithCreate, charset = charset,
prefix = if (isKeepCLIAndWrite) keepCLIPrefix else
prefix + commandLines.run {
if (size == 1) first()
else commandLines.joinToString(" && ")
},
onRun = if (!isKeepCLIAndWrite) { {
prefix.forEach(this::echoRun)
} } else null
)