Skip to content

Commit e73e961

Browse files
committed
Fix pre-release sorting
1 parent cbe292e commit e73e961

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

Sources/SemanticVersion/SemanticVersion.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,14 @@ extension SemanticVersion: Comparable {
4343
if lhs.major != rhs.major { return lhs.major < rhs.major }
4444
if lhs.minor != rhs.minor { return lhs.minor < rhs.minor }
4545
if lhs.patch != rhs.patch { return lhs.patch < rhs.patch }
46-
// Not entirely sure how much sense it makes to compare the pre and build values
47-
// but it's probably better than just ignoring them
48-
if lhs.preRelease != rhs.preRelease { return lhs.preRelease < rhs.preRelease }
46+
if lhs.preRelease != rhs.preRelease {
47+
// Ensure stable versions sort after their betas ...
48+
if lhs.isStable { return false }
49+
if rhs.isStable { return true }
50+
// ... otherwise sort by preRelease
51+
return lhs.preRelease < rhs.preRelease
52+
}
53+
// ... and build
4954
return lhs.build < rhs.build
5055
}
5156
}

Tests/SemanticVersionTests/SemanticVersionTests.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ final class SemanticVersionTests: XCTestCase {
8989
XCTAssertEqual(SemanticVersion("1.2.3-rc"), SemanticVersion(1, 2, 3, "rc"))
9090
XCTAssertEqual(SemanticVersion("v1.2.3-beta1"), SemanticVersion(1, 2, 3, "beta1"))
9191
XCTAssertEqual(SemanticVersion("v1.2.3-beta1+build5"), SemanticVersion(1, 2, 3, "beta1", "build5"))
92+
XCTAssertEqual(SemanticVersion("1.2.3-beta-foo"), SemanticVersion(1, 2, 3, "beta-foo"))
93+
XCTAssertEqual(SemanticVersion("1.2.3-beta-foo+build-42"), SemanticVersion(1, 2, 3, "beta-foo", "build-42"))
9294
XCTAssertEqual(SemanticVersion(""), nil)
9395
XCTAssertEqual(SemanticVersion("1"), nil)
9496
XCTAssertEqual(SemanticVersion("1.2"), nil)
@@ -109,6 +111,14 @@ final class SemanticVersionTests: XCTestCase {
109111
XCTAssert(SemanticVersion(1, 0, 0) < SemanticVersion(1, 0, 1))
110112
XCTAssert(SemanticVersion(1, 0, 0, "a") < SemanticVersion(1, 0, 0, "b"))
111113
XCTAssert(SemanticVersion(1, 0, 0, "a", "a") < SemanticVersion(1, 0, 0, "a", "b"))
114+
115+
// ensure betas come before releases
116+
XCTAssert(SemanticVersion(1, 0, 0, "b1") < SemanticVersion(1, 0, 0))
117+
XCTAssertFalse(SemanticVersion(1, 0, 0, "b1") > SemanticVersion(1, 0, 0))
118+
// but only if major/minor/patch are the same
119+
XCTAssert(SemanticVersion(1, 0, 0) < SemanticVersion(1, 0, 1, "b1"))
120+
// once the patch bumps up to the beta level again, it sorts higher
121+
XCTAssert(SemanticVersion(1, 0, 1) > SemanticVersion(1, 0, 1, "b1"))
112122
}
113123

114124
func test_isStable() throws {

0 commit comments

Comments
 (0)