Skip to content

Commit d0795a2

Browse files
authored
Handle install 6.4-snapshot properly (#561)
1 parent f278ec4 commit d0795a2

4 files changed

Lines changed: 45 additions & 5 deletions

File tree

Sources/Swiftly/OutputSchema.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ struct InstallToolchainInfo: OutputData {
285285
branch = .main
286286
} else if let major = branchMajor, let minor = branchMinor {
287287
let branchPatch = try? versionContainer.decodeIfPresent(String.self, forKey: .patch)
288-
branch = .release(major: major, minor: minor, patch: branchPatch)
288+
branch = .releaseNormalized(major: major, minor: minor, patch: branchPatch)
289289
} else {
290290
throw DecodingError.dataCorruptedError(
291291
forKey: ToolchainVersionCodingKeys.branch,

Sources/SwiftlyCore/HTTPClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ extension SwiftlyWebsiteAPI.Components.Schemas.DevToolchainForArch {
445445
message: "malformatted release branch: \"\(majorString).\(minorString)\"")
446446
}
447447
let patch = match.output.3.map(String.init)
448-
branch = .release(major: major, minor: minor, patch: patch)
448+
branch = .releaseNormalized(major: major, minor: minor, patch: patch)
449449
} else {
450450
branch = .main
451451
}

Sources/SwiftlyCore/ToolchainVersion.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ public enum ToolchainVersion: Sendable {
77
case main
88
case release(major: Int, minor: Int, patch: String? = nil)
99

10+
/// Constructs a release-snapshot branch, normalizing the patch component
11+
/// to match the swift.org URL scheme:
12+
/// - from Swift 6.4 onward, snapshots live under `/install/dev/X.Y.x/...`,
13+
/// - on older releases are passed through as-is.
14+
public static func releaseNormalized(major: Int, minor: Int, patch: String?) -> Self {
15+
if patch == nil, (major, minor) >= (6, 4) {
16+
return .release(major: major, minor: minor, patch: "x")
17+
}
18+
return .release(major: major, minor: minor, patch: patch)
19+
}
20+
1021
public var description: String {
1122
switch self {
1223
case .main:
@@ -145,7 +156,7 @@ public enum ToolchainVersion: Sendable {
145156
throw SwiftlyError(message: "invalid release snapshot version: \(string)")
146157
}
147158
let patch = match.output.3.map(String.init)
148-
self = ToolchainVersion(snapshotBranch: .release(major: major, minor: minor, patch: patch), date: String(match.output.4))
159+
self = ToolchainVersion(snapshotBranch: .releaseNormalized(major: major, minor: minor, patch: patch), date: String(match.output.4))
149160
} else if string == "xcode" {
150161
self = ToolchainVersion.xcodeVersion
151162
} else {
@@ -477,7 +488,7 @@ struct ReleaseSnapshotParser: ToolchainSelectorParser {
477488
}
478489

479490
let patch = match.output.3.map(String.init)
480-
return .snapshot(branch: .release(major: major, minor: minor, patch: patch), date: match.output.4.map(String.init))
491+
return .snapshot(branch: .releaseNormalized(major: major, minor: minor, patch: patch), date: match.output.4.map(String.init))
481492
}
482493
}
483494

Tests/SwiftlyTests/ToolchainSelectorTests.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import Testing
3939
try runTest(.snapshot(branch: .main, date: "2023-06-05"), parses)
4040
}
4141

42-
@Test func parseReleaseSnapshot() throws {
42+
@Test func parseDeprecatedReleaseSnapshot() throws {
4343
let parses = [
4444
"5.7-snapshot",
4545
"5.7-SNAPSHOT",
@@ -63,6 +63,35 @@ import Testing
6363
try runTest(.snapshot(branch: .release(major: 5, minor: 7, patch: "x"), date: nil), parses)
6464
}
6565

66+
@Test func parseReleaseSnapshot() throws {
67+
let parses = [
68+
"6.4-snapshot",
69+
"6.4.x-snapshot",
70+
"6.4-SNAPSHOT",
71+
"6.4.x-SNAPSHOT",
72+
"6.4-DEVELOPMENT-SNAPSHOT",
73+
"6.4.x-DEVELOPMENT-SNAPSHOT",
74+
"swift-6.4-snapshot",
75+
"swift-6.4.x-snapshot",
76+
"swift-6.4-SNAPSHOT",
77+
"swift-6.4.x-SNAPSHOT",
78+
"swift-6.4-DEVELOPMENT-SNAPSHOT",
79+
"swift-6.4.x-DEVELOPMENT-SNAPSHOT",
80+
]
81+
try runTest(.snapshot(branch: .release(major: 6, minor: 4, patch: "x"), date: nil), parses)
82+
}
83+
84+
@Test func releaseSnapshotXDependingOnVersion() throws {
85+
#expect(
86+
try ToolchainSelector(parsing: "6.4-snapshot")
87+
== ToolchainSelector(parsing: "6.4.x-snapshot")
88+
)
89+
#expect(
90+
try ToolchainSelector(parsing: "5.7-snapshot")
91+
!= ToolchainSelector(parsing: "5.7.x-snapshot")
92+
)
93+
}
94+
6695
@Test func parseReleaseSnapshotWithDate() throws {
6796
let parses = [
6897
"5.7-snapshot-2023-06-05",

0 commit comments

Comments
 (0)