Installation • Usage • Build Script • Migration Guides • Issues • Contributing • License
BartyCrouch incrementally updates your Strings files from your Code and from Interface Builder files. "Incrementally" means that BartyCrouch will by default keep both your already translated values and even your altered comments. Additionally you can also use BartyCrouch for machine translating from one language to 40+ other languages. Using BartyCrouch is as easy as running a few simple commands from the command line what can even be automated using a build script within your project.
- Xcode 9 and Swift 4
- Xcode Command Line Tools (see here for installation instructions)
Install Homebrew first if you don't have it already (more about Homebrew here):
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Bartycrouch now is part of Homebrew Core! No tap needed any more.
If you had installed a previous version (<= 3.8.0) via the tap, you should run the following once:
$ brew untap flinesoft/bartycrouch
To install Bartycrouch the first time, simply run the command:
$ brew install bartycrouch
To update to the newest version of BartyCrouch when you have an old version already installed run:
$ brew update
$ brew upgrade bartycrouch
Simply add the following line to your Podfile:
pod 'BartyCrouch'
Before using BartyCrouch please make sure you have committed your code.
With BartyCrouch you can run commands like these:
# Incrementally updates all Strings files of Storyboards/XIBs in project
$ bartycrouch interfaces -p "/absolute/path/to/project"
# Updates `Localizable.strings` files with new keys searching your code for `NSLocalizedString`
$ bartycrouch code -p "/path/to/code/directory" -l "/directory/containing/all/Localizables" -a
# Machine-translate all empty localization values using English as source language
$ bartycrouch translate -p "/path/to/project" -l en -i "<API_ID>" -s "<API_SECRET>"
# Normalize your Strings files to keep them nice and clean
$ bartycrouch normalize -p "/path/to/project" -l en -d -w -h -s
# Lint your Strings files to check if they are nice and clean
$ bartycrouch lint -p "/path/to/project" -d -e
Also you can make your life a lot easier by using the build script method described below.
The bartycrouch
main command accepts one of the following sub commands:
interfaces
: Incrementally updates Strings files of localized Storyboards and XIBs.code
: Incrementally updatesLocalizable.strings
files from.h
,.m
and.swift
files.translate
: Machine-translates values from a source Strings file to all other languages.normalize
: Normalizes Strings files with configurable options to keep them nice and clean.lint
: Lint your Strings files to check if they are nice and clean.
Note that each sub command accepts a different set of options. Some of them are required and some optional. You can combine all options with each other to create your own expected behavior. If you're not sure which options are available or required you can always look them up in terminal by running a sub command without options like so:
$ bartycrouch code
Missing required options: ["-p, --path", "-l, --localizables"]
Usage: /usr/local/bin/bartycrouch [options]
-p, --path:
Set the base path to recursively search within for code files (.h, .m, .mm, .swift).
-l, --localizables:
The path to the folder of your output `Localizable.strings` file to be updated.
...
Important Notice: Please make sure you always localize all localizable files in all the languages you support in your project. Otherwise BartyCrouch might not work as expected. If you don't need to localize a Storyboard (like the LaunchScreen) then you should simply unlocalize the screen entirely so it doesn't appear even in Base.lproj.
Some options are common to all sub commands and must (if required) or can always be specified.
For each command BartyCrouch needs to know where it should search for files to do its work. This is done by providing an absolute path to a directory using -p
.
Example:
# Finds all Storyboard / XIB files within the specified path as input
$ bartycrouch interfaces -p "/Users/Name/DemoProject/Sources"
BartyCrouch keeps non-empty values by default so nothing gets lost (except for keys which are no longer used). If you want to override all your existing translation values you can force BartyCrouch to do this by specifying the -o
command.
Example:
# Clears all values of Storyboards / XIBs Strings files
$ bartycrouch interfaces -p "/path/to/project" -o
If you want to know exactly which files BartyCrouch found and updated you can specify the -v
command to see a more verbose output.
Example:
$ bartycrouch interfaces -p "/path/to/project" -v
Incrementally updated keys of file '/path/to/project/de.lproj/Main.strings'.
Incrementally updated keys of file '/path/to/project/en.lproj/Main.strings'.
Incrementally updated keys of file '/path/to/project/fr.lproj/Main.strings'.
BartyCrouch: Successfully updated strings file(s) of Storyboard or XIB file.
Here's an overview of all options available for the sub command interfaces
:
path
(required),override
andverbose
(see Options for all Sub Commands above)default-to-base
unstripped
To use the Base localization values when adding new keys (instead of empty values) simply add the option -b
.
Example:
$ bartycrouch interfaces -p "/path/to/project" -b
If you use any service or other tool that alters your Strings files and if BartyCrouch seems to change the beginning and ends of those files due to different whitespacing/newline conventions, then you can simply use the -u
command to keep the beginning and end as they are. By default BartyCrouch adds exactly one line to both the beginning and end of a file. Note that this option keeps up to 10 newline/whitespace characters from the original file at both beginning and end.
Example:
$ bartycrouch interfaces -p "/path/to/project" -u
Here's an overview of all options available for the sub command code
:
path
(required),override
andverbose
(see Options for all Sub Commands above)localizable
(required)default-to-keys
additive
override-comments
extract-loc-strings
sort-by-keys
unstripped
custom-function
custom-localizable-name
Specifies the path to the directory which contains all Localizable.strings
files within <locale>.lproj
folders. BartyCrouch will search for all files named Localizable.strings
recursively within the specified path and incrementally update them. Make sure to specify a path with only your projects Localizable.strings
files.
Example:
$ bartycrouch code -p "/path/to/code/files" -l "/Users/Name/DemoProject/Sources/Supporting Files"
To use the keys as localization values when adding new keys (instead of empty values) simply add the option -k
.
Example:
$ bartycrouch code -p "/path/to/code/files" -l "/path/to/localizables" -k
To prevent BartyCrouch from deleting (seemingly) unused keys you can configure it to only add new keys keeping all existing ones by providing the option -a
. This can be useful for example when you want to generate your Localizable.strings
using BartyCrouch but use static strings (e.g. with Laurine) once they are added to your Localizables.
Example:
$ bartycrouch code -p "/path/to/code/files" -l "/path/to/localizables" -a
If you want to override all your existing translations comments you can enforce this by specifying the -c
command.
Example:
$ bartycrouch code -p "/path/to/code/files" -l "/path/to/localizables" -c
If you are using the NSLocalizedString
macro with more than two arguments (NSLocalizedString(key:tableName:bundle:value:comment:)
) then you should specify the -e
command to use the successor of the genstrings
command line tool which BartyCrouch uses to extract localizable strings from code files by default. The newer extractLocStrings
command will be used then instead.
Note that we are planning to make this the default behavior after testing it in practice with a major BartyCrouch upgrade (version 4.0+) in the near future – if you encounter any problems please open an issue!
Example:
$ bartycrouch code -p "/path/to/code/files" -l "/path/to/localizables" -e
If you want the order of translations in your resulting Localizable.strings
file to be alphabetically sorted by their keys (instead of simply adding new keys to the end and keeping them in that order forever) just use the option -s
. To ensure that you can still easily find your untranslated keys this option will check the value of your translations and place those without a translation at the end of the file. Once you translated those entries they will be correctly sorted amongst the translated keys on the next run of BartyCrouch.
Example:
$ bartycrouch code -p "/path/to/code/files" -l "/path/to/localizables" -s
If you use any service or other tool that alters your Strings files and if BartyCrouch seems to change the beginning and ends of those files due to different whitespacing/newline conventions, then you can simply use the -u
command to keep the beginning and end as they are. By default BartyCrouch adds exactly one line to both the beginning and end of a file. Note that this option keeps up to 10 newline/whitespace characters from the original file at both beginning and end.
Example:
$ bartycrouch interfaces -p "/path/to/project" -u
If you use a custom function in your code to localize your Strings (instead of NSLocalizedString
) you can specify it using this option. BartyCrouch passes this along to the genstrings
/extractLocStrings
tools. So you need to make sure your custom function follows the requirements of genstrings
/extractLocStrings
.
$ bartycrouch code -p "/path/to/code/files" -l "/path/to/Localizables" -f "YourCustomFunction"
If you want to use a different name for your Localizable.strings
file for whatever reason, you can specify a custom name using this option like this:
$ bartycrouch code -p "/path/to/code/files" -l "/path/to/Localizables" -n "MyCustomLocalizable"
Here's an overview of all options available for the sub command translate
:
path
(required),override
andverbose
(see Options for all Sub Commands above)id
(required)secret
(required)locale
(required)
BartyCrouch acts as a client for the Microsoft Translator API. In order to use that API you need to register here (the free tier allows for 2 million translations/month). Then you can add a client here which will provide you the id
and secret
credentials required for machine-translation.
Example:
$ bartycrouch translate -p "/path/to/project" -l en -i "<YOUR_API_ID>" -s "<YOUR_API_SECRET>"
This specifies the source language to use as the input for machine-translation. BartyCrouch can only translate keys which have a value in their source language.
Example:
# Uses Simpliied Chinese as the source language for translating to all other languages
$ bartycrouch translate -p "/path/to/project" -l "zh-Hans" -i "<API_ID>" -s "<API_SECRET>"
Here's an overview of all options available for the sub command normalize
:
path
(required),override
andverbose
(see Options for all Sub Commands above)locale
(required)prevent-duplicate-keys
warn-empty-values
harmonize-with-source
sort-by-keys
Specify the source locale from which to normalize other languages Strings files (.strings).
Example:
$ bartycrouch normalize -p "/path/to/code/files" -l en
Warns if Strings files contain duplicate keys or removes duplicates automatically if values are equal.
Example:
$ bartycrouch normalize -p "/path/to/code/files" -l en -d
Warns if Strings files contain keys with empty values. Designed to be used as part of Xcode build scripts.
Example:
$ bartycrouch normalize -p "/path/to/code/files" -l en -w
Makes sure all languages have exactly the same keys as the source language specified with -l
. This command will remove all keys from target languages files which don't appear in the source language file. And vice versa it also adds keys to target language files that are missing compared to the source language file.
Example:
$ bartycrouch normalize -p "/path/to/code/files" -l en -h
If you want the order of translations in your Strings files to be alphabetically sorted by their keys just use the option -s
. To ensure that you can still easily find your untranslated keys this option will check the value of your translations and place those without a translation at the end of the file. Once you translated those entries they will be correctly sorted amongst the translated keys on the next run of BartyCrouch.
Example:
$ bartycrouch normalize -p "/path/to/code/files" -l en -s
Here's an overview of all options available for the sub command lint
:
path
(required) (see Options for all Sub Commands above)duplicate-keys
empty-values
Fails if any Strings file contains duplicate keys. Designed to be used as part of a CI service.
Example:
$ bartycrouch lint -p "/path/to/code/files" -d
Fails if any Strings file contains a key with an empty value. Designed to be used as part of a CI service.
Example:
$ bartycrouch lint -p "/path/to/code/files" -e
You may want to update your Strings files on each build automatically what you can easily do by adding a run script to your target in Xcode. In order to do this select your target, choose the Build Phases
tab and click the + button on the top left corner of that pane. Select New Run Script Phase
and copy the following into the text box below the Shell: /bin/sh
of your new run script phase:
if which bartycrouch > /dev/null; then
# Incrementally update all Storyboards/XIBs strings files
bartycrouch interfaces -p "$PROJECT_DIR"
# Add new keys to Localizable.strings files from NSLocalizedString in code
bartycrouch code -p "$PROJECT_DIR" -l "$PROJECT_DIR" -a -s
else
echo "warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch"
fi
Note: Please make sure you commit your code using source control regularly when using the build script method.
If you want to use the machine translation functionality in addition then simply use the following build script instead:
if which bartycrouch > /dev/null; then
# Incrementally update all Storyboards/XIBs strings files
bartycrouch interfaces -p "$PROJECT_DIR"
# Add new keys to Localizable.strings files from NSLocalizedString in code
bartycrouch code -p "$PROJECT_DIR" -l "$PROJECT_DIR" -a -s
# Translate all empty values using the Microsoft Translator API
bartycrouch translate -p "$PROJECT_DIR" -l en -i "<API_ID>" -s "<API_SECRET>"
else
echo "warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch"
fi
It is recommended that you update the -p "$PROJECT_DIR"
appearances in this script to point to the directory of your own code only, for example by using -p "$PROJECT_DIR/Sources"
instead. Also you should alter -l "$PROJECT_DIR"
to a path more specific (e.g. -l "$PROJECT_DIR/Sources/Supporting Files"
). This is to make sure BartyCrouch doesn't change any Localizable.strings
files within frameworks included using the likes of Carthage or CocoaPods.
Alternatively, if you've installed BartyCrouch via CocoaPods the script should look like this:
"${PODS_ROOT}/BartyCrouch/bartycrouch" interfaces -p "$PROJECT_DIR"
Sometimes you may want to ignore some specific views containing localizable texts e.g. because their values are gonna be set programmatically.
For these cases you can simply include #bartycrouch-ignore!
or the shorthand #bc-ignore!
into your value within your base localized Storyboard/XIB file. Alternatively you can add #bc-ignore!
into the field "Comment For Localizer" box in the utilities pane.
This will tell BartyCrouch to ignore this specific view when updating your .strings
files.
Here's an example of how a base localized view in a XIB file with partly ignored strings might look like:
Here's an example with the alternative comment variant:
You can also use #bc-ignore!
in your NSLocalizedString
macros comment part to ignore them so they are not added to your Localizable.strings
. This is helpful when you are using a .stringsdict
file to handle pluralization (see docs).
For example you can do something like this:
func updateTimeLabel(minutes: Int) {
String.localizedStringWithFormat(NSLocalizedString("%d minute(s) ago", comment: "pluralized and localized minutes #bc-ignore!"), minutes)
}
The %d minute(s) ago
key will be taken from Localizable.stringsdict file, not from Localizable.strings.
This project follows Semantic Versioning.
Please follow the appropriate guide below when upgrading to a new major version of BartyCrouch (e.g. 1.5 -> 2.0).
- Change structure
bartycrouch -s "$BASE_PATH"
tobartycrouch interfaces -p "$BASE_PATH"
- Change structure
bartycrouch -t "{ id: <API_ID> }|{ secret: <API_SECRET> }" -s "$BASE_PATH" -l en
tobartycrouch translate -p "$BASE_PATH" -l en -i "<API_ID>" -s "<API_SECRET>"
- Use automatic file search with
-p
(was-s
before) instead of options-i
,-o
,-e
(those were deleted) - Rename usages of option "force" (
-f
) to be "override" (-o
)
It is recommended to update your build script to the currently suggested one if you were using it.
- Change command structure
bartycrouch "$BASE_PATH" -a
tobartycrouch -s "$BASE_PATH"
- Remove
-c
option if you were using it, BartyCrouch 2.x creates missing keys by default - Use the new
-t
-s
-l
options instead of adding all Strings files manually, e.g.:
Simplify this build script code
bartycrouch -t $CREDS -i "$EN_PATH/Localizable.strings" -a -c
bartycrouch -t $CREDS -i "$EN_PATH/Main.strings" -a
bartycrouch -t $CREDS -i "$EN_PATH/LaunchScreen.strings" -a
bartycrouch -t $CREDS -i "$EN_PATH/CustomView.strings" -a
by replacing it with this:
bartycrouch -t "$CREDS" -s "$PROJECT_DIR" -l en
--input-storyboard
and-in
were renamed to--input
and-i
--output-strings-files
and-out
were renamed to--output
and-o
- Multiple paths passed to
-output
are now separated by whitespace instead of comma- e.g.
-out "path/one,path/two"
should now be-o "path/one" "path/two"
- e.g.
--output-all-languages
and-all
were renamed to--auto
and-a
Contributions are welcome. Please just open an Issue on GitHub to discuss a point or request a feature there or send a Pull Request with your suggestion.
When sending a pull request please also make sure to:
- write tests for your changes in order to make sure they don't break in the future
- follow the same syntax and semantic in your commit messages (see rationale here)
Note that there is a framework target within the project to make testing easier.
This library is released under the MIT License. See LICENSE for details.