forked from yonaskolb/XcodeGen
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSettings.swift
More file actions
141 lines (120 loc) · 4.89 KB
/
Settings.swift
File metadata and controls
141 lines (120 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import Foundation
import JSONUtilities
import PathKit
import XcodeProj
public struct Settings: Equatable, JSONObjectConvertible, CustomStringConvertible {
public var buildSettings: BuildSettings
public var configSettings: [String: Settings]
public var groups: [String]
public init(buildSettings: BuildSettings = [:], configSettings: [String: Settings] = [:], groups: [String] = []) {
self.buildSettings = buildSettings
self.configSettings = configSettings
self.groups = groups
}
public init(dictionary: [String: Any]) {
buildSettings = dictionary
configSettings = [:]
groups = []
}
public static let empty: Settings = Settings(dictionary: [:])
public init(jsonDictionary: JSONDictionary) throws {
if jsonDictionary["configs"] != nil || jsonDictionary["groups"] != nil || jsonDictionary["base"] != nil {
groups = jsonDictionary.json(atKeyPath: "groups") ?? jsonDictionary.json(atKeyPath: "presets") ?? []
let buildSettingsDictionary: JSONDictionary = jsonDictionary.json(atKeyPath: "base") ?? [:]
buildSettings = buildSettingsDictionary
self.configSettings = try Self.extractValidConfigs(from: jsonDictionary)
} else {
buildSettings = jsonDictionary
configSettings = [:]
groups = []
}
}
/// Extracts and validates the `configs` mapping from the given JSON dictionary.
/// - Parameter jsonDictionary: The JSON dictionary to extract `configs` from.
/// - Returns: A dictionary mapping configuration names to `Settings` objects.
private static func extractValidConfigs(from jsonDictionary: JSONDictionary) throws -> [String: Settings] {
guard let configSettings = jsonDictionary["configs"] as? JSONDictionary else {
return [:]
}
let invalidConfigKeys = Set(
configSettings.filter { !($0.value is JSONDictionary) }
.map(\.key)
)
guard invalidConfigKeys.isEmpty else {
throw SpecParsingError.invalidConfigsMappingFormat(keys: invalidConfigKeys)
}
return try jsonDictionary.json(atKeyPath: "configs")
}
public static func == (lhs: Settings, rhs: Settings) -> Bool {
NSDictionary(dictionary: lhs.buildSettings).isEqual(to: rhs.buildSettings) &&
lhs.configSettings == rhs.configSettings &&
lhs.groups == rhs.groups
}
public var description: String {
var string: String = ""
if !buildSettings.isEmpty {
let buildSettingDescription = buildSettings.map { "\($0) = \($1)" }.joined(separator: "\n")
if !configSettings.isEmpty || !groups.isEmpty {
string += "base:\n " + buildSettingDescription.replacingOccurrences(of: "(.)\n", with: "$1\n ", options: .regularExpression, range: nil)
} else {
string += buildSettingDescription
}
}
if !configSettings.isEmpty {
if !string.isEmpty {
string += "\n"
}
for (config, buildSettings) in configSettings {
if !buildSettings.description.isEmpty {
string += "configs:\n"
string += " \(config):\n " + buildSettings.description.replacingOccurrences(of: "(.)\n", with: "$1\n ", options: .regularExpression, range: nil)
}
}
}
if !groups.isEmpty {
if !string.isEmpty {
string += "\n"
}
string += "groups:\n \(groups.joined(separator: "\n "))"
}
return string
}
}
extension Settings: ExpressibleByDictionaryLiteral {
public init(dictionaryLiteral elements: (String, Any)...) {
var dictionary: [String: Any] = [:]
elements.forEach { dictionary[$0.0] = $0.1 }
self.init(dictionary: dictionary)
}
}
extension Dictionary where Key == String, Value: Any {
public func merged(_ dictionary: [Key: Value]) -> [Key: Value] {
var mergedDictionary = self
mergedDictionary.merge(dictionary)
return mergedDictionary
}
public mutating func merge(_ dictionary: [Key: Value]) {
for (key, value) in dictionary {
self[key] = value
}
}
public func equals(_ dictionary: BuildSettings) -> Bool {
NSDictionary(dictionary: self).isEqual(to: dictionary)
}
}
public func += (lhs: inout BuildSettings, rhs: BuildSettings?) {
guard let rhs = rhs else { return }
lhs.merge(rhs)
}
extension Settings: JSONEncodable {
public func toJSONValue() -> Any {
if groups.count > 0 || configSettings.count > 0 {
return [
"base": buildSettings,
"groups": groups,
"configs": configSettings.mapValues { $0.toJSONValue() },
] as [String : Any]
}
return buildSettings
}
}