mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2024-12-11 07:16:40 +03:00
parent
331c8e5c23
commit
8e21cdfdb1
@ -2,6 +2,9 @@
|
||||
|
||||
## Next Version
|
||||
|
||||
#### Fixed
|
||||
- Fixed spec array properties (scripts, sources, dependencies, test suites, etc.) duplication [#599](https://github.com/yonaskolb/XcodeGen/pull/599) @haritowa
|
||||
|
||||
## 2.6.0
|
||||
|
||||
#### Added
|
||||
|
@ -8,6 +8,8 @@ public struct SpecFile {
|
||||
public let jsonDictionary: JSONDictionary
|
||||
public let subSpecs: [SpecFile]
|
||||
|
||||
private let filename: String
|
||||
|
||||
fileprivate struct Include {
|
||||
let path: Path
|
||||
let relativePaths: Bool
|
||||
@ -42,11 +44,12 @@ public struct SpecFile {
|
||||
try self.init(filename: path.lastComponent, basePath: path.parent())
|
||||
}
|
||||
|
||||
public init(jsonDictionary: JSONDictionary, basePath: Path = "", relativePath: Path = "", subSpecs: [SpecFile] = []) {
|
||||
public init(filename: String, jsonDictionary: JSONDictionary, basePath: Path = "", relativePath: Path = "", subSpecs: [SpecFile] = []) {
|
||||
self.basePath = basePath
|
||||
self.relativePath = relativePath
|
||||
self.jsonDictionary = jsonDictionary
|
||||
self.subSpecs = subSpecs
|
||||
self.filename = filename
|
||||
}
|
||||
|
||||
fileprivate init(include: Include, basePath: Path, relativePath: Path) throws {
|
||||
@ -65,7 +68,7 @@ public struct SpecFile {
|
||||
try SpecFile(include: include, basePath: basePath, relativePath: relativePath)
|
||||
}
|
||||
|
||||
self.init(jsonDictionary: jsonDictionary, basePath: basePath, relativePath: relativePath, subSpecs: subSpecs)
|
||||
self.init(filename: filename, jsonDictionary: jsonDictionary, basePath: basePath, relativePath: relativePath, subSpecs: subSpecs)
|
||||
}
|
||||
|
||||
static func loadDictionary(path: Path) throws -> JSONDictionary {
|
||||
@ -83,17 +86,36 @@ public struct SpecFile {
|
||||
}
|
||||
|
||||
public func resolvedDictionary(variables: [String: String] = [:]) -> JSONDictionary {
|
||||
var resolvedSpec = resolvingPaths().mergedDictionary()
|
||||
let resolvedDictionary = resolvedDictionaryWithUniqueTargets()
|
||||
return substitute(variables: variables, in: resolvedDictionary)
|
||||
}
|
||||
|
||||
private func resolvedDictionaryWithUniqueTargets() -> JSONDictionary {
|
||||
let resolvedSpec = resolvingPaths()
|
||||
|
||||
var value = Set<String>()
|
||||
return resolvedSpec.mergedDictionary(set: &value)
|
||||
}
|
||||
|
||||
private func substitute(variables: [String: String], in mergedDictionary: JSONDictionary) -> JSONDictionary {
|
||||
var resolvedSpec = mergedDictionary
|
||||
|
||||
for (key, value) in variables {
|
||||
resolvedSpec = resolvedSpec.replaceString("${\(key)}", with: value)
|
||||
}
|
||||
|
||||
return resolvedSpec
|
||||
}
|
||||
|
||||
func mergedDictionary() -> JSONDictionary {
|
||||
|
||||
func mergedDictionary(set mergedTargets: inout Set<String>) -> JSONDictionary {
|
||||
let name = (basePath + relativePath + Path(filename)).description
|
||||
|
||||
guard !mergedTargets.contains(name) else { return [:] }
|
||||
mergedTargets.insert(name)
|
||||
|
||||
return jsonDictionary.merged(onto:
|
||||
subSpecs
|
||||
.map { $0.mergedDictionary() }
|
||||
.map { $0.mergedDictionary(set: &mergedTargets) }
|
||||
.reduce([:]) { $1.merged(onto: $0) })
|
||||
}
|
||||
|
||||
@ -105,6 +127,7 @@ public struct SpecFile {
|
||||
|
||||
let jsonDictionary = Project.pathProperties.resolvingPaths(in: self.jsonDictionary, relativeTo: relativePath)
|
||||
return SpecFile(
|
||||
filename: filename,
|
||||
jsonDictionary: jsonDictionary,
|
||||
relativePath: self.relativePath,
|
||||
subSpecs: subSpecs.map { $0.resolvingPaths(relativeTo: relativePath) }
|
||||
|
13
Tests/Fixtures/duplicated_include/duplicated_import_root.yml
Normal file
13
Tests/Fixtures/duplicated_include/duplicated_import_root.yml
Normal file
@ -0,0 +1,13 @@
|
||||
name: DuplicatedImportRoot
|
||||
fileGroups:
|
||||
- First
|
||||
- Second
|
||||
targetTemplates:
|
||||
IncludedTemplate:
|
||||
type: application
|
||||
platform: iOS
|
||||
sources:
|
||||
- template
|
||||
preBuildScripts:
|
||||
- script: swiftlint
|
||||
name: Swiftlint
|
@ -0,0 +1,9 @@
|
||||
include:
|
||||
- duplicated_import_transitive.yml
|
||||
- duplicated_import_root.yml
|
||||
- duplicated_import_root.yml
|
||||
name: DuplicatedImportDependent
|
||||
targets:
|
||||
IncludedTarget:
|
||||
templates:
|
||||
- IncludedTemplate
|
@ -0,0 +1,3 @@
|
||||
include:
|
||||
- duplicated_import_root.yml
|
||||
name: DuplicatedImportTransitive
|
@ -9,6 +9,21 @@ import Yams
|
||||
|
||||
class SpecLoadingTests: XCTestCase {
|
||||
|
||||
func testSpecLoaderDuplicateImports() {
|
||||
describe {
|
||||
$0.it("merges each file only once") {
|
||||
let path = fixturePath + "duplicated_include/duplicated_import_sut.yml"
|
||||
let project = try loadSpec(path: path)
|
||||
|
||||
try expect(project.fileGroups) == ["First", "Second"]
|
||||
|
||||
let sutTarget = project.targets.first
|
||||
try expect(sutTarget?.sources) == [TargetSource(path: "template")]
|
||||
try expect(sutTarget?.preBuildScripts) == [BuildScript(script: .script("swiftlint"), name: "Swiftlint")]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testSpecLoader() {
|
||||
describe {
|
||||
$0.it("merges includes") {
|
||||
|
Loading…
Reference in New Issue
Block a user