mirror of
https://github.com/realm/SwiftLint.git
synced 2026-05-07 20:12:49 +00:00
116 lines
4.1 KiB
Swift
116 lines
4.1 KiB
Swift
import Foundation
|
|
import SourceKittenFramework
|
|
|
|
/// A value describing the version of the Swift compiler.
|
|
public struct SwiftVersion: RawRepresentable, Codable, VersionComparable, Sendable {
|
|
public typealias RawValue = String
|
|
|
|
public let rawValue: String
|
|
|
|
public init(rawValue: String) {
|
|
self.rawValue = rawValue
|
|
}
|
|
}
|
|
|
|
/// A comparable `major.minor.patch` version number.
|
|
public protocol VersionComparable: Comparable {
|
|
/// The version string.
|
|
var rawValue: String { get }
|
|
}
|
|
|
|
extension VersionComparable {
|
|
public static func == (lhs: Self, rhs: Self) -> Bool {
|
|
if let lhsComparators = lhs.comparators, let rhsComparators = rhs.comparators {
|
|
return lhsComparators == rhsComparators
|
|
}
|
|
return lhs.rawValue == rhs.rawValue
|
|
}
|
|
|
|
public static func < (lhs: Self, rhs: Self) -> Bool {
|
|
if let lhsComparators = lhs.comparators, let rhsComparators = rhs.comparators {
|
|
return lhsComparators.lexicographicallyPrecedes(rhsComparators)
|
|
}
|
|
return lhs.rawValue < rhs.rawValue
|
|
}
|
|
|
|
private var comparators: [Int]? {
|
|
let components = rawValue.split(separator: ".").compactMap { Int($0) }
|
|
guard let major = components.first else {
|
|
return nil
|
|
}
|
|
let minor = components.dropFirst(1).first ?? 0
|
|
let patch = components.dropFirst(2).first ?? 0
|
|
return [major, minor, patch]
|
|
}
|
|
}
|
|
|
|
public extension SwiftVersion {
|
|
/// Swift 5
|
|
static let five = SwiftVersion(rawValue: "5.0.0")
|
|
/// Swift 5.1
|
|
static let fiveDotOne = SwiftVersion(rawValue: "5.1.0")
|
|
/// Swift 5.2
|
|
static let fiveDotTwo = SwiftVersion(rawValue: "5.2.0")
|
|
/// Swift 5.3
|
|
static let fiveDotThree = SwiftVersion(rawValue: "5.3.0")
|
|
/// Swift 5.4
|
|
static let fiveDotFour = SwiftVersion(rawValue: "5.4.0")
|
|
/// Swift 5.5
|
|
static let fiveDotFive = SwiftVersion(rawValue: "5.5.0")
|
|
/// Swift 5.6
|
|
static let fiveDotSix = SwiftVersion(rawValue: "5.6.0")
|
|
/// Swift 5.7
|
|
static let fiveDotSeven = SwiftVersion(rawValue: "5.7.0")
|
|
/// Swift 5.8
|
|
static let fiveDotEight = SwiftVersion(rawValue: "5.8.0")
|
|
/// Swift 5.9
|
|
static let fiveDotNine = SwiftVersion(rawValue: "5.9.0")
|
|
/// Swift 6
|
|
static let six = SwiftVersion(rawValue: "6.0.0")
|
|
/// Swift 6.1
|
|
static let sixDotOne = SwiftVersion(rawValue: "6.1.0")
|
|
/// Swift 6.1.1
|
|
static let sixDotOneDotOne = SwiftVersion(rawValue: "6.1.1")
|
|
/// Swift 6.1.2
|
|
static let sixDotOneDotTwo = SwiftVersion(rawValue: "6.1.2")
|
|
/// Swift 6.2
|
|
static let sixDotTwo = SwiftVersion(rawValue: "6.2.0")
|
|
|
|
/// The current detected Swift compiler version, based on the currently accessible SourceKit version.
|
|
///
|
|
/// - note: Override by setting the `SWIFTLINT_SWIFT_VERSION` environment variable.
|
|
static let current: SwiftVersion = {
|
|
// Allow forcing the Swift version, useful in cases where SourceKit isn't available.
|
|
if let envVersion = ProcessInfo.processInfo.environment["SWIFTLINT_SWIFT_VERSION"] {
|
|
return SwiftVersion(rawValue: envVersion)
|
|
}
|
|
if !Request.disableSourceKit {
|
|
// This request was added in Swift 5.1
|
|
let params: SourceKitObject = ["key.request": UID("source.request.compiler_version")]
|
|
// Allow this specific SourceKit request outside of rule execution context
|
|
let result = CurrentRule.$allowSourceKitRequestWithoutRule.withValue(true) {
|
|
try? Request.customRequest(request: params).sendIfNotDisabled()
|
|
}
|
|
if let result,
|
|
let major = result.versionMajor, let minor = result.versionMinor, let patch = result.versionPatch {
|
|
return SwiftVersion(rawValue: "\(major).\(minor).\(patch)")
|
|
}
|
|
}
|
|
return .five
|
|
}()
|
|
}
|
|
|
|
private extension Dictionary where Key == String {
|
|
var versionMajor: Int? {
|
|
(self["key.version_major"] as? Int64).flatMap({ Int($0) })
|
|
}
|
|
|
|
var versionMinor: Int? {
|
|
(self["key.version_minor"] as? Int64).flatMap({ Int($0) })
|
|
}
|
|
|
|
var versionPatch: Int? {
|
|
(self["key.version_patch"] as? Int64).flatMap({ Int($0) })
|
|
}
|
|
}
|