Skip to content

Commit bf0272c

Browse files
authored
Move PackageCollectionsProtocol to async/await (#7726)
### Motivation: `async`/`await` is easier to read and reason about then the callback APIs ### Modifications: * `PackageCollectionsProtocol` is now expressed in terms of `async` methods instead of callbacks * Callback to `async` bridge methods are removed * Replaced usage of `DispatchGroup` with `async let` * `PackageMetadata.init` has default values for optional and array values ### Result: More readable code.
1 parent e8d3d42 commit bf0272c

File tree

6 files changed

+488
-985
lines changed

6 files changed

+488
-985
lines changed

Sources/PackageCollections/API.swift

Lines changed: 25 additions & 233 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,20 @@ public protocol PackageCollectionsProtocol {
2727
///
2828
/// - Parameters:
2929
/// - identifiers: Optional. If specified, only `PackageCollection`s with matching identifiers will be returned.
30-
/// - callback: The closure to invoke when result becomes available
31-
@available(*, noasync, message: "Use the async alternative")
3230
func listCollections(
33-
identifiers: Set<PackageCollectionsModel.CollectionIdentifier>?,
34-
callback: @escaping (Result<[PackageCollectionsModel.Collection], Error>) -> Void
35-
)
31+
identifiers: Set<PackageCollectionsModel.CollectionIdentifier>?
32+
) async throws -> [PackageCollectionsModel.Collection]
3633

3734
/// Refreshes all configured package collections.
38-
///
39-
/// - Parameters:
40-
/// - callback: The closure to invoke after triggering a refresh for the configured package collections.
41-
@available(*, noasync, message: "Use the async alternative")
42-
func refreshCollections(callback: @escaping (Result<[PackageCollectionsModel.CollectionSource], Error>) -> Void)
35+
func refreshCollections() async throws -> [PackageCollectionsModel.CollectionSource]
4336

4437
/// Refreshes a package collection.
4538
///
4639
/// - Parameters:
4740
/// - source: The package collection to be refreshed
48-
/// - callback: The closure to invoke with the refreshed `PackageCollection`
49-
@available(*, noasync, message: "Use the async alternative")
5041
func refreshCollection(
51-
_ source: PackageCollectionsModel.CollectionSource,
52-
callback: @escaping (Result<PackageCollectionsModel.Collection, Error>) -> Void
53-
)
42+
_ source: PackageCollectionsModel.CollectionSource
43+
) async throws -> PackageCollectionsModel.Collection
5444

5545
/// Adds a package collection.
5646
///
@@ -59,77 +49,46 @@ public protocol PackageCollectionsProtocol {
5949
/// - order: Optional. The order that the `PackageCollection` should take after being added to the list.
6050
/// By default the new collection is appended to the end (i.e., the least relevant order).
6151
/// - trustConfirmationProvider: The closure to invoke when the collection is not signed and user confirmation is required to proceed
62-
/// - callback: The closure to invoke with the newly added `PackageCollection`
63-
@available(*, noasync, message: "Use the async alternative")
6452
func addCollection(
6553
_ source: PackageCollectionsModel.CollectionSource,
6654
order: Int?,
67-
trustConfirmationProvider: ((PackageCollectionsModel.Collection, @escaping (Bool) -> Void) -> Void)?,
68-
callback: @escaping (Result<PackageCollectionsModel.Collection, Error>) -> Void
69-
)
55+
trustConfirmationProvider: ((PackageCollectionsModel.Collection, @escaping (Bool) -> Void) -> Void)?
56+
) async throws -> PackageCollectionsModel.Collection
7057

7158
/// Removes a package collection.
7259
///
7360
/// - Parameters:
7461
/// - source: The package collection's source
75-
/// - callback: The closure to invoke with the result becomes available
76-
@available(*, noasync, message: "Use the async alternative")
7762
func removeCollection(
78-
_ source: PackageCollectionsModel.CollectionSource,
79-
callback: @escaping (Result<Void, Error>) -> Void
80-
)
63+
_ source: PackageCollectionsModel.CollectionSource
64+
) async throws
8165

8266
/// Moves a package collection to a different order.
8367
///
8468
/// - Parameters:
8569
/// - source: The source of the `PackageCollection` to be reordered
8670
/// - order: The new order that the `PackageCollection` should be positioned after the move
87-
/// - callback: The closure to invoke with the result becomes available
88-
@available(*, noasync, message: "Use the async alternative")
8971
func moveCollection(
9072
_ source: PackageCollectionsModel.CollectionSource,
91-
to order: Int,
92-
callback: @escaping (Result<Void, Error>) -> Void
93-
)
73+
to order: Int
74+
) async throws
9475

9576
/// Updates settings of a `PackageCollection` source (e.g., if it is trusted or not).
9677
///
9778
/// - Parameters:
9879
/// - source: The `PackageCollection` source to be updated
99-
/// - callback: The closure to invoke when result becomes available
100-
@available(*, noasync, message: "Use the async alternative")
10180
func updateCollection(
102-
_ source: PackageCollectionsModel.CollectionSource,
103-
callback: @escaping (Result<PackageCollectionsModel.Collection, Error>) -> Void
104-
)
81+
_ source: PackageCollectionsModel.CollectionSource
82+
) async throws -> PackageCollectionsModel.Collection
10583

10684
/// Returns information about a package collection. The collection is not required to be in the configured list. If
10785
/// not found locally, the collection will be fetched from the source.
10886
///
10987
/// - Parameters:
11088
/// - source: The package collection's source
111-
/// - callback: The closure to invoke with the `PackageCollection`
112-
@available(*, noasync, message: "Use the async alternative")
11389
func getCollection(
114-
_ source: PackageCollectionsModel.CollectionSource,
115-
callback: @escaping (Result<PackageCollectionsModel.Collection, Error>) -> Void
116-
)
117-
118-
/// Returns metadata for the package identified by the given `PackageIdentity`, along with the
119-
/// identifiers of `PackageCollection`s where the package is found.
120-
///
121-
/// A failure is returned if the package is not found.
122-
///
123-
/// - Parameters:
124-
/// - identity: The package identity
125-
/// - location: The package location (optional for deduplication)
126-
/// - callback: The closure to invoke when result becomes available
127-
@available(*, noasync, message: "Use the async alternative")
128-
func getPackageMetadata(
129-
identity: PackageIdentity,
130-
location: String?,
131-
callback: @escaping (Result<PackageCollectionsModel.PackageMetadata, Error>) -> Void
132-
)
90+
_ source: PackageCollectionsModel.CollectionSource
91+
) async throws -> PackageCollectionsModel.Collection
13392

13493
/// Returns metadata for the package identified by the given `PackageIdentity`, along with the
13594
/// identifiers of `PackageCollection`s where the package is found.
@@ -141,25 +100,19 @@ public protocol PackageCollectionsProtocol {
141100
/// - location: The package location (optional for deduplication)
142101
/// - collections: Optional. If specified, only look for package in these collections. Data from the most recently
143102
/// processed collection will be used.
144-
/// - callback: The closure to invoke when result becomes available
145-
@available(*, noasync, message: "Use the async alternative")
146103
func getPackageMetadata(
147104
identity: PackageIdentity,
148105
location: String?,
149-
collections: Set<PackageCollectionsModel.CollectionIdentifier>?,
150-
callback: @escaping (Result<PackageCollectionsModel.PackageMetadata, Error>) -> Void
151-
)
106+
collections: Set<PackageCollectionsModel.CollectionIdentifier>?
107+
) async throws -> PackageCollectionsModel.PackageMetadata
152108

153109
/// Lists packages from the specified collections.
154110
///
155111
/// - Parameters:
156112
/// - collections: Optional. If specified, only packages in these collections are included.
157-
/// - callback: The closure to invoke when result becomes available
158-
@available(*, noasync, message: "Use the async alternative")
159113
func listPackages(
160-
collections: Set<PackageCollectionsModel.CollectionIdentifier>?,
161-
callback: @escaping (Result<PackageCollectionsModel.PackageSearchResult, Error>) -> Void
162-
)
114+
collections: Set<PackageCollectionsModel.CollectionIdentifier>?
115+
) async throws -> PackageCollectionsModel.PackageSearchResult
163116

164117
// MARK: - Target (Module) APIs
165118

@@ -171,12 +124,9 @@ public protocol PackageCollectionsProtocol {
171124
///
172125
/// - Parameters:
173126
/// - collections: Optional. If specified, only list targets within these collections.
174-
/// - callback: The closure to invoke when result becomes available
175-
@available(*, noasync, message: "Use the async alternative")
176127
func listTargets(
177-
collections: Set<PackageCollectionsModel.CollectionIdentifier>?,
178-
callback: @escaping (Result<PackageCollectionsModel.TargetListResult, Error>) -> Void
179-
)
128+
collections: Set<PackageCollectionsModel.CollectionIdentifier>?
129+
) async throws -> PackageCollectionsModel.TargetListResult
180130

181131
// MARK: - Search APIs
182132

@@ -188,13 +138,10 @@ public protocol PackageCollectionsProtocol {
188138
/// - Parameters:
189139
/// - query: The search query
190140
/// - collections: Optional. If specified, only search within these collections.
191-
/// - callback: The closure to invoke when result becomes available
192-
@available(*, noasync, message: "Use the async alternative")
193141
func findPackages(
194142
_ query: String,
195-
collections: Set<PackageCollectionsModel.CollectionIdentifier>?,
196-
callback: @escaping (Result<PackageCollectionsModel.PackageSearchResult, Error>) -> Void
197-
)
143+
collections: Set<PackageCollectionsModel.CollectionIdentifier>?
144+
) async throws -> PackageCollectionsModel.PackageSearchResult
198145

199146
/// Finds targets by name and returns the corresponding packages.
200147
///
@@ -206,168 +153,13 @@ public protocol PackageCollectionsProtocol {
206153
/// - searchType: Optional. Target names must either match exactly or contain the prefix.
207154
/// For more flexibility, use the `findPackages` API instead.
208155
/// - collections: Optional. If specified, only search within these collections.
209-
/// - callback: The closure to invoke when result becomes available
210-
@available(*, noasync, message: "Use the async alternative")
211156
func findTargets(
212157
_ query: String,
213158
searchType: PackageCollectionsModel.TargetSearchType?,
214-
collections: Set<PackageCollectionsModel.CollectionIdentifier>?,
215-
callback: @escaping (Result<PackageCollectionsModel.TargetSearchResult, Error>) -> Void
216-
)
159+
collections: Set<PackageCollectionsModel.CollectionIdentifier>?
160+
) async throws -> PackageCollectionsModel.TargetSearchResult
217161
}
218162

219-
public extension PackageCollectionsProtocol {
220-
func listCollections(
221-
identifiers: Set<PackageCollectionsModel.CollectionIdentifier>? = nil
222-
) async throws -> [PackageCollectionsModel.Collection] {
223-
try await safe_async {
224-
self.listCollections(identifiers: identifiers, callback: $0)
225-
}
226-
}
227-
228-
func refreshCollections() async throws -> [PackageCollectionsModel.CollectionSource] {
229-
try await safe_async {
230-
self.refreshCollections(callback: $0)
231-
}
232-
}
233-
234-
func refreshCollection(
235-
_ source: PackageCollectionsModel.CollectionSource
236-
) async throws -> PackageCollectionsModel.Collection {
237-
try await safe_async {
238-
self.refreshCollection(
239-
source,
240-
callback: $0
241-
)
242-
}
243-
}
244-
245-
func addCollection(
246-
_ source: PackageCollectionsModel.CollectionSource,
247-
order: Int? = nil,
248-
trustConfirmationProvider: ((PackageCollectionsModel.Collection, @escaping (Bool) -> Void) -> Void)? = nil
249-
) async throws -> PackageCollectionsModel.Collection {
250-
try await safe_async {
251-
self.addCollection(
252-
source,
253-
order: order,
254-
trustConfirmationProvider:trustConfirmationProvider,
255-
callback: $0
256-
)
257-
}
258-
}
259-
260-
func removeCollection(
261-
_ source: PackageCollectionsModel.CollectionSource
262-
) async throws {
263-
try await safe_async {
264-
self.removeCollection(
265-
source,
266-
callback: $0
267-
)
268-
}
269-
}
270-
271-
func moveCollection(
272-
_ source: PackageCollectionsModel.CollectionSource,
273-
to order: Int
274-
) async throws {
275-
try await safe_async {
276-
self.moveCollection(
277-
source,
278-
to: order,
279-
callback: $0
280-
)
281-
}
282-
}
283-
284-
func updateCollection(
285-
_ source: PackageCollectionsModel.CollectionSource
286-
) async throws -> PackageCollectionsModel.Collection {
287-
try await safe_async {
288-
self.updateCollection(
289-
source,
290-
callback: $0
291-
)
292-
}
293-
}
294-
295-
func getCollection(
296-
_ source: PackageCollectionsModel.CollectionSource
297-
) async throws -> PackageCollectionsModel.Collection {
298-
try await safe_async {
299-
self.getCollection(
300-
source,
301-
callback: $0
302-
)
303-
}
304-
}
305-
306-
func getPackageMetadata(
307-
identity: PackageIdentity,
308-
location: String? = nil,
309-
collections: Set<PackageCollectionsModel.CollectionIdentifier>? = nil
310-
) async throws -> PackageCollectionsModel.PackageMetadata {
311-
try await safe_async {
312-
self.getPackageMetadata(
313-
identity: identity,
314-
location: location,
315-
collections: collections,
316-
callback: $0
317-
)
318-
}
319-
}
320-
321-
func listPackages(
322-
collections: Set<PackageCollectionsModel.CollectionIdentifier>? = nil
323-
) async throws -> PackageCollectionsModel.PackageSearchResult {
324-
try await safe_async {
325-
self.listPackages(
326-
collections: collections,
327-
callback: $0
328-
)
329-
}
330-
}
331-
332-
func listTargets(
333-
collections: Set<PackageCollectionsModel.CollectionIdentifier>? = nil
334-
) async throws -> PackageCollectionsModel.TargetListResult {
335-
try await safe_async {
336-
self.listTargets(
337-
collections: collections,
338-
callback: $0
339-
)
340-
}
341-
}
342-
343-
func findPackages(
344-
_ query: String,
345-
collections: Set<PackageCollectionsModel.CollectionIdentifier>? = nil
346-
) async throws -> PackageCollectionsModel.PackageSearchResult {
347-
try await safe_async {
348-
self.findPackages(
349-
query,
350-
collections: collections,
351-
callback: $0
352-
)
353-
}
354-
}
355-
356-
func findTargets(
357-
_ query: String,
358-
searchType: PackageCollectionsModel.TargetSearchType? = nil,
359-
collections: Set<PackageCollectionsModel.CollectionIdentifier>? = nil
360-
) async throws -> PackageCollectionsModel.TargetSearchResult {
361-
try await safe_async {
362-
self.findTargets(
363-
query,
364-
searchType: searchType,
365-
collections: collections,
366-
callback: $0
367-
)
368-
}
369-
}
370-
}
371163

372164
public enum PackageCollectionError: Equatable, Error {
373165
/// Package collection is not signed and there is no record of user's trust selection

0 commit comments

Comments
 (0)