Skip to content

Commit 3740b2a

Browse files
committed
Improve output formatting with Swift Build backend
This emits an error if a build task fails, to improve clarity, and explicitly lists out some of the other messages we aren't handling right now.
1 parent ccbf01f commit 3740b2a

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

Sources/SwiftBuildSupport/SwiftBuildSystem.swift

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,28 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
334334
return configuredTarget
335335
}
336336

337-
func emitEvent(_ message: SwiftBuild.SwiftBuildMessage) throws {
337+
struct BuildState {
338+
private var activeTasks: [Int: SwiftBuild.SwiftBuildMessage.TaskStartedInfo] = [:]
339+
340+
mutating func started(task: SwiftBuild.SwiftBuildMessage.TaskStartedInfo) throws {
341+
if activeTasks[task.taskID] != nil {
342+
throw Diagnostics.fatalError
343+
}
344+
activeTasks[task.taskID] = task
345+
}
346+
347+
mutating func completed(task: SwiftBuild.SwiftBuildMessage.TaskCompleteInfo) throws -> SwiftBuild.SwiftBuildMessage.TaskStartedInfo {
348+
guard let task = activeTasks[task.taskID] else {
349+
throw Diagnostics.fatalError
350+
}
351+
return task
352+
}
353+
}
354+
355+
func emitEvent(_ message: SwiftBuild.SwiftBuildMessage, buildState: inout BuildState) throws {
338356
switch message {
339-
case .buildCompleted:
340-
progressAnimation.complete(success: true)
357+
case .buildCompleted(let info):
358+
progressAnimation.complete(success: info.result == .ok)
341359
case .didUpdateProgress(let progressInfo):
342360
var step = Int(progressInfo.percentComplete)
343361
if step < 0 { step = 0 }
@@ -365,15 +383,27 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
365383
case .remark: .debug
366384
}
367385
self.observabilityScope.emit(severity: severity, message: message)
368-
case .taskOutput(let info):
369-
self.observabilityScope.emit(info: "\(info.data)")
386+
case .output(let info):
387+
self.observabilityScope.emit(info: "\(String(decoding: info.data, as: UTF8.self))")
370388
case .taskStarted(let info):
389+
try buildState.started(task: info)
371390
if let commandLineDisplay = info.commandLineDisplayString {
372391
self.observabilityScope.emit(info: "\(info.executionDescription)\n\(commandLineDisplay)")
373392
} else {
374393
self.observabilityScope.emit(info: "\(info.executionDescription)")
375394
}
376-
default:
395+
case .taskComplete(let info):
396+
let startedInfo = try buildState.completed(task: info)
397+
if info.result != .success {
398+
self.observabilityScope.emit(severity: .error, message: "\(startedInfo.ruleInfo) failed with a nonzero exit code")
399+
}
400+
case .planningOperationStarted, .planningOperationCompleted, .reportBuildDescription, .reportPathMap, .preparedForIndex, .backtraceFrame, .buildStarted, .preparationComplete, .targetUpToDate, .targetStarted, .targetComplete, .taskUpToDate:
401+
break
402+
case .buildDiagnostic, .targetDiagnostic, .taskDiagnostic:
403+
break // deprecated
404+
case .buildOutput, .targetOutput, .taskOutput:
405+
break // deprecated
406+
@unknown default:
377407
break
378408
}
379409
}
@@ -383,8 +413,9 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
383413
delegate: PlanningOperationDelegate()
384414
)
385415

416+
var buildState = BuildState()
386417
for try await event in try await operation.start() {
387-
try emitEvent(event)
418+
try emitEvent(event, buildState: &buildState)
388419
}
389420

390421
await operation.waitForCompletion()

0 commit comments

Comments
 (0)