From 6ee42d5c68051c4e629db86ed5406c04afd377b1 Mon Sep 17 00:00:00 2001 From: ryohey Date: Tue, 26 Mar 2019 18:26:45 +0900 Subject: [PATCH 1/8] Add encoding protocol --- Sources/ProjectSpec/Encoding.swift | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Sources/ProjectSpec/Encoding.swift diff --git a/Sources/ProjectSpec/Encoding.swift b/Sources/ProjectSpec/Encoding.swift new file mode 100644 index 000000000..ee024177c --- /dev/null +++ b/Sources/ProjectSpec/Encoding.swift @@ -0,0 +1,19 @@ +import Foundation +import JSONUtilities + +public protocol JSONDictionaryEncodable { + func toJSONDictionary() -> JSONDictionary +} + +public protocol JSONArrayEncodable { + func toJSONArray() -> JSONArray +} + +public protocol JSONPrimitiveEncodable { + func toJSONValue() -> JSONRawType +} + +public protocol JSONDynamicEncodable { + // returns JSONDictionary or JSONArray or JSONRawType + func toJSONValue() -> Any +} From 010b1c38044899ac8aff8e885f76451683555eed Mon Sep 17 00:00:00 2001 From: ryohey Date: Tue, 26 Mar 2019 18:27:19 +0900 Subject: [PATCH 2/8] Implement encoding to JSON --- Sources/ProjectSpec/AggregateTarget.swift | 29 +++ Sources/ProjectSpec/BuildRule.swift | 29 +++ Sources/ProjectSpec/BuildScript.swift | 39 ++++ Sources/ProjectSpec/Dependency.swift | 41 ++++ Sources/ProjectSpec/DeploymentTarget.swift | 21 ++ Sources/ProjectSpec/Plist.swift | 9 + Sources/ProjectSpec/Project.swift | 53 +++++ Sources/ProjectSpec/Scheme.swift | 220 +++++++++++++++++++++ Sources/ProjectSpec/Settings.swift | 21 ++ Sources/ProjectSpec/SpecOptions.swift | 58 ++++++ Sources/ProjectSpec/Target.swift | 87 ++++++++ Sources/ProjectSpec/TargetScheme.swift | 29 +++ Sources/ProjectSpec/TargetSource.swift | 63 ++++++ 13 files changed, 699 insertions(+) diff --git a/Sources/ProjectSpec/AggregateTarget.swift b/Sources/ProjectSpec/AggregateTarget.swift index e25fb5532..e8159640c 100644 --- a/Sources/ProjectSpec/AggregateTarget.swift +++ b/Sources/ProjectSpec/AggregateTarget.swift @@ -62,6 +62,35 @@ extension AggregateTarget: NamedJSONDictionaryConvertible { } } +extension AggregateTarget: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [:] + + let settingsDict = settings.toJSONDictionary() + if settingsDict.count > 0 { + dict["settings"] = settingsDict + } + + if targets.count > 0 { + dict["targets"] = targets + } + if configFiles.count > 0 { + dict["configFiles"] = configFiles + } + if attributes.count > 0 { + dict["attributes"] = attributes + } + if buildScripts.count > 0 { + dict["buildScripts"] = buildScripts.map { $0.toJSONDictionary() } + } + if let scheme = scheme { + dict["scheme"] = scheme.toJSONDictionary() + } + + return dict + } +} + extension AggregateTarget: PathContainer { static var pathProperties: [PathProperty] { diff --git a/Sources/ProjectSpec/BuildRule.swift b/Sources/ProjectSpec/BuildRule.swift index 442dda248..a4e4ae36f 100644 --- a/Sources/ProjectSpec/BuildRule.swift +++ b/Sources/ProjectSpec/BuildRule.swift @@ -80,3 +80,32 @@ extension BuildRule: JSONObjectConvertible { name = jsonDictionary.json(atKeyPath: "name") } } + +extension BuildRule: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: [String: Any] = [ + "outputFiles": outputFiles, + "outputFilesCompilerFlags": outputFilesCompilerFlags, + ] + + if let name = name { + dict["name"] = name + } + + switch fileType { + case .pattern(let string): + dict["filePattern"] = string + case .type(let string): + dict["fileType"] = string + } + + switch action { + case .compilerSpec(let string): + dict["compilerSpec"] = string + case .script(let string): + dict["script"] = string + } + + return dict + } +} diff --git a/Sources/ProjectSpec/BuildScript.swift b/Sources/ProjectSpec/BuildScript.swift index 242a28133..2ed007787 100644 --- a/Sources/ProjectSpec/BuildScript.swift +++ b/Sources/ProjectSpec/BuildScript.swift @@ -61,6 +61,45 @@ extension BuildScript: JSONObjectConvertible { showEnvVars = jsonDictionary.json(atKeyPath: "showEnvVars") ?? true } } +extension BuildScript: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [:] + + if runOnlyWhenInstalling { + dict["runOnlyWhenInstalling"] = runOnlyWhenInstalling + } + if !showEnvVars { + dict["showEnvVars"] = showEnvVars + } + if inputFiles.count > 0 { + dict["inputFiles"] = inputFiles + } + if inputFileLists.count > 0 { + dict["inputFileLists"] = inputFileLists + } + if outputFiles.count > 0 { + dict["outputFiles"] = outputFiles + } + if outputFileLists.count > 0 { + dict["outputFileLists"] = outputFileLists + } + if let name = name { + dict["name"] = name + } + if let shell = shell { + dict["shell"] = shell + } + + switch script { + case .path(let string): + dict["path"] = string + case .script(let string): + dict["script"] = string + } + + return dict + } +} extension BuildScript: PathContainer { diff --git a/Sources/ProjectSpec/Dependency.swift b/Sources/ProjectSpec/Dependency.swift index d9495e441..8aea2f068 100644 --- a/Sources/ProjectSpec/Dependency.swift +++ b/Sources/ProjectSpec/Dependency.swift @@ -81,6 +81,47 @@ extension Dependency: JSONObjectConvertible { } } +extension Dependency: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [:] + + if !removeHeaders { + dict["removeHeaders"] = removeHeaders + } + if implicit { + dict["implicit"] = implicit + } + if weakLink { + dict["weak"] = weakLink + } + if let embed = embed { + dict["embed"] = embed + } + if let codeSign = codeSign { + dict["codeSign"] = codeSign + } + if let link = link { + dict["link"] = link + } + + switch type { + case .target: + dict["target"] = reference + case .framework: + dict["framework"] = reference + case .carthage(let findFrameworks): + dict["carthage"] = reference + if let findFrameworks = findFrameworks { + dict["findFrameworks"] = findFrameworks + } + case .sdk: + dict["sdk"] = reference + } + + return dict + } +} + extension Dependency: PathContainer { static var pathProperties: [PathProperty] { diff --git a/Sources/ProjectSpec/DeploymentTarget.swift b/Sources/ProjectSpec/DeploymentTarget.swift index cf797b020..2feff0957 100644 --- a/Sources/ProjectSpec/DeploymentTarget.swift +++ b/Sources/ProjectSpec/DeploymentTarget.swift @@ -78,3 +78,24 @@ extension DeploymentTarget: JSONObjectConvertible { macOS = try parseVersion("macOS") } } + +extension DeploymentTarget: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [:] + + if let iOS = iOS { + dict["iOS"] = iOS.string + } + if let tvOS = tvOS { + dict["tvOS"] = tvOS.string + } + if let watchOS = watchOS { + dict["watchOS"] = watchOS.string + } + if let macOS = macOS { + dict["macOS"] = macOS.string + } + + return dict + } +} diff --git a/Sources/ProjectSpec/Plist.swift b/Sources/ProjectSpec/Plist.swift index 1f295106e..9140b0801 100644 --- a/Sources/ProjectSpec/Plist.swift +++ b/Sources/ProjectSpec/Plist.swift @@ -25,6 +25,15 @@ extension Plist: JSONObjectConvertible { } } +extension Plist: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + return [ + "path": path, + "properties": properties + ] + } +} + extension Plist: PathContainer { static var pathProperties: [PathProperty] { diff --git a/Sources/ProjectSpec/Project.swift b/Sources/ProjectSpec/Project.swift index 7eb90873b..63660edca 100644 --- a/Sources/ProjectSpec/Project.swift +++ b/Sources/ProjectSpec/Project.swift @@ -230,3 +230,56 @@ extension BuildSettingsContainer { return configFiles.values.map { Path($0) } } } + +extension Project: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [ + "name": name, + "options": options.toJSONDictionary(), + ] + + let settingsDict = settings.toJSONDictionary() + if settingsDict.count > 0 { + dict["settings"] = settingsDict + } + + if fileGroups.count > 0 { + dict["fileGroups"] = fileGroups + } + if configFiles.count > 0 { + dict["configFiles"] = configFiles + } + if include.count > 0 { + dict["include"] = include + } + if attributes.count > 0 { + dict["attributes"] = attributes + } + + let targetPairs = targets.map { ($0.name, $0.toJSONDictionary()) } + if targetPairs.count > 0 { + dict["targets"] = Dictionary(uniqueKeysWithValues: targetPairs) + } + + let configsPairs = configs.map { ($0.name, $0.type?.rawValue) } + if configsPairs.count > 0 { + dict["configs"] = Dictionary(uniqueKeysWithValues: configsPairs) + } + + let aggregateTargetsPairs = aggregateTargets.map { ($0.name, $0.toJSONDictionary()) } + if aggregateTargetsPairs.count > 0 { + dict["aggregateTargets"] = Dictionary(uniqueKeysWithValues: aggregateTargetsPairs) + } + + let schemesPairs = schemes.map { ($0.name, $0.toJSONDictionary()) } + if schemesPairs.count > 0 { + dict["schemes"] = Dictionary(uniqueKeysWithValues: schemesPairs) + } + + if settingGroups.count > 0 { + dict["settingGroups"] = settingGroups.mapValues { $0.toJSONDictionary() } + } + + return dict + } +} diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 6865c2844..86a6acd08 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -218,6 +218,21 @@ extension Scheme.ExecutionAction: JSONObjectConvertible { } } +extension Scheme.ExecutionAction: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict = [ + "script": script, + "name": name, + ] + + if let settingsTarget = settingsTarget { + dict["settingsTarget"] = settingsTarget + } + + return dict + } +} + extension Scheme.Run: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { @@ -229,6 +244,29 @@ extension Scheme.Run: JSONObjectConvertible { } } +extension Scheme.Run: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [ + "commandLineArguments": commandLineArguments, + ] + + if preActions.count > 0 { + dict["preActions"] = preActions.map { $0.toJSONDictionary() } + } + if postActions.count > 0 { + dict["postActions"] = postActions.map { $0.toJSONDictionary() } + } + if environmentVariables.count > 0 { + dict["environmentVariables"] = environmentVariables.map { $0.toJSONDictionary() } + } + if let config = config { + dict["config"] = config + } + + return dict + } +} + extension Scheme.Test: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { @@ -254,6 +292,35 @@ extension Scheme.Test: JSONObjectConvertible { } } +extension Scheme.Test: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [ + "gatherCoverageData": gatherCoverageData, + ] + + if commandLineArguments.count > 0 { + dict["commandLineArguments"] = commandLineArguments + } + if targets.count > 0 { + dict["targets"] = targets.map { $0.toJSONValue() } + } + if preActions.count > 0 { + dict["preActions"] = preActions.map { $0.toJSONDictionary() } + } + if postActions.count > 0 { + dict["postActions"] = postActions.map { $0.toJSONDictionary() } + } + if environmentVariables.count > 0 { + dict["environmentVariables"] = environmentVariables.map { $0.toJSONDictionary() } + } + if let config = config { + dict["config"] = config + } + + return dict + } +} + extension Scheme.Test.TestTarget: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { @@ -263,6 +330,27 @@ extension Scheme.Test.TestTarget: JSONObjectConvertible { } } +extension Scheme.Test.TestTarget: JSONDynamicEncodable { + public func toJSONValue() -> Any { + if !randomExecutionOrder && !parallelizable { + return name + } + + var dict: JSONDictionary = [ + "name": name + ] + + if randomExecutionOrder { + dict["randomExecutionOrder"] = true + } + if parallelizable { + dict["parallelizable"] = true + } + + return dict + } +} + extension Scheme.Profile: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { @@ -274,6 +362,29 @@ extension Scheme.Profile: JSONObjectConvertible { } } +extension Scheme.Profile: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [ + "commandLineArguments": commandLineArguments, + ] + + if preActions.count > 0 { + dict["preActions"] = preActions.map { $0.toJSONDictionary() } + } + if postActions.count > 0 { + dict["postActions"] = postActions.map { $0.toJSONDictionary() } + } + if environmentVariables.count > 0 { + dict["environmentVariables"] = environmentVariables.map { $0.toJSONDictionary() } + } + if let config = config { + dict["config"] = config + } + + return dict + } +} + extension Scheme.Analyze: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { @@ -281,6 +392,18 @@ extension Scheme.Analyze: JSONObjectConvertible { } } +extension Scheme.Analyze: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [:] + + if let config = config { + dict["config"] = config + } + + return dict + } +} + extension Scheme.Archive: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { @@ -292,6 +415,30 @@ extension Scheme.Archive: JSONObjectConvertible { } } +extension Scheme.Archive: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [:] + + if !revealArchiveInOrganizer { + dict["revealArchiveInOrganizer"] = revealArchiveInOrganizer + } + if preActions.count > 0 { + dict["preActions"] = preActions.map { $0.toJSONDictionary() } + } + if postActions.count > 0 { + dict["postActions"] = postActions.map { $0.toJSONDictionary() } + } + if let config = config { + dict["config"] = config + } + if let customArchiveName = customArchiveName { + dict["customArchiveName"] = customArchiveName + } + + return dict + } +} + extension Scheme: NamedJSONDictionaryConvertible { public init(name: String, jsonDictionary: JSONDictionary) throws { @@ -305,6 +452,32 @@ extension Scheme: NamedJSONDictionaryConvertible { } } +extension Scheme: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict = [ + "build": build.toJSONDictionary() + ] + + if let run = run { + dict["run"] = run.toJSONDictionary() + } + if let test = test { + dict["test"] = test.toJSONDictionary() + } + if let analyze = analyze { + dict["analyze"] = analyze.toJSONDictionary() + } + if let profile = profile { + dict["profile"] = profile.toJSONDictionary() + } + if let archive = archive { + dict["archive"] = archive.toJSONDictionary() + } + + return dict + } +} + extension Scheme.Build: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { @@ -337,6 +510,31 @@ extension Scheme.Build: JSONObjectConvertible { } } +extension Scheme.Build: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + let targetPairs = targets.map { ($0.target, $0.buildTypes.map { $0.toJSONValue() }) } + + var dict: JSONDictionary = [ + "targets": Dictionary(uniqueKeysWithValues: targetPairs), + ] + + if !parallelizeBuild { + dict["parallelizeBuild"] = parallelizeBuild + } + if !buildImplicitDependencies { + dict["buildImplicitDependencies"] = buildImplicitDependencies + } + if preActions.count > 0 { + dict["preActions"] = preActions.map { $0.toJSONDictionary() } + } + if postActions.count > 0 { + dict["postActions"] = postActions.map { $0.toJSONDictionary() } + } + + return dict + } +} + extension BuildType: JSONPrimitiveConvertible { public typealias JSONType = String @@ -357,6 +555,18 @@ extension BuildType: JSONPrimitiveConvertible { } } +extension BuildType: JSONPrimitiveEncodable { + public func toJSONValue() -> JSONRawType { + switch self { + case .testing: return "testing" + case .profiling: return "profiling" + case .running: return "running" + case .archiving: return "archiving" + case .analyzing: return "analyzing" + } + } +} + extension XCScheme.EnvironmentVariable: JSONObjectConvertible { private static func parseValue(_ value: Any) -> String { @@ -393,3 +603,13 @@ extension XCScheme.EnvironmentVariable: JSONObjectConvertible { } } } + +extension XCScheme.EnvironmentVariable: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + return [ + "variable": variable, + "value": value, + "isEnabled": enabled + ] + } +} diff --git a/Sources/ProjectSpec/Settings.swift b/Sources/ProjectSpec/Settings.swift index 95254dd66..d06122c73 100644 --- a/Sources/ProjectSpec/Settings.swift +++ b/Sources/ProjectSpec/Settings.swift @@ -105,3 +105,24 @@ public func += (lhs: inout BuildSettings, rhs: BuildSettings?) { guard let rhs = rhs else { return } lhs.merge(rhs) } + +extension Settings: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + if groups.count > 0 || configSettings.count > 0 { + var dict: JSONDictionary = [:] + + if buildSettings.count > 0 { + dict["base"] = buildSettings + } + if groups.count > 0 { + dict["groups"] = groups + } + if configSettings.count > 0 { + dict["configs"] = configSettings.mapValues { $0.toJSONDictionary() } + } + + return dict + } + return buildSettings + } +} diff --git a/Sources/ProjectSpec/SpecOptions.swift b/Sources/ProjectSpec/SpecOptions.swift index 1abc8f426..afb4a2462 100644 --- a/Sources/ProjectSpec/SpecOptions.swift +++ b/Sources/ProjectSpec/SpecOptions.swift @@ -126,6 +126,64 @@ extension SpecOptions: JSONObjectConvertible { } } +extension SpecOptions: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [ + "deploymentTarget": deploymentTarget.toJSONDictionary(), + "transitivelyLinkDependencies": transitivelyLinkDependencies, + "groupSortPosition": groupSortPosition.rawValue, + ] + + if settingPresets != .all { + dict["settingPresets"] = settingPresets.rawValue + } + if createIntermediateGroups { + dict["createIntermediateGroups"] = createIntermediateGroups + } + if generateEmptyDirectories { + dict["generateEmptyDirectories"] = generateEmptyDirectories + } + if findCarthageFrameworks { + dict["findCarthageFrameworks"] = findCarthageFrameworks + } + if disabledValidations.count > 0 { + dict["disabledValidations"] = disabledValidations.map { $0.rawValue } + } + if let minimumXcodeGenVersion = minimumXcodeGenVersion { + dict["minimumXcodeGenVersion"] = minimumXcodeGenVersion.string + } + if let carthageBuildPath = carthageBuildPath { + dict["carthageBuildPath"] = carthageBuildPath + } + if let carthageExecutablePath = carthageExecutablePath { + dict["carthageExecutablePath"] = carthageExecutablePath + } + if let bundleIdPrefix = bundleIdPrefix { + dict["bundleIdPrefix"] = bundleIdPrefix + } + if let developmentLanguage = developmentLanguage { + dict["developmentLanguage"] = developmentLanguage + } + if let usesTabs = usesTabs { + dict["usesTabs"] = usesTabs + } + if let xcodeVersion = xcodeVersion { + dict["xcodeVersion"] = xcodeVersion + } + if let indentWidth = indentWidth { + dict["indentWidth"] = Int(indentWidth) + } + if let tabWidth = tabWidth { + dict["tabWidth"] = Int(tabWidth) + } + if let defaultConfig = defaultConfig { + dict["defaultConfig"] = defaultConfig + } + + return dict + } +} + extension SpecOptions: PathContainer { static var pathProperties: [PathProperty] { diff --git a/Sources/ProjectSpec/Target.swift b/Sources/ProjectSpec/Target.swift index b7eb1c00a..820eefc7a 100644 --- a/Sources/ProjectSpec/Target.swift +++ b/Sources/ProjectSpec/Target.swift @@ -272,6 +272,24 @@ extension LegacyTarget: JSONObjectConvertible { } } +extension LegacyTarget: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [ + "toolPath": toolPath, + "passSettings": passSettings, + ] + + if let arguments = arguments { + dict["arguments"] = arguments + } + if let workingDirectory = workingDirectory { + dict["workingDirectory"] = workingDirectory + } + + return dict + } +} + extension Target: NamedJSONDictionaryConvertible { public init(name: String, jsonDictionary: JSONDictionary) throws { @@ -342,3 +360,72 @@ extension Target: NamedJSONDictionaryConvertible { attributes = jsonDictionary.json(atKeyPath: "attributes") ?? [:] } } + + +extension Target: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [ + "type": type.name, + "platform": platform.rawValue, + ] + + let settingsDict = settings.toJSONDictionary() + if settingsDict.count > 0 { + dict["settings"] = settingsDict + } + + if productName != name { + dict["productName"] = productName + } + if configFiles.count > 0 { + dict["configFiles"] = configFiles + } + if attributes.count > 0 { + dict["attributes"] = attributes + } + if sources.count > 0 { + dict["sources"] = sources.map { $0.toJSONValue() } + } + if dependencies.count > 0 { + dict["dependencies"] = dependencies.map { $0.toJSONDictionary() } + } + if postCompileScripts.count > 0 { + dict["postCompileScripts"] = postCompileScripts.map{ $0.toJSONDictionary() } + } + if preBuildScripts.count > 0 { + dict["prebuildScripts"] = preBuildScripts.map{ $0.toJSONDictionary() } + } + if postBuildScripts.count > 0 { + dict["postbuildScripts"] = postBuildScripts.map{ $0.toJSONDictionary() } + } + if buildRules.count > 0 { + dict["buildRules"] = buildRules.map{ $0.toJSONDictionary() } + } + if let deploymentTarget = deploymentTarget { + dict["deploymentTarget"] = deploymentTarget.deploymentTarget + } + if let info = info { + dict["info"] = info.toJSONDictionary() + } + if let entitlements = entitlements { + dict["entitlements"] = entitlements.toJSONDictionary() + } + if let transitivelyLinkDependencies = transitivelyLinkDependencies { + dict["transitivelyLinkDependencies"] = transitivelyLinkDependencies + } + if let directlyEmbedCarthageDependencies = directlyEmbedCarthageDependencies { + dict["directlyEmbedCarthageDependencies"] = directlyEmbedCarthageDependencies + } + if let requiresObjCLinking = requiresObjCLinking { + dict["requiresObjCLinking"] = requiresObjCLinking + } + if let scheme = scheme { + dict["scheme"] = scheme.toJSONDictionary() + } + if let legacy = legacy { + dict["legacy"] = legacy.toJSONDictionary() + } + + return dict + } +} diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 22b018e9a..3dde710ed 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -54,3 +54,32 @@ extension TargetScheme: JSONObjectConvertible { postActions = jsonDictionary.json(atKeyPath: "postActions") ?? [] } } + +extension TargetScheme: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + var dict: JSONDictionary = [ + "gatherCoverageData": gatherCoverageData, + ] + + if configVariants.count > 0 { + dict["configVariants"] = configVariants + } + if commandLineArguments.count > 0 { + dict["commandLineArguments"] = commandLineArguments + } + if testTargets.count > 0 { + dict["testTargets"] = testTargets.map { $0.toJSONValue() } + } + if environmentVariables.count > 0 { + dict["environmentVariables"] = environmentVariables.map { $0.toJSONDictionary() } + } + if preActions.count > 0 { + dict["preActions"] = preActions.map { $0.toJSONDictionary() } + } + if postActions.count > 0 { + dict["postActions"] = postActions.map { $0.toJSONDictionary() } + } + + return dict + } +} diff --git a/Sources/ProjectSpec/TargetSource.swift b/Sources/ProjectSpec/TargetSource.swift index 6ed21bff9..9b3410207 100644 --- a/Sources/ProjectSpec/TargetSource.swift +++ b/Sources/ProjectSpec/TargetSource.swift @@ -181,6 +181,45 @@ extension TargetSource: JSONObjectConvertible { } } +extension TargetSource: JSONDynamicEncodable { + public func toJSONValue() -> Any { + var dict: JSONDictionary = [:] + + if compilerFlags.count > 0 { + dict["compilerFlags"] = compilerFlags + } + if excludes.count > 0 { + dict["excludes"] = excludes + } + if let name = name { + dict["name"] = name + } + if let headerVisibility = headerVisibility { + dict["headerVisibility"] = headerVisibility.rawValue + } + if let type = type { + dict["type"] = type.rawValue + } + if let buildPhase = buildPhase { + dict["buildPhase"] = buildPhase.toJSONValue() + } + if let createIntermediateGroups = createIntermediateGroups { + dict["createIntermediateGroups"] = createIntermediateGroups + } + if optional { + dict["optional"] = true + } + + if dict.count == 0 { + return path + } + + dict["path"] = path + + return dict + } +} + extension TargetSource.BuildPhase { public init(string: String) throws { @@ -204,6 +243,21 @@ extension TargetSource.BuildPhase: JSONObjectConvertible { } } +extension TargetSource.BuildPhase: JSONDynamicEncodable { + public func toJSONValue() -> Any { + switch self { + case .sources: return "sources" + case .headers: return "headers" + case .resources: return "resources" + case .copyFiles(let files): return ["copyFiles": files.toJSONDictionary()] + case .none: return "none" + case .frameworks: fatalError("invalid build phase") + case .runScript: fatalError("invalid build phase") + case .carbonResources: fatalError("invalid build phase") + } + } +} + extension TargetSource.BuildPhase.CopyFilesSettings: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { @@ -213,6 +267,15 @@ extension TargetSource.BuildPhase.CopyFilesSettings: JSONObjectConvertible { } } +extension TargetSource.BuildPhase.CopyFilesSettings: JSONDictionaryEncodable { + public func toJSONDictionary() -> JSONDictionary { + return [ + "destination": destination.rawValue, + "subpath": subpath + ] + } +} + extension TargetSource: PathContainer { static var pathProperties: [PathProperty] { From 0889882aacf6330d2d0e815fad9097eff373a3fa Mon Sep 17 00:00:00 2001 From: ryohey Date: Tue, 26 Mar 2019 18:27:40 +0900 Subject: [PATCH 3/8] Add test for JSON encoding --- Tests/XcodeGenKitTests/ProjectSpecTests.swift | 242 ++++++++++++++++++ 1 file changed, 242 insertions(+) diff --git a/Tests/XcodeGenKitTests/ProjectSpecTests.swift b/Tests/XcodeGenKitTests/ProjectSpecTests.swift index 9fa496c60..33aaeba64 100644 --- a/Tests/XcodeGenKitTests/ProjectSpecTests.swift +++ b/Tests/XcodeGenKitTests/ProjectSpecTests.swift @@ -256,6 +256,248 @@ class ProjectSpecTests: XCTestCase { } } } + + func testJSONEncodable() { + describe { + $0.it("encodes to json") { + let proj = Project(basePath: Path.current, + name: "ToJson", + configs: [Config(name: "DevelopmentConfig", type: .debug), Config(name: "ProductionConfig", type: .release)], + targets: [Target(name: "App", + type: .application, + platform: .iOS, + productName: "App", + deploymentTarget: Version(major: 0, minor: 1, patch: 2), + settings: Settings(buildSettings: ["foo": "bar"], + configSettings: ["foo" : Settings(buildSettings: ["nested": "config"], + configSettings: [:], + groups: ["config-setting-group"])], + groups: ["setting-group"]), + configFiles: ["foo": "bar"], + sources: [TargetSource(path: "Source", + name: "Source", + compilerFlags: ["-Werror"], + excludes: ["foo", "bar"], + type: .folder, + optional: true, + buildPhase: .resources, + headerVisibility: .private, + createIntermediateGroups: true)], + dependencies: [Dependency(type: .carthage(findFrameworks: true), + reference: "reference", + embed: true, + codeSign: true, + link: true, + implicit: true, + weakLink: true)], + info: Plist(path: "info.plist", attributes: ["foo": "bar"]), + entitlements: Plist(path: "entitlements.plist", attributes: ["foo": "bar"]), + transitivelyLinkDependencies: true, + directlyEmbedCarthageDependencies: true, + requiresObjCLinking: true, + preBuildScripts: [BuildScript(script: .script("pwd"), + name: "Foo script", + inputFiles: ["foo"], + outputFiles: ["bar"], + inputFileLists: ["foo.xcfilelist"], + outputFileLists: ["bar.xcfilelist"], + shell: "/bin/bash", + runOnlyWhenInstalling: true, + showEnvVars: true)], + postCompileScripts: [BuildScript(script: .path("cmd.sh"), + name: "Bar script", + inputFiles: ["foo"], + outputFiles: ["bar"], + inputFileLists: ["foo.xcfilelist"], + outputFileLists: ["bar.xcfilelist"], + shell: "/bin/bash", + runOnlyWhenInstalling: true, + showEnvVars: true)], + postBuildScripts: [BuildScript(script: .path("cmd.sh"), + name: "an another script", + inputFiles: ["foo"], + outputFiles: ["bar"], + inputFileLists: ["foo.xcfilelist"], + outputFileLists: ["bar.xcfilelist"], + shell: "/bin/bash", + runOnlyWhenInstalling: true, + showEnvVars: true)], + buildRules: [BuildRule(fileType: .pattern("*.xcassets"), + action: .script("pre_process_swift.py"), + name: "My Build Rule", + outputFiles: ["$(SRCROOT)/Generated.swift"], + outputFilesCompilerFlags: ["foo"]), + BuildRule(fileType: .type("sourcecode.swift"), + action: .compilerSpec("com.apple.xcode.tools.swift.compiler"), + name: nil, + outputFiles: ["bar"], + outputFilesCompilerFlags: ["foo"]),], + scheme: TargetScheme(testTargets: [Scheme.Test.TestTarget(name: "test target", + randomExecutionOrder: false, + parallelizable: false)], + configVariants: ["foo"], + gatherCoverageData: true, + commandLineArguments: ["foo": true], + environmentVariables: [XCScheme.EnvironmentVariable(variable: "environmentVariable", + value: "bar", + enabled: true)], + preActions: [Scheme.ExecutionAction(name: "preAction", + script: "bar", + settingsTarget: "foo")], + postActions: [Scheme.ExecutionAction(name: "postAction", + script: "bar", + settingsTarget: "foo")]), + legacy: LegacyTarget(toolPath: "foo", + passSettings: true, + arguments: "bar", + workingDirectory: "foo"), + attributes: ["foo": "bar"])], + aggregateTargets: [AggregateTarget(name: "aggregate target", + targets: ["App"], + settings: Settings(buildSettings: ["buildSettings": "bar"], + configSettings: ["configSettings": Settings(buildSettings: [:], + configSettings: [:], + groups: [])], + groups: ["foo"]), + configFiles: ["configFiles": "bar"], + buildScripts: [BuildScript(script: .path("script"), + name: "foo", + inputFiles: ["foo"], + outputFiles: ["bar"], + inputFileLists: ["foo.xcfilelist"], + outputFileLists: ["bar.xcfilelist"], + shell: "/bin/bash", + runOnlyWhenInstalling: true, + showEnvVars: false)], + scheme: TargetScheme(testTargets: [Scheme.Test.TestTarget(name: "test target", + randomExecutionOrder: false, + parallelizable: false)], + configVariants: ["foo"], + gatherCoverageData: true, + commandLineArguments: ["foo": true], + environmentVariables: [XCScheme.EnvironmentVariable(variable: "environmentVariable", + value: "bar", + enabled: true)], + preActions: [Scheme.ExecutionAction(name: "preAction", + script: "bar", + settingsTarget: "foo")], + postActions: [Scheme.ExecutionAction(name: "postAction", + script: "bar", + settingsTarget: "foo")]), + attributes: ["foo": "bar"])], + settings: Settings(buildSettings: ["foo": "bar"], + configSettings: ["foo" : Settings(buildSettings: ["nested": "config"], + configSettings: [:], + groups: ["config-setting-group"])], + groups: ["setting-group"]), + settingGroups: ["foo": Settings(buildSettings: ["foo": "bar"], + configSettings: ["foo" : Settings(buildSettings: ["nested": "config"], + configSettings: [:], + groups: ["config-setting-group"])], + groups: ["setting-group"])], + schemes: [Scheme(name: "scheme", + build: Scheme.Build(targets: [Scheme.BuildTarget(target: "foo", + buildTypes: [.archiving, .analyzing])], + parallelizeBuild: false, + buildImplicitDependencies: false, + preActions: [Scheme.ExecutionAction(name: "preAction", + script: "bar", + settingsTarget: "foo")], + postActions: [Scheme.ExecutionAction(name: "postAction", + script: "bar", + settingsTarget: "foo")]), + run: Scheme.Run(config: "run config", + commandLineArguments: ["foo": true], + preActions: [Scheme.ExecutionAction(name: "preAction", + script: "bar", + settingsTarget: "foo")], + postActions: [Scheme.ExecutionAction(name: "postAction", + script: "bar", + settingsTarget: "foo")], + environmentVariables: [XCScheme.EnvironmentVariable(variable: "foo", + value: "bar", + enabled: false)]), + test: Scheme.Test(config: "Config", + gatherCoverageData: true, + randomExecutionOrder: false, + parallelizable: false, + commandLineArguments: ["foo": true], + targets: [Scheme.Test.TestTarget(name: "foo", + randomExecutionOrder: false, + parallelizable: false)], + preActions: [Scheme.ExecutionAction(name: "preAction", + script: "bar", + settingsTarget: "foo")], + postActions: [Scheme.ExecutionAction(name: "postAction", + script: "bar", + settingsTarget: "foo")], + environmentVariables: [XCScheme.EnvironmentVariable(variable: "foo", + value: "bar", + enabled: false)]), + profile: Scheme.Profile(config: "profile config", + commandLineArguments: ["foo": true], + preActions: [Scheme.ExecutionAction(name: "preAction", + script: "bar", + settingsTarget: "foo")], + postActions: [Scheme.ExecutionAction(name: "postAction", + script: "bar", + settingsTarget: "foo")], + environmentVariables: [XCScheme.EnvironmentVariable(variable: "foo", + value: "bar", + enabled: false)]), + analyze: Scheme.Analyze(config: "analyze config"), + archive: Scheme.Archive(config: "archive config", + customArchiveName: "customArchiveName", + revealArchiveInOrganizer: true, + preActions: [Scheme.ExecutionAction(name: "preAction", + script: "bar", + settingsTarget: "foo")], + postActions: [Scheme.ExecutionAction(name: "postAction", + script: "bar", + settingsTarget: "foo")]))], + options: SpecOptions(minimumXcodeGenVersion: Version(major: 3, minor: 4, patch: 5), + carthageBuildPath: "carthageBuildPath", + carthageExecutablePath: "carthageExecutablePath", + createIntermediateGroups: true, + bundleIdPrefix: "bundleIdPrefix", + settingPresets: .project, + developmentLanguage: "developmentLanguage", + indentWidth: 123, + tabWidth: 456, + usesTabs: true, + xcodeVersion: "xcodeVersion", + deploymentTarget: DeploymentTarget(iOS: Version(major: 1, minor: 2, patch: 3), + tvOS: nil, + watchOS: Version(major: 4, minor: 5, patch: 6), + macOS: nil), + disabledValidations: [.missingConfigFiles], + defaultConfig: "defaultConfig", + transitivelyLinkDependencies: true, + groupSortPosition: .top, + generateEmptyDirectories: true, + findCarthageFrameworks: false), + fileGroups: ["foo", "bar"], + configFiles: ["configFiles": "bar"], + attributes: ["attributes": "bar"]) + + let json = proj.toJSONDictionary() + let restoredProj = try Project(basePath: Path.current, jsonDictionary: json) + + // Examin some properties to make debugging easier + try expect(proj.aggregateTargets) == restoredProj.aggregateTargets + try expect(proj.configFiles) == restoredProj.configFiles + try expect(proj.settings) == restoredProj.settings + try expect(proj.basePath) == restoredProj.basePath + try expect(proj.fileGroups) == restoredProj.fileGroups + try expect(proj.schemes) == restoredProj.schemes + try expect(proj.options) == restoredProj.options + try expect(proj.settingGroups) == restoredProj.settingGroups + try expect(proj.targets) == restoredProj.targets + + try expect(proj) == restoredProj + } + } + } } fileprivate func expectValidationError(_ project: Project, _ expectedError: SpecValidationError.ValidationError, file: String = #file, line: Int = #line) throws { From b27f71eac1acce957d7ea2cd885b16ff0f9c668a Mon Sep 17 00:00:00 2001 From: ryohey Date: Thu, 4 Apr 2019 23:08:38 +0900 Subject: [PATCH 4/8] Unify encoding protocols into JSONEncodable https://github.com/yonaskolb/XcodeGen/pull/545#discussion_r271690085 --- Sources/ProjectSpec/AggregateTarget.swift | 10 +-- Sources/ProjectSpec/BuildRule.swift | 4 +- Sources/ProjectSpec/BuildScript.swift | 4 +- Sources/ProjectSpec/Dependency.swift | 4 +- Sources/ProjectSpec/DeploymentTarget.swift | 4 +- Sources/ProjectSpec/Encoding.swift | 14 +--- Sources/ProjectSpec/Plist.swift | 4 +- Sources/ProjectSpec/Project.swift | 18 +++-- Sources/ProjectSpec/Scheme.swift | 80 +++++++++++----------- Sources/ProjectSpec/Settings.swift | 6 +- Sources/ProjectSpec/SpecOptions.swift | 6 +- Sources/ProjectSpec/Target.swift | 28 ++++---- Sources/ProjectSpec/TargetScheme.swift | 10 +-- Sources/ProjectSpec/TargetSource.swift | 10 +-- 14 files changed, 97 insertions(+), 105 deletions(-) diff --git a/Sources/ProjectSpec/AggregateTarget.swift b/Sources/ProjectSpec/AggregateTarget.swift index e8159640c..3d91ba395 100644 --- a/Sources/ProjectSpec/AggregateTarget.swift +++ b/Sources/ProjectSpec/AggregateTarget.swift @@ -62,11 +62,11 @@ extension AggregateTarget: NamedJSONDictionaryConvertible { } } -extension AggregateTarget: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension AggregateTarget: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [:] - let settingsDict = settings.toJSONDictionary() + let settingsDict = settings.toJSONValue() if settingsDict.count > 0 { dict["settings"] = settingsDict } @@ -81,10 +81,10 @@ extension AggregateTarget: JSONDictionaryEncodable { dict["attributes"] = attributes } if buildScripts.count > 0 { - dict["buildScripts"] = buildScripts.map { $0.toJSONDictionary() } + dict["buildScripts"] = buildScripts.map { $0.toJSONValue() } } if let scheme = scheme { - dict["scheme"] = scheme.toJSONDictionary() + dict["scheme"] = scheme.toJSONValue() } return dict diff --git a/Sources/ProjectSpec/BuildRule.swift b/Sources/ProjectSpec/BuildRule.swift index a4e4ae36f..9c4e3cea3 100644 --- a/Sources/ProjectSpec/BuildRule.swift +++ b/Sources/ProjectSpec/BuildRule.swift @@ -81,8 +81,8 @@ extension BuildRule: JSONObjectConvertible { } } -extension BuildRule: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension BuildRule: JSONEncodable { + public func toJSONValue() -> Any { var dict: [String: Any] = [ "outputFiles": outputFiles, "outputFilesCompilerFlags": outputFilesCompilerFlags, diff --git a/Sources/ProjectSpec/BuildScript.swift b/Sources/ProjectSpec/BuildScript.swift index 2ed007787..ed9aada8d 100644 --- a/Sources/ProjectSpec/BuildScript.swift +++ b/Sources/ProjectSpec/BuildScript.swift @@ -61,8 +61,8 @@ extension BuildScript: JSONObjectConvertible { showEnvVars = jsonDictionary.json(atKeyPath: "showEnvVars") ?? true } } -extension BuildScript: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension BuildScript: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [:] if runOnlyWhenInstalling { diff --git a/Sources/ProjectSpec/Dependency.swift b/Sources/ProjectSpec/Dependency.swift index 8aea2f068..6ea575b6a 100644 --- a/Sources/ProjectSpec/Dependency.swift +++ b/Sources/ProjectSpec/Dependency.swift @@ -81,8 +81,8 @@ extension Dependency: JSONObjectConvertible { } } -extension Dependency: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Dependency: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [:] if !removeHeaders { diff --git a/Sources/ProjectSpec/DeploymentTarget.swift b/Sources/ProjectSpec/DeploymentTarget.swift index 2feff0957..0968cfeee 100644 --- a/Sources/ProjectSpec/DeploymentTarget.swift +++ b/Sources/ProjectSpec/DeploymentTarget.swift @@ -79,8 +79,8 @@ extension DeploymentTarget: JSONObjectConvertible { } } -extension DeploymentTarget: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension DeploymentTarget: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [:] if let iOS = iOS { diff --git a/Sources/ProjectSpec/Encoding.swift b/Sources/ProjectSpec/Encoding.swift index ee024177c..46e1ad52e 100644 --- a/Sources/ProjectSpec/Encoding.swift +++ b/Sources/ProjectSpec/Encoding.swift @@ -1,19 +1,7 @@ import Foundation import JSONUtilities -public protocol JSONDictionaryEncodable { - func toJSONDictionary() -> JSONDictionary -} - -public protocol JSONArrayEncodable { - func toJSONArray() -> JSONArray -} - -public protocol JSONPrimitiveEncodable { - func toJSONValue() -> JSONRawType -} - -public protocol JSONDynamicEncodable { +public protocol JSONEncodable { // returns JSONDictionary or JSONArray or JSONRawType func toJSONValue() -> Any } diff --git a/Sources/ProjectSpec/Plist.swift b/Sources/ProjectSpec/Plist.swift index 9140b0801..e174a9ab0 100644 --- a/Sources/ProjectSpec/Plist.swift +++ b/Sources/ProjectSpec/Plist.swift @@ -25,8 +25,8 @@ extension Plist: JSONObjectConvertible { } } -extension Plist: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Plist: JSONEncodable { + public func toJSONValue() -> Any { return [ "path": path, "properties": properties diff --git a/Sources/ProjectSpec/Project.swift b/Sources/ProjectSpec/Project.swift index 63660edca..869ad3e94 100644 --- a/Sources/ProjectSpec/Project.swift +++ b/Sources/ProjectSpec/Project.swift @@ -231,14 +231,18 @@ extension BuildSettingsContainer { } } -extension Project: JSONDictionaryEncodable { +extension Project: JSONEncodable { + public func toJSONValue() -> Any { + return toJSONDictionary() + } + public func toJSONDictionary() -> JSONDictionary { var dict: JSONDictionary = [ "name": name, - "options": options.toJSONDictionary(), + "options": options.toJSONValue(), ] - let settingsDict = settings.toJSONDictionary() + let settingsDict = settings.toJSONValue() if settingsDict.count > 0 { dict["settings"] = settingsDict } @@ -256,7 +260,7 @@ extension Project: JSONDictionaryEncodable { dict["attributes"] = attributes } - let targetPairs = targets.map { ($0.name, $0.toJSONDictionary()) } + let targetPairs = targets.map { ($0.name, $0.toJSONValue()) } if targetPairs.count > 0 { dict["targets"] = Dictionary(uniqueKeysWithValues: targetPairs) } @@ -266,18 +270,18 @@ extension Project: JSONDictionaryEncodable { dict["configs"] = Dictionary(uniqueKeysWithValues: configsPairs) } - let aggregateTargetsPairs = aggregateTargets.map { ($0.name, $0.toJSONDictionary()) } + let aggregateTargetsPairs = aggregateTargets.map { ($0.name, $0.toJSONValue()) } if aggregateTargetsPairs.count > 0 { dict["aggregateTargets"] = Dictionary(uniqueKeysWithValues: aggregateTargetsPairs) } - let schemesPairs = schemes.map { ($0.name, $0.toJSONDictionary()) } + let schemesPairs = schemes.map { ($0.name, $0.toJSONValue()) } if schemesPairs.count > 0 { dict["schemes"] = Dictionary(uniqueKeysWithValues: schemesPairs) } if settingGroups.count > 0 { - dict["settingGroups"] = settingGroups.mapValues { $0.toJSONDictionary() } + dict["settingGroups"] = settingGroups.mapValues { $0.toJSONValue() } } return dict diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 86a6acd08..25eb51da1 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -218,8 +218,8 @@ extension Scheme.ExecutionAction: JSONObjectConvertible { } } -extension Scheme.ExecutionAction: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Scheme.ExecutionAction: JSONEncodable { + public func toJSONValue() -> Any { var dict = [ "script": script, "name": name, @@ -244,20 +244,20 @@ extension Scheme.Run: JSONObjectConvertible { } } -extension Scheme.Run: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Scheme.Run: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [ "commandLineArguments": commandLineArguments, ] if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONDictionary() } + dict["preActions"] = preActions.map { $0.toJSONValue() } } if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONDictionary() } + dict["postActions"] = postActions.map { $0.toJSONValue() } } if environmentVariables.count > 0 { - dict["environmentVariables"] = environmentVariables.map { $0.toJSONDictionary() } + dict["environmentVariables"] = environmentVariables.map { $0.toJSONValue() } } if let config = config { dict["config"] = config @@ -292,8 +292,8 @@ extension Scheme.Test: JSONObjectConvertible { } } -extension Scheme.Test: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Scheme.Test: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [ "gatherCoverageData": gatherCoverageData, ] @@ -305,13 +305,13 @@ extension Scheme.Test: JSONDictionaryEncodable { dict["targets"] = targets.map { $0.toJSONValue() } } if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONDictionary() } + dict["preActions"] = preActions.map { $0.toJSONValue() } } if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONDictionary() } + dict["postActions"] = postActions.map { $0.toJSONValue() } } if environmentVariables.count > 0 { - dict["environmentVariables"] = environmentVariables.map { $0.toJSONDictionary() } + dict["environmentVariables"] = environmentVariables.map { $0.toJSONValue() } } if let config = config { dict["config"] = config @@ -330,7 +330,7 @@ extension Scheme.Test.TestTarget: JSONObjectConvertible { } } -extension Scheme.Test.TestTarget: JSONDynamicEncodable { +extension Scheme.Test.TestTarget: JSONEncodable { public func toJSONValue() -> Any { if !randomExecutionOrder && !parallelizable { return name @@ -362,20 +362,20 @@ extension Scheme.Profile: JSONObjectConvertible { } } -extension Scheme.Profile: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Scheme.Profile: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [ "commandLineArguments": commandLineArguments, ] if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONDictionary() } + dict["preActions"] = preActions.map { $0.toJSONValue() } } if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONDictionary() } + dict["postActions"] = postActions.map { $0.toJSONValue() } } if environmentVariables.count > 0 { - dict["environmentVariables"] = environmentVariables.map { $0.toJSONDictionary() } + dict["environmentVariables"] = environmentVariables.map { $0.toJSONValue() } } if let config = config { dict["config"] = config @@ -392,8 +392,8 @@ extension Scheme.Analyze: JSONObjectConvertible { } } -extension Scheme.Analyze: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Scheme.Analyze: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [:] if let config = config { @@ -415,18 +415,18 @@ extension Scheme.Archive: JSONObjectConvertible { } } -extension Scheme.Archive: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Scheme.Archive: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [:] if !revealArchiveInOrganizer { dict["revealArchiveInOrganizer"] = revealArchiveInOrganizer } if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONDictionary() } + dict["preActions"] = preActions.map { $0.toJSONValue() } } if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONDictionary() } + dict["postActions"] = postActions.map { $0.toJSONValue() } } if let config = config { dict["config"] = config @@ -452,26 +452,26 @@ extension Scheme: NamedJSONDictionaryConvertible { } } -extension Scheme: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Scheme: JSONEncodable { + public func toJSONValue() -> Any { var dict = [ - "build": build.toJSONDictionary() + "build": build.toJSONValue() ] if let run = run { - dict["run"] = run.toJSONDictionary() + dict["run"] = run.toJSONValue() } if let test = test { - dict["test"] = test.toJSONDictionary() + dict["test"] = test.toJSONValue() } if let analyze = analyze { - dict["analyze"] = analyze.toJSONDictionary() + dict["analyze"] = analyze.toJSONValue() } if let profile = profile { - dict["profile"] = profile.toJSONDictionary() + dict["profile"] = profile.toJSONValue() } if let archive = archive { - dict["archive"] = archive.toJSONDictionary() + dict["archive"] = archive.toJSONValue() } return dict @@ -510,8 +510,8 @@ extension Scheme.Build: JSONObjectConvertible { } } -extension Scheme.Build: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Scheme.Build: JSONEncodable { + public func toJSONValue() -> Any { let targetPairs = targets.map { ($0.target, $0.buildTypes.map { $0.toJSONValue() }) } var dict: JSONDictionary = [ @@ -525,10 +525,10 @@ extension Scheme.Build: JSONDictionaryEncodable { dict["buildImplicitDependencies"] = buildImplicitDependencies } if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONDictionary() } + dict["preActions"] = preActions.map { $0.toJSONValue() } } if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONDictionary() } + dict["postActions"] = postActions.map { $0.toJSONValue() } } return dict @@ -555,8 +555,8 @@ extension BuildType: JSONPrimitiveConvertible { } } -extension BuildType: JSONPrimitiveEncodable { - public func toJSONValue() -> JSONRawType { +extension BuildType: JSONEncodable { + public func toJSONValue() -> Any { switch self { case .testing: return "testing" case .profiling: return "profiling" @@ -604,8 +604,8 @@ extension XCScheme.EnvironmentVariable: JSONObjectConvertible { } } -extension XCScheme.EnvironmentVariable: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension XCScheme.EnvironmentVariable: JSONEncodable { + public func toJSONValue() -> Any { return [ "variable": variable, "value": value, diff --git a/Sources/ProjectSpec/Settings.swift b/Sources/ProjectSpec/Settings.swift index d06122c73..b60268e87 100644 --- a/Sources/ProjectSpec/Settings.swift +++ b/Sources/ProjectSpec/Settings.swift @@ -106,8 +106,8 @@ public func += (lhs: inout BuildSettings, rhs: BuildSettings?) { lhs.merge(rhs) } -extension Settings: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Settings: JSONEncodable { + public func toJSONValue() -> Any { if groups.count > 0 || configSettings.count > 0 { var dict: JSONDictionary = [:] @@ -118,7 +118,7 @@ extension Settings: JSONDictionaryEncodable { dict["groups"] = groups } if configSettings.count > 0 { - dict["configs"] = configSettings.mapValues { $0.toJSONDictionary() } + dict["configs"] = configSettings.mapValues { $0.toJSONValue() } } return dict diff --git a/Sources/ProjectSpec/SpecOptions.swift b/Sources/ProjectSpec/SpecOptions.swift index afb4a2462..ce2f2e991 100644 --- a/Sources/ProjectSpec/SpecOptions.swift +++ b/Sources/ProjectSpec/SpecOptions.swift @@ -126,10 +126,10 @@ extension SpecOptions: JSONObjectConvertible { } } -extension SpecOptions: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension SpecOptions: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [ - "deploymentTarget": deploymentTarget.toJSONDictionary(), + "deploymentTarget": deploymentTarget.toJSONValue(), "transitivelyLinkDependencies": transitivelyLinkDependencies, "groupSortPosition": groupSortPosition.rawValue, ] diff --git a/Sources/ProjectSpec/Target.swift b/Sources/ProjectSpec/Target.swift index 820eefc7a..20c272bc6 100644 --- a/Sources/ProjectSpec/Target.swift +++ b/Sources/ProjectSpec/Target.swift @@ -272,8 +272,8 @@ extension LegacyTarget: JSONObjectConvertible { } } -extension LegacyTarget: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension LegacyTarget: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [ "toolPath": toolPath, "passSettings": passSettings, @@ -362,14 +362,14 @@ extension Target: NamedJSONDictionaryConvertible { } -extension Target: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension Target: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [ "type": type.name, "platform": platform.rawValue, ] - let settingsDict = settings.toJSONDictionary() + let settingsDict = settings.toJSONValue() if settingsDict.count > 0 { dict["settings"] = settingsDict } @@ -387,28 +387,28 @@ extension Target: JSONDictionaryEncodable { dict["sources"] = sources.map { $0.toJSONValue() } } if dependencies.count > 0 { - dict["dependencies"] = dependencies.map { $0.toJSONDictionary() } + dict["dependencies"] = dependencies.map { $0.toJSONValue() } } if postCompileScripts.count > 0 { - dict["postCompileScripts"] = postCompileScripts.map{ $0.toJSONDictionary() } + dict["postCompileScripts"] = postCompileScripts.map{ $0.toJSONValue() } } if preBuildScripts.count > 0 { - dict["prebuildScripts"] = preBuildScripts.map{ $0.toJSONDictionary() } + dict["prebuildScripts"] = preBuildScripts.map{ $0.toJSONValue() } } if postBuildScripts.count > 0 { - dict["postbuildScripts"] = postBuildScripts.map{ $0.toJSONDictionary() } + dict["postbuildScripts"] = postBuildScripts.map{ $0.toJSONValue() } } if buildRules.count > 0 { - dict["buildRules"] = buildRules.map{ $0.toJSONDictionary() } + dict["buildRules"] = buildRules.map{ $0.toJSONValue() } } if let deploymentTarget = deploymentTarget { dict["deploymentTarget"] = deploymentTarget.deploymentTarget } if let info = info { - dict["info"] = info.toJSONDictionary() + dict["info"] = info.toJSONValue() } if let entitlements = entitlements { - dict["entitlements"] = entitlements.toJSONDictionary() + dict["entitlements"] = entitlements.toJSONValue() } if let transitivelyLinkDependencies = transitivelyLinkDependencies { dict["transitivelyLinkDependencies"] = transitivelyLinkDependencies @@ -420,10 +420,10 @@ extension Target: JSONDictionaryEncodable { dict["requiresObjCLinking"] = requiresObjCLinking } if let scheme = scheme { - dict["scheme"] = scheme.toJSONDictionary() + dict["scheme"] = scheme.toJSONValue() } if let legacy = legacy { - dict["legacy"] = legacy.toJSONDictionary() + dict["legacy"] = legacy.toJSONValue() } return dict diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 3dde710ed..6878bf58b 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -55,8 +55,8 @@ extension TargetScheme: JSONObjectConvertible { } } -extension TargetScheme: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension TargetScheme: JSONEncodable { + public func toJSONValue() -> Any { var dict: JSONDictionary = [ "gatherCoverageData": gatherCoverageData, ] @@ -71,13 +71,13 @@ extension TargetScheme: JSONDictionaryEncodable { dict["testTargets"] = testTargets.map { $0.toJSONValue() } } if environmentVariables.count > 0 { - dict["environmentVariables"] = environmentVariables.map { $0.toJSONDictionary() } + dict["environmentVariables"] = environmentVariables.map { $0.toJSONValue() } } if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONDictionary() } + dict["preActions"] = preActions.map { $0.toJSONValue() } } if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONDictionary() } + dict["postActions"] = postActions.map { $0.toJSONValue() } } return dict diff --git a/Sources/ProjectSpec/TargetSource.swift b/Sources/ProjectSpec/TargetSource.swift index 9b3410207..a68ed31be 100644 --- a/Sources/ProjectSpec/TargetSource.swift +++ b/Sources/ProjectSpec/TargetSource.swift @@ -181,7 +181,7 @@ extension TargetSource: JSONObjectConvertible { } } -extension TargetSource: JSONDynamicEncodable { +extension TargetSource: JSONEncodable { public func toJSONValue() -> Any { var dict: JSONDictionary = [:] @@ -243,13 +243,13 @@ extension TargetSource.BuildPhase: JSONObjectConvertible { } } -extension TargetSource.BuildPhase: JSONDynamicEncodable { +extension TargetSource.BuildPhase: JSONEncodable { public func toJSONValue() -> Any { switch self { case .sources: return "sources" case .headers: return "headers" case .resources: return "resources" - case .copyFiles(let files): return ["copyFiles": files.toJSONDictionary()] + case .copyFiles(let files): return ["copyFiles": files.toJSONValue()] case .none: return "none" case .frameworks: fatalError("invalid build phase") case .runScript: fatalError("invalid build phase") @@ -267,8 +267,8 @@ extension TargetSource.BuildPhase.CopyFilesSettings: JSONObjectConvertible { } } -extension TargetSource.BuildPhase.CopyFilesSettings: JSONDictionaryEncodable { - public func toJSONDictionary() -> JSONDictionary { +extension TargetSource.BuildPhase.CopyFilesSettings: JSONEncodable { + public func toJSONValue() -> Any { return [ "destination": destination.rawValue, "subpath": subpath From 117b90d13f2a6af1792ef207962273c3b100318e Mon Sep 17 00:00:00 2001 From: ryohey Date: Thu, 4 Apr 2019 23:25:47 +0900 Subject: [PATCH 5/8] Don't omit empty arrays https://github.com/yonaskolb/XcodeGen/pull/545#discussion_r271688539 --- Sources/ProjectSpec/AggregateTarget.swift | 25 +++------ Sources/ProjectSpec/BuildScript.swift | 19 +++---- Sources/ProjectSpec/Project.swift | 57 +++++--------------- Sources/ProjectSpec/Scheme.swift | 65 +++++++---------------- Sources/ProjectSpec/Settings.swift | 18 ++----- Sources/ProjectSpec/SpecOptions.swift | 4 +- Sources/ProjectSpec/Target.swift | 39 ++++---------- Sources/ProjectSpec/TargetScheme.swift | 29 +++------- Sources/ProjectSpec/TargetSource.swift | 11 ++-- 9 files changed, 72 insertions(+), 195 deletions(-) diff --git a/Sources/ProjectSpec/AggregateTarget.swift b/Sources/ProjectSpec/AggregateTarget.swift index 3d91ba395..68e23a324 100644 --- a/Sources/ProjectSpec/AggregateTarget.swift +++ b/Sources/ProjectSpec/AggregateTarget.swift @@ -64,25 +64,14 @@ extension AggregateTarget: NamedJSONDictionaryConvertible { extension AggregateTarget: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [:] + var dict: JSONDictionary = [ + "settings": settings.toJSONValue(), + "targets": targets, + "configFiles": configFiles, + "attributes": attributes, + "buildScripts": buildScripts.map { $0.toJSONValue() } + ] - let settingsDict = settings.toJSONValue() - if settingsDict.count > 0 { - dict["settings"] = settingsDict - } - - if targets.count > 0 { - dict["targets"] = targets - } - if configFiles.count > 0 { - dict["configFiles"] = configFiles - } - if attributes.count > 0 { - dict["attributes"] = attributes - } - if buildScripts.count > 0 { - dict["buildScripts"] = buildScripts.map { $0.toJSONValue() } - } if let scheme = scheme { dict["scheme"] = scheme.toJSONValue() } diff --git a/Sources/ProjectSpec/BuildScript.swift b/Sources/ProjectSpec/BuildScript.swift index ed9aada8d..d485ea774 100644 --- a/Sources/ProjectSpec/BuildScript.swift +++ b/Sources/ProjectSpec/BuildScript.swift @@ -63,7 +63,12 @@ extension BuildScript: JSONObjectConvertible { } extension BuildScript: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [:] + var dict: JSONDictionary = [ + "inputFiles": inputFiles, + "inputFileLists": inputFileLists, + "outputFiles": outputFiles, + "outputFileLists": outputFileLists + ] if runOnlyWhenInstalling { dict["runOnlyWhenInstalling"] = runOnlyWhenInstalling @@ -71,18 +76,6 @@ extension BuildScript: JSONEncodable { if !showEnvVars { dict["showEnvVars"] = showEnvVars } - if inputFiles.count > 0 { - dict["inputFiles"] = inputFiles - } - if inputFileLists.count > 0 { - dict["inputFileLists"] = inputFileLists - } - if outputFiles.count > 0 { - dict["outputFiles"] = outputFiles - } - if outputFileLists.count > 0 { - dict["outputFileLists"] = outputFileLists - } if let name = name { dict["name"] = name } diff --git a/Sources/ProjectSpec/Project.swift b/Sources/ProjectSpec/Project.swift index 869ad3e94..2790d0085 100644 --- a/Sources/ProjectSpec/Project.swift +++ b/Sources/ProjectSpec/Project.swift @@ -237,53 +237,24 @@ extension Project: JSONEncodable { } public func toJSONDictionary() -> JSONDictionary { - var dict: JSONDictionary = [ - "name": name, - "options": options.toJSONValue(), - ] - - let settingsDict = settings.toJSONValue() - if settingsDict.count > 0 { - dict["settings"] = settingsDict - } - - if fileGroups.count > 0 { - dict["fileGroups"] = fileGroups - } - if configFiles.count > 0 { - dict["configFiles"] = configFiles - } - if include.count > 0 { - dict["include"] = include - } - if attributes.count > 0 { - dict["attributes"] = attributes - } - let targetPairs = targets.map { ($0.name, $0.toJSONValue()) } - if targetPairs.count > 0 { - dict["targets"] = Dictionary(uniqueKeysWithValues: targetPairs) - } - let configsPairs = configs.map { ($0.name, $0.type?.rawValue) } - if configsPairs.count > 0 { - dict["configs"] = Dictionary(uniqueKeysWithValues: configsPairs) - } - let aggregateTargetsPairs = aggregateTargets.map { ($0.name, $0.toJSONValue()) } - if aggregateTargetsPairs.count > 0 { - dict["aggregateTargets"] = Dictionary(uniqueKeysWithValues: aggregateTargetsPairs) - } - let schemesPairs = schemes.map { ($0.name, $0.toJSONValue()) } - if schemesPairs.count > 0 { - dict["schemes"] = Dictionary(uniqueKeysWithValues: schemesPairs) - } - if settingGroups.count > 0 { - dict["settingGroups"] = settingGroups.mapValues { $0.toJSONValue() } - } - - return dict + return [ + "name": name, + "options": options.toJSONValue(), + "settings": settings.toJSONValue(), + "fileGroups": fileGroups, + "configFiles": configFiles, + "include": include, + "attributes": attributes, + "targets": Dictionary(uniqueKeysWithValues: targetPairs), + "configs": Dictionary(uniqueKeysWithValues: configsPairs), + "aggregateTargets": Dictionary(uniqueKeysWithValues: aggregateTargetsPairs), + "schemes": Dictionary(uniqueKeysWithValues: schemesPairs), + "settingGroups": settingGroups.mapValues { $0.toJSONValue() } + ] } } diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 25eb51da1..1f497931c 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -248,17 +248,11 @@ extension Scheme.Run: JSONEncodable { public func toJSONValue() -> Any { var dict: JSONDictionary = [ "commandLineArguments": commandLineArguments, + "preActions": preActions.map { $0.toJSONValue() }, + "postActions": postActions.map { $0.toJSONValue() }, + "environmentVariables": environmentVariables.map { $0.toJSONValue() }, ] - if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONValue() } - } - if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONValue() } - } - if environmentVariables.count > 0 { - dict["environmentVariables"] = environmentVariables.map { $0.toJSONValue() } - } if let config = config { dict["config"] = config } @@ -296,23 +290,13 @@ extension Scheme.Test: JSONEncodable { public func toJSONValue() -> Any { var dict: JSONDictionary = [ "gatherCoverageData": gatherCoverageData, + "commandLineArguments": commandLineArguments, + "targets": targets.map { $0.toJSONValue() }, + "preActions": preActions.map { $0.toJSONValue() }, + "postActions": postActions.map { $0.toJSONValue() }, + "environmentVariables": environmentVariables.map { $0.toJSONValue() }, ] - - if commandLineArguments.count > 0 { - dict["commandLineArguments"] = commandLineArguments - } - if targets.count > 0 { - dict["targets"] = targets.map { $0.toJSONValue() } - } - if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONValue() } - } - if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONValue() } - } - if environmentVariables.count > 0 { - dict["environmentVariables"] = environmentVariables.map { $0.toJSONValue() } - } + if let config = config { dict["config"] = config } @@ -366,17 +350,11 @@ extension Scheme.Profile: JSONEncodable { public func toJSONValue() -> Any { var dict: JSONDictionary = [ "commandLineArguments": commandLineArguments, + "preActions": preActions.map { $0.toJSONValue() }, + "postActions": postActions.map { $0.toJSONValue() }, + "environmentVariables": environmentVariables.map { $0.toJSONValue() }, ] - if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONValue() } - } - if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONValue() } - } - if environmentVariables.count > 0 { - dict["environmentVariables"] = environmentVariables.map { $0.toJSONValue() } - } if let config = config { dict["config"] = config } @@ -417,17 +395,14 @@ extension Scheme.Archive: JSONObjectConvertible { extension Scheme.Archive: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [:] + var dict: JSONDictionary = [ + "preActions": preActions.map { $0.toJSONValue() }, + "postActions": postActions.map { $0.toJSONValue() } + ] if !revealArchiveInOrganizer { dict["revealArchiveInOrganizer"] = revealArchiveInOrganizer } - if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONValue() } - } - if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONValue() } - } if let config = config { dict["config"] = config } @@ -516,6 +491,8 @@ extension Scheme.Build: JSONEncodable { var dict: JSONDictionary = [ "targets": Dictionary(uniqueKeysWithValues: targetPairs), + "preActions": preActions.map { $0.toJSONValue() }, + "postActions": postActions.map { $0.toJSONValue() }, ] if !parallelizeBuild { @@ -524,12 +501,6 @@ extension Scheme.Build: JSONEncodable { if !buildImplicitDependencies { dict["buildImplicitDependencies"] = buildImplicitDependencies } - if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONValue() } - } - if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONValue() } - } return dict } diff --git a/Sources/ProjectSpec/Settings.swift b/Sources/ProjectSpec/Settings.swift index b60268e87..c223ab9fa 100644 --- a/Sources/ProjectSpec/Settings.swift +++ b/Sources/ProjectSpec/Settings.swift @@ -109,19 +109,11 @@ public func += (lhs: inout BuildSettings, rhs: BuildSettings?) { extension Settings: JSONEncodable { public func toJSONValue() -> Any { if groups.count > 0 || configSettings.count > 0 { - var dict: JSONDictionary = [:] - - if buildSettings.count > 0 { - dict["base"] = buildSettings - } - if groups.count > 0 { - dict["groups"] = groups - } - if configSettings.count > 0 { - dict["configs"] = configSettings.mapValues { $0.toJSONValue() } - } - - return dict + return [ + "base": buildSettings, + "groups": groups, + "configs": configSettings.mapValues { $0.toJSONValue() } + ] } return buildSettings } diff --git a/Sources/ProjectSpec/SpecOptions.swift b/Sources/ProjectSpec/SpecOptions.swift index ce2f2e991..e84716503 100644 --- a/Sources/ProjectSpec/SpecOptions.swift +++ b/Sources/ProjectSpec/SpecOptions.swift @@ -132,6 +132,7 @@ extension SpecOptions: JSONEncodable { "deploymentTarget": deploymentTarget.toJSONValue(), "transitivelyLinkDependencies": transitivelyLinkDependencies, "groupSortPosition": groupSortPosition.rawValue, + "disabledValidations": disabledValidations.map { $0.rawValue }, ] if settingPresets != .all { @@ -146,9 +147,6 @@ extension SpecOptions: JSONEncodable { if findCarthageFrameworks { dict["findCarthageFrameworks"] = findCarthageFrameworks } - if disabledValidations.count > 0 { - dict["disabledValidations"] = disabledValidations.map { $0.rawValue } - } if let minimumXcodeGenVersion = minimumXcodeGenVersion { dict["minimumXcodeGenVersion"] = minimumXcodeGenVersion.string } diff --git a/Sources/ProjectSpec/Target.swift b/Sources/ProjectSpec/Target.swift index 20c272bc6..e2a9f00e2 100644 --- a/Sources/ProjectSpec/Target.swift +++ b/Sources/ProjectSpec/Target.swift @@ -367,40 +367,21 @@ extension Target: JSONEncodable { var dict: JSONDictionary = [ "type": type.name, "platform": platform.rawValue, + "settings": settings.toJSONValue(), + "configFiles": configFiles, + "attributes": attributes, + "sources": sources.map { $0.toJSONValue() }, + "dependencies": dependencies.map { $0.toJSONValue() }, + "postCompileScripts": postCompileScripts.map{ $0.toJSONValue() }, + "prebuildScripts": preBuildScripts.map{ $0.toJSONValue() }, + "postbuildScripts": postBuildScripts.map{ $0.toJSONValue() }, + "buildRules": buildRules.map{ $0.toJSONValue() } ] - let settingsDict = settings.toJSONValue() - if settingsDict.count > 0 { - dict["settings"] = settingsDict - } - if productName != name { dict["productName"] = productName } - if configFiles.count > 0 { - dict["configFiles"] = configFiles - } - if attributes.count > 0 { - dict["attributes"] = attributes - } - if sources.count > 0 { - dict["sources"] = sources.map { $0.toJSONValue() } - } - if dependencies.count > 0 { - dict["dependencies"] = dependencies.map { $0.toJSONValue() } - } - if postCompileScripts.count > 0 { - dict["postCompileScripts"] = postCompileScripts.map{ $0.toJSONValue() } - } - if preBuildScripts.count > 0 { - dict["prebuildScripts"] = preBuildScripts.map{ $0.toJSONValue() } - } - if postBuildScripts.count > 0 { - dict["postbuildScripts"] = postBuildScripts.map{ $0.toJSONValue() } - } - if buildRules.count > 0 { - dict["buildRules"] = buildRules.map{ $0.toJSONValue() } - } + if let deploymentTarget = deploymentTarget { dict["deploymentTarget"] = deploymentTarget.deploymentTarget } diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 6878bf58b..5f906fb31 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -57,29 +57,14 @@ extension TargetScheme: JSONObjectConvertible { extension TargetScheme: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + return [ "gatherCoverageData": gatherCoverageData, + "configVariants": configVariants, + "commandLineArguments": commandLineArguments, + "testTargets": testTargets.map { $0.toJSONValue() }, + "environmentVariables": environmentVariables.map { $0.toJSONValue() }, + "preActions": preActions.map { $0.toJSONValue() }, + "postActions": postActions.map { $0.toJSONValue() }, ] - - if configVariants.count > 0 { - dict["configVariants"] = configVariants - } - if commandLineArguments.count > 0 { - dict["commandLineArguments"] = commandLineArguments - } - if testTargets.count > 0 { - dict["testTargets"] = testTargets.map { $0.toJSONValue() } - } - if environmentVariables.count > 0 { - dict["environmentVariables"] = environmentVariables.map { $0.toJSONValue() } - } - if preActions.count > 0 { - dict["preActions"] = preActions.map { $0.toJSONValue() } - } - if postActions.count > 0 { - dict["postActions"] = postActions.map { $0.toJSONValue() } - } - - return dict } } diff --git a/Sources/ProjectSpec/TargetSource.swift b/Sources/ProjectSpec/TargetSource.swift index a68ed31be..b89645138 100644 --- a/Sources/ProjectSpec/TargetSource.swift +++ b/Sources/ProjectSpec/TargetSource.swift @@ -183,14 +183,11 @@ extension TargetSource: JSONObjectConvertible { extension TargetSource: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [:] + var dict: JSONDictionary = [ + "compilerFlags": compilerFlags, + "excludes": excludes, + ] - if compilerFlags.count > 0 { - dict["compilerFlags"] = compilerFlags - } - if excludes.count > 0 { - dict["excludes"] = excludes - } if let name = name { dict["name"] = name } From d5649a1bd31a5de484e9b521dbbcf45effe3dd2d Mon Sep 17 00:00:00 2001 From: ryohey Date: Thu, 4 Apr 2019 23:42:06 +0900 Subject: [PATCH 6/8] Allow nil values --- Sources/ProjectSpec/AggregateTarget.swift | 13 +-- Sources/ProjectSpec/BuildRule.swift | 7 +- Sources/ProjectSpec/BuildScript.swift | 16 ++-- Sources/ProjectSpec/Dependency.swift | 15 ++-- Sources/ProjectSpec/DeploymentTarget.swift | 22 ++--- Sources/ProjectSpec/Encoding.swift | 2 +- Sources/ProjectSpec/Scheme.swift | 93 ++++++---------------- Sources/ProjectSpec/SpecOptions.swift | 42 +++------- Sources/ProjectSpec/Target.swift | 52 ++++-------- Sources/ProjectSpec/TargetSource.swift | 22 ++--- 10 files changed, 80 insertions(+), 204 deletions(-) diff --git a/Sources/ProjectSpec/AggregateTarget.swift b/Sources/ProjectSpec/AggregateTarget.swift index 68e23a324..d861958ff 100644 --- a/Sources/ProjectSpec/AggregateTarget.swift +++ b/Sources/ProjectSpec/AggregateTarget.swift @@ -64,19 +64,14 @@ extension AggregateTarget: NamedJSONDictionaryConvertible { extension AggregateTarget: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + return [ "settings": settings.toJSONValue(), "targets": targets, "configFiles": configFiles, "attributes": attributes, - "buildScripts": buildScripts.map { $0.toJSONValue() } - ] - - if let scheme = scheme { - dict["scheme"] = scheme.toJSONValue() - } - - return dict + "buildScripts": buildScripts.map { $0.toJSONValue() }, + "scheme": scheme?.toJSONValue() + ] as [String: Any?] } } diff --git a/Sources/ProjectSpec/BuildRule.swift b/Sources/ProjectSpec/BuildRule.swift index 9c4e3cea3..3f75e75fd 100644 --- a/Sources/ProjectSpec/BuildRule.swift +++ b/Sources/ProjectSpec/BuildRule.swift @@ -83,15 +83,12 @@ extension BuildRule: JSONObjectConvertible { extension BuildRule: JSONEncodable { public func toJSONValue() -> Any { - var dict: [String: Any] = [ + var dict: [String: Any?] = [ "outputFiles": outputFiles, "outputFilesCompilerFlags": outputFilesCompilerFlags, + "name": name ] - if let name = name { - dict["name"] = name - } - switch fileType { case .pattern(let string): dict["filePattern"] = string diff --git a/Sources/ProjectSpec/BuildScript.swift b/Sources/ProjectSpec/BuildScript.swift index d485ea774..14cfce0d2 100644 --- a/Sources/ProjectSpec/BuildScript.swift +++ b/Sources/ProjectSpec/BuildScript.swift @@ -63,25 +63,19 @@ extension BuildScript: JSONObjectConvertible { } extension BuildScript: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + var dict: [String: Any?] = [ "inputFiles": inputFiles, "inputFileLists": inputFileLists, "outputFiles": outputFiles, - "outputFileLists": outputFileLists + "outputFileLists": outputFileLists, + "runOnlyWhenInstalling": runOnlyWhenInstalling, + "name": name, + "shell": shell ] - if runOnlyWhenInstalling { - dict["runOnlyWhenInstalling"] = runOnlyWhenInstalling - } if !showEnvVars { dict["showEnvVars"] = showEnvVars } - if let name = name { - dict["name"] = name - } - if let shell = shell { - dict["shell"] = shell - } switch script { case .path(let string): diff --git a/Sources/ProjectSpec/Dependency.swift b/Sources/ProjectSpec/Dependency.swift index 6ea575b6a..121fff2d3 100644 --- a/Sources/ProjectSpec/Dependency.swift +++ b/Sources/ProjectSpec/Dependency.swift @@ -83,7 +83,11 @@ extension Dependency: JSONObjectConvertible { extension Dependency: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [:] + var dict: [String: Any?] = [ + "embed": embed, + "codeSign": codeSign, + "link": link + ] if !removeHeaders { dict["removeHeaders"] = removeHeaders @@ -94,15 +98,6 @@ extension Dependency: JSONEncodable { if weakLink { dict["weak"] = weakLink } - if let embed = embed { - dict["embed"] = embed - } - if let codeSign = codeSign { - dict["codeSign"] = codeSign - } - if let link = link { - dict["link"] = link - } switch type { case .target: diff --git a/Sources/ProjectSpec/DeploymentTarget.swift b/Sources/ProjectSpec/DeploymentTarget.swift index 0968cfeee..7cba891a7 100644 --- a/Sources/ProjectSpec/DeploymentTarget.swift +++ b/Sources/ProjectSpec/DeploymentTarget.swift @@ -81,21 +81,11 @@ extension DeploymentTarget: JSONObjectConvertible { extension DeploymentTarget: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [:] - - if let iOS = iOS { - dict["iOS"] = iOS.string - } - if let tvOS = tvOS { - dict["tvOS"] = tvOS.string - } - if let watchOS = watchOS { - dict["watchOS"] = watchOS.string - } - if let macOS = macOS { - dict["macOS"] = macOS.string - } - - return dict + return [ + "iOS": iOS?.string, + "tvOS": tvOS?.string, + "watchOS": watchOS?.string, + "macOS": macOS?.string, + ] } } diff --git a/Sources/ProjectSpec/Encoding.swift b/Sources/ProjectSpec/Encoding.swift index 46e1ad52e..6934f0b2d 100644 --- a/Sources/ProjectSpec/Encoding.swift +++ b/Sources/ProjectSpec/Encoding.swift @@ -2,6 +2,6 @@ import Foundation import JSONUtilities public protocol JSONEncodable { - // returns JSONDictionary or JSONArray or JSONRawType + // returns JSONDictionary or JSONArray or JSONRawType or nil func toJSONValue() -> Any } diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 1f497931c..67c8ffba5 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -220,16 +220,11 @@ extension Scheme.ExecutionAction: JSONObjectConvertible { extension Scheme.ExecutionAction: JSONEncodable { public func toJSONValue() -> Any { - var dict = [ + return [ "script": script, "name": name, + "settingsTarget": settingsTarget ] - - if let settingsTarget = settingsTarget { - dict["settingsTarget"] = settingsTarget - } - - return dict } } @@ -246,18 +241,13 @@ extension Scheme.Run: JSONObjectConvertible { extension Scheme.Run: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + return [ "commandLineArguments": commandLineArguments, "preActions": preActions.map { $0.toJSONValue() }, "postActions": postActions.map { $0.toJSONValue() }, "environmentVariables": environmentVariables.map { $0.toJSONValue() }, - ] - - if let config = config { - dict["config"] = config - } - - return dict + "config": config + ] as [String: Any?] } } @@ -288,20 +278,15 @@ extension Scheme.Test: JSONObjectConvertible { extension Scheme.Test: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + return [ "gatherCoverageData": gatherCoverageData, "commandLineArguments": commandLineArguments, "targets": targets.map { $0.toJSONValue() }, "preActions": preActions.map { $0.toJSONValue() }, "postActions": postActions.map { $0.toJSONValue() }, "environmentVariables": environmentVariables.map { $0.toJSONValue() }, - ] - - if let config = config { - dict["config"] = config - } - - return dict + "config": config + ] as [String: Any?] } } @@ -348,18 +333,13 @@ extension Scheme.Profile: JSONObjectConvertible { extension Scheme.Profile: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + return [ "commandLineArguments": commandLineArguments, "preActions": preActions.map { $0.toJSONValue() }, "postActions": postActions.map { $0.toJSONValue() }, "environmentVariables": environmentVariables.map { $0.toJSONValue() }, - ] - - if let config = config { - dict["config"] = config - } - - return dict + "config": config + ] as [String: Any?] } } @@ -372,13 +352,9 @@ extension Scheme.Analyze: JSONObjectConvertible { extension Scheme.Analyze: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [:] - - if let config = config { - dict["config"] = config - } - - return dict + return [ + "config": config + ] } } @@ -395,20 +371,16 @@ extension Scheme.Archive: JSONObjectConvertible { extension Scheme.Archive: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + var dict: [String: Any?] = [ "preActions": preActions.map { $0.toJSONValue() }, - "postActions": postActions.map { $0.toJSONValue() } + "postActions": postActions.map { $0.toJSONValue() }, + "config": config, + "customArchiveName": customArchiveName, ] if !revealArchiveInOrganizer { dict["revealArchiveInOrganizer"] = revealArchiveInOrganizer } - if let config = config { - dict["config"] = config - } - if let customArchiveName = customArchiveName { - dict["customArchiveName"] = customArchiveName - } return dict } @@ -429,27 +401,14 @@ extension Scheme: NamedJSONDictionaryConvertible { extension Scheme: JSONEncodable { public func toJSONValue() -> Any { - var dict = [ - "build": build.toJSONValue() - ] - - if let run = run { - dict["run"] = run.toJSONValue() - } - if let test = test { - dict["test"] = test.toJSONValue() - } - if let analyze = analyze { - dict["analyze"] = analyze.toJSONValue() - } - if let profile = profile { - dict["profile"] = profile.toJSONValue() - } - if let archive = archive { - dict["archive"] = archive.toJSONValue() - } - - return dict + return [ + "build": build.toJSONValue(), + "run": run?.toJSONValue(), + "test": test?.toJSONValue(), + "analyze": analyze?.toJSONValue(), + "profile": profile?.toJSONValue(), + "archive": archive?.toJSONValue(), + ] as [String: Any?] } } diff --git a/Sources/ProjectSpec/SpecOptions.swift b/Sources/ProjectSpec/SpecOptions.swift index e84716503..020b04949 100644 --- a/Sources/ProjectSpec/SpecOptions.swift +++ b/Sources/ProjectSpec/SpecOptions.swift @@ -128,11 +128,21 @@ extension SpecOptions: JSONObjectConvertible { extension SpecOptions: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + var dict: [String: Any?] = [ "deploymentTarget": deploymentTarget.toJSONValue(), "transitivelyLinkDependencies": transitivelyLinkDependencies, "groupSortPosition": groupSortPosition.rawValue, "disabledValidations": disabledValidations.map { $0.rawValue }, + "minimumXcodeGenVersion": minimumXcodeGenVersion?.string, + "carthageBuildPath": carthageBuildPath, + "carthageExecutablePath": carthageExecutablePath, + "bundleIdPrefix": bundleIdPrefix, + "developmentLanguage": developmentLanguage, + "usesTabs": usesTabs, + "xcodeVersion": xcodeVersion, + "indentWidth": indentWidth.flatMap { Int($0) }, + "tabWidth": tabWidth.flatMap { Int($0) }, + "defaultConfig": defaultConfig, ] if settingPresets != .all { @@ -147,36 +157,6 @@ extension SpecOptions: JSONEncodable { if findCarthageFrameworks { dict["findCarthageFrameworks"] = findCarthageFrameworks } - if let minimumXcodeGenVersion = minimumXcodeGenVersion { - dict["minimumXcodeGenVersion"] = minimumXcodeGenVersion.string - } - if let carthageBuildPath = carthageBuildPath { - dict["carthageBuildPath"] = carthageBuildPath - } - if let carthageExecutablePath = carthageExecutablePath { - dict["carthageExecutablePath"] = carthageExecutablePath - } - if let bundleIdPrefix = bundleIdPrefix { - dict["bundleIdPrefix"] = bundleIdPrefix - } - if let developmentLanguage = developmentLanguage { - dict["developmentLanguage"] = developmentLanguage - } - if let usesTabs = usesTabs { - dict["usesTabs"] = usesTabs - } - if let xcodeVersion = xcodeVersion { - dict["xcodeVersion"] = xcodeVersion - } - if let indentWidth = indentWidth { - dict["indentWidth"] = Int(indentWidth) - } - if let tabWidth = tabWidth { - dict["tabWidth"] = Int(tabWidth) - } - if let defaultConfig = defaultConfig { - dict["defaultConfig"] = defaultConfig - } return dict } diff --git a/Sources/ProjectSpec/Target.swift b/Sources/ProjectSpec/Target.swift index e2a9f00e2..c529c554c 100644 --- a/Sources/ProjectSpec/Target.swift +++ b/Sources/ProjectSpec/Target.swift @@ -274,19 +274,12 @@ extension LegacyTarget: JSONObjectConvertible { extension LegacyTarget: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + return [ "toolPath": toolPath, "passSettings": passSettings, - ] - - if let arguments = arguments { - dict["arguments"] = arguments - } - if let workingDirectory = workingDirectory { - dict["workingDirectory"] = workingDirectory - } - - return dict + "arguments": arguments, + "workingDirectory": workingDirectory, + ] as [String: Any?] } } @@ -364,7 +357,7 @@ extension Target: NamedJSONDictionaryConvertible { extension Target: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + var dict: [String: Any?] = [ "type": type.name, "platform": platform.rawValue, "settings": settings.toJSONValue(), @@ -375,38 +368,21 @@ extension Target: JSONEncodable { "postCompileScripts": postCompileScripts.map{ $0.toJSONValue() }, "prebuildScripts": preBuildScripts.map{ $0.toJSONValue() }, "postbuildScripts": postBuildScripts.map{ $0.toJSONValue() }, - "buildRules": buildRules.map{ $0.toJSONValue() } + "buildRules": buildRules.map{ $0.toJSONValue() }, + "deploymentTarget": deploymentTarget?.deploymentTarget, + "info": info?.toJSONValue(), + "entitlements": entitlements?.toJSONValue(), + "transitivelyLinkDependencies": transitivelyLinkDependencies, + "directlyEmbedCarthageDependencies": directlyEmbedCarthageDependencies, + "requiresObjCLinking": requiresObjCLinking, + "scheme": scheme?.toJSONValue(), + "legacy": legacy?.toJSONValue(), ] if productName != name { dict["productName"] = productName } - if let deploymentTarget = deploymentTarget { - dict["deploymentTarget"] = deploymentTarget.deploymentTarget - } - if let info = info { - dict["info"] = info.toJSONValue() - } - if let entitlements = entitlements { - dict["entitlements"] = entitlements.toJSONValue() - } - if let transitivelyLinkDependencies = transitivelyLinkDependencies { - dict["transitivelyLinkDependencies"] = transitivelyLinkDependencies - } - if let directlyEmbedCarthageDependencies = directlyEmbedCarthageDependencies { - dict["directlyEmbedCarthageDependencies"] = directlyEmbedCarthageDependencies - } - if let requiresObjCLinking = requiresObjCLinking { - dict["requiresObjCLinking"] = requiresObjCLinking - } - if let scheme = scheme { - dict["scheme"] = scheme.toJSONValue() - } - if let legacy = legacy { - dict["legacy"] = legacy.toJSONValue() - } - return dict } } diff --git a/Sources/ProjectSpec/TargetSource.swift b/Sources/ProjectSpec/TargetSource.swift index b89645138..8669094ab 100644 --- a/Sources/ProjectSpec/TargetSource.swift +++ b/Sources/ProjectSpec/TargetSource.swift @@ -183,26 +183,16 @@ extension TargetSource: JSONObjectConvertible { extension TargetSource: JSONEncodable { public func toJSONValue() -> Any { - var dict: JSONDictionary = [ + var dict: [String: Any?] = [ "compilerFlags": compilerFlags, "excludes": excludes, + "name": name, + "headerVisibility": headerVisibility?.rawValue, + "type": type?.rawValue, + "buildPhase": buildPhase?.toJSONValue(), + "createIntermediateGroups": createIntermediateGroups, ] - if let name = name { - dict["name"] = name - } - if let headerVisibility = headerVisibility { - dict["headerVisibility"] = headerVisibility.rawValue - } - if let type = type { - dict["type"] = type.rawValue - } - if let buildPhase = buildPhase { - dict["buildPhase"] = buildPhase.toJSONValue() - } - if let createIntermediateGroups = createIntermediateGroups { - dict["createIntermediateGroups"] = createIntermediateGroups - } if optional { dict["optional"] = true } From 65dec6b65242d1f14f856dcf7adadb107c5ed58d Mon Sep 17 00:00:00 2001 From: ryohey Date: Mon, 15 Apr 2019 00:29:12 +0900 Subject: [PATCH 7/8] Define default property values --- Sources/ProjectSpec/BuildScript.swift | 12 ++--- Sources/ProjectSpec/Dependency.swift | 19 ++++---- Sources/ProjectSpec/Scheme.swift | 62 ++++++++++++++++---------- Sources/ProjectSpec/SpecOptions.swift | 38 +++++++++------- Sources/ProjectSpec/Target.swift | 17 ++++--- Sources/ProjectSpec/TargetScheme.swift | 15 +++++-- Sources/ProjectSpec/TargetSource.swift | 9 ++-- 7 files changed, 107 insertions(+), 65 deletions(-) diff --git a/Sources/ProjectSpec/BuildScript.swift b/Sources/ProjectSpec/BuildScript.swift index 14cfce0d2..f1eaf33a5 100644 --- a/Sources/ProjectSpec/BuildScript.swift +++ b/Sources/ProjectSpec/BuildScript.swift @@ -2,6 +2,8 @@ import Foundation import JSONUtilities public struct BuildScript: Equatable { + public static let runOnlyWhenInstallingDefault = false + public static let showEnvVarsDefault = true public var script: ScriptType public var name: String? @@ -26,8 +28,8 @@ public struct BuildScript: Equatable { inputFileLists: [String] = [], outputFileLists: [String] = [], shell: String? = nil, - runOnlyWhenInstalling: Bool = false, - showEnvVars: Bool = true + runOnlyWhenInstalling: Bool = runOnlyWhenInstallingDefault, + showEnvVars: Bool = showEnvVarsDefault ) { self.script = script self.name = name @@ -57,8 +59,8 @@ extension BuildScript: JSONObjectConvertible { script = .path(path) } shell = jsonDictionary.json(atKeyPath: "shell") - runOnlyWhenInstalling = jsonDictionary.json(atKeyPath: "runOnlyWhenInstalling") ?? false - showEnvVars = jsonDictionary.json(atKeyPath: "showEnvVars") ?? true + runOnlyWhenInstalling = jsonDictionary.json(atKeyPath: "runOnlyWhenInstalling") ?? BuildScript.runOnlyWhenInstallingDefault + showEnvVars = jsonDictionary.json(atKeyPath: "showEnvVars") ?? BuildScript.showEnvVarsDefault } } extension BuildScript: JSONEncodable { @@ -73,7 +75,7 @@ extension BuildScript: JSONEncodable { "shell": shell ] - if !showEnvVars { + if showEnvVars != BuildScript.showEnvVarsDefault { dict["showEnvVars"] = showEnvVars } diff --git a/Sources/ProjectSpec/Dependency.swift b/Sources/ProjectSpec/Dependency.swift index 121fff2d3..8da36e6d6 100644 --- a/Sources/ProjectSpec/Dependency.swift +++ b/Sources/ProjectSpec/Dependency.swift @@ -2,15 +2,18 @@ import Foundation import JSONUtilities public struct Dependency: Equatable { + public static let removeHeadersDefault = true + public static let implicitDefault = false + public static let weakLinkDefault = false public var type: DependencyType public var reference: String public var embed: Bool? public var codeSign: Bool? - public var removeHeaders: Bool = true + public var removeHeaders: Bool = removeHeadersDefault public var link: Bool? - public var implicit: Bool = false - public var weakLink: Bool = false + public var implicit: Bool = implicitDefault + public var weakLink: Bool = weakLinkDefault public init( type: DependencyType, @@ -18,8 +21,8 @@ public struct Dependency: Equatable { embed: Bool? = nil, codeSign: Bool? = nil, link: Bool? = nil, - implicit: Bool = false, - weakLink: Bool = false + implicit: Bool = implicitDefault, + weakLink: Bool = weakLinkDefault ) { self.type = type self.reference = reference @@ -89,13 +92,13 @@ extension Dependency: JSONEncodable { "link": link ] - if !removeHeaders { + if removeHeaders != Dependency.removeHeadersDefault { dict["removeHeaders"] = removeHeaders } - if implicit { + if implicit != Dependency.implicitDefault { dict["implicit"] = implicit } - if weakLink { + if weakLink != Dependency.weakLinkDefault { dict["weak"] = weakLink } diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 67c8ffba5..58e6c56c9 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -44,6 +44,9 @@ public struct Scheme: Equatable { } public struct Build: Equatable { + public static let parallelizeBuildDefault = true + public static let buildImplicitDependenciesDefault = true + public var targets: [BuildTarget] public var parallelizeBuild: Bool public var buildImplicitDependencies: Bool @@ -51,8 +54,8 @@ public struct Scheme: Equatable { public var postActions: [ExecutionAction] public init( targets: [BuildTarget], - parallelizeBuild: Bool = true, - buildImplicitDependencies: Bool = true, + parallelizeBuild: Bool = parallelizeBuildDefault, + buildImplicitDependencies: Bool = buildImplicitDependenciesDefault, preActions: [ExecutionAction] = [], postActions: [ExecutionAction] = [] ) { @@ -86,6 +89,8 @@ public struct Scheme: Equatable { } public struct Test: BuildAction { + public static let gatherCoverageDataDefault = false + public var config: String? public var gatherCoverageData: Bool public var commandLineArguments: [String: Bool] @@ -95,14 +100,17 @@ public struct Scheme: Equatable { public var environmentVariables: [XCScheme.EnvironmentVariable] public struct TestTarget: Equatable, ExpressibleByStringLiteral { + public static let randomExecutionOrderDefault = false + public static let parallelizableDefault = false + public let name: String public var randomExecutionOrder: Bool public var parallelizable: Bool public init( name: String, - randomExecutionOrder: Bool = false, - parallelizable: Bool = false + randomExecutionOrder: Bool = randomExecutionOrderDefault, + parallelizable: Bool = parallelizableDefault ) { self.name = name self.randomExecutionOrder = randomExecutionOrder @@ -118,7 +126,7 @@ public struct Scheme: Equatable { public init( config: String, - gatherCoverageData: Bool = false, + gatherCoverageData: Bool = gatherCoverageDataDefault, randomExecutionOrder: Bool = false, parallelizable: Bool = false, commandLineArguments: [String: Bool] = [:], @@ -174,6 +182,8 @@ public struct Scheme: Equatable { } public struct Archive: BuildAction { + public static let revealArchiveInOrganizerDefault = true + public var config: String? public var customArchiveName: String? public var revealArchiveInOrganizer: Bool @@ -182,7 +192,7 @@ public struct Scheme: Equatable { public init( config: String, customArchiveName: String? = nil, - revealArchiveInOrganizer: Bool = true, + revealArchiveInOrganizer: Bool = revealArchiveInOrganizerDefault, preActions: [ExecutionAction] = [], postActions: [ExecutionAction] = [] ) { @@ -255,7 +265,7 @@ extension Scheme.Test: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { config = jsonDictionary.json(atKeyPath: "config") - gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? false + gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? Scheme.Test.gatherCoverageDataDefault commandLineArguments = jsonDictionary.json(atKeyPath: "commandLineArguments") ?? [:] if let targets = jsonDictionary["targets"] as? [Any] { self.targets = try targets.compactMap { target in @@ -294,8 +304,8 @@ extension Scheme.Test.TestTarget: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { name = try jsonDictionary.json(atKeyPath: "name") - randomExecutionOrder = jsonDictionary.json(atKeyPath: "randomExecutionOrder") ?? false - parallelizable = jsonDictionary.json(atKeyPath: "parallelizable") ?? false + randomExecutionOrder = jsonDictionary.json(atKeyPath: "randomExecutionOrder") ?? Scheme.Test.TestTarget.randomExecutionOrderDefault + parallelizable = jsonDictionary.json(atKeyPath: "parallelizable") ?? Scheme.Test.TestTarget.parallelizableDefault } } @@ -309,11 +319,11 @@ extension Scheme.Test.TestTarget: JSONEncodable { "name": name ] - if randomExecutionOrder { - dict["randomExecutionOrder"] = true + if randomExecutionOrder != Scheme.Test.TestTarget.randomExecutionOrderDefault { + dict["randomExecutionOrder"] = randomExecutionOrder } - if parallelizable { - dict["parallelizable"] = true + if parallelizable != Scheme.Test.TestTarget.parallelizableDefault { + dict["parallelizable"] = parallelizable } return dict @@ -363,7 +373,7 @@ extension Scheme.Archive: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { config = jsonDictionary.json(atKeyPath: "config") customArchiveName = jsonDictionary.json(atKeyPath: "customArchiveName") - revealArchiveInOrganizer = jsonDictionary.json(atKeyPath: "revealArchiveInOrganizer") ?? true + revealArchiveInOrganizer = jsonDictionary.json(atKeyPath: "revealArchiveInOrganizer") ?? Scheme.Archive.revealArchiveInOrganizerDefault preActions = jsonDictionary.json(atKeyPath: "preActions") ?? [] postActions = jsonDictionary.json(atKeyPath: "postActions") ?? [] } @@ -378,7 +388,7 @@ extension Scheme.Archive: JSONEncodable { "customArchiveName": customArchiveName, ] - if !revealArchiveInOrganizer { + if revealArchiveInOrganizer != Scheme.Archive.revealArchiveInOrganizerDefault { dict["revealArchiveInOrganizer"] = revealArchiveInOrganizer } @@ -439,8 +449,8 @@ extension Scheme.Build: JSONObjectConvertible { self.targets = targets.sorted { $0.target < $1.target } preActions = try jsonDictionary.json(atKeyPath: "preActions")?.map(Scheme.ExecutionAction.init) ?? [] postActions = try jsonDictionary.json(atKeyPath: "postActions")?.map(Scheme.ExecutionAction.init) ?? [] - parallelizeBuild = jsonDictionary.json(atKeyPath: "parallelizeBuild") ?? true - buildImplicitDependencies = jsonDictionary.json(atKeyPath: "buildImplicitDependencies") ?? true + parallelizeBuild = jsonDictionary.json(atKeyPath: "parallelizeBuild") ?? Scheme.Build.parallelizeBuildDefault + buildImplicitDependencies = jsonDictionary.json(atKeyPath: "buildImplicitDependencies") ?? Scheme.Build.buildImplicitDependenciesDefault } } @@ -454,10 +464,10 @@ extension Scheme.Build: JSONEncodable { "postActions": postActions.map { $0.toJSONValue() }, ] - if !parallelizeBuild { + if parallelizeBuild != Scheme.Build.parallelizeBuildDefault { dict["parallelizeBuild"] = parallelizeBuild } - if !buildImplicitDependencies { + if buildImplicitDependencies != Scheme.Build.buildImplicitDependenciesDefault { dict["buildImplicitDependencies"] = buildImplicitDependencies } @@ -498,6 +508,7 @@ extension BuildType: JSONEncodable { } extension XCScheme.EnvironmentVariable: JSONObjectConvertible { + public static let enabledDefault = true private static func parseValue(_ value: Any) -> String { if let bool = value as? Bool { @@ -517,7 +528,7 @@ extension XCScheme.EnvironmentVariable: JSONObjectConvertible { value = try jsonDictionary.json(atKeyPath: "value") } let variable: String = try jsonDictionary.json(atKeyPath: "variable") - let enabled: Bool = jsonDictionary.json(atKeyPath: "isEnabled") ?? true + let enabled: Bool = jsonDictionary.json(atKeyPath: "isEnabled") ?? XCScheme.EnvironmentVariable.enabledDefault self.init(variable: variable, value: value, enabled: enabled) } @@ -536,10 +547,15 @@ extension XCScheme.EnvironmentVariable: JSONObjectConvertible { extension XCScheme.EnvironmentVariable: JSONEncodable { public func toJSONValue() -> Any { - return [ + var dict: [String: Any] = [ "variable": variable, - "value": value, - "isEnabled": enabled + "value": value ] + + if enabled != XCScheme.EnvironmentVariable.enabledDefault { + dict["isEnabled"] = enabled + } + + return dict } } diff --git a/Sources/ProjectSpec/SpecOptions.swift b/Sources/ProjectSpec/SpecOptions.swift index 020b04949..fc55641ed 100644 --- a/Sources/ProjectSpec/SpecOptions.swift +++ b/Sources/ProjectSpec/SpecOptions.swift @@ -2,6 +2,12 @@ import Foundation import JSONUtilities public struct SpecOptions: Equatable { + public static let settingPresetsDefault = SettingPresets.all + public static let createIntermediateGroupsDefault = false + public static let transitivelyLinkDependenciesDefault = false + public static let groupSortPositionDefault = GroupSortPosition.bottom + public static let generateEmptyDirectoriesDefault = false + public static let findCarthageFrameworksDefault = false public var minimumXcodeGenVersion: Version? public var carthageBuildPath: String? @@ -62,9 +68,9 @@ public struct SpecOptions: Equatable { minimumXcodeGenVersion: Version? = nil, carthageBuildPath: String? = nil, carthageExecutablePath: String? = nil, - createIntermediateGroups: Bool = false, + createIntermediateGroups: Bool = createIntermediateGroupsDefault, bundleIdPrefix: String? = nil, - settingPresets: SettingPresets = .all, + settingPresets: SettingPresets = settingPresetsDefault, developmentLanguage: String? = nil, indentWidth: UInt? = nil, tabWidth: UInt? = nil, @@ -73,10 +79,10 @@ public struct SpecOptions: Equatable { deploymentTarget: DeploymentTarget = .init(), disabledValidations: [ValidationType] = [], defaultConfig: String? = nil, - transitivelyLinkDependencies: Bool = false, - groupSortPosition: GroupSortPosition = .bottom, - generateEmptyDirectories: Bool = false, - findCarthageFrameworks: Bool = false + transitivelyLinkDependencies: Bool = transitivelyLinkDependenciesDefault, + groupSortPosition: GroupSortPosition = groupSortPositionDefault, + generateEmptyDirectories: Bool = generateEmptyDirectoriesDefault, + findCarthageFrameworks: Bool = findCarthageFrameworksDefault ) { self.minimumXcodeGenVersion = minimumXcodeGenVersion self.carthageBuildPath = carthageBuildPath @@ -109,8 +115,8 @@ extension SpecOptions: JSONObjectConvertible { carthageBuildPath = jsonDictionary.json(atKeyPath: "carthageBuildPath") carthageExecutablePath = jsonDictionary.json(atKeyPath: "carthageExecutablePath") bundleIdPrefix = jsonDictionary.json(atKeyPath: "bundleIdPrefix") - settingPresets = jsonDictionary.json(atKeyPath: "settingPresets") ?? .all - createIntermediateGroups = jsonDictionary.json(atKeyPath: "createIntermediateGroups") ?? false + settingPresets = jsonDictionary.json(atKeyPath: "settingPresets") ?? SpecOptions.settingPresetsDefault + createIntermediateGroups = jsonDictionary.json(atKeyPath: "createIntermediateGroups") ?? SpecOptions.createIntermediateGroupsDefault developmentLanguage = jsonDictionary.json(atKeyPath: "developmentLanguage") usesTabs = jsonDictionary.json(atKeyPath: "usesTabs") xcodeVersion = jsonDictionary.json(atKeyPath: "xcodeVersion") @@ -119,10 +125,10 @@ extension SpecOptions: JSONObjectConvertible { deploymentTarget = jsonDictionary.json(atKeyPath: "deploymentTarget") ?? DeploymentTarget() disabledValidations = jsonDictionary.json(atKeyPath: "disabledValidations") ?? [] defaultConfig = jsonDictionary.json(atKeyPath: "defaultConfig") - transitivelyLinkDependencies = jsonDictionary.json(atKeyPath: "transitivelyLinkDependencies") ?? false - groupSortPosition = jsonDictionary.json(atKeyPath: "groupSortPosition") ?? .bottom - generateEmptyDirectories = jsonDictionary.json(atKeyPath: "generateEmptyDirectories") ?? false - findCarthageFrameworks = jsonDictionary.json(atKeyPath: "findCarthageFrameworks") ?? false + transitivelyLinkDependencies = jsonDictionary.json(atKeyPath: "transitivelyLinkDependencies") ?? SpecOptions.transitivelyLinkDependenciesDefault + groupSortPosition = jsonDictionary.json(atKeyPath: "groupSortPosition") ?? SpecOptions.groupSortPositionDefault + generateEmptyDirectories = jsonDictionary.json(atKeyPath: "generateEmptyDirectories") ?? SpecOptions.generateEmptyDirectoriesDefault + findCarthageFrameworks = jsonDictionary.json(atKeyPath: "findCarthageFrameworks") ?? SpecOptions.findCarthageFrameworksDefault } } @@ -145,16 +151,16 @@ extension SpecOptions: JSONEncodable { "defaultConfig": defaultConfig, ] - if settingPresets != .all { + if settingPresets != SpecOptions.settingPresetsDefault { dict["settingPresets"] = settingPresets.rawValue } - if createIntermediateGroups { + if createIntermediateGroups != SpecOptions.createIntermediateGroupsDefault { dict["createIntermediateGroups"] = createIntermediateGroups } - if generateEmptyDirectories { + if generateEmptyDirectories != SpecOptions.generateEmptyDirectoriesDefault { dict["generateEmptyDirectories"] = generateEmptyDirectories } - if findCarthageFrameworks { + if findCarthageFrameworks != SpecOptions.findCarthageFrameworksDefault { dict["findCarthageFrameworks"] = findCarthageFrameworks } diff --git a/Sources/ProjectSpec/Target.swift b/Sources/ProjectSpec/Target.swift index c529c554c..403c5ed95 100644 --- a/Sources/ProjectSpec/Target.swift +++ b/Sources/ProjectSpec/Target.swift @@ -3,6 +3,8 @@ import JSONUtilities import xcodeproj public struct LegacyTarget: Equatable { + public static let passSettingsDefault = false + public var toolPath: String public var arguments: String? public var passSettings: Bool @@ -10,7 +12,7 @@ public struct LegacyTarget: Equatable { public init( toolPath: String, - passSettings: Bool = false, + passSettings: Bool = passSettingsDefault, arguments: String? = nil, workingDirectory: String? = nil ) { @@ -267,19 +269,24 @@ extension LegacyTarget: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { toolPath = try jsonDictionary.json(atKeyPath: "toolPath") arguments = jsonDictionary.json(atKeyPath: "arguments") - passSettings = jsonDictionary.json(atKeyPath: "passSettings") ?? false + passSettings = jsonDictionary.json(atKeyPath: "passSettings") ?? LegacyTarget.passSettingsDefault workingDirectory = jsonDictionary.json(atKeyPath: "workingDirectory") } } extension LegacyTarget: JSONEncodable { public func toJSONValue() -> Any { - return [ + var dict: [String: Any?] = [ "toolPath": toolPath, - "passSettings": passSettings, "arguments": arguments, "workingDirectory": workingDirectory, - ] as [String: Any?] + ] + + if passSettings != LegacyTarget.passSettingsDefault { + dict["passSettings"] = passSettings + } + + return dict } } diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 5f906fb31..e059f6c56 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -3,6 +3,8 @@ import JSONUtilities import xcodeproj public struct TargetScheme: Equatable { + public static let gatherCoverageDataDefault = false + public var testTargets: [Scheme.Test.TestTarget] public var configVariants: [String] public var gatherCoverageData: Bool @@ -14,7 +16,7 @@ public struct TargetScheme: Equatable { public init( testTargets: [Scheme.Test.TestTarget] = [], configVariants: [String] = [], - gatherCoverageData: Bool = false, + gatherCoverageData: Bool = gatherCoverageDataDefault, commandLineArguments: [String: Bool] = [:], environmentVariables: [XCScheme.EnvironmentVariable] = [], preActions: [Scheme.ExecutionAction] = [], @@ -47,7 +49,7 @@ extension TargetScheme: JSONObjectConvertible { testTargets = [] } configVariants = jsonDictionary.json(atKeyPath: "configVariants") ?? [] - gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? false + gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? TargetScheme.gatherCoverageDataDefault commandLineArguments = jsonDictionary.json(atKeyPath: "commandLineArguments") ?? [:] environmentVariables = try XCScheme.EnvironmentVariable.parseAll(jsonDictionary: jsonDictionary) preActions = jsonDictionary.json(atKeyPath: "preActions") ?? [] @@ -57,8 +59,7 @@ extension TargetScheme: JSONObjectConvertible { extension TargetScheme: JSONEncodable { public func toJSONValue() -> Any { - return [ - "gatherCoverageData": gatherCoverageData, + var dict: [String: Any] = [ "configVariants": configVariants, "commandLineArguments": commandLineArguments, "testTargets": testTargets.map { $0.toJSONValue() }, @@ -66,5 +67,11 @@ extension TargetScheme: JSONEncodable { "preActions": preActions.map { $0.toJSONValue() }, "postActions": postActions.map { $0.toJSONValue() }, ] + + if gatherCoverageData != TargetScheme.gatherCoverageDataDefault { + dict["gatherCoverageData"] = gatherCoverageData + } + + return dict } } diff --git a/Sources/ProjectSpec/TargetSource.swift b/Sources/ProjectSpec/TargetSource.swift index 8669094ab..e21dbe781 100644 --- a/Sources/ProjectSpec/TargetSource.swift +++ b/Sources/ProjectSpec/TargetSource.swift @@ -4,6 +4,7 @@ import PathKit import xcodeproj public struct TargetSource: Equatable { + public static let optionalDefault = false public var path: String public var name: String? @@ -123,7 +124,7 @@ public struct TargetSource: Equatable { compilerFlags: [String] = [], excludes: [String] = [], type: SourceType? = nil, - optional: Bool = false, + optional: Bool = optionalDefault, buildPhase: BuildPhase? = nil, headerVisibility: HeaderVisibility? = nil, createIntermediateGroups: Bool? = nil @@ -169,7 +170,7 @@ extension TargetSource: JSONObjectConvertible { headerVisibility = jsonDictionary.json(atKeyPath: "headerVisibility") excludes = jsonDictionary.json(atKeyPath: "excludes") ?? [] type = jsonDictionary.json(atKeyPath: "type") - optional = jsonDictionary.json(atKeyPath: "optional") ?? false + optional = jsonDictionary.json(atKeyPath: "optional") ?? TargetSource.optionalDefault if let string: String = jsonDictionary.json(atKeyPath: "buildPhase") { buildPhase = try BuildPhase(string: string) @@ -193,8 +194,8 @@ extension TargetSource: JSONEncodable { "createIntermediateGroups": createIntermediateGroups, ] - if optional { - dict["optional"] = true + if optional != TargetSource.optionalDefault { + dict["optional"] = optional } if dict.count == 0 { From ea6fb60c72eee18139f922adc21217ef140deca5 Mon Sep 17 00:00:00 2001 From: ryohey Date: Sat, 20 Apr 2019 12:22:52 +0900 Subject: [PATCH 8/8] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d13a787f..30115b27e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +#### Added + +- Added ability to encode ProjectSpec to JSON [#545](https://github.com/yonaskolb/XcodeGen/pull/545) @ryohey + ## 2.5.0 #### Added