A µ-framework for representing, comparing, encoding and utilizing
semantic versions, eg.
Version.swift from the Swift Package Manager, with some minor
- More compact
- Not a massive-single-source-file (MSSF)
- Online documentation
- Extensions for
- Removal of the potentially fatal
- A “tolerant” initializer for user input like
- Idiomatic implementations for
- Initialization from
StringProtocol, not just
We have automatic monitoring for changes at Apple’s repo to alert us if we should need merge any fixes.
† Semantic versions can be losslessly expressed as strings; thus we do so.
Intwe can losslessly store a semantic version from a valid string, so we conform to the same protocol.
Hey there, I’m Max Howell. I’m a prolific producer of open source software and
probably you already use some of it (for example, I created
brew). I work
full-time on open source and it’s hard; currently I earn less than minimum
wage. Please help me continue my work, I appreciate it 🙏🏻
import Version // these two initializers are the same, use whichever suits the code context let v1 = Version(1,0,0) let v2 = Version(major: 1, minor: 0, patch: 0) let v3 = Version("1.2.3") // => 1.2.3: Version? let v4 = Version(tolerant: "10.1") // => 10.1.0: Version? let v5 = Version(tolerant: "10") // => 10.0.0: Version? // a real Version object from your app’s Info.plist let v6 = Bundle.main.version let range = Version(1,2,3)..<Version(2,0,0) let null: Version = .null // => Version(0,0,0) let foo = Version(1,2,3) < Version(2,0,0) // => true
package.append(.package(url: "https://github.com/mxcl/Version.git", from: "2.0.0"))
Waiting on: @Carthage#1945.
Ranges work as you expect, but there are caveats for prerelease identifiers, here are the rules:
1.0.0..<2.0.0does not include eg.
This is probably what you expected. However:
1.0.0..<2.0.0also does not include eg.
1.0.0..<2.0.0-betadoes include eg.
This is how the majority of Semantic Version libraries work.
Comparable, Equatable & Hashable
Both comparable and equatable ignore build metadata as per the specification. Thus:
Version("1.2.3+14") == Version("1.2.3+15") // => true Version("1.2.3+14") <= Version("1.2.3+15") // => true Version("1.2.3+14") < Version("1.2.3+15") // => false
This also means that
Hashable must mirror this behavior, thus:
dict[Version("1.2.3+14")] = 1 dict[Version("1.2.3+15")] = 2 dict.count // => 1 dict // => ["1.2.3+15": 2]
Be aware of this as it may catch you out, naturally this will also effect structures
that depend on