CommandLineToolkit
125 строк · 3.2 Кб
1import Foundation
2import ProcessController
3import SynchronousWaiter
4
5public final class FakeProcessController: ProcessController {
6public var subprocess: Subprocess
7
8public init(subprocess: Subprocess, processStatus: ProcessStatus = .notStarted) {
9self.subprocess = subprocess
10self.overridedProcessStatus = processStatus
11}
12
13public var processName: String {
14do {
15return try subprocess.arguments[0].stringValue()
16} catch {
17return "Error getting processName: \(error)"
18}
19}
20
21public var processId: Int32 {
22return 0
23}
24
25public func start() {
26for listener in startListeners {
27listener(self, {})
28}
29}
30
31public func waitForProcessToDie() {
32try? SynchronousWaiter().waitWhile { isProcessRunning }
33}
34
35public func waitForProcessToDieAsync() async {
36await withCheckedContinuation { continuation in
37try? SynchronousWaiter().waitWhile { isProcessRunning }
38continuation.resume()
39}
40}
41
42public var overridedProcessStatus: ProcessStatus = .notStarted
43
44public func processStatus() -> ProcessStatus {
45return overridedProcessStatus
46}
47
48public var signalsSent = [Int32]()
49
50public func send(signal: Int32) {
51signalsSent.append(signal)
52broadcastSignal(signal)
53}
54
55public func signalAndForceKillIfNeeded(
56terminationSignal: Int32,
57terminationSignalTimeout: TimeInterval,
58onKill: @escaping () -> ()
59) {
60send(signal: terminationSignal)
61invokeTerminationProcedures(exitCode: terminationSignal)
62onKill()
63}
64
65public func invokeTerminationProcedures(
66exitCode: Int32 = 0
67) {
68overridedProcessStatus = .terminated(exitCode: exitCode)
69broadcastTermination()
70}
71
72public var startListeners = [StartListener]()
73
74public func onStart(listener: @escaping StartListener) {
75startListeners.append(listener)
76}
77
78// Stdout
79
80public var stdoutListeners = [StdoutListener]()
81
82public func onStdout(listener: @escaping StdoutListener) {
83stdoutListeners.append(listener)
84}
85
86public func broadcastStdout(data: Data) {
87stdoutListeners.forEach { $0(self, data, { }) }
88}
89
90// Stderr
91
92public var stderrListeners = [StdoutListener]()
93
94public func onStderr(listener: @escaping StderrListener) {
95stderrListeners.append(listener)
96}
97
98public func broadcastStderr(data: Data) {
99stderrListeners.forEach { $0(self, data, { }) }
100}
101
102// Signalling
103
104public var signalListeners = [SignalListener]()
105
106public func onSignal(listener: @escaping SignalListener) {
107signalListeners.append(listener)
108}
109
110public func broadcastSignal(_ signal: Int32) {
111signalListeners.forEach { $0(self, signal, { }) }
112}
113
114// Termination
115
116public var terminationListeners = [TerminationListener]()
117
118public func onTermination(listener: @escaping TerminationListener) {
119terminationListeners.append(listener)
120}
121
122public func broadcastTermination() {
123terminationListeners.forEach { $0(self, { }) }
124}
125}
126