-
Notifications
You must be signed in to change notification settings - Fork 749
Expand file tree
/
Copy pathBasher.swift
More file actions
64 lines (52 loc) · 1.59 KB
/
Basher.swift
File metadata and controls
64 lines (52 loc) · 1.59 KB
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
import Foundation
// Only available on macOS
#if os(macOS)
/// Bash command runner
public struct Basher {
public enum BashError: Error, LocalizedError {
case errorDuringTask(code: Int32)
case noOutput(code: Int32)
public var errorDescription: String? {
switch self {
case .errorDuringTask(let code):
return "Task failed with code \(code)."
case .noOutput(let code):
return "Task had no output. Exit code: \(code)."
}
}
}
/// Runs the given bash command as a string
///
/// - Parameters:
/// - command: The bash command to run
/// - url: [optional] The URL to set as the `currentDirectoryURL`.
/// - Returns: The result of the command.
public static func run(command: String, from url: URL?) throws -> String {
let task = Process()
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.arguments = [
"-c",
command
]
task.launchPath = "/bin/bash"
if let url = url {
task.currentDirectoryURL = url
}
try task.run()
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
guard let output = String(bytes: data, encoding: .utf8) else {
CodegenLogger.log("[No output from pipe]", logLevel: .error)
throw BashError.noOutput(code: task.terminationStatus)
}
guard task.terminationStatus == 0 else {
CodegenLogger.log(output, logLevel: .error)
throw BashError.errorDuringTask(code: task.terminationStatus)
}
CodegenLogger.log(output)
return output
}
}
#endif