From e004f8fb3836188ddde9f287215a1293ae131715 Mon Sep 17 00:00:00 2001 From: David Jennes Date: Mon, 22 May 2017 18:36:55 +0200 Subject: [PATCH 1/4] Multiple tables support --- Sources/Parsers/StringsFileParser.swift | 15 +++++---------- Sources/Stencil/StringsContext.swift | 18 +++++++++--------- Tests/Resources | 2 +- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/Sources/Parsers/StringsFileParser.swift b/Sources/Parsers/StringsFileParser.swift index c7ceaf7..8904208 100644 --- a/Sources/Parsers/StringsFileParser.swift +++ b/Sources/Parsers/StringsFileParser.swift @@ -25,29 +25,24 @@ public enum StringsFileParserError: Error, CustomStringConvertible { } public final class StringsFileParser { - var entries = [Entry]() + var tables = [String: [Entry]]() public init() {} - public func addEntry(_ entry: Entry) { - entries.append(entry) - } - // Localizable.strings files are generally UTF16, not UTF8! public func parseFile(at path: Path) throws { guard let data = try? path.read() else { throw StringsFileParserError.failureOnLoading(path: path.string) } - let plist = try PropertyListSerialization - .propertyList(from: data, format: nil) - + let plist = try PropertyListSerialization.propertyList(from: data, format: nil) guard let dict = plist as? [String: String] else { throw StringsFileParserError.invalidFormat } - for (key, translation) in dict { - addEntry(try Entry(key: key, translation: translation)) + let name = path.lastComponentWithoutExtension + tables[name] = try dict.map { key, translation in + try Entry(key: key, translation: translation) } } diff --git a/Sources/Stencil/StringsContext.swift b/Sources/Stencil/StringsContext.swift index 7103d27..8c53810 100644 --- a/Sources/Stencil/StringsContext.swift +++ b/Sources/Stencil/StringsContext.swift @@ -30,7 +30,6 @@ private extension String { */ extension StringsFileParser { public func stencilContext() -> [String: Any] { - let entryToStringMapper = { (entry: Entry, keyPath: [String]) -> [String: Any] in let levelName = entry.keyStructure.last ?? "" @@ -47,14 +46,15 @@ extension StringsFileParser { return result } - let structuredStrings = structure( - entries: entries, - usingMapper: entryToStringMapper - ) - let tables: [[String: Any]] = [[ - "name": "Localizable", - "levels": structuredStrings - ]] + let tables = self.tables.map { name, entries in + return [ + "name": name, + "levels": structure( + entries: entries, + usingMapper: entryToStringMapper + ) + ] + } return [ "tables": tables diff --git a/Tests/Resources b/Tests/Resources index 98e0692..ca34235 160000 --- a/Tests/Resources +++ b/Tests/Resources @@ -1 +1 @@ -Subproject commit 98e0692d445ec0d5047c9732d4e0421ff0f2ece0 +Subproject commit ca342357ada17ecb0fd9e8d00323cb97b469d918 From 5a708a5ffcf5c76832897164c508c354d45ee63c Mon Sep 17 00:00:00 2001 From: David Jennes Date: Mon, 22 May 2017 20:33:02 +0200 Subject: [PATCH 2/4] changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b8405e..e66fa36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,9 @@ Due to the removal of legacy code, there are a few breaking changes in this new * Throw an error if a format string has mismatching types for the same placeholde position. [David Jennes](https://github.com/djbe) [#44](https://github.com/SwiftGen/SwiftGenKit/issues/44) +* Added support for multiple string tables. + [David Jennes](https://github.com/djbe) + [#41](https://github.com/SwiftGen/templates/issues/41) ### Internal Changes From f5b8dca0269a1ee427294935abd53d56bc686e4c Mon Sep 17 00:00:00 2001 From: David Jennes Date: Thu, 25 May 2017 00:14:30 +0200 Subject: [PATCH 3/4] Test multiple files --- Tests/SwiftGenKitTests/StringsTests.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Tests/SwiftGenKitTests/StringsTests.swift b/Tests/SwiftGenKitTests/StringsTests.swift index e5136fd..7d8fec7 100644 --- a/Tests/SwiftGenKitTests/StringsTests.swift +++ b/Tests/SwiftGenKitTests/StringsTests.swift @@ -52,4 +52,13 @@ class StringsTests: XCTestCase { let result = parser.stencilContext() XCTDiffContexts(result, expected: "structuredonly.plist", sub: .strings) } + + func testMultipleFiles() throws { + let parser = StringsFileParser() + try parser.parseFile(at: Fixtures.path(for: "Localizable.strings", sub: .strings)) + try parser.parseFile(at: Fixtures.path(for: "LocMultiline.strings", sub: .strings)) + + let result = parser.stencilContext() + XCTDiffContexts(result, expected: "multiple.plist", sub: .strings) + } } From 52dafe3e93f6aef1dcc71bf9fce4453d1fa0af97 Mon Sep 17 00:00:00 2001 From: David Jennes Date: Thu, 25 May 2017 00:21:30 +0200 Subject: [PATCH 4/4] Add duplicate table error --- Sources/Parsers/StringsFileParser.swift | 9 ++++++++- Tests/SwiftGenKitTests/StringsTests.swift | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Sources/Parsers/StringsFileParser.swift b/Sources/Parsers/StringsFileParser.swift index 8904208..97d99ae 100644 --- a/Sources/Parsers/StringsFileParser.swift +++ b/Sources/Parsers/StringsFileParser.swift @@ -8,12 +8,15 @@ import Foundation import PathKit public enum StringsFileParserError: Error, CustomStringConvertible { + case duplicateTable(name: String) case failureOnLoading(path: String) case invalidFormat case invalidPlaceholder(previous: StringsFileParser.PlaceholderType, new: StringsFileParser.PlaceholderType) public var description: String { switch self { + case .duplicateTable(let name): + return "Table \"\(name)\" already loaded, cannot add it again" case .failureOnLoading(let path): return "Failed to load a file at \"\(path)\"" case .invalidFormat: @@ -31,6 +34,11 @@ public final class StringsFileParser { // Localizable.strings files are generally UTF16, not UTF8! public func parseFile(at path: Path) throws { + let name = path.lastComponentWithoutExtension + + guard tables[name] == nil else { + throw StringsFileParserError.duplicateTable(name: name) + } guard let data = try? path.read() else { throw StringsFileParserError.failureOnLoading(path: path.string) } @@ -40,7 +48,6 @@ public final class StringsFileParser { throw StringsFileParserError.invalidFormat } - let name = path.lastComponentWithoutExtension tables[name] = try dict.map { key, translation in try Entry(key: key, translation: translation) } diff --git a/Tests/SwiftGenKitTests/StringsTests.swift b/Tests/SwiftGenKitTests/StringsTests.swift index 7d8fec7..30734a2 100644 --- a/Tests/SwiftGenKitTests/StringsTests.swift +++ b/Tests/SwiftGenKitTests/StringsTests.swift @@ -61,4 +61,18 @@ class StringsTests: XCTestCase { let result = parser.stencilContext() XCTDiffContexts(result, expected: "multiple.plist", sub: .strings) } + + func testMultipleFilesDuplicate() throws { + let parser = StringsFileParser() + try parser.parseFile(at: Fixtures.path(for: "Localizable.strings", sub: .strings)) + + do { + try parser.parseFile(at: Fixtures.path(for: "Localizable.strings", sub: .strings)) + XCTFail("Code did parse file successfully while it was expected to fail for duplicate file") + } catch StringsFileParserError.duplicateTable { + // That's the expected exception we want to happen + } catch let error { + XCTFail("Unexpected error occured while parsing: \(error)") + } + } }