diff --git a/Sources/SwiftlyCore/HTTPClient.swift b/Sources/SwiftlyCore/HTTPClient.swift index 85ee37be..c3644348 100644 --- a/Sources/SwiftlyCore/HTTPClient.swift +++ b/Sources/SwiftlyCore/HTTPClient.swift @@ -50,9 +50,17 @@ extension Components.Schemas.SwiftlyReleasePlatformArtifacts { } } +extension Components.Schemas.SwiftlyPlatformIdentifier { + public init(_ knownSwiftlyPlatformIdentifier: Components.Schemas.KnownSwiftlyPlatformIdentifier) { + self.init(value1: knownSwiftlyPlatformIdentifier) + } +} + public protocol HTTPRequestExecutor { func execute(_ request: HTTPClientRequest, timeout: TimeAmount) async throws -> HTTPClientResponse func getCurrentSwiftlyRelease() async throws -> Components.Schemas.SwiftlyRelease + func getReleaseToolchains() async throws -> [Components.Schemas.Release] + func getSnapshotToolchains(branch: Components.Schemas.SourceBranch, platform: Components.Schemas.PlatformIdentifier) async throws -> Components.Schemas.DevToolchains } internal struct SwiftlyUserAgentMiddleware: ClientMiddleware { @@ -128,6 +136,36 @@ internal class HTTPRequestExecutorImpl: HTTPRequestExecutor { let response = try await client.getCurrentSwiftlyRelease() return try response.ok.body.json } + + public func getReleaseToolchains() async throws -> [Components.Schemas.Release] { + let config = AsyncHTTPClientTransport.Configuration(client: self.httpClient, timeout: .seconds(30)) + let swiftlyUserAgent = SwiftlyUserAgentMiddleware() + + let client = Client( + serverURL: try Servers.Server1.url(), + transport: AsyncHTTPClientTransport(configuration: config), + middlewares: [swiftlyUserAgent] + ) + + let response = try await client.listReleases() + + return try response.ok.body.json + } + + public func getSnapshotToolchains(branch: Components.Schemas.SourceBranch, platform: Components.Schemas.PlatformIdentifier) async throws -> Components.Schemas.DevToolchains { + let config = AsyncHTTPClientTransport.Configuration(client: self.httpClient, timeout: .seconds(30)) + let swiftlyUserAgent = SwiftlyUserAgentMiddleware() + + let client = Client( + serverURL: try Servers.Server1.url(), + transport: AsyncHTTPClientTransport(configuration: config), + middlewares: [swiftlyUserAgent] + ) + + let response = try await client.listDevToolchains(.init(path: .init(branch: branch, platform: platform))) + + return try response.ok.body.json + } } private func makeRequest(url: String) -> HTTPClientRequest { @@ -136,13 +174,56 @@ private func makeRequest(url: String) -> HTTPClientRequest { return request } -struct SwiftOrgPlatform: Codable { - var name: String - var archs: [String]? +extension Components.Schemas.Release { + var stableName: String { + let components = self.name.components(separatedBy: ".") + if components.count == 2 { + return self.name + ".0" + } else { + return self.name + } + } +} - /// platform is a mapping from the 'name' field of the swift.org platform object +extension Components.Schemas.Architecture { + public init(_ knownArchitecture: Components.Schemas.KnownArchitecture) { + self.init(value1: knownArchitecture, value2: knownArchitecture.rawValue) + } + + public init(_ string: String) { + self.init(value2: string) + } +} + +extension Components.Schemas.PlatformIdentifier { + public init(_ knownPlatformIdentifier: Components.Schemas.KnownPlatformIdentifier) { + self.init(value1: knownPlatformIdentifier) + } + + public init(_ string: String) { + self.init(value2: string) + } +} + +extension Components.Schemas.SourceBranch { + public init(_ knownSourceBranch: Components.Schemas.KnownSourceBranch) { + self.init(value1: knownSourceBranch) + } + + public init(_ string: String) { + self.init(value2: string) + } +} + +extension Components.Schemas.Architecture { + static var x8664: Components.Schemas.Architecture = .init(Components.Schemas.KnownArchitecture.x8664) + static var aarch64: Components.Schemas.Architecture = .init(Components.Schemas.KnownArchitecture.aarch64) +} + +extension Components.Schemas.Platform { + /// platformDef is a mapping from the 'name' field of the swift.org platform object /// to swiftly's PlatformDefinition, if possible. - var platform: PlatformDefinition? { + var platformDef: PlatformDefinition? { // 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 switch self.name { case "Ubuntu 14.04": @@ -172,16 +253,16 @@ struct SwiftOrgPlatform: Codable { case "Ubuntu 24.04": PlatformDefinition(name: "ubuntu2404", nameFull: "ubuntu24.04", namePretty: "Ubuntu 24.04") case "Debian 12": - PlatformDefinition(name: "debian12", nameFull: "debian12", namePretty: "Debian 12") + PlatformDefinition(name: "debian12", nameFull: "debian12", namePretty: "Debian GNU/Linux 12") case "Fedora 39": - PlatformDefinition(name: "fedora39", nameFull: "fedora39", namePretty: "Fedora 39") + PlatformDefinition(name: "fedora39", nameFull: "fedora39", namePretty: "Fedora Linux 39") default: nil } } func matches(_ platform: PlatformDefinition) -> Bool { - guard let myPlatform = self.platform else { + guard let myPlatform = self.platformDef else { return false } @@ -189,29 +270,7 @@ struct SwiftOrgPlatform: Codable { } } -public struct SwiftOrgRelease: Codable { - var name: String - var platforms: [SwiftOrgPlatform] - - var stableName: String { - let components = self.name.components(separatedBy: ".") - if components.count == 2 { - return self.name + ".0" - } else { - return self.name - } - } -} - -public struct SwiftOrgSnapshotList: Codable { - var aarch64: [SwiftOrgSnapshot]? - var x86_64: [SwiftOrgSnapshot]? - var universal: [SwiftOrgSnapshot]? -} - -public struct SwiftOrgSnapshot: Codable { - var dir: String - +extension Components.Schemas.DevToolchainForArch { private static let snapshotRegex: Regex<(Substring, Substring?, Substring?, Substring)> = try! Regex("swift(?:-(\\d+)\\.(\\d+))?-DEVELOPMENT-SNAPSHOT-(\\d{4}-\\d{2}-\\d{2})") @@ -291,23 +350,22 @@ public struct SwiftlyHTTPClient { /// limit (default unlimited). public func getReleaseToolchains( platform: PlatformDefinition, - arch a: String? = nil, + arch a: Components.Schemas.Architecture? = nil, limit: Int? = nil, filter: ((ToolchainVersion.StableRelease) -> Bool)? = nil ) async throws -> [ToolchainVersion.StableRelease] { let arch = a ?? cpuArch - let url = "https://www.swift.org/api/v1/install/releases.json" - let swiftOrgReleases: [SwiftOrgRelease] = try await self.getFromJSON(url: url, type: [SwiftOrgRelease].self) + let releases = try await SwiftlyCore.httpRequestExecutor.getReleaseToolchains() - var swiftOrgFiltered: [ToolchainVersion.StableRelease] = try swiftOrgReleases.compactMap { swiftOrgRelease in + var swiftOrgFiltered: [ToolchainVersion.StableRelease] = try releases.compactMap { swiftOrgRelease in if platform.name != PlatformDefinition.macOS.name { // If the platform isn't xcode then verify that there is an offering for this platform name and arch guard let swiftOrgPlatform = swiftOrgRelease.platforms.first(where: { $0.matches(platform) }) else { return nil } - guard let archs = swiftOrgPlatform.archs, archs.contains(arch) else { + guard case let archs = swiftOrgPlatform.archs, archs.contains(arch) else { return nil } } @@ -349,35 +407,45 @@ public struct SwiftlyHTTPClient { limit: Int? = nil, filter: ((ToolchainVersion.Snapshot) -> Bool)? = nil ) async throws -> [ToolchainVersion.Snapshot] { - let arch = a ?? cpuArch + let platformId: Components.Schemas.PlatformIdentifier = switch platform.name { + // These are new platforms that aren't yet in the list of known platforms in the OpenAPI schema + case PlatformDefinition.ubuntu2404.name, PlatformDefinition.debian12.name, PlatformDefinition.fedora39.name: + .init(platform.name) + + case PlatformDefinition.ubuntu2204.name: + .init(.ubuntu2204) + case PlatformDefinition.ubuntu2004.name: + .init(.ubuntu2004) + case PlatformDefinition.rhel9.name: + .init(.ubi9) + case PlatformDefinition.amazonlinux2.name: + .init(.amazonlinux2) + case PlatformDefinition.macOS.name: + .init(.macos) + default: + throw SwiftlyError(message: "No snapshot toolchains available for platform \(platform.name)") + } - let platformName = if platform.name == PlatformDefinition.macOS.name { - "macos" - } else { - platform.name + let sourceBranch: Components.Schemas.SourceBranch = switch branch { + case .main: + .init(.main) + case let .release(major, minor): + .init("\(major).\(minor)") } - let url = "https://www.swift.org/api/v1/install/dev/\(branch.name)/\(platformName).json" + let devToolchains = try await SwiftlyCore.httpRequestExecutor.getSnapshotToolchains(branch: sourceBranch, platform: platformId) - // For a particular branch and platform the snapshots are listed underneath their architecture - let swiftOrgSnapshotArchs: SwiftOrgSnapshotList - do { - swiftOrgSnapshotArchs = try await self.getFromJSON(url: url, type: SwiftOrgSnapshotList.self) - } catch is JSONNotFoundError { - throw SnapshotBranchNotFoundError(branch: branch) - } catch { - throw error - } + let arch = a ?? cpuArch.value2 // These are the available snapshots for the branch, platform, and architecture let swiftOrgSnapshots = if platform.name == PlatformDefinition.macOS.name { - swiftOrgSnapshotArchs.universal ?? [SwiftOrgSnapshot]() + devToolchains.universal ?? [Components.Schemas.DevToolchainForArch]() } else if arch == "aarch64" { - swiftOrgSnapshotArchs.aarch64 ?? [SwiftOrgSnapshot]() + devToolchains.aarch64 ?? [Components.Schemas.DevToolchainForArch]() } else if arch == "x86_64" { - swiftOrgSnapshotArchs.x86_64 ?? [SwiftOrgSnapshot]() + devToolchains.x8664 ?? [Components.Schemas.DevToolchainForArch]() } else { - [SwiftOrgSnapshot]() + [Components.Schemas.DevToolchainForArch]() } // Convert these into toolchain snapshot versions that match the filter diff --git a/Sources/SwiftlyCore/SwiftlyCore.swift b/Sources/SwiftlyCore/SwiftlyCore.swift index f5b1b685..76a104b8 100644 --- a/Sources/SwiftlyCore/SwiftlyCore.swift +++ b/Sources/SwiftlyCore/SwiftlyCore.swift @@ -53,9 +53,9 @@ public func readLine(prompt: String) -> String? { } #if arch(x86_64) -public let cpuArch = "x86_64" +public let cpuArch = Components.Schemas.Architecture.x8664 #elseif arch(arm64) -public let cpuArch = "aarch64" +public let cpuArch = Components.Schemas.Architecture.aarch64 #else #error("Unsupported processor architecture") #endif diff --git a/Sources/SwiftlyCore/openapi-generator-config.yaml b/Sources/SwiftlyCore/openapi-generator-config.yaml index c8f6e7a7..15dbf7f5 100644 --- a/Sources/SwiftlyCore/openapi-generator-config.yaml +++ b/Sources/SwiftlyCore/openapi-generator-config.yaml @@ -4,4 +4,4 @@ generate: namingStrategy: idiomatic accessModifier: public filter: - tags: ["Swiftly"] + tags: ["Swiftly", "Toolchains"] diff --git a/Sources/SwiftlyCore/openapi.yaml b/Sources/SwiftlyCore/openapi.yaml index 46eaebe0..61d3efea 100644 --- a/Sources/SwiftlyCore/openapi.yaml +++ b/Sources/SwiftlyCore/openapi.yaml @@ -37,12 +37,12 @@ paths: in: path required: true schema: - $ref: '#/components/schemas/KnownSourceBranch' + $ref: '#/components/schemas/SourceBranch' - name: platform in: path required: true schema: - $ref: '#/components/schemas/KnownPlatformIdentifier' + $ref: '#/components/schemas/PlatformIdentifier' get: operationId: listDevToolchains summary: Fetch all development toolchains @@ -61,7 +61,7 @@ paths: in: path required: true schema: - $ref: '#/components/schemas/KnownSourceBranch' + $ref: '#/components/schemas/SourceBranch' get: operationId: listStaticSDKDevToolchains summary: Fetch all static SDK development toolchains diff --git a/Tests/SwiftlyTests/HTTPClientTests.swift b/Tests/SwiftlyTests/HTTPClientTests.swift index 645875d5..275e9ab2 100644 --- a/Tests/SwiftlyTests/HTTPClientTests.swift +++ b/Tests/SwiftlyTests/HTTPClientTests.swift @@ -6,9 +6,9 @@ final class HTTPClientTests: SwiftlyTests { func testGet() async throws { // GIVEN: we have a swiftly http client // WHEN: we make get request for a particular type of JSON - var releases: [SwiftOrgRelease] = try await SwiftlyCore.httpClient.getFromJSON( + var releases: [Components.Schemas.Release] = try await SwiftlyCore.httpClient.getFromJSON( url: "https://www.swift.org/api/v1/install/releases.json", - type: [SwiftOrgRelease].self, + type: [Components.Schemas.Release].self, headers: [:] ) // THEN: we get a decoded JSON response @@ -20,7 +20,7 @@ final class HTTPClientTests: SwiftlyTests { do { releases = try await SwiftlyCore.httpClient.getFromJSON( url: "https://www.swift.org/api/v1/install/releases-invalid.json", - type: [SwiftOrgRelease].self, + type: [Components.Schemas.Release].self, headers: [:] ) } catch { @@ -35,7 +35,7 @@ final class HTTPClientTests: SwiftlyTests { do { releases = try await SwiftlyCore.httpClient.getFromJSON( url: "https://invalid.swift.org/api/v1/install/releases.json", - type: [SwiftOrgRelease].self, + type: [Components.Schemas.Release].self, headers: [:] ) } catch { @@ -74,7 +74,7 @@ final class HTTPClientTests: SwiftlyTests { .release(major: 6, minor: 0), // This is available in swift.org API ] - for arch in ["x86_64", "aarch64"] { + for arch in [Components.Schemas.Architecture.x8664, Components.Schemas.Architecture.aarch64] { for platform in supportedPlatforms { // GIVEN: we have a swiftly http client with swift.org metadata capability // WHEN: we ask for the first five releases of a supported platform in a supported arch @@ -87,7 +87,7 @@ final class HTTPClientTests: SwiftlyTests { for branch in branches { // GIVEN: we have a swiftly http client with swift.org metadata capability // WHEN: we ask for the first five snapshots on a branch for a supported platform and arch - let snapshots = try await SwiftlyCore.httpClient.getSnapshotToolchains(platform: platform, arch: arch, branch: branch, limit: 5) + let snapshots = try await SwiftlyCore.httpClient.getSnapshotToolchains(platform: platform, arch: arch.value2!, branch: branch, limit: 5) // THEN: we get at least 3 releases XCTAssertTrue(3 <= snapshots.count) } diff --git a/Tests/SwiftlyTests/SwiftlyTests.swift b/Tests/SwiftlyTests/SwiftlyTests.swift index 3f1fefad..385d59f2 100644 --- a/Tests/SwiftlyTests/SwiftlyTests.swift +++ b/Tests/SwiftlyTests/SwiftlyTests.swift @@ -17,8 +17,8 @@ struct SwiftlyTestError: LocalizedError { let message: String } -class SwiftlyTests: XCTestCase { - override class func tearDown() { +public class SwiftlyTests: XCTestCase { + override public class func tearDown() { #if os(Linux) let deleteTestGPGKeys = Process() deleteTestGPGKeys.executableURL = URL(fileURLWithPath: "/usr/bin/env") @@ -36,13 +36,13 @@ class SwiftlyTests: XCTestCase { } // Below are some constants that can be used to write test cases. - static let oldStable = ToolchainVersion(major: 5, minor: 6, patch: 0) - static let oldStableNewPatch = ToolchainVersion(major: 5, minor: 6, patch: 3) - static let newStable = ToolchainVersion(major: 5, minor: 7, patch: 0) - static let oldMainSnapshot = ToolchainVersion(snapshotBranch: .main, date: "2022-09-10") - static let newMainSnapshot = ToolchainVersion(snapshotBranch: .main, date: "2022-10-22") - static let oldReleaseSnapshot = ToolchainVersion(snapshotBranch: .release(major: 5, minor: 7), date: "2022-08-27") - static let newReleaseSnapshot = ToolchainVersion(snapshotBranch: .release(major: 5, minor: 7), date: "2022-08-30") + public static let oldStable = ToolchainVersion(major: 5, minor: 6, patch: 0) + public static let oldStableNewPatch = ToolchainVersion(major: 5, minor: 6, patch: 3) + public static let newStable = ToolchainVersion(major: 5, minor: 7, patch: 0) + public static let oldMainSnapshot = ToolchainVersion(snapshotBranch: .main, date: "2025-03-10") + public static let newMainSnapshot = ToolchainVersion(snapshotBranch: .main, date: "2025-03-14") + public static let oldReleaseSnapshot = ToolchainVersion(snapshotBranch: .release(major: 6, minor: 0), date: "2025-02-09") + public static let newReleaseSnapshot = ToolchainVersion(snapshotBranch: .release(major: 6, minor: 0), date: "2025-02-11") static let allToolchains: Set = [ oldStable, @@ -467,6 +467,14 @@ private struct MockHTTPRequestExecutor: HTTPRequestExecutor { public func getCurrentSwiftlyRelease() async throws -> Components.Schemas.SwiftlyRelease { throw SwiftlyTestError(message: "Mocking of fetching the current swiftly release is not implemented in MockHTTPRequestExecutor.") } + + public func getReleaseToolchains() async throws -> [Components.Schemas.Release] { + throw SwiftlyTestError(message: "Mocking of fetching the release toolchains is not implemented in MockHTTPRequestExecutor.") + } + + public func getSnapshotToolchains(branch _: Components.Schemas.SourceBranch, platform _: Components.Schemas.PlatformIdentifier) async throws -> Components.Schemas.DevToolchains { + throw SwiftlyTestError(message: "Mocking of fetching the snapshot toolchains is not implemented in MockHTTPRequestExecutor.") + } } /// An `HTTPRequestExecutor` which will return a mocked response to any toolchain download requests. @@ -485,27 +493,134 @@ public class MockToolchainDownloader: HTTPRequestExecutor { private let latestSwiftlyVersion: SwiftlyVersion - public init(executables: [String]? = nil, latestSwiftlyVersion: SwiftlyVersion = SwiftlyCore.version, delegate: HTTPRequestExecutor) { + private let releaseToolchains: [ToolchainVersion.StableRelease] + + private let snapshotToolchains: [ToolchainVersion.Snapshot] + + public init( + executables: [String]? = nil, + latestSwiftlyVersion: SwiftlyVersion = SwiftlyCore.version, + releaseToolchains: [ToolchainVersion.StableRelease] = [ + SwiftlyTests.oldStable.asStableRelease!, + SwiftlyTests.newStable.asStableRelease!, + SwiftlyTests.oldStableNewPatch.asStableRelease!, + ToolchainVersion.StableRelease(major: 5, minor: 7, patch: 4), // Some tests look for a patch in the 5.7.x series larger than 5.0.3 + ToolchainVersion.StableRelease(major: 5, minor: 9, patch: 0), // Some tests try to update from 5.9.0 + ToolchainVersion.StableRelease(major: 5, minor: 9, patch: 1), + ToolchainVersion.StableRelease(major: 6, minor: 0, patch: 0), // Some tests check for a release larger than 5.8.0 to be present + ToolchainVersion.StableRelease(major: 6, minor: 0, patch: 1), // Some tests try to update from 6.0.0 + ToolchainVersion.StableRelease(major: 6, minor: 0, patch: 2), // Some tests try to update from 6.0.1 + ], + snapshotToolchains: [ToolchainVersion.Snapshot] = [ + SwiftlyTests.oldMainSnapshot.asSnapshot!, + SwiftlyTests.newMainSnapshot.asSnapshot!, + SwiftlyTests.oldReleaseSnapshot.asSnapshot!, + SwiftlyTests.newReleaseSnapshot.asSnapshot!, + ], + delegate: HTTPRequestExecutor + ) { self.executables = executables ?? ["swift"] #if os(Linux) self.signatures = [:] #endif self.delegate = delegate self.latestSwiftlyVersion = latestSwiftlyVersion + self.releaseToolchains = releaseToolchains + self.snapshotToolchains = snapshotToolchains } public func getCurrentSwiftlyRelease() async throws -> Components.Schemas.SwiftlyRelease { let release = Components.Schemas.SwiftlyRelease( version: self.latestSwiftlyVersion.description, platforms: [ - .init(platform: .init(value1: .darwin), arm64: "https://download.swift.org/swiftly-darwin.pkg", x8664: "https://download.swift.org/swiftly-darwin.pkg"), - .init(platform: .init(value1: .linux), arm64: "https://download.swift.org/swiftly-linux.tar.gz", x8664: "https://download.swift.org/swiftly-linux.tar.gz"), + .init(platform: .init(.darwin), arm64: "https://download.swift.org/swiftly-darwin.pkg", x8664: "https://download.swift.org/swiftly-darwin.pkg"), + .init(platform: .init(.linux), arm64: "https://download.swift.org/swiftly-linux.tar.gz", x8664: "https://download.swift.org/swiftly-linux.tar.gz"), ] ) return release } + public func getReleaseToolchains() async throws -> [Components.Schemas.Release] { + let currentPlatform = try await Swiftly.currentPlatform.detectPlatform(disableConfirmation: true, platform: nil) + + let platformName = switch currentPlatform { + case PlatformDefinition.ubuntu2004: + "Ubuntu 20.04" + case PlatformDefinition.amazonlinux2: + "Amazon Linux 2" + case PlatformDefinition.ubuntu2204: + "Ubuntu 22.04" + case PlatformDefinition.rhel9: + "Red Hat Universal Base Image 9" + case PlatformDefinition(name: "ubuntu2404", nameFull: "ubuntu24.04", namePretty: "Ubuntu 24.04"): + "Ubuntu 24.04" + case PlatformDefinition(name: "debian12", nameFull: "debian12", namePretty: "Debian GNU/Linux 12"): + "Debian 12" + case PlatformDefinition(name: "fedora39", nameFull: "fedora39", namePretty: "Fedora Linux 39"): + "Fedora 39" + case PlatformDefinition.macOS: + "Xcode" // NOTE: this is not actually a platform that gets added in the swift.org API for macos/xcode + default: + String?.none + } + + guard let platformName else { + throw SwiftlyTestError(message: "Could not detect the current platform in test: \(currentPlatform)") + } + + return self.releaseToolchains.map { releaseToolchain in + Components.Schemas.Release( + name: String(describing: releaseToolchain), + date: "", + platforms: platformName != "Xcode" ? [.init( + name: platformName, + platform: .init(value1: .linux, value2: "Linux"), + archs: [cpuArch] + )] : [], + tag: "", + xcode: "", + xcodeRelease: true + ) + } + } + + public func getSnapshotToolchains(branch: Components.Schemas.SourceBranch, platform _: Components.Schemas.PlatformIdentifier) async throws -> Components.Schemas.DevToolchains { + let currentPlatform = try await Swiftly.currentPlatform.detectPlatform(disableConfirmation: true, platform: nil) + + let releasesForBranch = self.snapshotToolchains.filter { snapshotVersion in + switch snapshotVersion.branch { + case .main: + branch.value1 == .main || branch.value1?.rawValue == "main" + case let .release(major, minor): + branch.value2 == "\(major).\(minor)" || branch.value1?.rawValue == "\(major).\(minor)" + } + } + + let devToolchainsForArch = releasesForBranch.map { branchSnapshot in + Components.Schemas.DevToolchainForArch( + name: Components.Schemas.DevToolchainKind?.none, + date: "", + dir: branch.value1 == .main || branch.value2 == "main" ? + "swift-DEVELOPMENT-SNAPSHOT-\(branchSnapshot.date)" : + "swift-6.0-DEVELOPMENT-SNAPSHOT-\(branchSnapshot.date)", + download: "", + downloadSignature: nil, + debugInfo: nil + ) + } + + if currentPlatform == PlatformDefinition.macOS { + return Components.Schemas.DevToolchains(universal: devToolchainsForArch) + } else if cpuArch == Components.Schemas.Architecture.x8664 { + return Components.Schemas.DevToolchains(x8664: devToolchainsForArch) + } else if cpuArch == Components.Schemas.Architecture.aarch64 { + return Components.Schemas.DevToolchains(aarch64: devToolchainsForArch) + } else { + return Components.Schemas.DevToolchains() + } + } + public func execute(_ request: HTTPClientRequest, timeout: TimeAmount) async throws -> HTTPClientResponse { guard let url = URL(string: request.url) else { throw SwiftlyTestError(message: "invalid request URL: \(request.url)") diff --git a/Tests/SwiftlyTests/UpdateTests.swift b/Tests/SwiftlyTests/UpdateTests.swift index f442b29b..1df791cc 100644 --- a/Tests/SwiftlyTests/UpdateTests.swift +++ b/Tests/SwiftlyTests/UpdateTests.swift @@ -177,7 +177,7 @@ final class UpdateTests: SwiftlyTests { for branch in branches { try await self.withTestHome { try await self.withMockedToolchain { - let date = "2024-06-18" + let date = branch == .main ? SwiftlyTests.oldMainSnapshot.asSnapshot!.date : SwiftlyTests.oldReleaseSnapshot.asSnapshot!.date try await self.installMockedToolchain(selector: .snapshot(branch: branch, date: date)) var update = try self.parseCommand(