@@ -50,9 +50,17 @@ extension Components.Schemas.SwiftlyReleasePlatformArtifacts {
5050 }
5151}
5252
53+ extension Components . Schemas . SwiftlyPlatformIdentifier {
54+ public init ( _ knownSwiftlyPlatformIdentifier: Components . Schemas . KnownSwiftlyPlatformIdentifier ) {
55+ self . init ( value1: knownSwiftlyPlatformIdentifier)
56+ }
57+ }
58+
5359public protocol HTTPRequestExecutor {
5460 func execute( _ request: HTTPClientRequest , timeout: TimeAmount ) async throws -> HTTPClientResponse
5561 func getCurrentSwiftlyRelease( ) async throws -> Components . Schemas . SwiftlyRelease
62+ func getReleaseToolchains( ) async throws -> [ Components . Schemas . Release ]
63+ func getSnapshotToolchains( branch: Components . Schemas . SourceBranch , platform: Components . Schemas . PlatformIdentifier ) async throws -> Components . Schemas . DevToolchains
5664}
5765
5866struct SwiftlyUserAgentMiddleware : ClientMiddleware {
@@ -128,6 +136,36 @@ class HTTPRequestExecutorImpl: HTTPRequestExecutor {
128136 let response = try await client. getCurrentSwiftlyRelease ( )
129137 return try response. ok. body. json
130138 }
139+
140+ public func getReleaseToolchains( ) async throws -> [ Components . Schemas . Release ] {
141+ let config = AsyncHTTPClientTransport . Configuration ( client: self . httpClient, timeout: . seconds( 30 ) )
142+ let swiftlyUserAgent = SwiftlyUserAgentMiddleware ( )
143+
144+ let client = Client (
145+ serverURL: try Servers . Server1. url ( ) ,
146+ transport: AsyncHTTPClientTransport ( configuration: config) ,
147+ middlewares: [ swiftlyUserAgent]
148+ )
149+
150+ let response = try await client. listReleases ( )
151+
152+ return try response. ok. body. json
153+ }
154+
155+ public func getSnapshotToolchains( branch: Components . Schemas . SourceBranch , platform: Components . Schemas . PlatformIdentifier ) async throws -> Components . Schemas . DevToolchains {
156+ let config = AsyncHTTPClientTransport . Configuration ( client: self . httpClient, timeout: . seconds( 30 ) )
157+ let swiftlyUserAgent = SwiftlyUserAgentMiddleware ( )
158+
159+ let client = Client (
160+ serverURL: try Servers . Server1. url ( ) ,
161+ transport: AsyncHTTPClientTransport ( configuration: config) ,
162+ middlewares: [ swiftlyUserAgent]
163+ )
164+
165+ let response = try await client. listDevToolchains ( . init( path: . init( branch: branch, platform: platform) ) )
166+
167+ return try response. ok. body. json
168+ }
131169}
132170
133171private func makeRequest( url: String ) -> HTTPClientRequest {
@@ -136,13 +174,56 @@ private func makeRequest(url: String) -> HTTPClientRequest {
136174 return request
137175}
138176
139- struct SwiftOrgPlatform : Codable {
140- var name : String
141- var archs : [ String ] ?
177+ extension Components . Schemas . Release {
178+ var stableName : String {
179+ let components = self . name. components ( separatedBy: " . " )
180+ if components. count == 2 {
181+ return self . name + " .0 "
182+ } else {
183+ return self . name
184+ }
185+ }
186+ }
142187
143- /// platform is a mapping from the 'name' field of the swift.org platform object
188+ extension Components . Schemas . Architecture {
189+ public init ( _ knownArchitecture: Components . Schemas . KnownArchitecture ) {
190+ self . init ( value1: knownArchitecture, value2: knownArchitecture. rawValue)
191+ }
192+
193+ public init ( _ string: String ) {
194+ self . init ( value2: string)
195+ }
196+ }
197+
198+ extension Components . Schemas . PlatformIdentifier {
199+ public init ( _ knownPlatformIdentifier: Components . Schemas . KnownPlatformIdentifier ) {
200+ self . init ( value1: knownPlatformIdentifier)
201+ }
202+
203+ public init ( _ string: String ) {
204+ self . init ( value2: string)
205+ }
206+ }
207+
208+ extension Components . Schemas . SourceBranch {
209+ public init ( _ knownSourceBranch: Components . Schemas . KnownSourceBranch ) {
210+ self . init ( value1: knownSourceBranch)
211+ }
212+
213+ public init ( _ string: String ) {
214+ self . init ( value2: string)
215+ }
216+ }
217+
218+ extension Components . Schemas . Architecture {
219+ static var x8664 : Components . Schemas . Architecture = . init( Components . Schemas. KnownArchitecture. x8664)
220+ static var aarch64 : Components . Schemas . Architecture = . init( Components . Schemas. KnownArchitecture. aarch64)
221+ }
222+
223+ extension Components . Schemas . Platform {
224+ /// platformDef is a mapping from the 'name' field of the swift.org platform object
144225 /// to swiftly's PlatformDefinition, if possible.
145- var platform : PlatformDefinition ? {
226+ var platformDef : PlatformDefinition ? {
146227 // 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
147228 switch self . name {
148229 case " Ubuntu 14.04 " :
@@ -172,46 +253,24 @@ struct SwiftOrgPlatform: Codable {
172253 case " Ubuntu 24.04 " :
173254 PlatformDefinition ( name: " ubuntu2404 " , nameFull: " ubuntu24.04 " , namePretty: " Ubuntu 24.04 " )
174255 case " Debian 12 " :
175- PlatformDefinition ( name: " debian12 " , nameFull: " debian12 " , namePretty: " Debian 12 " )
256+ PlatformDefinition ( name: " debian12 " , nameFull: " debian12 " , namePretty: " Debian GNU/Linux 12 " )
176257 case " Fedora 39 " :
177- PlatformDefinition ( name: " fedora39 " , nameFull: " fedora39 " , namePretty: " Fedora 39 " )
258+ PlatformDefinition ( name: " fedora39 " , nameFull: " fedora39 " , namePretty: " Fedora Linux 39 " )
178259 default :
179260 nil
180261 }
181262 }
182263
183264 func matches( _ platform: PlatformDefinition ) -> Bool {
184- guard let myPlatform = self . platform else {
265+ guard let myPlatform = self . platformDef else {
185266 return false
186267 }
187268
188269 return myPlatform. name == platform. name
189270 }
190271}
191272
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-
206- public struct SwiftOrgSnapshotList : Codable {
207- var aarch64 : [ SwiftOrgSnapshot ] ?
208- var x86_64 : [ SwiftOrgSnapshot ] ?
209- var universal : [ SwiftOrgSnapshot ] ?
210- }
211-
212- public struct SwiftOrgSnapshot : Codable {
213- var dir : String
214-
273+ extension Components . Schemas . DevToolchainForArch {
215274 private static let snapshotRegex : Regex < ( Substring , Substring ? , Substring ? , Substring ) > =
216275 try ! Regex ( " swift(?:-( \\ d+) \\ .( \\ d+))?-DEVELOPMENT-SNAPSHOT-( \\ d{4}- \\ d{2}- \\ d{2}) " )
217276
@@ -291,23 +350,22 @@ public struct SwiftlyHTTPClient {
291350 /// limit (default unlimited).
292351 public func getReleaseToolchains(
293352 platform: PlatformDefinition ,
294- arch a: String ? = nil ,
353+ arch a: Components . Schemas . Architecture ? = nil ,
295354 limit: Int ? = nil ,
296355 filter: ( ( ToolchainVersion . StableRelease ) -> Bool ) ? = nil
297356 ) async throws -> [ ToolchainVersion . StableRelease ] {
298357 let arch = a ?? cpuArch
299358
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)
359+ let releases = try await SwiftlyCore . httpRequestExecutor. getReleaseToolchains ( )
302360
303- var swiftOrgFiltered : [ ToolchainVersion . StableRelease ] = try swiftOrgReleases . compactMap { swiftOrgRelease in
361+ var swiftOrgFiltered : [ ToolchainVersion . StableRelease ] = try releases . compactMap { swiftOrgRelease in
304362 if platform. name != PlatformDefinition . macOS. name {
305363 // If the platform isn't xcode then verify that there is an offering for this platform name and arch
306364 guard let swiftOrgPlatform = swiftOrgRelease. platforms. first ( where: { $0. matches ( platform) } ) else {
307365 return nil
308366 }
309367
310- guard let archs = swiftOrgPlatform. archs, archs. contains ( arch) else {
368+ guard case let archs = swiftOrgPlatform. archs, archs. contains ( arch) else {
311369 return nil
312370 }
313371 }
@@ -349,35 +407,45 @@ public struct SwiftlyHTTPClient {
349407 limit: Int ? = nil ,
350408 filter: ( ( ToolchainVersion . Snapshot ) -> Bool ) ? = nil
351409 ) async throws -> [ ToolchainVersion . Snapshot ] {
352- let arch = a ?? cpuArch
410+ let platformId : Components . Schemas . PlatformIdentifier = switch platform. name {
411+ // These are new platforms that aren't yet in the list of known platforms in the OpenAPI schema
412+ case PlatformDefinition . ubuntu2404. name, PlatformDefinition . debian12. name, PlatformDefinition . fedora39. name:
413+ . init( platform. name)
414+
415+ case PlatformDefinition . ubuntu2204. name:
416+ . init( . ubuntu2204)
417+ case PlatformDefinition . ubuntu2004. name:
418+ . init( . ubuntu2004)
419+ case PlatformDefinition . rhel9. name:
420+ . init( . ubi9)
421+ case PlatformDefinition . amazonlinux2. name:
422+ . init( . amazonlinux2)
423+ case PlatformDefinition . macOS. name:
424+ . init( . macos)
425+ default :
426+ throw SwiftlyError ( message: " No snapshot toolchains available for platform \( platform. name) " )
427+ }
353428
354- let platformName = if platform. name == PlatformDefinition . macOS. name {
355- " macos "
356- } else {
357- platform. name
429+ let sourceBranch : Components . Schemas . SourceBranch = switch branch {
430+ case . main:
431+ . init( . main)
432+ case let . release( major, minor) :
433+ . init( " \( major) . \( minor) " )
358434 }
359435
360- let url = " https://www.swift.org/api/v1/install/dev/ \ ( branch. name ) / \( platformName ) .json "
436+ let devToolchains = try await SwiftlyCore . httpRequestExecutor . getSnapshotToolchains ( branch: sourceBranch , platform : platformId )
361437
362- // For a particular branch and platform the snapshots are listed underneath their architecture
363- let swiftOrgSnapshotArchs : SwiftOrgSnapshotList
364- do {
365- swiftOrgSnapshotArchs = try await self . getFromJSON ( url: url, type: SwiftOrgSnapshotList . self)
366- } catch is JSONNotFoundError {
367- throw SnapshotBranchNotFoundError ( branch: branch)
368- } catch {
369- throw error
370- }
438+ let arch = a ?? cpuArch. value2
371439
372440 // These are the available snapshots for the branch, platform, and architecture
373441 let swiftOrgSnapshots = if platform. name == PlatformDefinition . macOS. name {
374- swiftOrgSnapshotArchs . universal ?? [ SwiftOrgSnapshot ] ( )
442+ devToolchains . universal ?? [ Components . Schemas . DevToolchainForArch ] ( )
375443 } else if arch == " aarch64 " {
376- swiftOrgSnapshotArchs . aarch64 ?? [ SwiftOrgSnapshot ] ( )
444+ devToolchains . aarch64 ?? [ Components . Schemas . DevToolchainForArch ] ( )
377445 } else if arch == " x86_64 " {
378- swiftOrgSnapshotArchs . x86_64 ?? [ SwiftOrgSnapshot ] ( )
446+ devToolchains . x8664 ?? [ Components . Schemas . DevToolchainForArch ] ( )
379447 } else {
380- [ SwiftOrgSnapshot ] ( )
448+ [ Components . Schemas . DevToolchainForArch ] ( )
381449 }
382450
383451 // Convert these into toolchain snapshot versions that match the filter
0 commit comments