Skip to content

Commit 466f17f

Browse files
Merge pull request #24 from SwiftPackageIndex/drop-Foundation-requirement
Drop foundation requirement
2 parents 40245e0 + 259270e commit 466f17f

File tree

8 files changed

+176
-207
lines changed

8 files changed

+176
-207
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
matrix:
1212
# https://github.com/actions/virtual-environments
13-
os: [macos-12, ubuntu-20.04]
13+
os: [macos-13, ubuntu-24.04]
1414
runs-on: ${{ matrix.os }}
1515
steps:
1616
- uses: actions/checkout@v4
@@ -23,8 +23,8 @@ jobs:
2323
run-tests:
2424
strategy:
2525
matrix:
26-
swift-version: ['5.6', '5.7', '5.8', '5.9', '5.10']
27-
runs-on: ubuntu-20.04
26+
swift-version: ['5.10', '6.0', '6.1']
27+
runs-on: ubuntu-24.04
2828
steps:
2929
- uses: actions/checkout@v4
3030
- uses: fwal/setup-swift@v2

Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import PackageDescription
1818

1919
let package = Package(
2020
name: "SemanticVersion",
21+
platforms: [.macOS("13.0")],
2122
products: [
2223
.library(
2324
name: "SemanticVersion",

Sources/SemanticVersion/NSRegularExpression+ext.swift

Lines changed: 0 additions & 48 deletions
This file was deleted.

Sources/SemanticVersion/SemanticVersion+Codable.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#if canImport(Foundation)
16+
1517
import Foundation
1618

1719
public enum SemanticVersionStrategy {
@@ -100,3 +102,5 @@ extension SemanticVersion: Codable {
100102
}
101103
}
102104
}
105+
106+
#endif
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright Dave Verwer, Sven A. Schmidt, and other contributors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
16+
extension SemanticVersion: LosslessStringConvertible {
17+
18+
/// Initialize a version from a string. Returns `nil` if the string is not a semantic version.
19+
/// - Parameter string: Version string.
20+
public init?(_ string: String) {
21+
guard let match = string.wholeMatch(of: semVerRegex) else { return nil }
22+
guard
23+
let major = Int(match.major),
24+
let minor = Int(match.minor),
25+
let patch = Int(match.patch)
26+
else { return nil }
27+
self = .init(major, minor, patch,
28+
match.prerelease.map(String.init) ?? "",
29+
match.buildmetadata.map(String.init) ?? "")
30+
}
31+
32+
public var description: String {
33+
let pre = preRelease.isEmpty ? "" : "-" + preRelease
34+
let bld = build.isEmpty ? "" : "+" + build
35+
return "\(major).\(minor).\(patch)\(pre)\(bld)"
36+
}
37+
}
38+
39+
40+
// Source: https://regex101.com/r/Ly7O1x/3/
41+
// Linked from https://semver.org
42+
let semVerRegex = #/
43+
^
44+
v? # SPI extension: allow leading 'v'
45+
(?<major>0|[1-9]\d*)
46+
\.
47+
(?<minor>0|[1-9]\d*)
48+
\.
49+
(?<patch>0|[1-9]\d*)
50+
(?:-
51+
(?<prerelease>
52+
(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
53+
(?:\.
54+
(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
55+
)
56+
*)
57+
)?
58+
(?:\+
59+
(?<buildmetadata>[0-9a-zA-Z-]+
60+
(?:\.[0-9a-zA-Z-]+)
61+
*)
62+
)?
63+
$
64+
/#

Sources/SemanticVersion/SemanticVersion.swift

Lines changed: 18 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
import Foundation
16-
1715

1816
/// `SemanticVersion` is a struct representing a software or project version according to ["Semantic Versioning"](https://semver.org).
1917
///
@@ -50,28 +48,6 @@ public struct SemanticVersion: Equatable, Hashable {
5048
}
5149
}
5250

53-
extension SemanticVersion: LosslessStringConvertible {
54-
55-
/// Initialize a version from a string. Returns `nil` if the string is not a semantic version.
56-
/// - Parameter string: Version string.
57-
public init?(_ string: String) {
58-
let groups = semVerRegex.matchGroups(string)
59-
guard
60-
groups.count == semVerRegex.numberOfCaptureGroups,
61-
let major = Int(groups[0]),
62-
let minor = Int(groups[1]),
63-
let patch = Int(groups[2])
64-
else { return nil }
65-
self = .init(major, minor, patch, groups[3], groups[4])
66-
}
67-
68-
public var description: String {
69-
let pre = preRelease.isEmpty ? "" : "-" + preRelease
70-
let bld = build.isEmpty ? "" : "+" + build
71-
return "\(major).\(minor).\(patch)\(pre)\(bld)"
72-
}
73-
}
74-
7551

7652
extension SemanticVersion: Comparable {
7753
public static func < (lhs: SemanticVersion, rhs: SemanticVersion) -> Bool {
@@ -140,7 +116,8 @@ extension SemanticVersion.PreReleaseIdentifier: Comparable {
140116
}
141117

142118

143-
extension Array: Comparable where Element == SemanticVersion.PreReleaseIdentifier {
119+
#if compiler(>=6)
120+
extension Array: @retroactive Comparable where Element == SemanticVersion.PreReleaseIdentifier {
144121
public static func < (lhs: Self, rhs: Self) -> Bool {
145122
// Per section 11.4 of the semver spec, compare left to right until a
146123
// difference is found.
@@ -154,64 +131,24 @@ extension Array: Comparable where Element == SemanticVersion.PreReleaseIdentifie
154131
return lhs.count < rhs.count
155132
}
156133
}
134+
#else
135+
extension Array: Comparable where Element == SemanticVersion.PreReleaseIdentifier {
136+
public static func < (lhs: Self, rhs: Self) -> Bool {
137+
// Per section 11.4 of the semver spec, compare left to right until a
138+
// difference is found.
139+
// See: https://semver.org/#spec-item-11
140+
for (lhIdentifier, rhIdentifier) in zip(lhs, rhs) {
141+
if lhIdentifier != rhIdentifier { return lhIdentifier < rhIdentifier }
142+
}
157143

158-
#if swift(>=5.5)
159-
extension SemanticVersion: Sendable {}
144+
// 11.4.4 - A larger set of identifiers will have a higher precendence
145+
// than a smaller set, if all the preceding identifiers are equal.
146+
return lhs.count < rhs.count
147+
}
148+
}
160149
#endif
161150

162151

163-
// Source: https://regex101.com/r/Ly7O1x/3/
164-
// Linked from https://semver.org
165-
#if swift(>=5)
166-
167-
let semVerRegex = NSRegularExpression(#"""
168-
^
169-
v? # SPI extension: allow leading 'v'
170-
(?<major>0|[1-9]\d*)
171-
\.
172-
(?<minor>0|[1-9]\d*)
173-
\.
174-
(?<patch>0|[1-9]\d*)
175-
(?:-
176-
(?<prerelease>
177-
(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
178-
(?:\.
179-
(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
180-
)
181-
*)
182-
)?
183-
(?:\+
184-
(?<buildmetadata>[0-9a-zA-Z-]+
185-
(?:\.[0-9a-zA-Z-]+)
186-
*)
187-
)?
188-
$
189-
"""#, options: [.allowCommentsAndWhitespace])
190-
191-
#else
192-
193-
let semVerRegex = NSRegularExpression("""
194-
^
195-
v? # SPI extension: allow leading 'v'
196-
(?<major>0|[1-9]\\d*)
197-
\\.
198-
(?<minor>0|[1-9]\\d*)
199-
\\.
200-
(?<patch>0|[1-9]\\d*)
201-
(?:-
202-
(?<prerelease>
203-
(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)
204-
(?:\\.
205-
(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)
206-
)
207-
*)
208-
)?
209-
(?:\\+
210-
(?<buildmetadata>[0-9a-zA-Z-]+
211-
(?:\\.[0-9a-zA-Z-]+)
212-
*)
213-
)?
214-
$
215-
""", options: [.allowCommentsAndWhitespace])
216-
152+
#if swift(>=5.5)
153+
extension SemanticVersion: Sendable {}
217154
#endif

Tests/SemanticVersionTests/SemanticVersionCodingTests.swift renamed to Tests/SemanticVersionTests/SemanticVersionCodableTests.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
1+
// Copyright Dave Verwer, Sven A. Schmidt, and other contributors.
12
//
2-
// SemanticVersionCodingTests.swift
3-
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
46
//
5-
// Created by Chris Eplett on 11/3/23.
7+
// http://www.apache.org/licenses/LICENSE-2.0
68
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#if canImport(Foundation)
716

817
import XCTest
918

1019
import SemanticVersion
1120

12-
final class SemanticVersionCodingTests: XCTestCase {
21+
final class SemanticVersionCodableTests: XCTestCase {
1322
func test_defaultCodable_is_default() throws {
1423
XCTAssertEqual(.defaultCodable, JSONEncoder().semanticVersionEncodingStrategy)
1524
XCTAssertEqual(.defaultCodable, JSONDecoder().semanticVersionDecodingStrategy)
@@ -191,3 +200,5 @@ final class SemanticVersionCodingTests: XCTestCase {
191200
}
192201
}
193202
}
203+
204+
#endif

0 commit comments

Comments
 (0)