This repository contains a complete implementation of a Version
struct that conforms to the rules of semantic versioning which are described at semver.org.
Add the following dependency to your Package.swift
:
.package(url: "https://github.com/sersoft-gmbh/semver", from: "4.0.0"),
Swift | SemVer Package |
---|---|
< 5.3.0 | 1.x.y - 2.x.y |
>= 5.3.0, < 5.9.0 | 3.x.y |
>= 5.9.0 | 4.x.y |
You can create a version like this:
let version = Version(major: 1, minor: 2, patch: 3,
prerelease: "beta", 1, // prerelease could also be ["beta", 1]
metadata: "exp", "test") // metadata could also be ["exp, test"]
version.versionString() // -> "1.2.3-beta.1+exp.test"
Of course there are simpler ways:
let initialRelease = Version(major: 1)
initialRelease.versionString() // -> "1.0.0"
let minorRelease = Version(major: 2, minor: 1)
minorRelease.versionString() // -> "2.1.0"
let patchRelease = Version(major: 3, minor: 2, patch: 1)
patchRelease.versionString() // -> "3.2.1"
And there is also a Swift macro for statically creating versions.
As seen in above's examples, there's a func to return a string represenation of a Version
. The versionString(formattedWith options: FormattingOptions = default)
function allows to retrieve a formatted string using the options passed. By default the full version is returned.
The following options currently exist:
.dropPatchIfZero
: If patch
is 0
, it won't be added to the version string..dropMinorIfZero
: If minor
and patch
are both 0
, only the major
number is added. Requires .dropPatchIfZero
..dropTrailingZeros
: A convenience combination of .dropPatchIfZero
and .dropMinorIfZero
..includePrerelease
: If prerelease
are not empty, they are added to the version string..includeMetadata
: If metadata
is not empty, it is added to the version string..fullVersion
: A convenience combination of .includePrerelease
and .includeMetadata
. The default if you don't pass anything to versionString
.let version = Version(major: 1, minor: 2, patch: 3,
prerelease: "beta",
metadata: "exp", "test")
version.versionString(formattedWith: .includePrerelease]) // -> "1.2.3-beta"
version.versionString(formattedWith: .includeMetadata) // -> "1.2.3+exp.test"
version.versionString(formattedWith: []) // -> "1.2.3"
let version2 = Version(major: 2)
version2.versionString(formattedWith: .dropPatchIfZero) // -> "2.0"
version2.versionString(formattedWith: .dropTrailingZeros) // -> "2"
A Version
can also be created from a String. All Strings created by the versionString
func should result in the same Version
they were created from:
let version = Version(major: 1, minor: 2, patch: 3,
prerelease: "beta",
metadata: "exp", "test")
let str = version.versionString() // -> "1.2.3-beta+exp.test"
let recreatedVersion = Version(str) // recreatedVersion is Optional<Version>
recreatedVersion == version // -> true
A Version
can also be compared to other versions. This also follows the rules of semantic versioning. This means that metadata
has no effect on comparing at all. This also means that a version with and without metadata are treated as equal:
let versionWithMetadata = Version(major: 1, minor: 2, patch: 3,
metadata: "exp", "test")
let versionWithoutMetadata = Version(major: 1, minor: 2, patch: 3)
versionWithMetadata == versionWithoutMetadata // -> true
Otherwise, comparing two Version
's basically compares their major/minor/patch numbers. A Version
with prerelease
identifiers is ordered before a the same version without prerelease
identifiers:
let preReleaseVersion = Version(major: 1, minor: 2, patch: 3,
prerelease: "beta")
let finalVersion = Version(major: 1, minor: 2, patch: 3)
preReleaseVersion < finalVersion // -> true
If you need to check whether two versions are completely identical, there's the isIdentical(to:)
method, which also checks metadata
.
Version
performs some validity checks on its fields. This means, that no negative numbers are allowed for major
, minor
and patch
. Also, the prerelease
and metadata
Strings must only contain alphanumeric characters plus -
(hyphen). However, to keep working with Version
production-safe, these rules are only checked in non-optimized builds (using assert()
). The result of using not allowed numbers / characters in optimized builds is undetermined. While calling versionString()
very likely won't break, it certainly won't be possible to recreate a version containing invalid numbers / characters using init(_ description: String)
.
Version
conforms to Codable
! The encoding / decoding behavior can be controlled by using the .versionEncodingStrategy
and .versionDecodingStrategy
CodingUserInfoKey
s. For JSONEncoder
/JSONDecoder
and PropertyListEncoder
/PropertyListDecoder
, there are the convenience properties semverVersionEncodingStrategy
/semverVersionDecodingStrategy
in place.
If a Version
should be constructed from a String
that is known at compile time, the #version
macro can be used. It will parse the String
at compile time and generate code that initializes a Version
from the result:
let version = #version("1.2.3")
results in
let version = Version(major: 1, minor: 2, patch: 3, prerelase: [], metadata: [])
The API is documented using header doc. If you prefer to view the documentation as a webpage, there is an online version available for you.
If you find a bug / like to see a new feature in SemVer there are a few ways of helping out:
See LICENSE file.
Copyright © 2016-2023 ser.soft GmbH.
link |
Stars: 8 |
Last commit: 5 days ago |
#version(...)
macro.Version.PrereleaseIdentifier
for type safe prerelease identifiers.prerelease: String
property.preReleaseIdentifiers: Array<String>
with prerelease: Array<Version.PrereleaseIdentifier>
.Full Changelog: https://github.com/sersoft-gmbh/semver/compare/3.8.0...4.0.0
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics