mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2026-03-18 20:02:25 +00:00
87 lines
2.9 KiB
Swift
87 lines
2.9 KiB
Swift
//
|
|
// SpecLoader.swift
|
|
// XcodeGen
|
|
//
|
|
// Created by Yonas Kolb on 30/8/17.
|
|
//
|
|
//
|
|
|
|
import Foundation
|
|
import ProjectSpec
|
|
import PathKit
|
|
import Yams
|
|
import JSONUtilities
|
|
|
|
public struct SpecLoader {
|
|
|
|
public static func loadSpec(path: Path) throws -> ProjectSpec {
|
|
let dictionary = try loadDictionary(path: path)
|
|
let filteredDictionary = SpecLoader.filterNull(dictionary) as! [String: Any]
|
|
return try ProjectSpec(jsonDictionary: filteredDictionary)
|
|
}
|
|
|
|
private static func loadDictionary(path: Path) throws -> JSONDictionary {
|
|
let string: String = try path.read()
|
|
let yaml = try Yams.load(yaml: string)
|
|
guard var json = yaml as? JSONDictionary else {
|
|
throw JSONUtilsError.fileNotAJSONDictionary
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
private static func filterNull(_ object: Any) -> Any {
|
|
var returnedValue: Any = object
|
|
if let dict = object as? [String: Any] {
|
|
var mutabledic: [String: Any] = [:]
|
|
for (key, value) in dict {
|
|
mutabledic[key] = SpecLoader.filterNull(value)
|
|
}
|
|
returnedValue = mutabledic
|
|
} else if let array = object as? [Any] {
|
|
var mutableArray: [Any] = array
|
|
for (index, value) in array.enumerated() {
|
|
mutableArray[index] = SpecLoader.filterNull(value)
|
|
}
|
|
returnedValue = mutableArray
|
|
}
|
|
return (object is NSNull) ? "" : returnedValue
|
|
}
|
|
}
|