ph1ps/swift-semantic-version

Repository files navigation

A fast, spec-compliant semantic versioning library for Swift.

This library provides a lightweight and efficient implementation of Semantic Versioning 2.0.0 in Swift.
It offers a structured SemanticVersion type for representing versions with:

  • major: Major version component (e.g., 1 in 1.2.3).
  • minor: Minor version component (e.g., 2 in 1.2.3).
  • : version component (e.g., 3 in 1.2.3).
  • prerelease: Optional prerelease identifiers (e.g., ["alpha", "1"] in 1.2.3-alpha.1).
  • build: Optional build metadata (e.g., "build.5" in 1.2.3+build.5).

Parsing, comparison, and validation are fully compliant with the Semantic Versioning 2.0.0 specification.

You can parse a version string at runtime using the failable initializer:

let version = SemanticVersion(versionString) // -> Optional<SemanticVersion>

If the string is not a valid semantic version, the initializer will return nil.

This library also provides a macro for compile-time safe parsing of semantic versions:

let version = #SemanticVersion("1.2.3-alpha.1+build.5") // -> SemanticVersion

If the provided string is invalid, a compile-time error will be produced.
This ensures that all semantic versions used in your code are guaranteed to be valid at build time.

To use the macro:

  1. Add SemanticVersionMacro as a dependency in your Package.swift:
.target(
  name: "YourTarget",
  dependencies: [
    .product(name: "SemanticVersionMacro", package: "swift-semantic-version")
  ]
)
  1. Import SemanticVersionMacro in the file where you use the macro:
import SemanticVersionMacro

This library uses Swift 6.1’s package traits feature to offer two selectable parsing backends:

  • FoundationBackend (default): Uses Foundation's NSRegularExpression for parsing.
  • StringProcessingBackend: Ues Swift's native Regex literals for parsing.

To configure which parsing backend is used, specify traits in your Package.swift dependency declaration:

.package(
  url: "https://.com/ph1ps/swift-semantic-version",
  from: <current version>,
  traits: [
    "StringProcessingBackend"
  ]
)

FoundationBackend generally provides faster parsing performance, while StringProcessingBackend is slightly slower.

p0p25p50p75p90p99p100Samples
FoundationBackend invalid (μs)5657575758692349653
FoundationBackend valid (μs)1001041051061101313856415
StringProcessingBackend invalid (μs)1621641641651661863644685
StringProcessingBackend valid (μs)1219122712311237124614012038774
DetailsThe benchmarks use a set of 30 valid and 40 invalid semantic version strings, based on a variety of real-world examples and edge cases. Each benchmark measures the time taken to parse all provided versions repeatedly under scaled iterations.

FoundationBackend has a big impact on binary size for platforms where Foundation is statically linked like Musl or Wasm. StringProcessingBackend on the other hand uses a pure Swift Standard Library implementation, which means no impact on binary size.

MuslWasm
FoundationBackend (MB)?58.3
StringProcessingBackend (MB)?9.3
DetailsThe binary size was measured by building an executable target simply that instantiates a SemanticVersion. The bytes of the resulting binary were taken.
  • swift build --swift-sdk wasm32-unknown-wasi
  • swift build --swift-sdk x86_64-swift-linux-musl

The different traits have different platform availabilities due to their implementation details, which might be important to you, if you want to increase platform coverage.

iOSiPadOSmacOSmacCatalysttvOSwatchOSvisionOS
FoundationBackend8.08.010.1513.19.02.01.0
StringProcessingBackend16.016.013.016.016.09.01.0

About

A fast, spec-compliant semantic versioning library for Swift

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages