Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ Here's an overview of all options available for the sub command `interfaces`:
- `path` (required), `override` and `verbose` (see [Options for all Sub Commands](#options-for-all-sub-commands) above)
- `default-to-base`
- `unstripped`
- `ignore-empty-strings`

#### Default to Base (aka `-b`, `--default-to-base`) <small>*optional*</small>

Expand All @@ -211,6 +212,16 @@ Example:
$ bartycrouch interfaces -p "/path/to/project" -u
```

#### Ignore empty strings (aka `-i`, `--ignore-empty-strings`) <small>*optional*</small>

With this options set, strings that are empty, or only contain whitespace, will not appear in the localization files.

Example:

```shell
$ bartycrouch interfaces -p "/path/to/project" -i
```

---

### Options for `code`
Expand Down
13 changes: 7 additions & 6 deletions Sources/Code/CommandLineActor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public class CommandLineActor {
customLocalizableName: customLocalizableName.value
)

case let .interfacesOptions(defaultToBaseOption, unstripped):
self.actOnInterfaces(path: path, override: override, verbose: verbose, defaultToBase: defaultToBaseOption.value, unstripped: unstripped.value)
case let .interfacesOptions(defaultToBaseOption, unstripped, ignoreEmptyStrings):
self.actOnInterfaces(path: path, override: override, verbose: verbose, defaultToBase: defaultToBaseOption.value, unstripped: unstripped.value, ignoreEmptyStrings: ignoreEmptyStrings.value)

case let .translateOptions(idOption, secretOption, localeOption):
guard let id = idOption.value else {
Expand Down Expand Up @@ -90,7 +90,7 @@ public class CommandLineActor {
)
}

private func actOnInterfaces(path: String, override: Bool, verbose: Bool, defaultToBase: Bool, unstripped: Bool) {
private func actOnInterfaces(path: String, override: Bool, verbose: Bool, defaultToBase: Bool, unstripped: Bool, ignoreEmptyStrings: Bool) {
let inputFilePaths = StringsFilesSearch.shared.findAllIBFiles(within: path, withLocale: "Base")

guard !inputFilePaths.isEmpty else { print("No input files found.", level: .warning); exit(EX_OK) }
Expand All @@ -109,7 +109,7 @@ public class CommandLineActor {
}

self.incrementalInterfacesUpdate(
inputFilePath, outputStringsFilePaths, override: override, verbose: verbose, defaultToBase: defaultToBase, unstripped: unstripped
inputFilePath, outputStringsFilePaths, override: override, verbose: verbose, defaultToBase: defaultToBase, unstripped: unstripped, ignoreEmptyStrings: ignoreEmptyStrings
)
}
}
Expand Down Expand Up @@ -320,7 +320,7 @@ public class CommandLineActor {
}

private func incrementalInterfacesUpdate(
_ inputFilePath: String, _ outputStringsFilePaths: [String], override: Bool, verbose: Bool, defaultToBase: Bool, unstripped: Bool
_ inputFilePath: String, _ outputStringsFilePaths: [String], override: Bool, verbose: Bool, defaultToBase: Bool, unstripped: Bool, ignoreEmptyStrings: Bool
) {
let extractedStringsFilePath = inputFilePath + ".tmpstrings"

Expand All @@ -339,7 +339,8 @@ public class CommandLineActor {
withStringsFileAtPath: extractedStringsFilePath,
addNewValuesAsEmpty: !defaultToBase,
override: override,
keepWhitespaceSurroundings: unstripped
keepWhitespaceSurroundings: unstripped,
ignoreEmptyStrings: ignoreEmptyStrings
)

if verbose {
Expand Down
13 changes: 10 additions & 3 deletions Sources/Code/CommandLineParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class CommandLineParser {
customFunction: StringOption,
customLocalizableName: StringOption
)
case interfacesOptions(defaultToBase: BoolOption, unstripped: BoolOption)
case interfacesOptions(defaultToBase: BoolOption, unstripped: BoolOption, ignoreEmptyStrings: BoolOption)
case translateOptions(id: StringOption, secret: StringOption, locale: StringOption)
case normalizeOptions(
locale: StringOption,
Expand Down Expand Up @@ -143,6 +143,13 @@ public class CommandLineParser {
required: false,
helpMessage: "Fails if Strings files contain duplicate keys. Designed to be used as part of a CI service."
)

private let ignoreEmptyStrings = BoolOption(
shortFlag: "i",
longFlag: "ignore-empty-strings",
required: false,
helpMessage: "Ignores empty strings and strings consisting of whitespace only."
)

// MARK: - Initializers
public init(arguments: [String] = CommandLine.arguments) {
Expand Down Expand Up @@ -260,9 +267,9 @@ public class CommandLineParser {
)

let commonOptions: CommonOptions = (path: path, override: override, verbose: verbose)
let subCommandOptions = SubCommandOptions.interfacesOptions(defaultToBase: defaultToBase, unstripped: unstripped)
let subCommandOptions = SubCommandOptions.interfacesOptions(defaultToBase: defaultToBase, unstripped: unstripped, ignoreEmptyStrings: ignoreEmptyStrings)

commandLine.addOptions(path, override, verbose, defaultToBase, unstripped)
commandLine.addOptions(path, override, verbose, defaultToBase, unstripped, ignoreEmptyStrings)
return (commandLine, commonOptions, subCommandOptions)
}

Expand Down
4 changes: 3 additions & 1 deletion Sources/Code/StringsFileUpdater.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public class StringsFileUpdater {
withStringsFileAtPath otherStringFilePath: String,
addNewValuesAsEmpty: Bool, ignoreBaseKeysAndComment ignores: [String] = defaultIgnoreKeys,
override: Bool = false, updateCommentWithBase: Bool = true, keepExistingKeys: Bool = false,
overrideComments: Bool = false, sortByKeys: Bool = false, keepWhitespaceSurroundings: Bool = false
overrideComments: Bool = false, sortByKeys: Bool = false, keepWhitespaceSurroundings: Bool = false,
ignoreEmptyStrings: Bool = false
) {
do {
let newContentString = try String(contentsOfFile: otherStringFilePath)
Expand All @@ -59,6 +60,7 @@ public class StringsFileUpdater {
for newTranslation in newTranslations {
// skip keys marked for ignore
guard !newTranslation.value.containsAny(of: ignores) else { continue }
if ignoreEmptyStrings && newTranslation.value.isBlank { continue }

// Skip keys that have been marked for ignore in comment
if let newComment = newTranslation.comment, newComment.containsAny(of: ignores) { continue }
Expand Down
Binary file modified Tests/Assets/Strings Files/NewExample.strings
Binary file not shown.
Binary file modified Tests/Assets/Strings Files/OldExample.strings
Binary file not shown.
14 changes: 11 additions & 3 deletions Tests/Code/StringsFileUpdaterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class StringsFileUpdaterTests: XCTestCase {
("cHL-Zc-L39.normalTitle", "Example Button 3", " Class = \"UIButton\"; normalTitle = \"Example Button 3\"; ObjectID = \"cHL-Zc-L39\"; "),
("test.key", "This is a test key", " Completely custom comment structure in one line "),
("test.key.ignored", "This is a test key to be ignored #bc-ignore!", " Completely custom comment structure in one line to be ignored "),
("test.key.ignoreEmptyStrings", " ", " This key should be ignored when ignoreEmptyKeys is set "),
("abc-12-345.normalTitle", "😀", " Class = \"UIButton\"; normalTitle = \"😀\"; ObjectID = \"abc-12-345\"; "),
("em1-3S-vgp.text", "Refrakční vzdálenost v metrech",
" Class = \"UILabel\"; text = \"Refraktionsentfernung in Meter\"; ObjectID = \"em1-3S-vgp\"; ")
Expand Down Expand Up @@ -120,6 +121,8 @@ class StringsFileUpdaterTests: XCTestCase {
"\"test.key\" = \"This is a test key\";", "",
"/* Completely custom comment structure in one line to be ignored */",
"\"test.key.ignored\" = \"This is a test key to be ignored #bc-ignore!\";", "",
"/* This key should be ignored when ignoreEmptyKeys is set */",
"\"test.key.ignoreEmptyStrings\" = \" \";", "",
"/* Class = \"UIButton\"; normalTitle = \"😀\"; ObjectID = \"abc-12-345\"; */",
"\"abc-12-345.normalTitle\" = \"😀\";", "",
"/* Class = \"UILabel\"; text = \"Refraktionsentfernung in Meter\"; ObjectID = \"em1-3S-vgp\"; */",
Expand All @@ -133,7 +136,7 @@ class StringsFileUpdaterTests: XCTestCase {
XCTAssertEqual(oldLinesInFile[index], expectedLine)
}

stringsFileUpdater.incrementallyUpdateKeys(withStringsFileAtPath: newStringsFilePath, addNewValuesAsEmpty: true, updateCommentWithBase: false)
stringsFileUpdater.incrementallyUpdateKeys(withStringsFileAtPath: newStringsFilePath, addNewValuesAsEmpty: true, updateCommentWithBase: false, ignoreEmptyStrings: true)

let expectedLinesAfterIncrementalUpdate = [
"", "/* Class = \"UIButton\"; normalTitle = \"Example Button 1\"; ObjectID = \"35F-cl-mdI\"; */",
Expand Down Expand Up @@ -180,6 +183,8 @@ class StringsFileUpdaterTests: XCTestCase {
"\"test.key\" = \"This is a test key\";", "",
"/* Completely custom comment structure in one line to be ignored */",
"\"test.key.ignored\" = \"This is a test key to be ignored #bc-ignore!\";", "",
"/* This key should be ignored when ignoreEmptyKeys is set */",
"\"test.key.ignoreEmptyStrings\" = \" \";", "",
"/* Class = \"UIButton\"; normalTitle = \"😀\"; ObjectID = \"abc-12-345\"; */",
"\"abc-12-345.normalTitle\" = \"😀\";", "",
"/* Class = \"UILabel\"; text = \"Refraktionsentfernung in Meter\"; ObjectID = \"em1-3S-vgp\"; */",
Expand All @@ -197,7 +202,8 @@ class StringsFileUpdaterTests: XCTestCase {
withStringsFileAtPath: newStringsFilePath,
addNewValuesAsEmpty: true,
updateCommentWithBase: false,
keepWhitespaceSurroundings: true
keepWhitespaceSurroundings: true,
ignoreEmptyStrings: true
)

let expectedLinesAfterIncrementalUpdate = [
Expand Down Expand Up @@ -245,6 +251,8 @@ class StringsFileUpdaterTests: XCTestCase {
"\"test.key\" = \"This is a test key\";", "",
"/* Completely custom comment structure in one line to be ignored */",
"\"test.key.ignored\" = \"This is a test key to be ignored #bc-ignore!\";", "",
"/* This key should be ignored when ignoreEmptyKeys is set */",
"\"test.key.ignoreEmptyStrings\" = \" \";", "",
"/* Class = \"UIButton\"; normalTitle = \"😀\"; ObjectID = \"abc-12-345\"; */",
"\"abc-12-345.normalTitle\" = \"😀\";", "",
"/* Class = \"UILabel\"; text = \"Refraktionsentfernung in Meter\"; ObjectID = \"em1-3S-vgp\"; */",
Expand All @@ -258,7 +266,7 @@ class StringsFileUpdaterTests: XCTestCase {
XCTAssertEqual(oldLinesInFile[index], expectedLine)
}

stringsFileUpdater.incrementallyUpdateKeys(withStringsFileAtPath: newStringsFilePath, addNewValuesAsEmpty: false)
stringsFileUpdater.incrementallyUpdateKeys(withStringsFileAtPath: newStringsFilePath, addNewValuesAsEmpty: false, ignoreEmptyStrings: true)

let expectedLinesAfterIncrementalUpdate = [
"", "/* Class = \"UIButton\"; normalTitle = \"New Example Button 1\"; ObjectID = \"35F-cl-mdI\"; */",
Expand Down