mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2026-03-18 20:02:25 +00:00
Add Version type
This commit is contained in:
@@ -11,19 +11,19 @@ import JSONUtilities
|
||||
|
||||
public struct PlatformVersions: Equatable {
|
||||
|
||||
public var iOS: String?
|
||||
public var tvOS: String?
|
||||
public var watchOS: String?
|
||||
public var macOS: String?
|
||||
public var iOS: Version?
|
||||
public var tvOS: Version?
|
||||
public var watchOS: Version?
|
||||
public var macOS: Version?
|
||||
|
||||
public init(iOS: String? = nil, tvOS: String? = nil, watchOS: String? = nil, macOS: String? = nil) {
|
||||
public init(iOS: Version? = nil, tvOS: Version? = nil, watchOS: Version? = nil, macOS: Version? = nil) {
|
||||
self.iOS = iOS
|
||||
self.tvOS = tvOS
|
||||
self.watchOS = watchOS
|
||||
self.macOS = macOS
|
||||
}
|
||||
|
||||
public func version(for platform: Platform) -> String? {
|
||||
public func version(for platform: Platform) -> Version? {
|
||||
switch platform {
|
||||
case .iOS: return iOS
|
||||
case .tvOS: return tvOS
|
||||
@@ -52,23 +52,31 @@ extension Platform {
|
||||
}
|
||||
}
|
||||
|
||||
extension Version {
|
||||
|
||||
/// doesn't print patch
|
||||
public var platformVersion: String {
|
||||
return "\(major).\(minor)\(patch > 0 ? ".\(patch)" : "")"
|
||||
}
|
||||
}
|
||||
|
||||
extension PlatformVersions: JSONObjectConvertible {
|
||||
|
||||
public init(jsonDictionary: JSONDictionary) throws {
|
||||
|
||||
func parseVersion(_ platform: String) -> String? {
|
||||
func parseVersion(_ platform: String) throws -> Version? {
|
||||
if let string: String = jsonDictionary.json(atKeyPath: .key(platform)) {
|
||||
return string
|
||||
return try Version(string)
|
||||
} else if let double: Double = jsonDictionary.json(atKeyPath: .key(platform)) {
|
||||
return String(double)
|
||||
return try Version(double)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
iOS = parseVersion("iOS")
|
||||
tvOS = parseVersion("tvOS")
|
||||
watchOS = parseVersion("watchOS")
|
||||
macOS = parseVersion("macOS")
|
||||
iOS = try parseVersion("iOS")
|
||||
tvOS = try parseVersion("tvOS")
|
||||
watchOS = try parseVersion("watchOS")
|
||||
macOS = try parseVersion("macOS")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ public enum SpecParsingError: Error, CustomStringConvertible {
|
||||
case unknownTargetPlatform(String)
|
||||
case invalidDependency([String: Any])
|
||||
case unknownSourceBuildPhase(String)
|
||||
case invalidVersion(String)
|
||||
|
||||
public var description: String {
|
||||
switch self {
|
||||
@@ -12,6 +13,7 @@ public enum SpecParsingError: Error, CustomStringConvertible {
|
||||
case let .unknownTargetPlatform(platform): return "Unknown Target platform: \(platform)"
|
||||
case let .invalidDependency(dependency): return "Unknown Target dependency: \(dependency)"
|
||||
case let .unknownSourceBuildPhase(buildPhase): return "Unknown Source Build Phase: \(buildPhase)"
|
||||
case let .invalidVersion(version): return "Invalid version: \(version)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public struct Target {
|
||||
public var configFiles: [String: String]
|
||||
public var scheme: TargetScheme?
|
||||
public var legacy: LegacyTarget?
|
||||
public var platformVersion: String?
|
||||
public var platformVersion: Version?
|
||||
|
||||
public var isLegacy: Bool {
|
||||
return legacy != nil
|
||||
@@ -44,7 +44,7 @@ public struct Target {
|
||||
return name
|
||||
}
|
||||
|
||||
public init(name: String, type: PBXProductType, platform: Platform, platformVersion: String? = nil, settings: Settings = .empty, configFiles: [String: String] = [:], sources: [TargetSource] = [], dependencies: [Dependency] = [], prebuildScripts: [BuildScript] = [], postbuildScripts: [BuildScript] = [], scheme: TargetScheme? = nil, legacy: LegacyTarget? = nil) {
|
||||
public init(name: String, type: PBXProductType, platform: Platform, platformVersion: Version? = nil, settings: Settings = .empty, configFiles: [String: String] = [:], sources: [TargetSource] = [], dependencies: [Dependency] = [], prebuildScripts: [BuildScript] = [], postbuildScripts: [BuildScript] = [], scheme: TargetScheme? = nil, legacy: LegacyTarget? = nil) {
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.platform = platform
|
||||
@@ -212,9 +212,9 @@ extension Target: NamedJSONDictionaryConvertible {
|
||||
}
|
||||
|
||||
if let string: String = jsonDictionary.json(atKeyPath: "platformVersion") {
|
||||
platformVersion = string
|
||||
platformVersion = try Version(string)
|
||||
} else if let double: Double = jsonDictionary.json(atKeyPath: "platformVersion") {
|
||||
platformVersion = String(double)
|
||||
platformVersion = try Version(double)
|
||||
} else {
|
||||
platformVersion = nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import Foundation
|
||||
|
||||
public struct Version: CustomStringConvertible, Equatable {
|
||||
|
||||
public var major: UInt
|
||||
public var minor: UInt
|
||||
public var patch: UInt
|
||||
|
||||
public init(_ string: String) throws {
|
||||
let components = try string.split(separator: ".").map { (componentString) -> UInt in
|
||||
guard let uint = UInt(componentString) else {
|
||||
throw SpecParsingError.invalidVersion(string)
|
||||
}
|
||||
return uint
|
||||
}
|
||||
major = components[0]
|
||||
minor = (components.count >= 2) ? components[1] : 0
|
||||
patch = (components.count == 3) ? components[2] : 0
|
||||
}
|
||||
|
||||
public init(_ double: Double) throws {
|
||||
try self.init(String(double))
|
||||
}
|
||||
|
||||
public init(major: UInt, minor: UInt? = 0, patch: UInt? = 0) {
|
||||
self.major = major
|
||||
self.minor = minor ?? 0
|
||||
self.patch = patch ?? 0
|
||||
}
|
||||
|
||||
public var string: String {
|
||||
return "\(major).\(minor).\(patch)"
|
||||
}
|
||||
|
||||
public var description: String {
|
||||
return string
|
||||
}
|
||||
|
||||
public func bumpingMajor() -> Version {
|
||||
return Version(major: major + 1, minor: 0, patch: 0)
|
||||
}
|
||||
|
||||
public func bumpingMinor() -> Version {
|
||||
return Version(major: major, minor: minor + 1, patch: 0)
|
||||
}
|
||||
|
||||
public func bumpingPatch() -> Version {
|
||||
return Version(major: major, minor: minor, patch: patch + 1)
|
||||
}
|
||||
|
||||
public static func ==(lhs: Version, rhs: Version) -> Bool {
|
||||
return lhs.major == rhs.major &&
|
||||
lhs.minor == rhs.minor &&
|
||||
lhs.patch == rhs.patch
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ extension ProjectSpec {
|
||||
// apply custom platform version
|
||||
for platform in Platform.all {
|
||||
if let version = options.platformVersions.version(for: platform) {
|
||||
buildSettings[platform.versionBuildSetting] = version
|
||||
buildSettings[platform.versionBuildSetting] = version.platformVersion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ extension ProjectSpec {
|
||||
|
||||
// apply custom platform version
|
||||
if let version = target.platformVersion {
|
||||
buildSettings[target.platform.versionBuildSetting] = version
|
||||
buildSettings[target.platform.versionBuildSetting] = version.platformVersion
|
||||
}
|
||||
|
||||
// Prevent setting presets from overrwriting settings in target xcconfig files
|
||||
|
||||
@@ -14,17 +14,6 @@ func projectSpecTests() {
|
||||
let dynamicLibrary = Target(name: "MyDynamicLibrary", type: .dynamicLibrary, platform: .iOS,
|
||||
settings: Settings(buildSettings: ["SETTING_2": "VALUE"]))
|
||||
|
||||
$0.describe("Types") {
|
||||
$0.it("is a framework when it has the right extension") {
|
||||
try expect(framework.type.isFramework).to.beTrue()
|
||||
}
|
||||
|
||||
$0.it("is a library when it has the right type") {
|
||||
try expect(staticLibrary.type.isLibrary).to.beTrue()
|
||||
try expect(dynamicLibrary.type.isLibrary).to.beTrue()
|
||||
}
|
||||
}
|
||||
|
||||
func expectValidationError(_ spec: ProjectSpec, _ expectedError: SpecValidationError.ValidationError) throws {
|
||||
do {
|
||||
try spec.validate()
|
||||
@@ -39,6 +28,40 @@ func projectSpecTests() {
|
||||
throw failure("Supposed to fail with \"\(expectedError)\"")
|
||||
}
|
||||
|
||||
$0.describe("Types") {
|
||||
$0.it("is a framework when it has the right extension") {
|
||||
try expect(framework.type.isFramework).to.beTrue()
|
||||
}
|
||||
|
||||
$0.it("is a library when it has the right type") {
|
||||
try expect(staticLibrary.type.isLibrary).to.beTrue()
|
||||
try expect(dynamicLibrary.type.isLibrary).to.beTrue()
|
||||
}
|
||||
}
|
||||
|
||||
$0.describe("Deployment Version") {
|
||||
|
||||
$0.it("has correct build setting") {
|
||||
try expect(Platform.iOS.versionBuildSetting) == "IPHONEOS_DEPLOYMENT_TARGET"
|
||||
try expect(Platform.tvOS.versionBuildSetting) == "TVOS_DEPLOYMENT_TARGET"
|
||||
try expect(Platform.watchOS.versionBuildSetting) == "WATCHOS_DEPLOYMENT_TARGET"
|
||||
try expect(Platform.macOS.versionBuildSetting) == "MACOSX_DEPLOYMENT_TARGET"
|
||||
}
|
||||
|
||||
$0.it("parses versions correctly") {
|
||||
try expect(Version("2").platformVersion) == "2.0"
|
||||
try expect(Version("2.0").platformVersion) == "2.0"
|
||||
try expect(Version("2.1").platformVersion) == "2.1"
|
||||
try expect(Version("2.1.0").platformVersion) == "2.1"
|
||||
try expect(Version("2.12.0").platformVersion) == "2.12"
|
||||
try expect(Version("2.1.2").platformVersion) == "2.1.2"
|
||||
try expect(Version("2.0.2").platformVersion) == "2.0.2"
|
||||
try expect(Version(2).platformVersion) == "2.0"
|
||||
try expect(Version(2.0).platformVersion) == "2.0"
|
||||
try expect(Version(2.1).platformVersion) == "2.1"
|
||||
}
|
||||
}
|
||||
|
||||
$0.describe("Validation") {
|
||||
|
||||
let baseSpec = ProjectSpec(basePath: "", name: "", configs: [Config(name: "invalid")])
|
||||
|
||||
@@ -230,14 +230,18 @@ func specLoadingTests() {
|
||||
createIntermediateGroups: true,
|
||||
bundleIdPrefix: "com.test",
|
||||
developmentLanguage: "ja",
|
||||
platformVersions: PlatformVersions(iOS: "11.1", tvOS: "10.0", watchOS: "3.0", macOS: "10.12"))
|
||||
platformVersions: PlatformVersions(
|
||||
iOS: "11.1",
|
||||
tvOS: "10.0",
|
||||
watchOS: "3.0",
|
||||
macOS: "10.12.1"))
|
||||
let expected = ProjectSpec(basePath: "", name: "test", options: options)
|
||||
let dictionary: [String: Any] = ["options": [
|
||||
"carthageBuildPath": "../Carthage/Build",
|
||||
"bundleIdPrefix": "com.test",
|
||||
"createIntermediateGroups": true,
|
||||
"developmentLanguage": "ja",
|
||||
"platformVersions": ["iOS": 11.1, "tvOS": 10.0, "watchOS": "3.0", "macOS": "10.12" ]
|
||||
"platformVersions": ["iOS": 11.1, "tvOS": 10.0, "watchOS": "3", "macOS": "10.12.1" ]
|
||||
]]
|
||||
let parsedSpec = try getProjectSpec(dictionary)
|
||||
try expect(parsedSpec) == expected
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Foundation
|
||||
import Spectre
|
||||
import xcproj
|
||||
import ProjectSpec
|
||||
|
||||
func expectError<T: Error>(_ expectedError: T, _ closure: () throws -> Void) throws where T: CustomStringConvertible {
|
||||
do {
|
||||
@@ -88,3 +89,11 @@ public protocol Named {
|
||||
extension XCBuildConfiguration: Named {}
|
||||
extension PBXNativeTarget: Named {}
|
||||
extension XCScheme: Named {}
|
||||
|
||||
extension Version: ExpressibleByStringLiteral {
|
||||
|
||||
/// Will return nil literal not Semver
|
||||
public init(stringLiteral value: String) {
|
||||
try! self.init(value)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user