cupertino-packages/mxcl/Version
Mihaela Mihaljevic 717311488d data(packages): initial import, 2026-05-27
Per-owner per-repo Swift package source trees, extracted from
codeload.github.com tarballs by `cupertino fetch --source
packages --skip-metadata`. 12 owners covering 137 seed packages
plus transitive dependencies discovered via Package.swift walks
at raw.githubusercontent.com.

Lifted from cupertino-docs/packages/ subtree
(cupertino-docs@26fc51c92). The subtree is being removed from
cupertino-docs in a follow-up commit so per-source-corpus repos
stay separable.

326 MB total, 1 fetch error (logged at fetch time, not blocking
indexer).
2026-05-27 11:35:02 +02:00
..
Sources data(packages): initial import, 2026-05-27 2026-05-27 11:35:02 +02:00
Tests data(packages): initial import, 2026-05-27 2026-05-27 11:35:02 +02:00
.archive.tar.gz data(packages): initial import, 2026-05-27 2026-05-27 11:35:02 +02:00
LICENSE data(packages): initial import, 2026-05-27 2026-05-27 11:35:02 +02:00
manifest.json data(packages): initial import, 2026-05-27 2026-05-27 11:35:02 +02:00
Package.swift data(packages): initial import, 2026-05-27 2026-05-27 11:35:02 +02:00
Package@swift-5.3.swift data(packages): initial import, 2026-05-27 2026-05-27 11:35:02 +02:00
README.md data(packages): initial import, 2026-05-27 2026-05-27 11:35:02 +02:00

Version badge-platforms badge-languages badge-ci badge-jazzy badge-codecov

A µ-framework for representing, comparing, encoding and utilizing semantic versions, eg. 1.2.3 or 2.0.0-beta.

This is Version.swift from the Swift Package Manager, with some minor adjustments:

  1. More compact Codable implementation †
  2. Implements LosslessStringConvertible
  3. Not a massive-single-source-file (MSSF)
  4. Online documentation
  5. Extensions for Bundle and ProcessInfo
  6. Removal of the potentially fatal ExpressibleByStringLiteral conformance
  7. A “tolerant” initializer for user input like 10.0 or v3
  8. Idiomatic implementations for Range<Version>
  9. Initialization from StringProtocol, not just String

We have automatic monitoring for changes at Apples repo to alert us if we should need merge any fixes.

Semantic versions can be losslessly expressed as strings; thus we do so.

‡ Like Int we can losslessly store a semantic version from a valid string, so we conform to the same protocol.

Usage

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 apps 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

Installation

SwiftPM:

package.append(.package(url: "https://github.com/mxcl/Version.git", from: "2.0.0"))

Ranges

Ranges work as you expect, but there are caveats for prerelease identifiers, here are the rules:

1.0.0..<2.0.0 does not include eg. 2.0.0-alpha

This is probably what you expected. However:

1.0.0..<2.0.0 also does not include eg. 1.5.0-alpha

However:

1.0.0..<2.0.0-beta does include eg. 2.0.0-alpha

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 Hashable, eg. Set.