Add target.attributes

This commit is contained in:
Yonas Kolb 2018-03-27 14:21:15 +11:00
parent 40b934ee6c
commit ebde9de151
6 changed files with 44 additions and 24 deletions

View File

@ -160,6 +160,7 @@ Settings are merged in the following order: groups, base, configs.
- [ ] **dependencies**: **[[Dependency](#dependency)]** - Dependencies for the target
- [ ] **scheme**: **[Target Scheme](#target-scheme)** - Generated scheme with tests or config variants
- [ ] **legacy**: **[Legacy Target](#legacy-target)** - When present, opt-in to make an Xcode "External Build System" legacy target instead.
- [ ] **attributes**: **[String: Any]** - This sets values in the project `TargetAttributes`. It is merged with `attributes` from the project and anything automatically added by XcodeGen, with any duplicate values being override by values specified here. This is for advanced use only.
### Product Type
This will provide default build settings for a certain product type. It can be any of the following:

View File

@ -43,6 +43,7 @@ public struct Target {
public var scheme: TargetScheme?
public var legacy: LegacyTarget?
public var deploymentTarget: Version?
public var attributes: [String: Any]
internal var productName: String?
public var isLegacy: Bool {
@ -69,7 +70,8 @@ public struct Target {
prebuildScripts: [BuildScript] = [],
postbuildScripts: [BuildScript] = [],
scheme: TargetScheme? = nil,
legacy: LegacyTarget? = nil
legacy: LegacyTarget? = nil,
attributes: [String: Any] = [:]
) {
self.name = name
self.type = type
@ -83,6 +85,7 @@ public struct Target {
self.postbuildScripts = postbuildScripts
self.scheme = scheme
self.legacy = legacy
self.attributes = attributes
}
}
@ -175,7 +178,8 @@ extension Target: Equatable {
lhs.prebuildScripts == rhs.prebuildScripts &&
lhs.postbuildScripts == rhs.postbuildScripts &&
lhs.scheme == rhs.scheme &&
lhs.legacy == rhs.legacy
lhs.legacy == rhs.legacy &&
NSDictionary(dictionary: lhs.attributes).isEqual(to: rhs.attributes)
}
}
@ -282,5 +286,6 @@ extension Target: NamedJSONDictionaryConvertible {
postbuildScripts = jsonDictionary.json(atKeyPath: "postbuildScripts") ?? []
scheme = jsonDictionary.json(atKeyPath: "scheme")
legacy = jsonDictionary.json(atKeyPath: "legacy")
attributes = jsonDictionary.json(atKeyPath: "attributes") ?? [:]
}
}

View File

@ -218,35 +218,37 @@ public class PBXProjGenerator {
func generateTargetAttributes() -> [String: Any]? {
var targetAttributes: [String: Any] = [:]
// look up TEST_TARGET_NAME build setting
func testTargetName(_ target: PBXTarget) -> String? {
guard let configurationList = target.buildConfigurationList else { return nil }
guard let buildConfigurationReferences = self.proj.objects.configurationLists[configurationList]?.buildConfigurations else { return nil }
let configs = buildConfigurationReferences
.flatMap { ref in self.proj.objects.buildConfigurations[ref] }
return configs
.flatMap { $0.buildSettings["TEST_TARGET_NAME"] as? String }
.first
}
var targetAttributes: [String: [String: Any]] = [:]
let uiTestTargets = proj.objects.nativeTargets.objectReferences.filter { $0.object.productType == .uiTestBundle }
for uiTestTarget in uiTestTargets {
// look up TEST_TARGET_NAME build setting
func testTargetName(_ target: PBXTarget) -> String? {
guard let configurationList = target.buildConfigurationList else { return nil }
guard let buildConfigurationReferences = self.proj.objects.configurationLists[configurationList]?.buildConfigurations else { return nil }
let configs = buildConfigurationReferences
.flatMap { ref in self.proj.objects.buildConfigurations[ref] }
return configs
.flatMap { $0.buildSettings["TEST_TARGET_NAME"] as? String }
.first
}
guard let name = testTargetName(uiTestTarget.object) else { continue }
guard let target = self.proj.objects.targets(named: name).first else { continue }
targetAttributes[uiTestTarget.reference] = ["TestTargetID": target.reference]
targetAttributes[uiTestTarget.reference, default: [:]].merge(["TestTargetID": target.reference])
}
for target in spec.targets {
if !target.attributes.isEmpty, let targetObject = targetObjects[target.name] {
targetAttributes[targetObject.reference, default: [:]].merge(target.attributes)
}
}
guard !targetAttributes.isEmpty else { return nil }
return [
"TargetAttributes": targetAttributes,
]
return targetAttributes.isEmpty ? nil : ["TargetAttributes": targetAttributes]
}
func sortGroups(group: ObjectReference<PBXGroup>) {

View File

@ -678,6 +678,9 @@
NT_123503999387 = {
TestTargetID = NT_825232110500;
};
NT_825232110500 = {
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = CL_844877120535 /* Build configuration list for PBXProject "Project" */;

View File

@ -23,6 +23,8 @@ targets:
type: application
platform: iOS
deploymentTarget: 11.2
attributes:
ProvisioningStyle: Automatic
sources:
- StandaloneFiles/StandaloneAssets.xcassets
- path: App_iOS

View File

@ -208,7 +208,12 @@ func projectGeneratorTests() {
}
$0.it("generates target attributes") {
var appTargetWithAttributes = application
appTargetWithAttributes.attributes = ["ProvisioningStyle": "Automatic"]
var testTargetWithAttributes = uiTest
testTargetWithAttributes.attributes = ["ProvisioningStyle": "Manual"]
var spec = ProjectSpec(basePath: "", name: "test", targets: [appTargetWithAttributes, framework, testTargetWithAttributes])
let pbxProject = try getPbxProj(spec)
guard let targetAttributes = pbxProject.objects.projects.referenceValues.first?.attributes["TargetAttributes"] as? [String: [String: Any]] else {
@ -224,6 +229,8 @@ func projectGeneratorTests() {
}
try expect(targetAttributes[uiTestTarget.reference]?["TestTargetID"] as? String) == appTarget.reference
try expect(targetAttributes[uiTestTarget.reference]?["ProvisioningStyle"] as? String) == "Manual"
try expect(targetAttributes[appTarget.reference]?["ProvisioningStyle"] as? String) == "Automatic"
}
$0.it("generates platform version") {