Merge pull request #534 from tomquist/support-nested-templates

Add support for nested templates
This commit is contained in:
Yonas Kolb 2019-03-17 21:55:25 +11:00 committed by GitHub
commit 8dd2ec89cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 143 additions and 2 deletions

View File

@ -6,6 +6,7 @@
- Added `missingConfigFiles` to `options.disabledValidations` to optionally skip checking for the existence of config files.
- Added ability to automatically include Carthage related dependencies via `includeRelated: true` [#506](https://github.com/yonaskolb/XcodeGen/pull/506) @rpassis
- Added ability to define a per-platform `deploymentTarget` for Multi-Platform targets. [#510](https://github.com/yonaskolb/XcodeGen/pull/510) @ainopara
- Added support for nested target templates [#534](https://github.com/yonaskolb/XcodeGen/pull/534) @tomquist
#### Fixed
- Sources outside a project spec's directory will be correctly referenced as relative paths in the project file. [#524](https://github.com/yonaskolb/XcodeGen/pull/524)

View File

@ -139,9 +139,28 @@ extension Target {
let targetTemplatesDictionary: [String: JSONDictionary] = jsonDictionary["targetTemplates"] as? [String: JSONDictionary] ?? [:]
for (targetName, var target) in targetsDictionary {
// Recursively collects all nested template names of a given dictionary.
func collectTemplates(of jsonDictionary: JSONDictionary,
into allTemplates: inout [String],
insertAt insertionIndex: inout Int) {
guard let templates = jsonDictionary["templates"] as? [String] else {
return
}
for template in templates where !allTemplates.contains(template) {
guard let templateDictionary = targetTemplatesDictionary[template] else {
continue
}
allTemplates.insert(template, at: insertionIndex)
collectTemplates(of: templateDictionary, into: &allTemplates, insertAt: &insertionIndex)
insertionIndex += 1
}
}
if let templates = target["templates"] as? [String] {
for (targetName, var target) in targetsDictionary {
var templates: [String] = []
var index: Int = 0
collectTemplates(of: target, into: &templates, insertAt: &index)
if !templates.isEmpty {
var mergedDictionary: JSONDictionary = [:]
for template in templates {
if let templateDictionary = targetTemplatesDictionary[template] {

View File

@ -366,6 +366,127 @@ class SpecLoadingTests: XCTestCase {
try expect(target.configFiles["debug"]) == "Configs/Framework/debug.xcconfig" // replaces $target_name
}
$0.it("parses nested target templates") {
let targetDictionary: [String: Any] = [
"deploymentTarget": "1.2.0",
"sources": ["targetSource"],
"templates": ["temp2"],
]
let project = try getProjectSpec([
"targets": ["Framework": targetDictionary],
"targetTemplates": [
"temp": [
"type": "framework",
"platform": "iOS",
"sources": ["nestedTemplateSource1"],
],
"temp1": [
"type": "application",
"sources": ["nestedTemplateSource2"],
],
"temp2": [
"platform": "tvOS",
"deploymentTarget": "1.1.0",
"configFiles": ["debug": "Configs/$target_name/debug.xcconfig"],
"templates": ["temp", "temp1"],
"sources": ["templateSource"],
]
],
])
let target = project.targets.first!
try expect(target.type) == .application // uses value of last nested template
try expect(target.platform) == .tvOS // uses latest value
try expect(target.deploymentTarget) == Version("1.2.0") // keeps value
try expect(target.sources) == ["nestedTemplateSource1", "nestedTemplateSource2", "templateSource", "targetSource"] // merges array in order
try expect(target.configFiles["debug"]) == "Configs/Framework/debug.xcconfig" // replaces $target_name
}
$0.it("parses complex nested target templates") {
let targetDictionary: [String: Any] = [
"type": "framework",
"platform": "iOS",
"templates": ["temp"],
"sources": ["target"],
]
let project = try getProjectSpec([
"targets": ["Framework": targetDictionary],
"targetTemplates": [
"temp": [
"templates": ["a", "d"],
"sources": ["temp"],
],
"a": [
"templates": ["b", "c"],
"sources": ["a"],
],
"b": [
"sources": ["b"],
],
"c": [
"sources": ["c"],
],
"d": [
"sources": ["d"],
"templates": ["e"],
],
"e": [
"sources": ["e"],
],
],
])
let target = project.targets.first!
try expect(target.type) == .framework // uses value of last nested template
try expect(target.platform) == .iOS // uses latest value
try expect(target.sources) == ["b", "c", "a", "e", "d", "temp", "target"] // merges array in order
}
$0.it("parses nested target templates with cycle") {
let targetDictionary: [String: Any] = [
"deploymentTarget": "1.2.0",
"sources": ["targetSource"],
"templates": ["temp2"],
]
let project = try getProjectSpec([
"targets": ["Framework": targetDictionary],
"targetTemplates": [
"temp": [
"type": "framework",
"platform": "iOS",
"templates": ["temp1"],
"sources": ["nestedTemplateSource1"],
],
"temp1": [
"platform": "macOS",
"templates": ["temp2"],
"sources": ["nestedTemplateSource2"],
],
"temp2": [
"platform": "tvOS",
"deploymentTarget": "1.1.0",
"configFiles": ["debug": "Configs/$target_name/debug.xcconfig"],
"templates": ["temp", "temp1"],
"sources": ["templateSource"],
]
],
])
let target = project.targets.first!
try expect(target.type) == .framework // uses value
try expect(target.platform) == .tvOS // uses latest value
try expect(target.deploymentTarget) == Version("1.2.0") // keeps value
try expect(target.sources) == ["nestedTemplateSource2", "nestedTemplateSource1", "templateSource", "targetSource"] // merges array in order
try expect(target.configFiles["debug"]) == "Configs/Framework/debug.xcconfig" // replaces $target_name
}
$0.it("parses aggregate targets") {
let dictionary: [String: Any] = [
"targets": ["target_1", "target_2"],