From e636664aaa58992501d2e53539d614a00a534367 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Mon, 19 Mar 2018 13:13:31 -0700 Subject: [PATCH] Add defaultConfigurationName to options This allows users to set the defaultConfigurationName project wide. This setting corresponds to the drop down in the project settings that says "Use CONFIG for command line builds". This affects which configuration Xcode looks in for some settings, even if you pass `-configuration FOO`. --- Sources/ProjectSpec/ProjectSpec.swift | 6 +++++- Sources/ProjectSpec/SpecValidation.swift | 6 ++++++ Sources/ProjectSpec/SpecValidationError.swift | 3 +++ Sources/XcodeGenKit/PBXProjGenerator.swift | 3 ++- Tests/XcodeGenKitTests/ProjectGeneratorTests.swift | 14 ++++++++++++++ Tests/XcodeGenKitTests/ProjectSpecTests.swift | 6 ++++++ 6 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Sources/ProjectSpec/ProjectSpec.swift b/Sources/ProjectSpec/ProjectSpec.swift index 6d329a72..1d06a811 100644 --- a/Sources/ProjectSpec/ProjectSpec.swift +++ b/Sources/ProjectSpec/ProjectSpec.swift @@ -32,6 +32,7 @@ public struct ProjectSpec { public var indentWidth: UInt? public var xcodeVersion: String? public var deploymentTarget: DeploymentTarget + public var defaultConfigurationName: String? public enum SettingPresets: String { case all @@ -66,7 +67,8 @@ public struct ProjectSpec { usesTabs: Bool? = nil, xcodeVersion: String? = nil, deploymentTarget: DeploymentTarget = .init(), - disabledValidations: [ValidationType] = [] + disabledValidations: [ValidationType] = [], + defaultConfigurationName: String? = nil ) { self.carthageBuildPath = carthageBuildPath self.carthageExecutablePath = carthageExecutablePath @@ -80,6 +82,7 @@ public struct ProjectSpec { self.xcodeVersion = xcodeVersion self.deploymentTarget = deploymentTarget self.disabledValidations = disabledValidations + self.defaultConfigurationName = defaultConfigurationName } public static func == (lhs: ProjectSpec.Options, rhs: ProjectSpec.Options) -> Bool { @@ -217,5 +220,6 @@ extension ProjectSpec.Options: JSONObjectConvertible { tabWidth = (jsonDictionary.json(atKeyPath: "tabWidth") as Int?).flatMap(UInt.init) deploymentTarget = jsonDictionary.json(atKeyPath: "deploymentTarget") ?? DeploymentTarget() disabledValidations = jsonDictionary.json(atKeyPath: "disabledValidations") ?? [] + defaultConfigurationName = jsonDictionary.json(atKeyPath: "defaultConfigurationName") } } diff --git a/Sources/ProjectSpec/SpecValidation.swift b/Sources/ProjectSpec/SpecValidation.swift index 70110b53..22628c0e 100644 --- a/Sources/ProjectSpec/SpecValidation.swift +++ b/Sources/ProjectSpec/SpecValidation.swift @@ -47,6 +47,12 @@ extension ProjectSpec { } } + if let configName = options.defaultConfigurationName { + if !configs.contains(where: { $0.name == configName }) { + errors.append(.missingDefaultConfigurationName(configName: configName)) + } + } + for settings in settingGroups.values { errors += validateSettings(settings) } diff --git a/Sources/ProjectSpec/SpecValidationError.swift b/Sources/ProjectSpec/SpecValidationError.swift index 117c8644..32bab93f 100644 --- a/Sources/ProjectSpec/SpecValidationError.swift +++ b/Sources/ProjectSpec/SpecValidationError.swift @@ -19,6 +19,7 @@ public struct SpecValidationError: Error, CustomStringConvertible { case invalidFileGroup(String) case invalidConfigFileConfig(String) case missingConfigForTargetScheme(target: String, configType: ConfigType) + case missingDefaultConfigurationName(configName: String) public var description: String { switch self { @@ -50,6 +51,8 @@ public struct SpecValidationError: Error, CustomStringConvertible { return "Config file has invalid config \(config.quoted)" case let .missingConfigForTargetScheme(target, configType): return "Target \(target.quoted) is missing a config of type \(configType.rawValue) to generate its scheme" + case let .missingDefaultConfigurationName(name): + return "Default configuration \(name) doesn't exist" } } } diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 78c1333f..e0f0b28f 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -70,11 +70,12 @@ public class PBXProjGenerator { ) } + let configName = spec.options.defaultConfigurationName ?? buildConfigs.first?.object.name ?? "" let buildConfigList = createObject( id: spec.name, XCConfigurationList( buildConfigurations: buildConfigs.map { $0.reference }, - defaultConfigurationName: buildConfigs.first?.object.name ?? "" + defaultConfigurationName: configName ) ) diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index a8c5a435..36757c52 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -96,6 +96,20 @@ func projectGeneratorTests() { try expect(XCodeVersion.parse(version)) == expected } } + + $0.it("uses the default configuration name") { + let options = ProjectSpec.Options(defaultConfigurationName: "Bconfig") + let spec = ProjectSpec(basePath: "", name: "test", configs: [Config(name: "Aconfig"), Config(name: "Bconfig")], targets: [framework], options: options) + let pbxProject = try getPbxProj(spec) + + guard let projectConfigListReference = pbxProject.objects.projects.values.first?.buildConfigurationList, + let defaultConfigurationName = pbxProject.objects.configurationLists[projectConfigListReference]?.defaultConfigurationName + else { + throw failure("Default configuration name not found") + } + + try expect(defaultConfigurationName) == "Bconfig" + } } $0.describe("Config") { diff --git a/Tests/XcodeGenKitTests/ProjectSpecTests.swift b/Tests/XcodeGenKitTests/ProjectSpecTests.swift index fcac1c02..7bed6d88 100644 --- a/Tests/XcodeGenKitTests/ProjectSpecTests.swift +++ b/Tests/XcodeGenKitTests/ProjectSpecTests.swift @@ -167,6 +167,12 @@ func projectSpecTests() { )] try spec.validate() } + + $0.it("validates missing default configurations") { + var spec = baseSpec + spec.options = ProjectSpec.Options(defaultConfigurationName: "foo") + try expectValidationError(spec, .missingDefaultConfigurationName(configName: "foo")) + } } } }