Files
XcodeGen/Sources/ProjectSpec/SpecLoader.swift
T
Yonas Kolb e8188ad9f8 swiftformat
2017-11-13 21:33:59 +01:00

75 lines
2.5 KiB
Swift

//
// SpecLoader.swift
// XcodeGen
//
// Created by Yonas Kolb on 30/8/17.
//
//
import Foundation
import PathKit
import Yams
import JSONUtilities
extension ProjectSpec {
public init(path: Path) throws {
let dictionary = try ProjectSpec.loadDictionary(path: path)
try self.init(basePath: path.parent(), jsonDictionary: dictionary)
}
private 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
}
private static 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
}
}