From 6ee42d5c68051c4e629db86ed5406c04afd377b1 Mon Sep 17 00:00:00 2001 From: ryohey Date: Tue, 26 Mar 2019 18:26:45 +0900 Subject: [PATCH 01/21] 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 00000000..ee024177 --- /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 02/21] 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 e25fb553..e8159640 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 442dda24..a4e4ae36 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 242a2813..2ed00778 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 d9495e44..8aea2f06 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 cf797b02..2feff095 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 1f295106..9140b080 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 7eb90873..63660edc 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 6865c284..86a6acd0 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 95254dd6..d06122c7 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 1abc8f42..afb4a246 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 b7eb1c00..820eefc7 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 22b018e9..3dde710e 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 6ed21bff..9b341020 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 03/21] 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 9fa496c6..33aaeba6 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 04/21] 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 e8159640..3d91ba39 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 a4e4ae36..9c4e3cea 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 2ed00778..ed9aada8 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 8aea2f06..6ea575b6 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 2feff095..0968cfee 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 ee024177..46e1ad52 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 9140b080..e174a9ab 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 63660edc..869ad3e9 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 86a6acd0..25eb51da 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 d06122c7..b60268e8 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 afb4a246..ce2f2e99 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 820eefc7..20c272bc 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 3dde710e..6878bf58 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 9b341020..a68ed31b 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 05/21] 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 | 61 ++++++--------------- 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, 74 insertions(+), 197 deletions(-) diff --git a/Sources/ProjectSpec/AggregateTarget.swift b/Sources/ProjectSpec/AggregateTarget.swift index 3d91ba39..68e23a32 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 ed9aada8..d485ea77 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 869ad3e9..2790d008 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 = [ + let targetPairs = targets.map { ($0.name, $0.toJSONValue()) } + let configsPairs = configs.map { ($0.name, $0.type?.rawValue) } + let aggregateTargetsPairs = aggregateTargets.map { ($0.name, $0.toJSONValue()) } + let schemesPairs = schemes.map { ($0.name, $0.toJSONValue()) } + + 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() } ] - - 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 } } diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 25eb51da..1f497931 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 b60268e8..c223ab9f 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 ce2f2e99..e8471650 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 20c272bc..e2a9f00e 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 6878bf58..5f906fb3 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 a68ed31b..b8964513 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 06/21] 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 68e23a32..d861958f 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 9c4e3cea..3f75e75f 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 d485ea77..14cfce0d 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 6ea575b6..121fff2d 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 0968cfee..7cba891a 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 46e1ad52..6934f0b2 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 1f497931..67c8ffba 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 e8471650..020b0494 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 e2a9f00e..c529c554 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 b8964513..8669094a 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 07/21] 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 14cfce0d..f1eaf33a 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 121fff2d..8da36e6d 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 67c8ffba..58e6c56c 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 020b0494..fc55641e 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 c529c554..403c5ed9 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 5f906fb3..e059f6c5 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 8669094a..e21dbe78 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 08/21] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d13a787..30115b27 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 From e15e7543bce9fe143d39c65decb9b0f7f6e276e7 Mon Sep 17 00:00:00 2001 From: Tian Zhang Date: Mon, 22 Apr 2019 12:19:21 -0700 Subject: [PATCH 09/21] Intents-service need to populate LD_RUNPATH_SEARCH_PATHS explicitly --- SettingPresets/Products/app-extension.intents-service.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 SettingPresets/Products/app-extension.intents-service.yml diff --git a/SettingPresets/Products/app-extension.intents-service.yml b/SettingPresets/Products/app-extension.intents-service.yml new file mode 100644 index 00000000..fb762bf9 --- /dev/null +++ b/SettingPresets/Products/app-extension.intents-service.yml @@ -0,0 +1 @@ +LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks @executable_path/../../../../Frameworks" From 2990d3fc3fdff73aa922e6f9a1a4517997e1a5c9 Mon Sep 17 00:00:00 2001 From: Tian Zhang Date: Mon, 22 Apr 2019 12:23:29 -0700 Subject: [PATCH 10/21] Changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30115b27..79f111d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ - Added ability to encode ProjectSpec to JSON [#545](https://github.com/yonaskolb/XcodeGen/pull/545) @ryohey +#### Fixed +- Fixed an issue that prevents watchOS Intents Extension from running correctly. [#TBD](https://github.com/yonaskolb/XcodeGen/pull/TDB) @KhaosT + ## 2.5.0 #### Added From 699bd078c304b42c7b28425fe05383fb8449435e Mon Sep 17 00:00:00 2001 From: Tian Zhang Date: Mon, 22 Apr 2019 12:28:40 -0700 Subject: [PATCH 11/21] Issue number --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79f111d8..14ee5ffe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ - Added ability to encode ProjectSpec to JSON [#545](https://github.com/yonaskolb/XcodeGen/pull/545) @ryohey #### Fixed -- Fixed an issue that prevents watchOS Intents Extension from running correctly. [#TBD](https://github.com/yonaskolb/XcodeGen/pull/TDB) @KhaosT +- Fixed an issue that prevents watchOS Intents Extension from running correctly. [#571](https://github.com/yonaskolb/XcodeGen/pull/571) @KhaosT ## 2.5.0 From 3baa3b3e4d68910928ccc3be9b7c4583a9d34d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81s=20Cecilia=20Luque?= Date: Tue, 7 May 2019 18:43:17 +0200 Subject: [PATCH 12/21] Updated compatibilityVersion --- CHANGELOG.md | 3 +++ Sources/XcodeGenKit/PBXProjGenerator.swift | 2 +- Sources/XcodeGenKit/Version.swift | 4 ++-- Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30115b27..a2efa022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ - Added ability to encode ProjectSpec to JSON [#545](https://github.com/yonaskolb/XcodeGen/pull/545) @ryohey +#### Changed +- Follow up on the Xcode 10.2 updates done in [#555](https://github.com/yonaskolb/XcodeGen/pull/555): updated the `compatibilityVersion` project setting to `Xcode 10.0`. With the `compatibilityVersion` set to `Xcode 9.3`, Xcode automatically sets the `ObjectVersion` from `51` to `50` [#578](https://github.com/yonaskolb/XcodeGen/pull/578) @acecilia + ## 2.5.0 #### Added diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 39ca69b0..8f04353e 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -87,7 +87,7 @@ public class PBXProjGenerator { PBXProject( name: project.name, buildConfigurationList: buildConfigList, - compatibilityVersion: project.compatabilityVersion, + compatibilityVersion: project.compatibilityVersion, mainGroup: mainGroup, developmentRegion: project.options.developmentLanguage ?? "en" ) diff --git a/Sources/XcodeGenKit/Version.swift b/Sources/XcodeGenKit/Version.swift index 63904f67..3e122732 100644 --- a/Sources/XcodeGenKit/Version.swift +++ b/Sources/XcodeGenKit/Version.swift @@ -11,8 +11,8 @@ extension Project { return "1.3" } - var compatabilityVersion: String { - return "Xcode 9.3" + var compatibilityVersion: String { + return "Xcode 10.0" } var objectVersion: UInt { diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index bf38f623..6675904b 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -1498,7 +1498,7 @@ }; }; buildConfigurationList = D91E14E36EC0B415578456F264E0161E /* Build configuration list for PBXProject "Project" */; - compatibilityVersion = "Xcode 9.3"; + compatibilityVersion = "Xcode 10.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( From eef2a974e91a7cd79df286dcf13b47293cf8590d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81s=20Cecilia=20Luque?= Date: Tue, 7 May 2019 18:44:30 +0200 Subject: [PATCH 13/21] Changelog update --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2efa022..e5688cae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ - Added ability to encode ProjectSpec to JSON [#545](https://github.com/yonaskolb/XcodeGen/pull/545) @ryohey #### Changed -- Follow up on the Xcode 10.2 updates done in [#555](https://github.com/yonaskolb/XcodeGen/pull/555): updated the `compatibilityVersion` project setting to `Xcode 10.0`. With the `compatibilityVersion` set to `Xcode 9.3`, Xcode automatically sets the `ObjectVersion` from `51` to `50` [#578](https://github.com/yonaskolb/XcodeGen/pull/578) @acecilia +- Follow up on the Xcode 10.2 updates done in [#555](https://github.com/yonaskolb/XcodeGen/pull/555): updated the `compatibilityVersion` project setting to `Xcode 10.0`. With the `compatibilityVersion` set to `Xcode 9.3`, Xcode automatically sets the `ObjectVersion` from `51` to `50` [#581](https://github.com/yonaskolb/XcodeGen/pull/581) @acecilia ## 2.5.0 From ef85a2cf10faa74bd0b40892c95ca6cfdc3c77d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81s=20Cecilia=20Luque?= Date: Tue, 7 May 2019 18:57:21 +0200 Subject: [PATCH 14/21] Generate fixtures --- .../Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj index b809ab72..6be39879 100644 --- a/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj @@ -315,7 +315,7 @@ LastUpgradeCheck = 1020; }; buildConfigurationList = D91E14E36EC0B415578456F264E0161E /* Build configuration list for PBXProject "Project" */; - compatibilityVersion = "Xcode 9.3"; + compatibilityVersion = "Xcode 10.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( From bb311b1ca75a3c138d4399c4b6acb9332be7f83b Mon Sep 17 00:00:00 2001 From: Andras Kadar Date: Wed, 8 May 2019 08:31:21 +0200 Subject: [PATCH 15/21] Allow skipping tests in test targets --- Docs/ProjectSpec.md | 8 +++++++- Sources/ProjectSpec/Scheme.swift | 8 +++++++- Sources/XcodeGenKit/SchemeGenerator.swift | 3 ++- Tests/XcodeGenKitTests/SpecLoadingTests.swift | 4 +++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index ff8ba02f..de79d1c4 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -691,6 +691,7 @@ A multiline script can be written using the various YAML multiline methods, for - [x] **name**: **String** - The name of the target - [ ] **parallelizable**: **Bool** - Whether to run tests in parallel. Defaults to false - [ ] **randomExecutionOrder**: **Bool** - Whether to run tests in a random order. Defaults to false +- [ ] **skippedTests**: **[String]** - List of tests in the test target to skip. Defaults to empty. ### Archive Action @@ -719,7 +720,12 @@ schemes: config: prod-debug commandLineArguments: "--option testValue" gatherCoverageData: true - targets: [Tester1, Tester2] + targets: + - Tester1 + - name: Tester2 + parallelizable: true + randomExecutionOrder: true + skippedTests: [Test/testExample()] environmentVariables: - variable: TEST_ENV_VAR value: VALUE diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 58e6c56c..4630e5ea 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -102,25 +102,30 @@ public struct Scheme: Equatable { public struct TestTarget: Equatable, ExpressibleByStringLiteral { public static let randomExecutionOrderDefault = false public static let parallelizableDefault = false + public static let skippedTestsDefault: [String] = [] public let name: String public var randomExecutionOrder: Bool public var parallelizable: Bool + public var skippedTests: [String] public init( name: String, randomExecutionOrder: Bool = randomExecutionOrderDefault, - parallelizable: Bool = parallelizableDefault + parallelizable: Bool = parallelizableDefault, + skippedTests: [String] = skippedTestsDefault ) { self.name = name self.randomExecutionOrder = randomExecutionOrder self.parallelizable = parallelizable + self.skippedTests = skippedTests } public init(stringLiteral value: String) { name = value randomExecutionOrder = false parallelizable = false + skippedTests = [] } } @@ -306,6 +311,7 @@ extension Scheme.Test.TestTarget: JSONObjectConvertible { name = try jsonDictionary.json(atKeyPath: "name") randomExecutionOrder = jsonDictionary.json(atKeyPath: "randomExecutionOrder") ?? Scheme.Test.TestTarget.randomExecutionOrderDefault parallelizable = jsonDictionary.json(atKeyPath: "parallelizable") ?? Scheme.Test.TestTarget.parallelizableDefault + skippedTests = jsonDictionary.json(atKeyPath: "skippedTests") ?? Scheme.Test.TestTarget.skippedTestsDefault } } diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index fb1b021d..5b6c3d14 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -133,7 +133,8 @@ public class SchemeGenerator { skipped: false, parallelizable: testTarget.parallelizable, randomExecutionOrdering: testTarget.randomExecutionOrder, - buildableReference: testBuilEntries.buildableReference + buildableReference: testBuilEntries.buildableReference, + skippedTests: testTarget.skippedTests.map(XCScheme.SkippedTest.init) ) } diff --git a/Tests/XcodeGenKitTests/SpecLoadingTests.swift b/Tests/XcodeGenKitTests/SpecLoadingTests.swift index 82fc6c47..10357158 100644 --- a/Tests/XcodeGenKitTests/SpecLoadingTests.swift +++ b/Tests/XcodeGenKitTests/SpecLoadingTests.swift @@ -729,6 +729,7 @@ class SpecLoadingTests: XCTestCase { "name": "Target2", "parallelizable": true, "randomExecutionOrder": true, + "skippedTests": ["Test/testExample()"] ], ], "gatherCoverageData": true, @@ -760,7 +761,8 @@ class SpecLoadingTests: XCTestCase { Scheme.Test.TestTarget( name: "Target2", randomExecutionOrder: true, - parallelizable: true + parallelizable: true, + skippedTests: ["Test/testExample()"] ), ] ) From 5bf1678e1fc3bc538eeda7598bb72b136b367938 Mon Sep 17 00:00:00 2001 From: Andras Kadar Date: Fri, 17 May 2019 09:29:30 +0200 Subject: [PATCH 16/21] Remove default empty array & add changelog --- CHANGELOG.md | 1 + Sources/ProjectSpec/Scheme.swift | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30115b27..c43c8b13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ #### Added - Added ability to encode ProjectSpec to JSON [#545](https://github.com/yonaskolb/XcodeGen/pull/545) @ryohey +- Added ability to skip tests [#582](https://github.com/yonaskolb/XcodeGen/pull/582) @kadarandras ## 2.5.0 diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 4630e5ea..29ee1241 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -102,7 +102,6 @@ public struct Scheme: Equatable { public struct TestTarget: Equatable, ExpressibleByStringLiteral { public static let randomExecutionOrderDefault = false public static let parallelizableDefault = false - public static let skippedTestsDefault: [String] = [] public let name: String public var randomExecutionOrder: Bool @@ -113,7 +112,7 @@ public struct Scheme: Equatable { name: String, randomExecutionOrder: Bool = randomExecutionOrderDefault, parallelizable: Bool = parallelizableDefault, - skippedTests: [String] = skippedTestsDefault + skippedTests: [String] = [] ) { self.name = name self.randomExecutionOrder = randomExecutionOrder @@ -311,7 +310,7 @@ extension Scheme.Test.TestTarget: JSONObjectConvertible { name = try jsonDictionary.json(atKeyPath: "name") randomExecutionOrder = jsonDictionary.json(atKeyPath: "randomExecutionOrder") ?? Scheme.Test.TestTarget.randomExecutionOrderDefault parallelizable = jsonDictionary.json(atKeyPath: "parallelizable") ?? Scheme.Test.TestTarget.parallelizableDefault - skippedTests = jsonDictionary.json(atKeyPath: "skippedTests") ?? Scheme.Test.TestTarget.skippedTestsDefault + skippedTests = jsonDictionary.json(atKeyPath: "skippedTests") ?? [] } } From f4919f80b0f06be0cb428c7bf6ad1d409c1ab92e Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Sat, 1 Jun 2019 21:28:01 -0700 Subject: [PATCH 17/21] improve line spacing --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f3ebef18..33297f2d 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ XcodeGen is a command line tool written in Swift that generates your Xcode proje The project spec is a YAML or JSON file that defines your targets, configurations, schemes, custom build settings and many other options. All your source directories are automatically parsed and referenced appropriately while preserving your folder structure. Sensible defaults are used in many places, so you only need to customize what is needed. Very complex projects can also be defined using more advanced features. -- ✅ Generate projects on demand and remove your `.xcodeproj` file from git, which means **no more merge conflicts**! +- ✅ Generate projects on demand and remove your `.xcodeproj` from git, which means **no more merge conflicts**! - ✅ Groups and files in Xcode are always **synced** to your directories on disk - ✅ Easy **configuration** of projects which is human readable and git friendly - ✅ Easily copy and paste **files and directories** without having to edit anything in Xcode From ae35da8d17ac04805fa0b379481b4363974f41ba Mon Sep 17 00:00:00 2001 From: Thi Date: Mon, 10 Jun 2019 10:43:23 +0900 Subject: [PATCH 18/21] Don't bundle `.pch` files as resources Fixes #593 --- Sources/XcodeGenKit/SourceGenerator.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift index 03305a4b..4ed48631 100644 --- a/Sources/XcodeGenKit/SourceGenerator.swift +++ b/Sources/XcodeGenKit/SourceGenerator.swift @@ -219,7 +219,8 @@ class SourceGenerator { "gpx", "lproj", "xcfilelist", - "apns": + "apns", + "pch": return nil default: return .resources From 9da8154ba63c673d6f0f738a2d515f058f784cca Mon Sep 17 00:00:00 2001 From: Thi Date: Mon, 10 Jun 2019 11:06:56 +0900 Subject: [PATCH 19/21] Add changelog entry for #597 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c43c8b13..c5ce1569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ - Added ability to encode ProjectSpec to JSON [#545](https://github.com/yonaskolb/XcodeGen/pull/545) @ryohey - Added ability to skip tests [#582](https://github.com/yonaskolb/XcodeGen/pull/582) @kadarandras +#### Fixed + +- Fixed `.pch` files being bundled as resources [#597](https://github.com/yonaskolb/XcodeGen/pull/597) @thii + ## 2.5.0 #### Added From f48914c1672fcddacf90b7992dcab0a847d91187 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Fri, 14 Jun 2019 11:03:39 +1000 Subject: [PATCH 20/21] Update CHANGELOG.md --- CHANGELOG.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ab8ed5f..23ddb7f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,15 +8,12 @@ - Added ability to skip tests [#582](https://github.com/yonaskolb/XcodeGen/pull/582) @kadarandras #### Fixed - - Fixed `.pch` files being bundled as resources [#597](https://github.com/yonaskolb/XcodeGen/pull/597) @thii +- Fixed an issue that prevents watchOS Intents Extension from running correctly. [#571](https://github.com/yonaskolb/XcodeGen/pull/571) @KhaosT #### Changed - Follow up on the Xcode 10.2 updates done in [#555](https://github.com/yonaskolb/XcodeGen/pull/555): updated the `compatibilityVersion` project setting to `Xcode 10.0`. With the `compatibilityVersion` set to `Xcode 9.3`, Xcode automatically sets the `ObjectVersion` from `51` to `50` [#581](https://github.com/yonaskolb/XcodeGen/pull/581) @acecilia -#### Fixed -- Fixed an issue that prevents watchOS Intents Extension from running correctly. [#571](https://github.com/yonaskolb/XcodeGen/pull/571) @KhaosT - ## 2.5.0 #### Added From 73dc56120a5b5fb953469d7db290c41819d5100e Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Fri, 14 Jun 2019 11:05:02 +1000 Subject: [PATCH 21/21] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23ddb7f4..6740687f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ - Fixed an issue that prevents watchOS Intents Extension from running correctly. [#571](https://github.com/yonaskolb/XcodeGen/pull/571) @KhaosT #### Changed -- Follow up on the Xcode 10.2 updates done in [#555](https://github.com/yonaskolb/XcodeGen/pull/555): updated the `compatibilityVersion` project setting to `Xcode 10.0`. With the `compatibilityVersion` set to `Xcode 9.3`, Xcode automatically sets the `ObjectVersion` from `51` to `50` [#581](https://github.com/yonaskolb/XcodeGen/pull/581) @acecilia +- Updated the default `compatibilityVersion` project setting from `Xcode 9.3` to `Xcode 10.0` [#581](https://github.com/yonaskolb/XcodeGen/pull/581) @acecilia ## 2.5.0