@@ -141,18 +141,45 @@ func printJobInfo(_ job: Job, _ start: Bool, _ verbose: Bool) {
141141 }
142142}
143143
144+ class JSONOutputDelegate : Encodable {
145+ enum SDKFailureKind : String , Encodable {
146+ case BrokenTextualInterface
147+ }
148+ struct SDKFailure : Encodable {
149+ let inputPath : String
150+ let kind : SDKFailureKind
151+ }
152+ var allFailures = [ SDKFailure] ( )
153+ func jobFinished( _ job: Job , _ result: ProcessResult ) {
154+ switch result. exitStatus {
155+ case . terminated( code: let code) :
156+ if code == 0 {
157+ break
158+ } else {
159+ allFailures. append ( SDKFailure ( inputPath: getLastInputPath ( job) . pathString,
160+ kind: . BrokenTextualInterface) )
161+ }
162+ default :
163+ break
164+ }
165+ }
166+ }
167+
144168fileprivate class ModuleCompileDelegate : JobExecutionDelegate {
145169 var failingModules = Set < String > ( )
146170 var commandMap : [ Int : String ] = [ : ]
147171 let diagnosticsEngine : DiagnosticsEngine
148172 let verbose : Bool
149173 var failingCriticalOutputs : Set < VirtualPath >
150174 let logPath : AbsolutePath ?
151- public init ( _ jobs: [ Job ] , _ diagnosticsEngine: DiagnosticsEngine , _ verbose: Bool , _ logPath: AbsolutePath ? ) {
175+ let jsonDelegate : JSONOutputDelegate
176+ init ( _ jobs: [ Job ] , _ diagnosticsEngine: DiagnosticsEngine , _ verbose: Bool ,
177+ _ logPath: AbsolutePath ? , _ jsonDelegate: JSONOutputDelegate ) {
152178 self . diagnosticsEngine = diagnosticsEngine
153179 self . verbose = verbose
154180 self . failingCriticalOutputs = Set < VirtualPath > ( jobs. compactMap ( ModuleCompileDelegate . getCriticalOutput) )
155181 self . logPath = logPath
182+ self . jsonDelegate = jsonDelegate
156183 }
157184
158185 /// Dangling jobs are macabi-only modules. We should run those jobs if foundation
@@ -175,6 +202,7 @@ fileprivate class ModuleCompileDelegate: JobExecutionDelegate {
175202 }
176203
177204 public func jobFinished( job: Job , result: ProcessResult , pid: Int ) {
205+ self . jsonDelegate. jobFinished ( job, result)
178206 switch result. exitStatus {
179207 case . terminated( code: let code) :
180208 if code == 0 {
@@ -249,6 +277,7 @@ fileprivate class ABICheckingDelegate: JobExecutionDelegate {
249277
250278public class PrebuiltModuleGenerationDelegate : JobExecutionDelegate {
251279
280+ fileprivate let jsonDelegate : JSONOutputDelegate
252281 fileprivate let compileDelegate : ModuleCompileDelegate
253282 fileprivate let abiCheckDelegate : ABICheckingDelegate
254283
@@ -264,7 +293,10 @@ public class PrebuiltModuleGenerationDelegate: JobExecutionDelegate {
264293
265294 public init ( _ jobs: [ Job ] , _ diagnosticsEngine: DiagnosticsEngine ,
266295 _ verbose: Bool , _ logPath: AbsolutePath ? ) {
267- self . compileDelegate = ModuleCompileDelegate ( jobs. filter ( ModuleCompileDelegate . canHandle) , diagnosticsEngine, verbose, logPath)
296+ self . jsonDelegate = JSONOutputDelegate ( )
297+ self . compileDelegate = ModuleCompileDelegate ( jobs. filter ( ModuleCompileDelegate . canHandle) ,
298+ diagnosticsEngine, verbose, logPath,
299+ self . jsonDelegate)
268300 self . abiCheckDelegate = ABICheckingDelegate ( verbose, logPath)
269301 }
270302
@@ -285,6 +317,13 @@ public class PrebuiltModuleGenerationDelegate: JobExecutionDelegate {
285317 public var hasCriticalFailure : Bool {
286318 return compileDelegate. hasCriticalFailure
287319 }
320+ public func emitJsonOutput( to path: AbsolutePath ) throws {
321+ let data = try JSONEncoder ( ) . encode ( self . jsonDelegate)
322+ if let json = try ? JSONSerialization . jsonObject ( with: data, options: . mutableContainers) ,
323+ let jsonData = try ? JSONSerialization . data ( withJSONObject: json, options: . prettyPrinted) {
324+ try localFileSystem. writeFileContents ( path, bytes: ByteString ( jsonData) )
325+ }
326+ }
288327}
289328
290329public struct PrebuiltModuleInput {
0 commit comments