Skip to content

Commit d92b355

Browse files
committed
[Utility] Add diagnostic data for Process
1 parent 71943b7 commit d92b355

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

Sources/Utility/Diagnostics.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,47 @@ public enum PackageLocation {
167167
}
168168
}
169169
}
170+
171+
/// An Swift error enum that can be used as a stub to early exit from a method.
172+
///
173+
/// It is not expected for this enum to contain any payload or information about the
174+
/// error. The actual errors and warnings are supposed to be added using the Diagnostics
175+
/// engine.
176+
public enum Diagnostics: Swift.Error {
177+
case fatalError
178+
}
179+
180+
/// Diagnostic for the process execution failure.
181+
public struct ProcessExecutionError: DiagnosticData {
182+
public static let id = DiagnosticID(
183+
type: ProcessExecutionError.self,
184+
name: "org.swift.diags.process.execution",
185+
description: {
186+
$0 <<< { "The '" + $0.result.arguments[0] + "' subprocess exited with" }
187+
$0 <<< .substitution({
188+
let `self` = $0 as! ProcessExecutionError
189+
switch self.result.exitStatus {
190+
case .terminated(let code):
191+
return "termination code \(code)"
192+
case .signalled(let signal):
193+
return "signal \(signal)"
194+
}
195+
})
196+
$0 <<< ".\n"
197+
198+
$0 <<< "stdout: " <<< .substitution({
199+
(try? ($0 as! ProcessExecutionError).result.utf8Output()) ?? ""
200+
}) <<< "\n"
201+
$0 <<< "stderr: " <<< .substitution({
202+
(try? ($0 as! ProcessExecutionError).result.utf8stderrOutput()) ?? ""
203+
}) <<< "\n"
204+
}
205+
)
206+
207+
/// The process result.
208+
public let result: ProcessResult
209+
210+
public init(_ result: ProcessResult) {
211+
self.result = result
212+
}
213+
}

Sources/Utility/Process.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Basic
12+
13+
extension Process {
14+
@discardableResult
15+
static public func checkNonZeroExit(arguments: [String], environment: [String: String] = env, diagnostics: DiagnosticsEngine) throws -> String {
16+
let process = Process(arguments: arguments, environment: environment, redirectOutput: true)
17+
try process.launch()
18+
let result = try process.waitUntilExit()
19+
// Throw if there was a non zero termination.
20+
guard result.exitStatus == .terminated(code: 0) else {
21+
diagnostics.emit(data: ProcessExecutionError(result))
22+
throw Diagnostics.fatalError
23+
}
24+
return try result.utf8Output()
25+
}
26+
}

0 commit comments

Comments
 (0)