Skip to content

Latest commit

 

History

History
193 lines (145 loc) · 5.19 KB

SemanticVersion.md

File metadata and controls

193 lines (145 loc) · 5.19 KB

SemanticVersion

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:

  • Codable support
  • ExpressibleByIntegerLiteral and ExpressibleByFloatLiteral support
  • #semanticVersion macro
  • Build plugin
  • Throwable .build method with detailed errors

Overview

The SemanticVersion module provides three main components:

  1. SemanticVersion: A Swift struct implementing the Semantic Versioning 2.0.0 specification
  2. SemanticVersionMacro: A compile-time macro for creating SemanticVersion instances
  3. SemanticVersionBuildToolPlugin: A build plugin for automatic version generation

Components

SemanticVersion

A value type representing a semantic version with major, minor, and patch components, plus optional prerelease and build metadata identifiers.

Features

  • Semantic Versioning 2.0.0 Compliance: Full implementation of the specification
  • Comparison Support: Implements Comparable for 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

Basic Usage

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) // 3

SemanticVersionMacro

A compile-time macro that parses version strings and generates optimized SemanticVersion initialization code.

Features

  • 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

Usage

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")

SemanticVersionBuildToolPlugin

A Swift Package Manager build plugin that automatically generates version information from a .version file.

Features

  • Automatic Generation: Reads .version file 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

Setup

  1. Create a .version file in your package root:
1.2.3
  1. Add the plugin and SemanticVersion dependency to your target in Package.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"),
    ],
  )
]
  1. Use the generated version:
let version = TargetVersions.myTarget
print("Version: \(version)") // Version: 1.2.3

Generated Code

For 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: [])
}

Integration Examples

Package.swift Configuration

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"),
      ],
    )
  ]
)

Version Management

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