mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2026-03-18 20:02:25 +00:00
Merge pull request #489 from ellneal/feature/current-directory-expander.yml
Spec file relative directory expansion
This commit is contained in:
@@ -7,6 +7,9 @@
|
||||
- Added support for the `instrumentsPackage` product type [#482](https://github.com/yonaskolb/XcodeGen/pull/482) @ksulliva
|
||||
- Added support for `inputFileLists` and `outputFileLists` within project build scripts [#500](https://github.com/yonaskolb/XcodeGen/pull/500) @lukewakeford
|
||||
|
||||
#### Changed
|
||||
- **BREAKING** All the paths within included files are now relative to that file and not the root spec. This can be disabled with a `relativePaths: false` on the include. See [docs](https://github.com/yonaskolb/XcodeGen/blob/master/Docs/ProjectSpec.md#include) for more details [#489](https://github.com/yonaskolb/XcodeGen/pull/489) @ellneal
|
||||
|
||||
#### Fixed
|
||||
- Fixed `--project` argument not taking effect [#487](https://github.com/yonaskolb/XcodeGen/pull/487) @monowerker
|
||||
- Fixed Sticker Packs from generating an empty Source file phase which caused in error in the new build system [#492](https://github.com/yonaskolb/XcodeGen/pull/492) @rpassis
|
||||
|
||||
+16
-1
@@ -45,7 +45,22 @@ Required properties are marked with checkbox. Some of the YAML examples don't sh
|
||||
|
||||
One or more specs can be included in the project spec. This can be used to split your project spec into multiple files, for easier structuring or sharing between multiple specs. Included specs can also include other specs and so on.
|
||||
|
||||
Include can either be a list of string paths or a single string path. They will be merged in order and then the current spec will be merged on top.
|
||||
Include can either be a list of includes or a single include. They will be merged in order and then the current spec will be merged on top.
|
||||
|
||||
An include can be provided via a string (the path) or an object of the form:
|
||||
|
||||
**Include Object**
|
||||
|
||||
- [x] **path**: **String** - The path to the included file.
|
||||
- [ ] **relativePaths**: **Bool** - Dictates whether the included spec specifies paths relative to itself (the default) or the root spec file.
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- includedFile.yml
|
||||
- path: path/to/includedFile.yml
|
||||
relativePaths: false
|
||||
```
|
||||
|
||||
By default specs are merged additively. That is for every value:
|
||||
|
||||
- if existing value and new value are both dictionaries merge them and continue down the hierachy
|
||||
|
||||
@@ -61,3 +61,15 @@ extension AggregateTarget: NamedJSONDictionaryConvertible {
|
||||
attributes = jsonDictionary.json(atKeyPath: "attributes") ?? [:]
|
||||
}
|
||||
}
|
||||
|
||||
extension AggregateTarget: PathContainer {
|
||||
|
||||
static var pathProperties: [PathProperty] {
|
||||
return [
|
||||
.dictionary([
|
||||
.string("configFiles"),
|
||||
.object("buildScripts", BuildScript.pathProperties),
|
||||
]),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,3 +61,12 @@ extension BuildScript: JSONObjectConvertible {
|
||||
showEnvVars = jsonDictionary.json(atKeyPath: "showEnvVars") ?? true
|
||||
}
|
||||
}
|
||||
|
||||
extension BuildScript: PathContainer {
|
||||
|
||||
static var pathProperties: [PathProperty] {
|
||||
return [
|
||||
.string("path"),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,3 +72,12 @@ extension Dependency: JSONObjectConvertible {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Dependency: PathContainer {
|
||||
|
||||
static var pathProperties: [PathProperty] {
|
||||
return [
|
||||
.string("framework"),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import Foundation
|
||||
import JSONUtilities
|
||||
import PathKit
|
||||
|
||||
protocol PathContainer {
|
||||
|
||||
static var pathProperties: [PathProperty] { get }
|
||||
}
|
||||
|
||||
enum PathProperty {
|
||||
case string(String)
|
||||
case dictionary([PathProperty])
|
||||
case object(String, [PathProperty])
|
||||
}
|
||||
|
||||
extension Array where Element == PathProperty {
|
||||
|
||||
func resolvingPaths(in jsonDictionary: JSONDictionary, relativeTo path: Path) -> JSONDictionary {
|
||||
var result = jsonDictionary
|
||||
|
||||
for pathProperty in self {
|
||||
switch pathProperty {
|
||||
case .string(let key):
|
||||
if let source = result[key] as? String {
|
||||
result[key] = (path + source).string
|
||||
} else if let source = result[key] as? [String] {
|
||||
result[key] = source.map { (path + $0).string }
|
||||
} else if let source = result[key] as? [String: String] {
|
||||
result[key] = source.mapValues { (path + $0).string }
|
||||
}
|
||||
case .dictionary(let pathProperties):
|
||||
for (key, dictionary) in result {
|
||||
if let source = dictionary as? JSONDictionary {
|
||||
result[key] = pathProperties.resolvingPaths(in: source, relativeTo: path)
|
||||
}
|
||||
}
|
||||
case .object(let key, let pathProperties):
|
||||
if let source = result[key] as? JSONDictionary {
|
||||
result[key] = pathProperties.resolvingPaths(in: source, relativeTo: path)
|
||||
} else if let source = result[key] as? [JSONDictionary] {
|
||||
result[key] = source.map { pathProperties.resolvingPaths(in: $0, relativeTo: path) }
|
||||
} else if let source = result[key] as? [String: JSONDictionary] {
|
||||
result[key] = source.mapValues { pathProperties.resolvingPaths(in: $0, relativeTo: path) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -24,3 +24,12 @@ extension Plist: JSONObjectConvertible {
|
||||
properties = jsonDictionary.json(atKeyPath: "properties") ?? [:]
|
||||
}
|
||||
}
|
||||
|
||||
extension Plist: PathContainer {
|
||||
|
||||
static var pathProperties: [PathProperty] {
|
||||
return [
|
||||
.string("path"),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,8 +133,16 @@ extension Project: Equatable {
|
||||
extension Project {
|
||||
|
||||
public init(basePath: Path, jsonDictionary: JSONDictionary) throws {
|
||||
let spec = Spec(relativePath: Path(), jsonDictionary: jsonDictionary)
|
||||
try self.init(spec: spec, basePath: basePath)
|
||||
}
|
||||
|
||||
public init(spec: Spec, basePath: Path) throws {
|
||||
self.basePath = basePath
|
||||
let jsonDictionary = try Project.resolveProject(jsonDictionary: jsonDictionary)
|
||||
|
||||
let spec = spec.resolvingPaths()
|
||||
let jsonDictionary = try Project.resolveProject(jsonDictionary: spec.resolvedDictionary())
|
||||
|
||||
name = try jsonDictionary.json(atKeyPath: "name")
|
||||
settings = jsonDictionary.json(atKeyPath: "settings") ?? .empty
|
||||
settingGroups = jsonDictionary.json(atKeyPath: "settingGroups")
|
||||
@@ -166,6 +174,18 @@ extension Project {
|
||||
}
|
||||
}
|
||||
|
||||
extension Project: PathContainer {
|
||||
|
||||
static var pathProperties: [PathProperty] {
|
||||
return [
|
||||
.string("configFiles"),
|
||||
.object("options", SpecOptions.pathProperties),
|
||||
.object("targets", Target.pathProperties),
|
||||
.object("aggregateTargets", AggregateTarget.pathProperties),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
extension Project {
|
||||
|
||||
public var allFiles: [Path] {
|
||||
|
||||
@@ -101,24 +101,6 @@ extension Dictionary where Key == String, Value: Any {
|
||||
}
|
||||
}
|
||||
|
||||
func merge(dictionary: JSONDictionary, onto base: JSONDictionary) -> JSONDictionary {
|
||||
var merged = base
|
||||
|
||||
for (key, value) in dictionary {
|
||||
if key.hasSuffix(":REPLACE") {
|
||||
let newKey = key.replacingOccurrences(of: ":REPLACE", with: "")
|
||||
merged[newKey] = value
|
||||
} else if let dictionary = value as? JSONDictionary, let base = merged[key] as? JSONDictionary {
|
||||
merged[key] = merge(dictionary: dictionary, onto: base)
|
||||
} else if let array = value as? [Any], let base = merged[key] as? [Any] {
|
||||
merged[key] = base + array
|
||||
} else {
|
||||
merged[key] = value
|
||||
}
|
||||
}
|
||||
return merged
|
||||
}
|
||||
|
||||
public func += (lhs: inout BuildSettings, rhs: BuildSettings?) {
|
||||
guard let rhs = rhs else { return }
|
||||
lhs.merge(rhs)
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
import Foundation
|
||||
import JSONUtilities
|
||||
import PathKit
|
||||
|
||||
public struct Spec {
|
||||
public let relativePath: Path
|
||||
public let jsonDictionary: JSONDictionary
|
||||
public let subSpecs: [Spec]
|
||||
|
||||
public init(relativePath: Path, jsonDictionary: JSONDictionary, subSpecs: [Spec] = []) {
|
||||
self.relativePath = relativePath
|
||||
self.jsonDictionary = jsonDictionary
|
||||
self.subSpecs = subSpecs
|
||||
}
|
||||
|
||||
public init(filename: String, basePath: Path, relativePath: Path = Path()) throws {
|
||||
let path = basePath + relativePath + filename
|
||||
|
||||
// Depending on the extension we will either load the file as YAML or JSON
|
||||
var json: [String: Any]
|
||||
if path.extension?.lowercased() == "json" {
|
||||
let data: Data = try path.read()
|
||||
let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
|
||||
guard let jsonDictionary = jsonData as? [String: Any] else {
|
||||
fatalError("Invalid JSON at path \(path)")
|
||||
}
|
||||
json = jsonDictionary
|
||||
} else {
|
||||
json = try loadYamlDictionary(path: path)
|
||||
}
|
||||
|
||||
let processIncludeOption = { (option: Any) -> (String, Bool)? in
|
||||
if let option = option as? String {
|
||||
return (option, true)
|
||||
} else if let option = option as? JSONDictionary, let path = option["path"] as? String {
|
||||
return (path, (option["relativePaths"] as? Bool) ?? true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
let includeSources: [(String, Bool)]
|
||||
if let sources = json["include"] as? [Any] {
|
||||
includeSources = sources.compactMap { processIncludeOption($0) }
|
||||
} else if let source = json["include"] {
|
||||
includeSources = [processIncludeOption(source)].compactMap { $0 }
|
||||
} else {
|
||||
includeSources = []
|
||||
}
|
||||
|
||||
let includes = try includeSources.map { include -> Spec in
|
||||
let path = Path(include.0)
|
||||
let basePath = include.1 ? basePath + relativePath : basePath + relativePath + path.parent()
|
||||
let relativePath = include.1 ? path.parent() : Path()
|
||||
|
||||
return try Spec(filename: path.lastComponent, basePath: basePath, relativePath: relativePath)
|
||||
}
|
||||
|
||||
self.relativePath = relativePath
|
||||
self.jsonDictionary = json
|
||||
self.subSpecs = includes
|
||||
}
|
||||
|
||||
public func resolvedDictionary() -> JSONDictionary {
|
||||
return jsonDictionary.merged(onto:
|
||||
subSpecs
|
||||
.map { $0.resolvedDictionary() }
|
||||
.reduce([:]) { $1.merged(onto: $0) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension Spec {
|
||||
|
||||
func resolvingPaths(relativeTo basePath: Path = Path()) -> Spec {
|
||||
let relativePath = (basePath + self.relativePath).normalize()
|
||||
guard relativePath != Path() else {
|
||||
return self
|
||||
}
|
||||
|
||||
let jsonDictionary = Project.pathProperties.resolvingPaths(in: self.jsonDictionary, relativeTo: relativePath)
|
||||
|
||||
return Spec(
|
||||
relativePath: self.relativePath,
|
||||
jsonDictionary: jsonDictionary,
|
||||
subSpecs: self.subSpecs.map { template in
|
||||
return template.resolvingPaths(relativeTo: relativePath)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension Dictionary where Key == String, Value: Any {
|
||||
|
||||
func merged(onto other: Dictionary<Key, Value>) -> Dictionary<Key, Value> {
|
||||
var merged = other
|
||||
|
||||
for (key, value) in self {
|
||||
if key.hasSuffix(":REPLACE") {
|
||||
let newKey = key[key.startIndex ..< key.index(key.endIndex, offsetBy: -8)]
|
||||
merged[Key(newKey)] = value
|
||||
} else if let dictionary = value as? Dictionary<Key, Value>, let base = merged[key] as? Dictionary<Key, Value> {
|
||||
merged[key] = dictionary.merged(onto: base) as? Value
|
||||
} else if let array = value as? [Any], let base = merged[key] as? [Any] {
|
||||
merged[key] = (base + array) as? Value
|
||||
} else {
|
||||
merged[key] = value
|
||||
}
|
||||
}
|
||||
return merged
|
||||
}
|
||||
}
|
||||
@@ -1,48 +1,16 @@
|
||||
import Foundation
|
||||
import JSONUtilities
|
||||
import PathKit
|
||||
import Yams
|
||||
|
||||
extension Project {
|
||||
|
||||
public init(path: Path) throws {
|
||||
let dictionary = try Project.loadDictionary(path: path)
|
||||
try self.init(basePath: path.parent(), jsonDictionary: dictionary)
|
||||
let basePath = path.parent()
|
||||
let template = try Spec(filename: path.lastComponent, basePath: basePath)
|
||||
try self.init(spec: template, basePath: basePath)
|
||||
}
|
||||
|
||||
public static func loadDictionary(path: Path) throws -> JSONDictionary {
|
||||
|
||||
// Depending on the extension we will either load the file as YAML or JSON
|
||||
var json: [String: Any]
|
||||
if path.extension?.lowercased() == "json" {
|
||||
let data: Data = try path.read()
|
||||
let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
|
||||
guard let jsonDictionary = jsonData as? [String: Any] else {
|
||||
fatalError("Invalid JSON at path \(path)")
|
||||
}
|
||||
json = jsonDictionary
|
||||
} else {
|
||||
json = try loadYamlDictionary(path: path)
|
||||
}
|
||||
|
||||
var includes: [String]
|
||||
if let includeString = json["include"] as? String {
|
||||
includes = [includeString]
|
||||
} else if let includeArray = json["include"] as? [String] {
|
||||
includes = includeArray
|
||||
} else {
|
||||
includes = []
|
||||
}
|
||||
|
||||
if !includes.isEmpty {
|
||||
var includeDictionary: JSONDictionary = [:]
|
||||
for include in includes {
|
||||
let includePath = path.parent() + include
|
||||
let dictionary = try loadDictionary(path: includePath)
|
||||
includeDictionary = merge(dictionary: dictionary, onto: includeDictionary)
|
||||
}
|
||||
json = merge(dictionary: json, onto: includeDictionary)
|
||||
}
|
||||
return json
|
||||
return try Spec(filename: path.lastComponent, basePath: path.parent()).jsonDictionary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,3 +120,14 @@ extension SpecOptions: JSONObjectConvertible {
|
||||
generateEmptyDirectories = jsonDictionary.json(atKeyPath: "generateEmptyDirectories") ?? false
|
||||
}
|
||||
}
|
||||
|
||||
extension SpecOptions: PathContainer {
|
||||
|
||||
static var pathProperties: [PathProperty] {
|
||||
return [
|
||||
.string("carthageBuildPath"),
|
||||
.string("carthageExecutablePath"),
|
||||
.string("defaultConfig"),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +110,26 @@ extension Target: CustomStringConvertible {
|
||||
}
|
||||
}
|
||||
|
||||
extension Target: PathContainer {
|
||||
|
||||
static var pathProperties: [PathProperty] {
|
||||
return [
|
||||
.dictionary([
|
||||
.string("sources"),
|
||||
.object("sources", TargetSource.pathProperties),
|
||||
.string("configFiles"),
|
||||
.object("dependencies", Dependency.pathProperties),
|
||||
.object("info", Plist.pathProperties),
|
||||
.object("entitlements", Plist.pathProperties),
|
||||
.object("preBuildScripts", BuildScript.pathProperties),
|
||||
.object("prebuildScripts", BuildScript.pathProperties),
|
||||
.object("postCompileScripts", BuildScript.pathProperties),
|
||||
.object("postBuildScripts", BuildScript.pathProperties),
|
||||
]),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
extension Target {
|
||||
|
||||
static func resolveTargetTemplates(jsonDictionary: JSONDictionary) throws -> JSONDictionary {
|
||||
@@ -125,10 +145,10 @@ extension Target {
|
||||
var mergedDictionary: JSONDictionary = [:]
|
||||
for template in templates {
|
||||
if let templateDictionary = targetTemplatesDictionary[template] {
|
||||
mergedDictionary = merge(dictionary: templateDictionary, onto: mergedDictionary)
|
||||
mergedDictionary = templateDictionary.merged(onto: mergedDictionary)
|
||||
}
|
||||
}
|
||||
target = merge(dictionary: target, onto: mergedDictionary)
|
||||
target = target.merged(onto: mergedDictionary)
|
||||
}
|
||||
targetsDictionary[targetName] = target
|
||||
}
|
||||
|
||||
@@ -207,3 +207,13 @@ extension TargetSource.BuildPhase.CopyFilesSettings: JSONObjectConvertible {
|
||||
phaseOrder = .postCompile
|
||||
}
|
||||
}
|
||||
|
||||
extension TargetSource: PathContainer {
|
||||
|
||||
static var pathProperties: [PathProperty] {
|
||||
return [
|
||||
.string("path"),
|
||||
.string("excludes"),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@ public class SpecLoader {
|
||||
}
|
||||
|
||||
public func loadProject(path: Path) throws -> Project {
|
||||
let dictionary = try Project.loadDictionary(path: path)
|
||||
let project = try Project(basePath: path.parent(), jsonDictionary: dictionary)
|
||||
let template = try Spec(filename: path.lastComponent, basePath: path.parent())
|
||||
let project = try Project(spec: template, basePath: path.parent())
|
||||
|
||||
self.project = project
|
||||
projectDictionary = dictionary
|
||||
projectDictionary = template.jsonDictionary
|
||||
|
||||
return project
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
include:
|
||||
path: legacy_paths_test/legacy_included_paths_test.yml
|
||||
relativePaths: false
|
||||
name: NewName
|
||||
@@ -0,0 +1,33 @@
|
||||
configFiles:
|
||||
IncludedConfig: config
|
||||
options:
|
||||
carthageBuildPath: carthage_build
|
||||
carthageExecutablePath: carthage_executable
|
||||
targets:
|
||||
IncludedTarget:
|
||||
type: application
|
||||
platform: tvOS
|
||||
configFiles:
|
||||
Config: config
|
||||
sources:
|
||||
- source
|
||||
dependencies:
|
||||
- framework: Framework
|
||||
info:
|
||||
path: info
|
||||
entitlements:
|
||||
path: entitlements
|
||||
preBuildScripts:
|
||||
- path: preBuildScript
|
||||
postCompileScripts:
|
||||
- path: postCompileScript
|
||||
postBuildScripts:
|
||||
- path: postBuildScript
|
||||
aggregateTargets:
|
||||
IncludedAggregateTarget:
|
||||
targets:
|
||||
- IncludedTarget
|
||||
configFiles:
|
||||
Config: config
|
||||
buildScripts:
|
||||
- path: buildScript
|
||||
@@ -0,0 +1,32 @@
|
||||
include: paths_test/included_paths_test.yml
|
||||
name: NewName
|
||||
configFiles:
|
||||
NewConfig: config
|
||||
targets:
|
||||
NewTarget:
|
||||
type: application
|
||||
platform: iOS
|
||||
configFiles:
|
||||
Config: config
|
||||
sources:
|
||||
- source
|
||||
dependencies:
|
||||
- framework: Framework
|
||||
info:
|
||||
path: info
|
||||
entitlements:
|
||||
path: entitlements
|
||||
preBuildScripts:
|
||||
- path: preBuildScript
|
||||
postCompileScripts:
|
||||
- path: postCompileScript
|
||||
postBuildScripts:
|
||||
- path: postBuildScript
|
||||
aggregateTargets:
|
||||
NewAggregateTarget:
|
||||
targets:
|
||||
- NewTarget
|
||||
configFiles:
|
||||
Config: config
|
||||
buildScripts:
|
||||
- path: buildScript
|
||||
@@ -0,0 +1,31 @@
|
||||
include: recursive_test/recursive_test.yml
|
||||
configFiles:
|
||||
IncludedConfig: config
|
||||
targets:
|
||||
IncludedTarget:
|
||||
type: application
|
||||
platform: tvOS
|
||||
configFiles:
|
||||
Config: config
|
||||
sources:
|
||||
- source
|
||||
dependencies:
|
||||
- framework: Framework
|
||||
info:
|
||||
path: info
|
||||
entitlements:
|
||||
path: entitlements
|
||||
preBuildScripts:
|
||||
- path: preBuildScript
|
||||
postCompileScripts:
|
||||
- path: postCompileScript
|
||||
postBuildScripts:
|
||||
- path: postBuildScript
|
||||
aggregateTargets:
|
||||
IncludedAggregateTarget:
|
||||
targets:
|
||||
- IncludedTarget
|
||||
configFiles:
|
||||
Config: config
|
||||
buildScripts:
|
||||
- path: buildScript
|
||||
@@ -0,0 +1,33 @@
|
||||
options:
|
||||
carthageBuildPath: carthage_build
|
||||
carthageExecutablePath: carthage_executable
|
||||
configFiles:
|
||||
RecursiveConfig: config
|
||||
targets:
|
||||
RecursiveTarget:
|
||||
type: application
|
||||
platform: macOS
|
||||
configFiles:
|
||||
Config: config
|
||||
sources:
|
||||
- source
|
||||
dependencies:
|
||||
- framework: Framework
|
||||
info:
|
||||
path: info
|
||||
entitlements:
|
||||
path: entitlements
|
||||
prebuildScripts:
|
||||
- path: prebuildScript
|
||||
postCompileScripts:
|
||||
- path: postCompileScript
|
||||
postBuildScripts:
|
||||
- path: postBuildScript
|
||||
aggregateTargets:
|
||||
RecursiveAggregateTarget:
|
||||
targets:
|
||||
- RecursiveTarget
|
||||
configFiles:
|
||||
Config: config
|
||||
buildScripts:
|
||||
- path: buildScript
|
||||
@@ -26,6 +26,124 @@ class SpecLoadingTests: XCTestCase {
|
||||
]
|
||||
}
|
||||
|
||||
$0.it("expands directories") {
|
||||
let path = fixturePath + "paths_test.yml"
|
||||
let project = try Project(path: path)
|
||||
|
||||
try expect(project.configFiles) == [
|
||||
"IncludedConfig": "paths_test/config",
|
||||
"NewConfig": "config",
|
||||
"RecursiveConfig": "paths_test/recursive_test/config",
|
||||
]
|
||||
|
||||
try expect(project.options) == SpecOptions(
|
||||
carthageBuildPath: "paths_test/recursive_test/carthage_build",
|
||||
carthageExecutablePath: "paths_test/recursive_test/carthage_executable"
|
||||
)
|
||||
|
||||
try expect(project.aggregateTargets) == [
|
||||
AggregateTarget(
|
||||
name: "IncludedAggregateTarget",
|
||||
targets: ["IncludedTarget"],
|
||||
configFiles: ["Config": "paths_test/config"],
|
||||
buildScripts: [BuildScript(script: .path("paths_test/buildScript"))]
|
||||
),
|
||||
AggregateTarget(
|
||||
name: "NewAggregateTarget",
|
||||
targets: ["NewTarget"],
|
||||
configFiles: ["Config": "config"],
|
||||
buildScripts: [BuildScript(script: .path("buildScript"))]
|
||||
),
|
||||
AggregateTarget(
|
||||
name: "RecursiveAggregateTarget",
|
||||
targets: ["RecursiveTarget"],
|
||||
configFiles: ["Config": "paths_test/recursive_test/config"],
|
||||
buildScripts: [BuildScript(script: .path("paths_test/recursive_test/buildScript"))]
|
||||
),
|
||||
]
|
||||
|
||||
try expect(project.targets) == [
|
||||
Target(
|
||||
name: "IncludedTarget",
|
||||
type: .application,
|
||||
platform: .tvOS,
|
||||
configFiles: ["Config": "paths_test/config"],
|
||||
sources: ["paths_test/source"],
|
||||
dependencies: [Dependency(type: .framework, reference: "paths_test/Framework")],
|
||||
info: Plist(path: "paths_test/info"),
|
||||
entitlements: Plist(path: "paths_test/entitlements"),
|
||||
preBuildScripts: [BuildScript(script: .path("paths_test/preBuildScript"))],
|
||||
postCompileScripts: [BuildScript(script: .path("paths_test/postCompileScript"))],
|
||||
postBuildScripts: [BuildScript(script: .path("paths_test/postBuildScript"))]
|
||||
),
|
||||
Target(
|
||||
name: "NewTarget",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
configFiles: ["Config": "config"],
|
||||
sources: ["source"],
|
||||
dependencies: [Dependency(type: .framework, reference: "Framework")],
|
||||
info: Plist(path: "info"),
|
||||
entitlements: Plist(path: "entitlements"),
|
||||
preBuildScripts: [BuildScript(script: .path("preBuildScript"))],
|
||||
postCompileScripts: [BuildScript(script: .path("postCompileScript"))],
|
||||
postBuildScripts: [BuildScript(script: .path("postBuildScript"))]
|
||||
),
|
||||
Target(
|
||||
name: "RecursiveTarget",
|
||||
type: .application,
|
||||
platform: .macOS,
|
||||
configFiles: ["Config": "paths_test/recursive_test/config"],
|
||||
sources: ["paths_test/recursive_test/source"],
|
||||
dependencies: [Dependency(type: .framework, reference: "paths_test/recursive_test/Framework")],
|
||||
info: Plist(path: "paths_test/recursive_test/info"),
|
||||
entitlements: Plist(path: "paths_test/recursive_test/entitlements"),
|
||||
preBuildScripts: [BuildScript(script: .path("paths_test/recursive_test/prebuildScript"))],
|
||||
postCompileScripts: [BuildScript(script: .path("paths_test/recursive_test/postCompileScript"))],
|
||||
postBuildScripts: [BuildScript(script: .path("paths_test/recursive_test/postBuildScript"))]
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
$0.it("respects directory expansion preference") {
|
||||
let path = fixturePath + "legacy_paths_test.yml"
|
||||
let project = try Project(path: path)
|
||||
|
||||
try expect(project.configFiles) == [
|
||||
"IncludedConfig": "config",
|
||||
]
|
||||
|
||||
try expect(project.options) == SpecOptions(
|
||||
carthageBuildPath: "carthage_build",
|
||||
carthageExecutablePath: "carthage_executable"
|
||||
)
|
||||
|
||||
try expect(project.aggregateTargets) == [
|
||||
AggregateTarget(
|
||||
name: "IncludedAggregateTarget",
|
||||
targets: ["IncludedTarget"],
|
||||
configFiles: ["Config": "config"],
|
||||
buildScripts: [BuildScript(script: .path("buildScript"))]
|
||||
),
|
||||
]
|
||||
|
||||
try expect(project.targets) == [
|
||||
Target(
|
||||
name: "IncludedTarget",
|
||||
type: .application,
|
||||
platform: .tvOS,
|
||||
configFiles: ["Config": "config"],
|
||||
sources: ["source"],
|
||||
dependencies: [Dependency(type: .framework, reference: "Framework")],
|
||||
info: Plist(path: "info"),
|
||||
entitlements: Plist(path: "entitlements"),
|
||||
preBuildScripts: [BuildScript(script: .path("preBuildScript"))],
|
||||
postCompileScripts: [BuildScript(script: .path("postCompileScript"))],
|
||||
postBuildScripts: [BuildScript(script: .path("postBuildScript"))]
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
$0.it("parses yaml types") {
|
||||
let path = fixturePath + "yaml.yml"
|
||||
let dictionary = try loadYamlDictionary(path: path)
|
||||
@@ -537,7 +655,8 @@ fileprivate func getProjectSpec(_ project: [String: Any], file: String = #file,
|
||||
projectDictionary[key] = value
|
||||
}
|
||||
do {
|
||||
return try Project(basePath: "", jsonDictionary: projectDictionary)
|
||||
let template = Spec(relativePath: "", jsonDictionary: projectDictionary)
|
||||
return try Project(spec: template, basePath: "")
|
||||
} catch {
|
||||
throw failure("\(error)", file: file, line: line)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user