Skip to content

Commit

Permalink
Move to using SemanticVersion
Browse files Browse the repository at this point in the history
Uses `SemanticVersion` type rather than `VersionTriplet`. We have 4 types in DocC to represent a semantic version, and want to converge towards using only SemanticVersion:
swiftlang#970
  • Loading branch information
anferbui committed Jun 28, 2024
1 parent d67cc9f commit 7efe5c1
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ public class DocumentationContentRenderer {
}

// Verify that the current platform is in beta and the version number matches the introduced platform version.
guard current.beta && VersionTriplet(semanticVersion: introduced) == current.version else {
guard current.beta && SemanticVersion(introduced).isEqualToVersionTriplet(current.version) else {
return false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import Foundation
import SymbolKit

extension VersionTriplet {
extension SemanticVersion {
enum Precision: Int {
case all = 0, patch, minor

Expand Down Expand Up @@ -45,10 +45,21 @@ extension VersionTriplet {
.joined(separator: ".")
}

init(semanticVersion: SymbolGraph.SemanticVersion) {
init(_ semanticVersion: SymbolGraph.SemanticVersion) {
self.major = semanticVersion.major
self.minor = semanticVersion.minor
self.patch = semanticVersion.patch
self.prerelease = semanticVersion.prerelease
self.buildMetadata = semanticVersion.buildMetadata
}

/// Compares a version triplet to a semantic version.
/// - Parameter version: A version triplet to compare to this semantic version.
/// - Returns: Returns whether the given triple represents the same version as the current version.
func isEqualToVersionTriplet(_ version: VersionTriplet) -> Bool {
return major == version.major &&
minor == version.minor &&
patch == version.patch
}
}

Expand Down Expand Up @@ -123,10 +134,10 @@ public struct AvailabilityRenderItem: Codable, Hashable, Equatable {
let platformName = availability.domain.map({ PlatformName(operatingSystemName: $0.rawValue) })
name = platformName?.displayName

let introducedVersion = availability.introducedVersion.flatMap { VersionTriplet(semanticVersion: $0) }
let introducedVersion = availability.introducedVersion.flatMap { SemanticVersion($0) }
introduced = introducedVersion?.stringRepresentation(precisionUpToNonsignificant: .minor)
deprecated = availability.deprecatedVersion.flatMap { VersionTriplet(semanticVersion: $0).stringRepresentation(precisionUpToNonsignificant: .minor) }
obsoleted = availability.obsoletedVersion.flatMap { VersionTriplet(semanticVersion: $0).stringRepresentation(precisionUpToNonsignificant: .minor) }
deprecated = availability.deprecatedVersion.flatMap { SemanticVersion($0).stringRepresentation(precisionUpToNonsignificant: .minor) }
obsoleted = availability.obsoletedVersion.flatMap { SemanticVersion($0).stringRepresentation(precisionUpToNonsignificant: .minor) }
message = availability.message
renamed = availability.renamed
unconditionallyUnavailable = availability.isUnconditionallyUnavailable
Expand All @@ -144,8 +155,8 @@ public struct AvailabilityRenderItem: Codable, Hashable, Equatable {
isBeta = AvailabilityRenderItem.isBeta(introduced: availability.introduced, current: current)
}

private static func isBeta(introduced: VersionTriplet?, current: PlatformVersion?) -> Bool {
guard let introduced, let current, current.beta, introduced == current.version else {
private static func isBeta(introduced: SemanticVersion?, current: PlatformVersion?) -> Bool {
guard let introduced, let current, current.beta, introduced.isEqualToVersionTriplet(current.version) else {
return false
}

Expand Down
10 changes: 5 additions & 5 deletions Sources/SwiftDocC/Semantics/Metadata/Availability.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ extension Metadata {

/// The platform version that this page applies to.
@DirectiveArgumentWrapped
public var introduced: VersionTriplet
public var introduced: SemanticVersion

// FIXME: `isBeta` and `isDeprecated` properties/arguments
// cf. https://github.com/apple/swift-docc/issues/441
Expand All @@ -121,17 +121,17 @@ extension Metadata {
}
}

extension VersionTriplet: DirectiveArgumentValueConvertible {
extension SemanticVersion: DirectiveArgumentValueConvertible {
static let separator = "."

init?(rawDirectiveArgumentValue: String) {
guard !rawDirectiveArgumentValue.hasSuffix(VersionTriplet.separator),
!rawDirectiveArgumentValue.hasPrefix(VersionTriplet.separator) else {
guard !rawDirectiveArgumentValue.hasSuffix(Self.separator),
!rawDirectiveArgumentValue.hasPrefix(Self.separator) else {
return nil
}

// Split the string into major, minor and patch components
let availabilityComponents = rawDirectiveArgumentValue.split(separator: .init(VersionTriplet.separator), maxSplits: 2)
let availabilityComponents = rawDirectiveArgumentValue.split(separator: .init(Self.separator), maxSplits: 2)
guard !availabilityComponents.isEmpty else {
return nil
}
Expand Down
30 changes: 1 addition & 29 deletions Tests/SwiftDocCTests/Infrastructure/VersionTripletTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,5 @@ class VersionTripletTests: XCTestCase {

// Test the autogenerated equality conformance for coherence
XCTAssertEqual(VersionTriplet(5,2,1), VersionTriplet(5,2,1))
}

func testStringRepresentation() {
let oneComponent = VersionTriplet(1, 0, 0)

XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .minor), "1.0")
XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .patch), "1.0.0")
XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .all), "1.0.0")

let twoComponents = VersionTriplet(1, 2, 0)
XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .minor), "1.2")
XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .patch), "1.2.0")
XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .all), "1.2.0")

let threeComponents = VersionTriplet(1, 2, 3)
XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .minor), "1.2.3")
XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .patch), "1.2.3")
XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .all), "1.2.3")

let zeroVersion = VersionTriplet(0, 0, 0)
XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .minor), "0.0")
XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .patch), "0.0.0")
XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .all), "0.0.0")

let zeroMinorVersion = VersionTriplet(1, 0, 1)
XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .minor), "1.0.1")
XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .patch), "1.0.1")
XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .all), "1.0.1")
}
}
}
2 changes: 1 addition & 1 deletion Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1566,7 +1566,7 @@ class SemaToRenderNodeTests: XCTestCase {
let platforms = (renderNode.metadata.platforms ?? []).sorted(by: { lhs, rhs in lhs.name! < rhs.name! })

XCTAssertEqual(platforms.count,6)
let versionString = VersionTriplet(semanticVersion: version).stringRepresentation(precisionUpToNonsignificant: .patch)
let versionString = SemanticVersion(version).stringRepresentation(precisionUpToNonsignificant: .patch)

XCTAssertEqual(platforms[0].name, "Mac Catalyst")
XCTAssertEqual(platforms[0].introduced, versionString)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,47 @@ import SymbolKit
class SemanticVersionStringRepresentationTests: XCTestCase {
func testConversionToVersionTriplet() {
let symbolOne = SymbolGraph.SemanticVersion(major: 1, minor: 0, patch: 0)
XCTAssertEqual(VersionTriplet(semanticVersion: symbolOne), VersionTriplet(1, 0, 0))
XCTAssertEqual(SemanticVersion(symbolOne), SemanticVersion(major: 1, minor: 0, patch: 0))

let symbolTwo = SymbolGraph.SemanticVersion(major: 1, minor: 2, patch: 0)
XCTAssertEqual(VersionTriplet(semanticVersion: symbolTwo), VersionTriplet(1, 2, 0))
XCTAssertEqual(SemanticVersion(symbolTwo), SemanticVersion(major: 1, minor: 2, patch: 0))

let symbolThree = SymbolGraph.SemanticVersion(major: 1, minor: 2, patch: 3)
XCTAssertEqual(VersionTriplet(semanticVersion: symbolThree), VersionTriplet(1, 2, 3))
XCTAssertEqual(SemanticVersion(symbolThree), SemanticVersion(major: 1, minor: 2, patch: 3))

let symbolFour = SymbolGraph.SemanticVersion(major: 0, minor: 0, patch: 0)
XCTAssertEqual(VersionTriplet(semanticVersion: symbolFour), VersionTriplet(0, 0, 0))
XCTAssertEqual(SemanticVersion(symbolFour), SemanticVersion(major: 0, minor: 0, patch: 0))

let symbolFive = SymbolGraph.SemanticVersion(major: 1, minor: 0, patch: 1)
XCTAssertEqual(VersionTriplet(semanticVersion: symbolFive), VersionTriplet(1, 0, 1))
XCTAssertEqual(SemanticVersion(symbolFive), SemanticVersion(major: 1, minor: 0, patch: 1))
}

func testStringRepresentation() {
let oneComponent = SemanticVersion(major: 1, minor: 0, patch: 0)

XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .minor), "1.0")
XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .patch), "1.0.0")
XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .all), "1.0.0")

let twoComponents = SemanticVersion(major: 1, minor: 2, patch: 0)
XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .minor), "1.2")
XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .patch), "1.2.0")
XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .all), "1.2.0")

let threeComponents = SemanticVersion(major: 1, minor: 2, patch: 3)
XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .minor), "1.2.3")
XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .patch), "1.2.3")
XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .all), "1.2.3")

let zeroVersion = SemanticVersion(major: 0, minor: 0, patch: 0)
XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .minor), "0.0")
XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .patch), "0.0.0")
XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .all), "0.0.0")

let zeroMinorVersion = SemanticVersion(major: 1, minor: 0, patch: 1)
XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .minor), "1.0.1")
XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .patch), "1.0.1")
XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .all), "1.0.1")
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class MetadataAvailabilityTests: XCTestCase {
try assertDirective(Metadata.self, source: source) { directive, problems in
let directive = try XCTUnwrap(directive)
let platforms = directive.availability.map { $0.platform }
let introducedVersions = directive.availability.map { $0.introducedVersion }
let introducedVersions = directive.availability.map { $0.introduced }



Expand All @@ -97,9 +97,9 @@ class MetadataAvailabilityTests: XCTestCase {
.other("Package")
])
XCTAssertEqual(introducedVersions, [
VersionTriplet(3, 5, 2),
VersionTriplet(3, 5, 0),
VersionTriplet(3, 0, 0)
SemanticVersion(major: 3, minor: 5, patch: 2),
SemanticVersion(major: 3, minor: 5, patch: 0),
SemanticVersion(major: 3, minor: 0, patch: 0)
])

XCTAssertEqual(0, problems.count)
Expand Down

0 comments on commit 7efe5c1

Please sign in to comment.