A comprehensive Swift implementation of semantic versioning with compile-time macro support and build tool integration.
SemanticVersion is based on swiftlang/swift-package-manager/Verion under Apache License.
New features:
CodablesupportExpressibleByIntegerLiteralandExpressibleByFloatLiteralsupport#semanticVersionmacro- Build plugin
- Throwable
.buildmethod with detailed errors
The SemanticVersion module provides three main components:
- SemanticVersion: A Swift struct implementing the Semantic Versioning 2.0.0 specification
- SemanticVersionMacro: A compile-time macro for creating SemanticVersion instances
- SemanticVersionBuildToolPlugin: A build plugin for automatic version generation
A value type representing a semantic version with major, minor, and patch components, plus optional prerelease and build metadata identifiers.
- Semantic Versioning 2.0.0 Compliance: Full implementation of the specification
- Comparison Support: Implements
Comparablefor version ordering - String Conversion: Supports parsing from and converting to strings
- Codable Support: JSON/Plist encoding and decoding
- Literal Support: Create versions from string, integer, and float literals
- Validation: Compile-time and runtime validation of version components
import SemanticVersion
// Create versions
let version1 = SemanticVersion(1, 2, 3)
let version2 = SemanticVersion(1, 2, 4, prereleaseIdentifiers: ["beta", "1"])
// Create versions with literals
let version3: SemanticVersion = "2.0.0"
let version4: SemanticVersion = 2
let version5: SemanticVersion = 3.14
// Compare versions
print(version1 < version2) // true
print(version2.isPrerelease) // true
print(version1.isRelease) // true
// Access components
print(version1.major) // 1
print(version1.minor) // 2
print(version1.patch) // 3A compile-time macro that parses version strings and generates optimized SemanticVersion initialization code.
- Compile-Time Parsing: Version validation at build time
- Multiple Input Types: Supports string, integer, and float literals
- Error Reporting: Clear diagnostic messages for invalid versions
- Zero Runtime Cost: Generates direct initialization code
import SemanticVersionMacro
// String literal
let version1 = #semanticVersion("1.2.3")
// Integer literal (major version only)
let version2 = #semanticVersion(2)
// Float literal (major.minor)
let version3 = #semanticVersion(1.5)
// Complex versions
let prerelease = #semanticVersion("2.0.0-beta.1")
let withBuild = #semanticVersion("1.0.0+build.123")A Swift Package Manager build plugin that automatically generates version information from a .version file.
- Automatic Generation: Reads
.versionfile and creates Swift code - Per-Target Support: Generates version constants for each target
- Build Integration: Rebuilds when version file changes
- Xcode Compatible: Works with both SPM and Xcode projects
- Create a
.versionfile in your package root:
1.2.3
- Add the plugin and
SemanticVersiondependency to your target inPackage.swift:
dependencies: [
.package(url: "https://github.com/MacPaw/cocoa-tools-cli.git", from: "0.1.0"),
],
targets: [
.target(
name: "MyTarget",
dependencies: [
.product(name: "SemanticVersion", package: "cocoa-tools"),
],
plugins: [
.plugin(name: "SemanticVersionBuildToolPlugin", package: "cocoa-tools"),
],
)
]- Use the generated version:
let version = TargetVersions.myTarget
print("Version: \(version)") // Version: 1.2.3For a target named MyTarget, the plugin generates:
// MyTargetVersion.swift (generated)
import SemanticVersion
extension TargetVersions {
public static let myTarget: SemanticVersion = .init(1, 2, 3, prereleaseIdentifiers: [], buildMetadataIdentifiers: [])
}let package = Package(
name: "MyPackage",
dependencies: [
.package(url: "https://github.com/MacPaw/cocoa-tools-cli.git", from: "0.1.0"),
],
targets: [
.target(
name: "Core",
dependencies: [
.product(name: "SemanticVersion", package: "cocoa-tools"),
],
plugins: [
.plugin(name: "SemanticVersionBuildToolPlugin", package: "cocoa-tools"),
],
)
]
)import SemanticVersion
struct AppVersion {
static let current = TargetVersions.core
/// Custom version display string.
static var displayString: String {
var result = "\(current.major).\(current.minor).\(current.patch)"
if current.isPrerelease {
result += "-\(current.prereleaseIdentifiers.joined(separator: "."))"
}
if let buildVersion = current.buildVersion {
result += " (build \(buildVersion))"
}
return result
}
}