@@ -53,6 +53,12 @@ extension Components.Schemas.SwiftlyReleasePlatformArtifacts {
5353public protocol HTTPRequestExecutor {
5454 func execute( _ request: HTTPClientRequest , timeout: TimeAmount ) async throws -> HTTPClientResponse
5555 func getCurrentSwiftlyRelease( ) async throws -> Components . Schemas . SwiftlyRelease
56+ func getReleaseToolchains(
57+ platform: PlatformDefinition ,
58+ arch a: Components . Schemas . Architecture ? ,
59+ limit: Int ? ,
60+ filter: ( ( ToolchainVersion . StableRelease ) -> Bool ) ?
61+ ) async throws -> [ ToolchainVersion . StableRelease ]
5662}
5763
5864internal struct SwiftlyUserAgentMiddleware : ClientMiddleware {
@@ -128,6 +134,61 @@ internal class HTTPRequestExecutorImpl: HTTPRequestExecutor {
128134 let response = try await client. getCurrentSwiftlyRelease ( )
129135 return try response. ok. body. json
130136 }
137+
138+ public func getReleaseToolchains(
139+ platform: PlatformDefinition ,
140+ arch a: Components . Schemas . Architecture ? = nil ,
141+ limit: Int ? = nil ,
142+ filter: ( ( ToolchainVersion . StableRelease ) -> Bool ) ? = nil
143+ ) async throws -> [ ToolchainVersion . StableRelease ] {
144+ let arch = a ?? cpuArch
145+
146+ let config = AsyncHTTPClientTransport . Configuration ( client: self . httpClient, timeout: . seconds( 30 ) )
147+ let swiftlyUserAgent = SwiftlyUserAgentMiddleware ( )
148+
149+ let client = Client (
150+ serverURL: try Servers . Server1. url ( ) ,
151+ transport: AsyncHTTPClientTransport ( configuration: config) ,
152+ middlewares: [ swiftlyUserAgent]
153+ )
154+
155+ let response = try await client. listReleases ( )
156+
157+ var swiftOrgFiltered : [ ToolchainVersion . StableRelease ] = try response. ok. body. json. compactMap { swiftOrgRelease in
158+ if platform. name != PlatformDefinition . macOS. name {
159+ // If the platform isn't xcode then verify that there is an offering for this platform name and arch
160+ guard let swiftOrgPlatform = swiftOrgRelease. platforms. first ( where: { $0. matches ( platform) } ) else {
161+ return nil
162+ }
163+
164+ guard case let archs = swiftOrgPlatform. archs, archs. contains ( arch) else {
165+ return nil
166+ }
167+ }
168+
169+ guard let version = try ? ToolchainVersion ( parsing: swiftOrgRelease. stableName) ,
170+ case let . stable( release) = version
171+ else {
172+ throw SwiftlyError ( message: " error parsing swift.org release version: \( swiftOrgRelease. stableName) " )
173+ }
174+
175+ if let filter {
176+ guard filter ( release) else {
177+ return nil
178+ }
179+ }
180+
181+ return release
182+ }
183+
184+ swiftOrgFiltered. sort ( by: > )
185+
186+ return if let limit = limit {
187+ Array ( swiftOrgFiltered. prefix ( limit) )
188+ } else {
189+ swiftOrgFiltered
190+ }
191+ }
131192}
132193
133194private func makeRequest( url: String ) -> HTTPClientRequest {
@@ -136,13 +197,21 @@ private func makeRequest(url: String) -> HTTPClientRequest {
136197 return request
137198}
138199
139- struct SwiftOrgPlatform : Codable {
140- var name : String
141- var archs : [ String ] ?
200+ extension Components . Schemas . Release {
201+ var stableName : String {
202+ let components = self . name. components ( separatedBy: " . " )
203+ if components. count == 2 {
204+ return self . name + " .0 "
205+ } else {
206+ return self . name
207+ }
208+ }
209+ }
142210
143- /// platform is a mapping from the 'name' field of the swift.org platform object
211+ extension Components . Schemas . Platform {
212+ /// platformDef is a mapping from the 'name' field of the swift.org platform object
144213 /// to swiftly's PlatformDefinition, if possible.
145- var platform : PlatformDefinition ? {
214+ var platformDef : PlatformDefinition ? {
146215 // NOTE: some of these platforms are represented on swift.org metadata, but not supported by swiftly and so they don't have constants in PlatformDefinition
147216 switch self . name {
148217 case " Ubuntu 14.04 " :
@@ -181,28 +250,14 @@ struct SwiftOrgPlatform: Codable {
181250 }
182251
183252 func matches( _ platform: PlatformDefinition ) -> Bool {
184- guard let myPlatform = self . platform else {
253+ guard let myPlatform = self . platformDef else {
185254 return false
186255 }
187256
188257 return myPlatform. name == platform. name
189258 }
190259}
191260
192- public struct SwiftOrgRelease : Codable {
193- var name : String
194- var platforms : [ SwiftOrgPlatform ]
195-
196- var stableName : String {
197- let components = self . name. components ( separatedBy: " . " )
198- if components. count == 2 {
199- return self . name + " .0 "
200- } else {
201- return self . name
202- }
203- }
204- }
205-
206261public struct SwiftOrgSnapshotList : Codable {
207262 var aarch64 : [ SwiftOrgSnapshot ] ?
208263 var x86_64 : [ SwiftOrgSnapshot ] ?
@@ -291,49 +346,11 @@ public struct SwiftlyHTTPClient {
291346 /// limit (default unlimited).
292347 public func getReleaseToolchains(
293348 platform: PlatformDefinition ,
294- arch a: String ? = nil ,
349+ arch a: Components . Schemas . Architecture ? = nil ,
295350 limit: Int ? = nil ,
296351 filter: ( ( ToolchainVersion . StableRelease ) -> Bool ) ? = nil
297352 ) async throws -> [ ToolchainVersion . StableRelease ] {
298- let arch = a ?? cpuArch
299-
300- let url = " https://www.swift.org/api/v1/install/releases.json "
301- let swiftOrgReleases : [ SwiftOrgRelease ] = try await self . getFromJSON ( url: url, type: [ SwiftOrgRelease ] . self)
302-
303- var swiftOrgFiltered : [ ToolchainVersion . StableRelease ] = try swiftOrgReleases. compactMap { swiftOrgRelease in
304- if platform. name != PlatformDefinition . macOS. name {
305- // If the platform isn't xcode then verify that there is an offering for this platform name and arch
306- guard let swiftOrgPlatform = swiftOrgRelease. platforms. first ( where: { $0. matches ( platform) } ) else {
307- return nil
308- }
309-
310- guard let archs = swiftOrgPlatform. archs, archs. contains ( arch) else {
311- return nil
312- }
313- }
314-
315- guard let version = try ? ToolchainVersion ( parsing: swiftOrgRelease. stableName) ,
316- case let . stable( release) = version
317- else {
318- throw SwiftlyError ( message: " error parsing swift.org release version: \( swiftOrgRelease. stableName) " )
319- }
320-
321- if let filter {
322- guard filter ( release) else {
323- return nil
324- }
325- }
326-
327- return release
328- }
329-
330- swiftOrgFiltered. sort ( by: > )
331-
332- return if let limit = limit {
333- Array ( swiftOrgFiltered. prefix ( limit) )
334- } else {
335- swiftOrgFiltered
336- }
353+ try await SwiftlyCore . httpRequestExecutor. getReleaseToolchains ( platform: platform, arch: a, limit: limit, filter: filter)
337354 }
338355
339356 public struct SnapshotBranchNotFoundError : LocalizedError {
@@ -349,7 +366,7 @@ public struct SwiftlyHTTPClient {
349366 limit: Int ? = nil ,
350367 filter: ( ( ToolchainVersion . Snapshot ) -> Bool ) ? = nil
351368 ) async throws -> [ ToolchainVersion . Snapshot ] {
352- let arch = a ?? cpuArch
369+ let arch = a ?? String ( describing : cpuArch)
353370
354371 let platformName = if platform. name == PlatformDefinition . macOS. name {
355372 " macos "
0 commit comments