mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2024-12-11 07:16:40 +03:00
Merge pull request #534 from tomquist/support-nested-templates
Add support for nested templates
This commit is contained in:
commit
8dd2ec89cc
@ -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)
|
||||
|
@ -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] {
|
||||
|
@ -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"],
|
||||
|
Loading…
Reference in New Issue
Block a user