diff --git a/Sources/SwiftGen/Config/Config.swift b/Sources/SwiftGen/Config/Config.swift index f481835a..7549d37c 100644 --- a/Sources/SwiftGen/Config/Config.swift +++ b/Sources/SwiftGen/Config/Config.swift @@ -7,7 +7,7 @@ // import PathKit -import Yams +import SwiftGenKit // MARK: - Config @@ -27,8 +27,7 @@ extension Config { if !file.exists { throw Config.Error.pathNotFound(path: file) } - let content: String = try file.read() - let anyConfig = try Yams.load(yaml: content) + let anyConfig = try YAML.read(path: file) guard let config = anyConfig as? [String: Any] else { throw Config.Error.wrongType(key: nil, expected: "Dictionary", got: type(of: anyConfig)) } diff --git a/Sources/SwiftGenKit/Utils/YAML.swift b/Sources/SwiftGenKit/Utils/YAML.swift new file mode 100644 index 00000000..69143b64 --- /dev/null +++ b/Sources/SwiftGenKit/Utils/YAML.swift @@ -0,0 +1,63 @@ +// +// YAML.swift +// SwiftGenKit +// +// Created by David Jennes on 30/07/2018. +// Copyright © 2018 AliSoftware. All rights reserved. +// + +import PathKit +import Yams + +public enum YAML { + /// Read the contents of a YAML file located at the given path (only the first document). + /// + /// - parameter path: The path to the YAML file + /// - returns: The decoded document + public static func read(path: Path) throws -> Any? { + let contents: String = try path.read() + return try decode(string: contents) + } + + /// Decode the contents of YAML string (only the first document). + /// + /// - parameter string: The YAML string + /// - returns: The decoded document + public static func decode(string: String) throws -> Any? { + return try Yams.load(yaml: string) + } + + /// Encode the given object to YAML and write it to the given path + /// + /// - parameter object: The object to encode + /// - parameter path: The path to the output file + public static func write(object: Any, to path: Path) throws { + let string = try encode(object: object) + try path.write(string) + } + + /// Encode the given object to YAML and return it as a string + /// + /// - parameter object: The object to encode + /// - returns: The encoded YAML string + public static func encode(object: Any) throws -> String { + let node = try represent(object: object) + return try Yams.serialize(node: node) + } + + private static func represent(object: Any) throws -> Node { + switch object { + case let string as String: + return Node(string, .implicit, .doubleQuoted) + case let array as [Any]: + return Node(try array.map(represent), Tag(.seq)) + case let dictionary as [String: Any]: + let pairs = try dictionary.map { (Node($0.key), try represent(object: $0.value)) } + return Node(pairs.sorted { $0.0 < $1.0 }, Tag(.map)) + case let representable as NodeRepresentable: + return try representable.represented() + default: + throw YamlError.representer(problem: "Failed to represent \(object) as a Yams.Node") + } + } +} diff --git a/SwiftGen.xcodeproj/project.pbxproj b/SwiftGen.xcodeproj/project.pbxproj index dd71a9f1..a58d00d3 100644 --- a/SwiftGen.xcodeproj/project.pbxproj +++ b/SwiftGen.xcodeproj/project.pbxproj @@ -83,6 +83,7 @@ DDCCACDB209551240017FB43 /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCCACD7209551230017FB43 /* Platform.swift */; }; DDCCACDC209551240017FB43 /* Segue.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCCACD8209551230017FB43 /* Segue.swift */; }; DDCCACDD209551240017FB43 /* Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCCACD9209551230017FB43 /* Scene.swift */; }; + DDD2D709210F293E00D678E0 /* YAML.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD2D708210F293E00D678E0 /* YAML.swift */; }; DDDE51131FAF6AD4004203BE /* StringsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDE506D1FAF6AD4004203BE /* StringsTests.swift */; }; DDDE51141FAF6AD4004203BE /* FontsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDE506E1FAF6AD4004203BE /* FontsTests.swift */; }; DDDE51941FAF6AD4004203BE /* XCAssetsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDE50F51FAF6AD4004203BE /* XCAssetsTests.swift */; }; @@ -322,6 +323,7 @@ DDCCACD7209551230017FB43 /* Platform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; }; DDCCACD8209551230017FB43 /* Segue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Segue.swift; sourceTree = ""; }; DDCCACD9209551230017FB43 /* Scene.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scene.swift; sourceTree = ""; }; + DDD2D708210F293E00D678E0 /* YAML.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YAML.swift; sourceTree = ""; }; DDDE504B1FAF687A004203BE /* Templates UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Templates UnitTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; DDDE506D1FAF6AD4004203BE /* StringsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringsTests.swift; sourceTree = ""; }; DDDE506E1FAF6AD4004203BE /* FontsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FontsTests.swift; sourceTree = ""; }; @@ -676,6 +678,7 @@ children = ( DDC8211420967180007A55F3 /* Path.swift */, DDC82116209672E1007A55F3 /* String.swift */, + DDD2D708210F293E00D678E0 /* YAML.swift */, ); path = Utils; sourceTree = ""; @@ -1298,6 +1301,7 @@ DD428E1D1FC50FBF001649D6 /* ColorsXMLFileParser.swift in Sources */, DDCCACDA209551240017FB43 /* Storyboard.swift in Sources */, DD428E1F1FC50FBF001649D6 /* InterfaceBuilderParser.swift in Sources */, + DDD2D709210F293E00D678E0 /* YAML.swift in Sources */, DDCCACDC209551240017FB43 /* Segue.swift in Sources */, DD9F688620956074004EB720 /* PlaceholderType.swift in Sources */, DD428E251FC50FBF001649D6 /* AssetsCatalogContext.swift in Sources */, diff --git a/Tests/SwiftGenKitTests/TestsHelper.swift b/Tests/SwiftGenKitTests/TestsHelper.swift index 85e1f9b1..d20e1aab 100644 --- a/Tests/SwiftGenKitTests/TestsHelper.swift +++ b/Tests/SwiftGenKitTests/TestsHelper.swift @@ -6,8 +6,8 @@ import Foundation import PathKit +import SwiftGenKit import XCTest -import Yams private let colorCode: (String) -> String = ProcessInfo().environment["XcodeColors"] == "YES" ? { "\u{001b}[\($0);" } : { _ in "" } @@ -136,8 +136,7 @@ func XCTDiffContexts(_ result: [String: Any], if ProcessInfo().environment["GENERATE_CONTEXTS"] == "YES" { let target = Path(#file).parent().parent() + "Fixtures/StencilContexts" + directory.rawValue + fileName do { - let data = try Yams.serialize(node: YamsFix.represent(result)) - try target.write(data) + try YAML.write(object: result, to: target) } catch let error { fatalError("Unable to write context file \(target): \(error)") } @@ -186,8 +185,7 @@ class Fixtures { static func context(for name: String, sub: Directory) -> [String: Any] { let path = self.path(for: name, subDirectory: "StencilContexts/\(sub.rawValue)") - guard let data: String = try? path.read(), - let yaml = try? Yams.load(yaml: data), + guard let yaml = try? YAML.read(path: path), let result = yaml as? [String: Any] else { fatalError("Unable to load fixture content") } @@ -195,23 +193,3 @@ class Fixtures { return result } } - -// MARK: - Temporary fix until Yams fixes string dumping - -enum YamsFix { - static func represent(_ any: Any) throws -> Node { - switch any { - case let string as String: - return Node(string, .implicit, .doubleQuoted) - case let array as [Any]: - return Node(try array.map(represent), Tag(.seq)) - case let dictionary as [String: Any]: - let pairs = try dictionary.map { (Node($0.key), try represent($0.value)) } - return Node(pairs.sorted { $0.0 < $1.0 }, Tag(.map)) - case let representable as NodeRepresentable: - return try representable.represented() - default: - throw YamlError.representer(problem: "Failed to represent \(any) as a Yams.Node") - } - } -} diff --git a/Tests/TemplatesTests/TestsHelper.swift b/Tests/TemplatesTests/TestsHelper.swift index 2d7879cb..f9b0a2a4 100644 --- a/Tests/TemplatesTests/TestsHelper.swift +++ b/Tests/TemplatesTests/TestsHelper.swift @@ -7,8 +7,8 @@ import Foundation import PathKit import StencilSwiftKit +import SwiftGenKit import XCTest -import Yams private let colorCode: (String) -> String = ProcessInfo().environment["XcodeColors"] == "YES" ? { "\u{001b}[\($0);" } : { _ in "" } @@ -103,8 +103,7 @@ class Fixtures { static func context(for name: String, sub: Directory) -> [String: Any] { let path = self.path(for: name, subDirectory: "StencilContexts/\(sub.rawValue)") - guard let data: String = try? path.read(), - let yaml = try? Yams.load(yaml: data), + guard let yaml = try? YAML.read(path: path), let result = yaml as? [String: Any] else { fatalError("Unable to load fixture content") }