@@ -17,6 +17,7 @@ import Dispatch
17
17
import PackageGraph
18
18
import PackageModel
19
19
import SourceControl
20
+ import _Concurrency
20
21
21
22
struct DeprecatedAPIDiff : ParsableCommand {
22
23
static let configuration = CommandConfiguration ( commandName: " experimental-api-diff " ,
@@ -119,50 +120,53 @@ struct APIDiff: AsyncSwiftCommand {
119
120
swiftCommandState: swiftCommandState
120
121
)
121
122
122
- let results = ThreadSafeArrayStore < SwiftAPIDigester . ComparisonResult > ( )
123
- let group = DispatchGroup ( )
124
- let semaphore = DispatchSemaphore ( value: Int ( try buildSystem. buildPlan. destinationBuildParameters. workers) )
125
123
var skippedModules : Set < String > = [ ]
126
124
127
- for module in modulesToDiff {
128
- let moduleBaselinePath = baselineDir. appending ( " \( module) .json " )
129
- guard swiftCommandState. fileSystem. exists ( moduleBaselinePath) else {
130
- print ( " \n Skipping \( module) because it does not exist in the baseline " )
131
- skippedModules. insert ( module)
132
- continue
133
- }
134
- semaphore. wait ( )
135
- DispatchQueue . sharedConcurrent. async ( group: group) {
136
- do {
137
- if let comparisonResult = try apiDigesterTool. compareAPIToBaseline (
138
- at: moduleBaselinePath,
139
- for: module,
140
- buildPlan: try buildSystem. buildPlan,
141
- except: breakageAllowlistPath
142
- ) {
143
- results. append ( comparisonResult)
125
+ let results = await withTaskGroup ( of: SwiftAPIDigester . ComparisonResult? . self, returning: [ SwiftAPIDigester . ComparisonResult ] . self) { taskGroup in
126
+
127
+ for module in modulesToDiff {
128
+ let moduleBaselinePath = baselineDir. appending ( " \( module) .json " )
129
+ guard swiftCommandState. fileSystem. exists ( moduleBaselinePath) else {
130
+ print ( " \n Skipping \( module) because it does not exist in the baseline " )
131
+ skippedModules. insert ( module)
132
+ continue
133
+ }
134
+ taskGroup. addTask {
135
+ do {
136
+ if let comparisonResult = try apiDigesterTool. compareAPIToBaseline (
137
+ at: moduleBaselinePath,
138
+ for: module,
139
+ buildPlan: try buildSystem. buildPlan,
140
+ except: breakageAllowlistPath
141
+ ) {
142
+ return comparisonResult
143
+ }
144
+ } catch {
145
+ swiftCommandState. observabilityScope. emit ( error: " failed to compare API to baseline " , underlyingError: error)
144
146
}
145
- } catch {
146
- swiftCommandState. observabilityScope. emit ( error: " failed to compare API to baseline " , underlyingError: error)
147
+ return nil
147
148
}
148
- semaphore. signal ( )
149
149
}
150
+ var results = [ SwiftAPIDigester . ComparisonResult] ( )
151
+ for await result in taskGroup {
152
+ guard let result else { continue }
153
+ results. append ( result)
154
+ }
155
+ return results
150
156
}
151
157
152
- group. wait ( )
153
-
154
158
let failedModules = modulesToDiff
155
159
. subtracting ( skippedModules)
156
160
. subtracting ( results. map ( \. moduleName) )
157
161
for failedModule in failedModules {
158
162
swiftCommandState. observabilityScope. emit ( error: " failed to read API digester output for \( failedModule) " )
159
163
}
160
164
161
- for result in results. get ( ) {
165
+ for result in results {
162
166
try self . printComparisonResult ( result, observabilityScope: swiftCommandState. observabilityScope)
163
167
}
164
168
165
- guard failedModules. isEmpty && results. get ( ) . allSatisfy ( \. hasNoAPIBreakingChanges) else {
169
+ guard failedModules. isEmpty && results. allSatisfy ( \. hasNoAPIBreakingChanges) else {
166
170
throw ExitCode . failure
167
171
}
168
172
}
0 commit comments