Skip to content

Commit cc2a9da

Browse files
committed
Add streamLineForCommand
1 parent 9d6c09b commit cc2a9da

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

Tool/Sources/Terminal/Terminal.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ public protocol TerminalType {
99
environment: [String: String]
1010
) -> AsyncThrowingStream<String, Error>
1111

12+
func streamLineForCommand(
13+
_ command: String,
14+
arguments: [String],
15+
currentDirectoryURL: URL?,
16+
environment: [String: String]
17+
) -> AsyncThrowingStream<String, Error>
18+
1219
func runCommand(
1320
_ command: String,
1421
arguments: [String],
@@ -133,6 +140,46 @@ public final class Terminal: TerminalType, @unchecked Sendable {
133140
return contentStream
134141
}
135142

143+
public func streamLineForCommand(
144+
_ command: String = "/bin/bash",
145+
arguments: [String],
146+
currentDirectoryURL: URL? = nil,
147+
environment: [String: String]
148+
) -> AsyncThrowingStream<String, Error> {
149+
let chunkStream = streamCommand(
150+
command,
151+
arguments: arguments,
152+
currentDirectoryURL: currentDirectoryURL,
153+
environment: environment
154+
)
155+
156+
return AsyncThrowingStream<String, Error> { continuation in
157+
Task {
158+
var buffer = ""
159+
do {
160+
for try await chunk in chunkStream {
161+
buffer.append(chunk)
162+
163+
while let range = buffer.range(of: "\n") {
164+
let line = String(buffer[..<range.lowerBound])
165+
buffer.removeSubrange(buffer.startIndex...range.upperBound)
166+
continuation.yield(line)
167+
}
168+
}
169+
170+
let trailing = buffer.trimmingCharacters(in: .whitespacesAndNewlines)
171+
if !trailing.isEmpty {
172+
continuation.yield(trailing)
173+
}
174+
175+
continuation.finish()
176+
} catch {
177+
continuation.finish(throwing: error)
178+
}
179+
}
180+
}
181+
}
182+
136183
public func runCommand(
137184
_ command: String = "/bin/bash",
138185
arguments: [String],

0 commit comments

Comments
 (0)