Files
XcodeGen/Sources/XcodeGenKit/SpecLoader.swift
T
Palmero, Antonio 62f72d39bc Filter out NSNull elements from the json dictionary.
This change allows us to override default BuildSettings.
For example:

If I want to keep the attribute SWIFT_OBJC_INTERFACE_HEADER_NAME empty,
(by default it contains some value). I just need to override this value
in the settings spec.

Before If I keep property empty, then in the generated settings the value
appear as <null>.

The method implemented recursively loop through the json dictionary
looking for NSNull objects and replace them by an empty string.

Filter out NSNull elements from the json dictionary.

This change allows us to override default BuildSettings.
For example:

If I want to keep the attribute SWIFT_OBJC_INTERFACE_HEADER_NAME empty,
(by default it contains some value). I just need to override this value
in the settings spec.

Before If I keep property empty, then in the generated settings the value
appear as <null>.

The method implemented recursively loop through the json dictionary
looking for NSNull objects and replace them by an empty string.
2017-09-13 13:58:32 +02:00

76 lines
2.5 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
}
if let includes = json["include"] as? [String] {
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 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
}
}