Template support for input parameters #4
75
Library/Sources/Internal/Tasks/RunProcessTask.swift
Normal file
75
Library/Sources/Internal/Tasks/RunProcessTask.swift
Normal file
@ -0,0 +1,75 @@
|
||||
import Foundation
|
||||
|
||||
struct RunProcessTask {
|
||||
|
||||
// MARK: Type aliases
|
||||
|
||||
typealias Output = String
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private var process: Processable
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
init(process: Processable) {
|
||||
self.process = process
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
@discardableResult
|
||||
mutating func callAsFunction(
|
||||
path: String, arguments: [String] = []
|
||||
) async throws (RunProcessError) -> Output {
|
||||
process.executableURL = URL(at: path)
|
||||
process.arguments = arguments
|
||||
|
||||
let pipeError = Pipe()
|
||||
let pipeOutput = Pipe()
|
||||
|
||||
process.standardError = pipeError
|
||||
process.standardOutput = pipeOutput
|
||||
|
||||
async let streamOutput = pipeOutput.availableData.append()
|
||||
async let streamError = pipeError.availableData.append()
|
||||
|
||||
do {
|
||||
try process.run()
|
||||
|
||||
let dataOutput = await streamOutput
|
||||
let dataError = await streamError
|
||||
|
||||
guard dataError.isEmpty else {
|
||||
guard let errorOutput = String(data: dataError, encoding: .utf8) else {
|
||||
throw RunProcessError.unexpected
|
||||
}
|
||||
|
||||
throw RunProcessError.output(errorOutput)
|
||||
}
|
||||
|
||||
guard let output = String(data: dataOutput, encoding: .utf8) else {
|
||||
throw RunProcessError.unexpected
|
||||
}
|
||||
|
||||
return await withCheckedContinuation { continuation in
|
||||
process.terminationHandler = { _ in
|
||||
continuation.resume(returning: output)
|
||||
}
|
||||
}
|
||||
} catch let error as RunProcessError {
|
||||
throw error
|
||||
} catch {
|
||||
throw RunProcessError.captured(error)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Errors
|
||||
|
||||
public enum RunProcessError: Error {
|
||||
case captured(_ error: Error)
|
||||
case output(_ output: String)
|
||||
case unexpected
|
||||
}
|
@ -14,10 +14,7 @@ public struct CreateRootFolderTask {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
public func callAsFunction(
|
||||
name: String,
|
||||
at location: URL? = nil
|
||||
) async throws -> URL {
|
||||
public func callAsFunction(name: String, at location: URL? = nil) async throws -> URL {
|
||||
guard !name.isEmpty else {
|
||||
throw CreateRootFolderError.nameIsEmpty
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user