@@ -17,6 +17,7 @@ import Dispatch
1717import PackageGraph
1818import PackageModel
1919import SourceControl
20+ import _Concurrency
2021
2122struct DeprecatedAPIDiff : ParsableCommand {
2223 static let configuration = CommandConfiguration ( commandName: " experimental-api-diff " ,
@@ -119,50 +120,53 @@ struct APIDiff: AsyncSwiftCommand {
119120 swiftCommandState: swiftCommandState
120121 )
121122
122- let results = ThreadSafeArrayStore < SwiftAPIDigester . ComparisonResult > ( )
123- let group = DispatchGroup ( )
124- let semaphore = DispatchSemaphore ( value: Int ( try buildSystem. buildPlan. destinationBuildParameters. workers) )
125123 var skippedModules : Set < String > = [ ]
126124
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)
144146 }
145- } catch {
146- swiftCommandState. observabilityScope. emit ( error: " failed to compare API to baseline " , underlyingError: error)
147+ return nil
147148 }
148- semaphore. signal ( )
149149 }
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
150156 }
151157
152- group. wait ( )
153-
154158 let failedModules = modulesToDiff
155159 . subtracting ( skippedModules)
156160 . subtracting ( results. map ( \. moduleName) )
157161 for failedModule in failedModules {
158162 swiftCommandState. observabilityScope. emit ( error: " failed to read API digester output for \( failedModule) " )
159163 }
160164
161- for result in results. get ( ) {
165+ for result in results {
162166 try self . printComparisonResult ( result, observabilityScope: swiftCommandState. observabilityScope)
163167 }
164168
165- guard failedModules. isEmpty && results. get ( ) . allSatisfy ( \. hasNoAPIBreakingChanges) else {
169+ guard failedModules. isEmpty && results. allSatisfy ( \. hasNoAPIBreakingChanges) else {
166170 throw ExitCode . failure
167171 }
168172 }
0 commit comments