diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index c1a6259c..cc4889ca 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -133,6 +133,13 @@ Note that target names can also be changed by adding a `name` property to a targ - [ ] **indentWidth**: **Int** - If this is specified, the Xcode project will override the user's setting for indent width in number of spaces. - [ ] **tabWidth**: **Int** - If this is specified, the Xcode project will override the user's setting for indent width in number of spaces. - [ ] **xcodeVersion**: **String** - The version of Xcode. This defaults to the latest version periodically. You can specify it in the format `0910` or `9.1` +- [ ] **projectFormat**: **String** - The version of Xcode project. By default this is set to `xcode16_0` + - `xcode16_3`: Xcode 16.3 + - `xcode16_0`: Xcode 16.0 + - `xcode15_3`: Xcode 15.3 + - `xcode15_0`: Xcode 15.0 + - `xcode14_0`: Xcode 14.0 + - [ ] **deploymentTarget**: **[[Platform](#platform): String]** - A project wide deployment target can be specified for each platform otherwise the default SDK version in Xcode will be used. This will be overridden by any custom build settings that set the deployment target eg `IPHONEOS_DEPLOYMENT_TARGET`. Target specific deployment targets can also be set with [Target](#target).deploymentTarget. - [ ] **disabledValidations**: **[String]** - A list of validations that can be disabled if they're too strict for your use case. By default this is set to an empty array. Currently these are the available options: - `missingConfigs`: Disable errors for configurations in yaml files that don't exist in the project itself. This can be useful if you include the same yaml file in different projects @@ -156,7 +163,7 @@ Note that target names can also be changed by adding a `name` property to a targ - [ ] **defaultSourceDirectoryType**: **String** - When a [Target source](#target-source) doesn't specify a type and is a directory, this is the type that will be used. If nothing is specified for either then `group` will be used. - `group` (default) - `folder` - - `syncedFolder` + - `syncedFolder`: Can be used starting from **projectFormat** `xcode16_0` ```yaml options: diff --git a/Sources/ProjectSpec/SpecOptions.swift b/Sources/ProjectSpec/SpecOptions.swift index c10c3469..07582d42 100644 --- a/Sources/ProjectSpec/SpecOptions.swift +++ b/Sources/ProjectSpec/SpecOptions.swift @@ -24,6 +24,7 @@ public struct SpecOptions: Equatable { public var tabWidth: UInt? public var indentWidth: UInt? public var xcodeVersion: String? + public var projectFormat: String? public var deploymentTarget: DeploymentTarget public var defaultConfig: String? public var transitivelyLinkDependencies: Bool @@ -88,6 +89,7 @@ public struct SpecOptions: Equatable { tabWidth: UInt? = nil, usesTabs: Bool? = nil, xcodeVersion: String? = nil, + projectFormat: String? = nil, deploymentTarget: DeploymentTarget = .init(), disabledValidations: [ValidationType] = [], defaultConfig: String? = nil, @@ -115,6 +117,7 @@ public struct SpecOptions: Equatable { self.indentWidth = indentWidth self.usesTabs = usesTabs self.xcodeVersion = xcodeVersion + self.projectFormat = projectFormat self.deploymentTarget = deploymentTarget self.disabledValidations = disabledValidations self.defaultConfig = defaultConfig @@ -148,6 +151,7 @@ extension SpecOptions: JSONObjectConvertible { developmentLanguage = jsonDictionary.json(atKeyPath: "developmentLanguage") usesTabs = jsonDictionary.json(atKeyPath: "usesTabs") xcodeVersion = jsonDictionary.json(atKeyPath: "xcodeVersion") + projectFormat = jsonDictionary.json(atKeyPath: "projectFormat") indentWidth = (jsonDictionary.json(atKeyPath: "indentWidth") as Int?).flatMap(UInt.init) tabWidth = (jsonDictionary.json(atKeyPath: "tabWidth") as Int?).flatMap(UInt.init) deploymentTarget = jsonDictionary.json(atKeyPath: "deploymentTarget") ?? DeploymentTarget() @@ -186,6 +190,7 @@ extension SpecOptions: JSONEncodable { "developmentLanguage": developmentLanguage, "usesTabs": usesTabs, "xcodeVersion": xcodeVersion, + "projectFormat": projectFormat, "indentWidth": indentWidth.flatMap { Int($0) }, "tabWidth": tabWidth.flatMap { Int($0) }, "defaultConfig": defaultConfig, diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 8dcad5af..84088a1b 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -102,7 +102,7 @@ public class PBXProjGenerator { name: project.name, buildConfigurationList: buildConfigList, compatibilityVersion: project.compatibilityVersion, - preferredProjectObjectVersion: Int(project.objectVersion), + preferredProjectObjectVersion: project.preferredProjectObjectVersion.map { Int($0) }, minimizedProjectReferenceProxies: project.minimizedProjectReferenceProxies, mainGroup: mainGroup, developmentRegion: developmentRegion diff --git a/Sources/XcodeGenKit/ProjectFormat.swift b/Sources/XcodeGenKit/ProjectFormat.swift new file mode 100644 index 00000000..0405518f --- /dev/null +++ b/Sources/XcodeGenKit/ProjectFormat.swift @@ -0,0 +1,37 @@ +public extension ProjectFormat { + static let `default`: ProjectFormat = .xcode16_0 +} + +public enum ProjectFormat: String { + case xcode16_3 + case xcode16_0 + case xcode15_3 + case xcode15_0 + case xcode14_0 + + public var objectVersion: UInt { + switch self { + case .xcode16_3: 90 + case .xcode16_0: 77 + case .xcode15_3: 63 + case .xcode15_0: 60 + case .xcode14_0: 56 + } + } + + public var preferredProjectObjectVersion: UInt? { + switch self { + case .xcode16_3, .xcode16_0: objectVersion + case .xcode15_3, .xcode15_0, .xcode14_0: nil + } + } + + public var compatibilityVersion: String? { + switch self { + case .xcode16_3, .xcode16_0: nil + case .xcode15_3: "Xcode 15.3" + case .xcode15_0: "Xcode 15.0" + case .xcode14_0: "Xcode 14.0" + } + } +} diff --git a/Sources/XcodeGenKit/Version.swift b/Sources/XcodeGenKit/Version.swift index 7b7246e9..b5ba54d4 100644 --- a/Sources/XcodeGenKit/Version.swift +++ b/Sources/XcodeGenKit/Version.swift @@ -7,16 +7,24 @@ extension Project { XCodeVersion.parse(options.xcodeVersion ?? "14.3") } + public var projectFormat: ProjectFormat { + options.projectFormat.flatMap(ProjectFormat.init) ?? .default + } + var schemeVersion: String { "1.7" } - var compatibilityVersion: String { - "Xcode 14.0" + var compatibilityVersion: String? { + projectFormat.compatibilityVersion } var objectVersion: UInt { - 77 + projectFormat.objectVersion + } + + var preferredProjectObjectVersion: UInt? { + projectFormat.preferredProjectObjectVersion } var minimizedProjectReferenceProxies: Int { diff --git a/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj index 5b62b813..11c93aec 100644 --- a/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj @@ -324,7 +324,6 @@ LastUpgradeCheck = 1430; }; buildConfigurationList = D91E14E36EC0B415578456F2 /* Build configuration list for PBXProject "Project" */; - compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( diff --git a/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj b/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj index eef5a9d7..a1e8db31 100644 --- a/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj @@ -244,7 +244,6 @@ LastUpgradeCheck = 1430; }; buildConfigurationList = 425866ADA259DB93FC4AF1E3 /* Build configuration list for PBXProject "SPM" */; - compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( diff --git a/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj index 00cc8462..25d6d75f 100644 --- a/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj @@ -122,7 +122,6 @@ LastUpgradeCheck = 1430; }; buildConfigurationList = 3DFC1105373EDB6483D4BC5D /* Build configuration list for PBXProject "AnotherProject" */; - compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index 6aa8bed9..02b6fcf0 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -2447,7 +2447,6 @@ ); }; buildConfigurationList = D91E14E36EC0B415578456F2 /* Build configuration list for PBXProject "Project" */; - compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( diff --git a/Tests/Fixtures/scheme_test/TestProject.xcodeproj/project.pbxproj b/Tests/Fixtures/scheme_test/TestProject.xcodeproj/project.pbxproj index baed78ca..8d945120 100644 --- a/Tests/Fixtures/scheme_test/TestProject.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/scheme_test/TestProject.xcodeproj/project.pbxproj @@ -74,7 +74,6 @@ LastUpgradeCheck = 1430; }; buildConfigurationList = E903F6E8184E2A86CEC31778 /* Build configuration list for PBXProject "TestProject" */; - compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = (