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
7652extension 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
0 commit comments