88 lines
2.1 KiB
Swift
88 lines
2.1 KiB
Swift
|
//
|
||
|
// RunProcessUseCase.swift
|
||
|
// Piper ~ App
|
||
|
//
|
||
|
// Created by Javier Cicchelli on 05/10/2024.
|
||
|
// Copyright © 2024 Röck+Cöde. All rights reserved.
|
||
|
//
|
||
|
|
||
|
import Foundation
|
||
|
|
||
|
struct RunProcessUseCase {
|
||
|
|
||
|
// MARK: Type aliases
|
||
|
|
||
|
typealias Output = String
|
||
|
|
||
|
// MARK: Properties
|
||
|
|
||
|
private let path: String
|
||
|
private let arguments: [String]?
|
||
|
|
||
|
// MARK: Initialisers
|
||
|
|
||
|
init(
|
||
|
path: String,
|
||
|
arguments: [String] = []
|
||
|
) {
|
||
|
self.path = path
|
||
|
self.arguments = arguments
|
||
|
}
|
||
|
|
||
|
// MARK: Functions
|
||
|
|
||
|
func callAsFunction() async throws -> Output {
|
||
|
let process = Process()
|
||
|
|
||
|
process.executableURL = URL(fileURLWithPath: 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
|
||
|
|
||
|
enum RunProcessError: Error {
|
||
|
case captured(_ error: Error)
|
||
|
case output(_ output: String)
|
||
|
case unexpected
|
||
|
}
|