Localization/I18n: Incrementally update/translate your Strings files from .swift, .h, .m(m), .storyboard or .xib files.

Overview

CI Status Version: 4.6.0 Swift: 5.4 License: MIT
PayPal: Donate GitHub: Become a sponsor Patreon: Become a patron

InstallationConfigurationUsageBuild ScriptDonationMigration GuidesIssuesContributingLicense

BartyCrouch

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 60+ 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.

Checkout this blog post to learn how you can effectively use BartyCrouch in your projects.

Requirements

  • Xcode 12.5+ & Swift 5.4+
  • Xcode Command Line Tools (see here for installation instructions)

Getting Started

Installation

Via Homebrew

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 upgrade bartycrouch
Via Mint

To install or update to the latest version of BartyCrouch simply run this command:

mint install Flinesoft/BartyCrouch

Configuration

To configure BartyCrouch for your project, first create a configuration file within your projects root directory. BartyCrouch can do this for you:

bartycrouch init

Now you should have a file named .bartycrouch.toml with the following contents:

[update]
tasks = ["interfaces", "code", "transform", "normalize"]

[update.interfaces]
paths = ["."]
defaultToBase = false
ignoreEmptyStrings = false
unstripped = false

[update.code]
codePaths = ["."]
localizablePaths = ["."]
defaultToKeys = false
additive = true
unstripped = false

[update.transform]
codePaths = ["."]
localizablePaths = ["."]
transformer = "foundation"
supportedLanguageEnumPath = "."
typeName = "BartyCrouch"
translateMethodName = "translate"

[update.normalize]
paths = ["."]
sourceLocale = "en"
harmonizeWithSource = true
sortByKeys = true

[lint]
paths = ["."]
duplicateKeys = true
emptyValues = true

This is the default configuration of BartyCrouch and should work for most projects as is. In order to use BartyCrouch to its extent, it is recommended though to consider making the following changes:

  1. To speed it up significantly, provide more specific paths for any key containing path if possible (especially in the update.transform section, e.g. ["App/Sources"] for codePaths or ["App/Supporting Files"] for supportedLanguageEnumPaths).
  2. Remove the code task if your project is Swift-only and you use the new transform update task.
  3. If you are using SwiftGen with the structured-swift4 template, you will probably want to use the transform task and change its transformer option to swiftgenStructured.
  4. If you decided to use the transform task, create a new file in your project (e.g. under SupportingFiles) named BartyCrouch.swift and copy the following code:
//  This file is required in order for the `transform` task of the translation helper tool BartyCrouch to work.
//  See here for more details: https://github.com/Flinesoft/BartyCrouch

import Foundation

enum BartyCrouch {
    enum SupportedLanguage: String {
        // TODO: remove unsupported languages from the following cases list & add any missing languages
        case arabic = "ar"
        case chineseSimplified = "zh-Hans"
        case chineseTraditional = "zh-Hant"
        case english = "en"
        case french = "fr"
        case german = "de"
        case hindi = "hi"
        case italian = "it"
        case japanese = "ja"
        case korean = "ko"
        case malay = "ms"
        case portuguese = "pt-BR"
        case russian = "ru"
        case spanish = "es"
        case turkish = "tr"
    }

    static func translate(key: String, translations: [SupportedLanguage: String], comment: String? = nil) -> String {
        let typeName = String(describing: BartyCrouch.self)
        let methodName = #function

        print(
            "Warning: [BartyCrouch]",
            "Untransformed \(typeName).\(methodName) method call found with key '\(key)' and base translations '\(translations)'.",
            "Please ensure that BartyCrouch is installed and configured correctly."
        )

        // fall back in case something goes wrong with BartyCrouch transformation
        return "BC: TRANSFORMATION FAILED!"
    }
}
  1. If you don't develop in English as the first localized language, you should update the sourceLocale of the normalize task.
  2. If you want to use the machine translation feature of BartyCrouch, add translate to the tasks list at the top and copy the following section into the configuration file with secret replaced by your Microsoft Translator Text API Subscription Key:
[update.translate]
paths = "."
secret = "<#Subscription Key#>"
sourceLocale = "en"

Usage

Before using BartyCrouch please make sure you have committed your code. Also, we highly recommend using the build script method described below.


bartycrouch accepts one of the following sub commands:

  • update: Updates your .strings file contents according to your configuration.
  • lint: Checks your .strings file contents for empty values & duplicate keys.

Also the following command line options can be provided:

  • -v, --verbose: Prints more detailed information about the executed command.
  • -x, --xcode-output: Prints warnings & errors in Xcode compatible format.
  • -w, --fail-on-warnings: Returns a failed status code if any warning is encountered.
  • -p, --path: Specifies a different path than current to run BartyCrouch from there.

update subcommand

The update subcommand can be run with one or multiple of the following tasks:

  • interfaces: Updates .strings files of Storyboards & XIBs.
  • code: Updates Localizable.strings file from NSLocalizedString entries in code.
  • transform: A mode where BartyCrouch replaces a specific method call to provide translations in multiple languages in a single line. Only supports Swift files.
  • translate: Updates missing translations in other languages than the source language.
  • normalize: Sorts & cleans up .strings files.

In order to configure which tasks are executed, edit this section in the config file:

[update]
tasks = ["interfaces", "code", "transform", "normalize"]
Options for interfaces
  • paths: The directory / directories to search for Storyboards & XIB files.
  • defaultToBase: Add Base translation as value to new keys.
  • ignoreEmptyStrings: Doesn't add views with empty values.
  • unstripped: Keeps whitespaces at beginning & end of Strings files.
Options for code
  • codePaths: The directory / directories to search for Swift code files.
  • localizablePaths: The enclosing path(s) containing the localized Localizable.strings files.
  • defaultToKeys: Add new keys both as key and value.
  • additive: Prevents cleaning up keys not found in code.
  • customFunction: Use alternative name to NSLocalizedString.
  • customLocalizableName: Use alternative name for Localizable.strings.
  • unstripped: Keeps whitespaces at beginning & end of Strings files.
  • plistArguments: Use a plist file to store all the code files for the ExtractLocStrings tool. (Recommended for large projects.)
Options for transform
  • codePaths: The directory / directories to search for Swift code files.
  • localizablePaths: The enclosing path(s) containing the localized Localizable.strings files.
  • transformer: Specifies the replacement code. Use foundation for NSLocalizedString or swiftgenStructured for L10n entries.
  • supportedLanguageEnumPath: The enclosing path containing the SupportedLanguage enum.
  • typeName: The name of the type enclosing the SupportedLanguage enum and translate method.
  • translateMethodName: The name of the translate method to be replaced.
  • customLocalizableName: Use alternative name for Localizable.strings.
Options for translate
Options for normalize
  • paths: The directory / directories to search for Strings files.
  • sourceLocale: The source language to harmonize keys of other languages with.
  • harmonizeWithSource: Synchronizes keys with source language.
  • sortByKeys: Alphabetically sorts translations by their keys.

lint subcommand

The lint subcommand was designed to analyze a project for typical translation issues. The current checks include:

  • duplicateKeys: Finds duplicate keys within the same file.
  • emptyValues: Finds empty values for any language.

Note that the lint command can be used both on CI and within Xcode via the build script method:

  • In Xcode the -x or --xcode-output command line argument should be used to get warnings which point you directly to the found issue.
  • When running on the CI you should specify the -w or --fail-on-warnings argument to make sure BartyCrouch fails if any warnings are encountered.

Localization Workflow via transform

When the transform update task is configured (see recommended step 4 in the Configuration section above) and you are using the build script method, you can use the following simplified process for writing localized code during development:

  1. Instead of NSLocalizedString calls you can use BartyCrouch.translate and specify a key, translations (if any) and optionally a comment. For example:
self.title = BartyCrouch.translate(key: "onboarding.first-page.header-title",  translations: [.english: "Welcome!"])
  1. Once you build your app, BartyCrouch will automatically add the new translation key to all your Localizable.strings files and add the provided translations as values for the provided languages.
  2. Additionally, during the same build BartyCrouch will automatically replace the above call to BartyCrouch.translate with the proper translation call, depending on your transformer option setting.

The resulting code depends on your transformer option setting:

When set to foundation, the above code will transform to:

self.title = NSLocalizedString("onboarding.first-page.header-title", comment: "")

When set to swiftgenStructured it will transform to:

self.title = L10n.Onboarding.FirstPage.headerTitle

Advantages of transform over the code task:

  • You can provide translations for keys without switching to the Strings files.
  • In case you use SwiftGen, you don't need to replace calls to NSLocalizedString with L10n calls manually after running BartyCrouch.
  • Can be combined with the machine translation feature to provide a source language translation in code and let BartyCrouch translate it to all supported languages in a single line & without ever leaving the code.

Disadvantages of transform over the code task:

  • Only works for Swift Code. No support for Objective-C. (You can use both methods simultaneously though.)
  • Xcode will mark the freshly transformed code as errors (but build will succeed anyways) until next build.
  • Not as fast as code since SwiftSyntax currently isn't particularly fast. (But this should improve over time!)

NOTE: As of version 4.x of BartyCrouch formatted localized Strings are not supported by this automatic feature.

Build Script

In order to truly profit from BartyCrouch's ability to update & lint your .strings files you can make it a natural part of your development workflow within 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
    bartycrouch update -x
    bartycrouch lint -x
else
    echo "warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch"
fi

Next, make sure the BartyCrouch script runs before the steps Compiling Sources (and SwiftGen if used) by moving it per drag & drop, for example right after Target Dependencies.

Now BartyCrouch will be run on each build and you won't need to call it manually ever (again). Additionally, all your co-workers who don't have BartyCrouch installed will see a warning with a hint on how to install it.

Note: Please make sure you commit your code using source control regularly when using the build script method.


Exclude specific Views / NSLocalizedStrings from Localization

Sometimes you may want to ignore some specific views containing localizable texts e.g. because their values are going to 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 might be 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, that's why it should be ignored by BartyCrouch.

Donation

BartyCrouch was brought to you by Cihat Gündüz in his free time. If you want to thank me and support the development of this project, please make a small donation on PayPal. In case you also like my other open source contributions and articles, please consider motivating me by becoming a sponsor on GitHub or a patron on Patreon.

Thank you very much for any donation, it really helps out a lot! 💯

Migration Guides

See the file MIGRATION_GUIDES.md.

Contributing

Contributions are welcome. Feel free to open an issue on GitHub with your ideas or implement an idea yourself and post a pull request. If you want to contribute code, please try to follow the same syntax and semantic in your commit messages (see rationale here). Also, please make sure to add an entry to the CHANGELOG.md file which explains your change.

After Release Checklist:

  1. Run make portable_zip to generate .build/release/portable_bartycrouch.zip
  2. Create new release with text from new CHANGELOG.md section & attach portable_bartycrouch.zip as binary
  3. Run pod trunk push to make a new release known to CocoaPods
  4. Update tag and revision in Formula/bartycrouch.rb, commit & push change
  5. Run brew bump-formula-pr bartycrouch --tag=<tag> --revision=<revision>

License

This library is released under the MIT License. See LICENSE for details.

Comments
  • BartyCrouch:  Could not parse syntax tree of Swift file.

    BartyCrouch: Could not parse syntax tree of Swift file.

    Expected Behavior

    No warning's should show

    Actual Behavior

    Two warnings shows as follows

    • BartyCrouch: Could not find 'SupportedLanguage' enum within 'BartyCrouch' enum within path.
    • BartyCrouch: Could not parse syntax tree of Swift file. #199

    Steps to Reproduce the Problem

    1. Open any project on Xcode 12.0 (12A7209)
    2. Proceed to build project with implmentation
    3. Then in the build warnings you will get the following errors [September 23rd, 2020]

    Specifications

    • Version: iOS 14
    • Platform: Mac OS
    • IDE Version: Xcode 12.0 (12A7209)

    Example

    Screen Shot 2020-09-23 at 1 17 46 AM bug 
    opened by trujamal 21
  • Exception: 'Couldn't posix_spawn: error 7'

    Exception: 'Couldn't posix_spawn: error 7'

    Hi,

    bartycrouch code -p "$HOME/Dev/Projects/Project1" -l "$HOME/Dev/Projects/Project1/" 2018-03-20 20:43:16.367 bartycrouch[90434:6107769] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't posix_spawn: error 7' *** First throw call stack: ( 0 CoreFoundation 0x00007fff3fa27fcb __exceptionPreprocess + 171 1 libobjc.A.dylib 0x00007fff666cac76 objc_exception_throw + 48 2 CoreFoundation 0x00007fff3fab99ed +[NSException raise:format:] + 205 3 Foundation 0x00007fff41c5eaf0 -[NSConcreteTask launchWithDictionary:error:] + 4486 4 bartycrouch 0x0000000103a1dce7 bartycrouch + 257255 5 bartycrouch 0x0000000103a32221 bartycrouch + 340513 6 bartycrouch 0x0000000103a31831 bartycrouch + 337969 7 bartycrouch 0x0000000103a1f53d bartycrouch + 263485 8 bartycrouch 0x0000000103a20d67 bartycrouch + 269671 9 bartycrouch 0x0000000103a24e29 bartycrouch + 286249 10 bartycrouch 0x00000001039e148a bartycrouch + 9354 11 bartycrouch 0x00000001039e11f9 bartycrouch + 8697 12 libdyld.dylib 0x00007fff672ba115 start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException Abort trap: 6

    opened by Droppix 18
  • Handling long list of arguments for extractLocStrings

    Handling long list of arguments for extractLocStrings

    Handling long list of arguments for extractLocStrings by writing them in a arguments plist file.

    This solves errors that causes crash with Exception: 'Couldn't posix_spawn: error 7'.

    Fixes Flinesoft/BartyCrouch#92 This PR with minor modifications can also fix Flinesoft/BartyCrouch#99

    opened by csknns 16
  • Error! No file exists at output path '<path><file>.strings'.

    Error! No file exists at output path '.strings'.

    I'm honestly having a hard time understanding why I have this error. I have a Storyboard localized in base + 1 language, Then I have a Localizable.strings file for the NSLocalizedString(s) in code (which I performed using in swift a ".localized" extension to String). Here's the storyboard with its .strings file localized in italian screen shot 2017-08-18 at 09 50 46 here some other xib localized (some using .strings some using localized .xib) screen shot 2017-08-18 at 09 50 53

    I have this error:

    $ nowr-ios (master) $ bartycrouch interfaces -p .
    BartyCrouch: Successfully updated strings file(s) of Storyboard or XIB file.
    Error! No file exists at output path './nowr-ios/Code/it.lproj/LoginViewController.strings'.
    

    Am I missing something obvious or is there a bug?

    opened by superandrew 13
  • Illegal instruction: 4  bartycrouch lint -x

    Illegal instruction: 4 bartycrouch lint -x

    Happens every time I build. I have to perform a clean build folder before building in order to run the app. Any Ideas what is causing it? Bartycrouch installed via Homebrew, Xcode 11.1.

    /Users/xxxxx/xxxxx/xxxxx/xxxxx/Build/Intermediates/xxxxx.build/Debug-iphoneos/xxxxx.build/Script-61962FBF23631A6400AC3F60.sh: line 7: 34489 Illegal instruction: 4 bartycrouch update -x /Users/xxxxx/xxxxx/xxxxx/xxxxx/Build/Intermediates/xxxxx.build/Debug-iphoneos/xxxxx.build/Script-61962FBF23631A6400AC3F60.sh: line 7: 34527 Illegal instruction: 4 bartycrouch lint -x Command PhaseScriptExecution failed with a nonzero exit code

    Scrip I'm running in build phases:

    if which bartycrouch > /dev/null; then
        bartycrouch update -x
        bartycrouch lint -x
    else
        echo "warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch"
    fi
    
    help wanted 
    opened by swebal 12
  • Base language detection

    Base language detection

    I have a project, with following language-related properties in project.pbxproj developmentRegion = English; knownRegions = ( en, Base, sk, cs, ); Also the Info.plist has <key>CFBundleDevelopmentRegion</key> set to <string>en</string>. All the designer files (storyboard, views etc.) are designed in English.

    Whenever I run bartycrouch interfaces -p "." in the project root folder, I get all the *.strings files updated, however all the strings from the designer files are written into files in the cs.lproj folder (where the Czech language is supposed to be) instead of the en.proj folder.

    Is there something wrong with my project? Or is there a way (parameter?) to specify my base language for bartycrouch?

    Thank you

    opened by AlmightyCZ 12
  • Comments are not being updated with `code` option

    Comments are not being updated with `code` option

    Given that I have fully translated app with code String files And I have String let sample = NSLocalizedString("category.sample", comment: "Sample") When I change a comment for sample String to comment: "New Sample" Then comment is not updated in Strings file.

    Are you going to implement that feature in future?

    Btw. super useful tool! Thanks

    enhancement 
    opened by m9rc1n 12
  • Error 260 - tmpstrings not found

    Error 260 - tmpstrings not found

    Hello,

    i am trying to use BartyCrouch, but i always get the error 260 while domain is NSCocoaErrorDomain.

    I am using this command (all my subfolders like en.lproj with the Localizable.strings files are in the subfolder Localizable. And Beatsnap is the root folder where all code is structures (also subfolders here)

    bartycrouch code -p Beatsnap/ -l Beatsnap/Localizable -a -v

    and getting this response

    Error Domain=NSCocoaErrorDomain Code=260 "The file “Localizable.strings” couldn’t be opened because there is no such file." UserInfo={NSFilePath=Beatsnap//tmpstrings/Localizable.strings, NSUnderlyingError=0x7f92a2600af0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
    Incrementally updated keys of file 'Beatsnap/Localizable/Base.lproj/Localizable.strings'.
    Error Domain=NSCocoaErrorDomain Code=260 "The file “Localizable.strings” couldn’t be opened because there is no such file." UserInfo={NSFilePath=Beatsnap//tmpstrings/Localizable.strings, NSUnderlyingError=0x7f92a251ea10 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
    Incrementally updated keys of file 'Beatsnap/Localizable/de.lproj/Localizable.strings'.
    Error Domain=NSCocoaErrorDomain Code=260 "The file “Localizable.strings” couldn’t be opened because there is no such file." UserInfo={NSFilePath=Beatsnap//tmpstrings/Localizable.strings, NSUnderlyingError=0x7f92a2700ec0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
    Incrementally updated keys of file 'Beatsnap/Localizable/en.lproj/Localizable.strings'.
    BartyCrouch: Successfully updated strings file(s) of Code files.
    

    And even though i added another NSLocalizedString and says "Successfully updated..." the file Beatsnap/Localizable/en.lproj/Localizable.strings is not changed

    duplicate 
    opened by mlostekk 12
  • New issues after upgrade to latest version

    New issues after upgrade to latest version

    Expected Behavior

    Compiling without any warnings/errors

    Actual Behavior

    Two new warnings - one was solved, one still exist:

    Solved one: Could not parse syntax tree of Swift File I solved it by adding path to supportedLanguageEnumPath from update.transform section

    Not solved warning: Could not find SupportedLanguage enum within BartyCrouch enum within path I check few things at .bartycrouch.toml file but warning still occur

    My toml file:

    [update]
    tasks = ["interfaces", "transform", "normalize"]
    
    [update.interfaces]
    paths = ["."]
    defaultToBase = false
    ignoreEmptyStrings = false
    unstripped = false
    
    [update.transform]
    codePaths = ["."]
    localizablePaths = ["."]
    transformer = "swiftgenStructured"
    supportedLanguageEnumPath = "GU1DE/SupportingFiles"
    typeName = "BartyCrouch"
    translateMethodName = "translate"
    
    [update.normalize]
    paths = ["."]
    sourceLocale = "en"
    harmonizeWithSource = true
    sortByKeys = true
    
    [lint]
    paths = ["."]
    duplicateKeys = true
    emptyValues = true
    
    

    Specifications

    • Version: latest
    • Platform: macOS Catalina 10.15.7
    • IDE Version: Xcode 12.0.1

    BR Mateusz

    help wanted 
    opened by MSlaski 11
  • No Translation attempted: No source language files found. No input files found

    No Translation attempted: No source language files found. No input files found

    I have a fairly non-standard setup for a macOS project with multiple targets.

    My config file is "vanilla":

    [update]
    tasks = ["interfaces", "code", "transform", "normalize", "translate"]
    
    [update.interfaces]
    paths = ["."]
    defaultToBase = false
    ignoreEmptyStrings = false
    unstripped = false
    
    [update.code]
    codePaths = ["."]
    localizablePaths = ["."]
    defaultToKeys = false
    additive = true
    unstripped = false
    plistArguments = true
    
    [update.transform]
    codePaths = ["."]
    localizablePaths = ["."]
    transformer = "foundation"
    supportedLanguageEnumPath = "."
    typeName = "BartyCrouch"
    translateMethodName = "translate"
    
    [update.normalize]
    paths = ["."]
    sourceLocale = "en"
    harmonizeWithSource = true
    sortByKeys = true
    
    [update.translate]
    paths = "."
    secret = "--removed for posting but valid--"
    sourceLocale = "en"
    
    [lint]
    paths = ["."]
    duplicateKeys = true
    emptyValues = true
    
    

    running the update task outputs:

    2020-07-16 17:27:55.151: ✅  ./Base.lproj/RemoveGPSData.xib:  Successfully updated strings file(s) of Storyboard or XIB file.
    Task 'Update Interfaces' took 4.585 seconds.
    Starting Task 'Update Code' ...
    2020-07-16 17:27:55.697: ℹ️  Incrementally updated keys of file '/Users/frankreiff/Dropbox/git/abfa4/Resources/FMT5/de.lproj/Localizable.strings'.
    2020-07-16 17:27:55.710: ℹ️  Incrementally updated keys of file '/Users/frankreiff/Dropbox/git/abfa4/Resources/Distribution/de.lproj/Localizable.strings'.
    2020-07-16 17:27:55.721: ℹ️  Incrementally updated keys of file '/Users/frankreiff/Dropbox/git/abfa4/Resources/Distribution/fr.lproj/Localizable.strings'.
    2020-07-16 17:27:55.735: ℹ️  Incrementally updated keys of file '/Users/frankreiff/Dropbox/git/abfa4/Resources/FDC5/de.lproj/Localizable.strings'.
    2020-07-16 17:27:55.751: ℹ️  Incrementally updated keys of file '/Users/frankreiff/Dropbox/git/abfa4/Resources/PDC/de.lproj/Localizable.strings'.
    2020-07-16 17:27:55.772: ℹ️  Incrementally updated keys of file '/Users/frankreiff/Dropbox/git/abfa4/Code/App/Base.lproj/Localizable.strings'.
    2020-07-16 17:27:55.773: ✅  .:  Successfully updated strings file(s) of Code files.
    Task 'Update Code' took 0.622 seconds.
    Starting Task 'Code Transform' ...
    Task 'Code Transform' took 0.255 seconds.
    Starting Task 'Normalize' ...
    2020-07-16 17:27:56.059: ⚠️  No source language files found.
    Starting Task 'Translate' ...
    2020-07-16 17:27:56.090: ⚠️  No input files found.
    

    Indicating that the Localizable.strings files are found just fine, but then the 'Normalize' and 'Translate' tasks don't seem to be finding anything.

    The ‘/Users/frankreiff/Dropbox/git/abfa4/Resources/Distribution/fr.lproj/Localizable.strings‘ file has hundreds of empty translations. All the other xib and .strings files are all already localized in French and German.

    I'm sure I'm missing something.. just not sure what :-)

    Any help would be appreciated.

    bug 
    opened by frankrei 11
  • dyld: Library not loaded: @rpath/lib_InternalSwiftSyntaxParser.dylib

    dyld: Library not loaded: @rpath/lib_InternalSwiftSyntaxParser.dylib

    Hi I'm having this issue:

    dyld: Library not loaded: @rpath/lib_InternalSwiftSyntaxParser.dylib
      Referenced from: /usr/local/bin/bartycrouch
      Reason: image not found
    zsh: abort      bartycrouch init
    

    I saw an issue reported here but its closed, in that one you said that we should install using brew. I installed BartyCrouch using brew since the beginning following the tutorial https://medium.com/@mds6058/localization-in-ios-and-how-to-make-it-not-suck-3adcbc3ec08f

    I'm using xcode 11.3.1 (I need this version, so installed Xcode manually, downloading the xip 11.3.1:/) is this the problem? Do I need 11.4? Or maybe the file locations? I've MacOS Catalina 10.15.4

    Thanks

    question 
    opened by EinSoldiatGott 11
  • Fix multiple code paths

    Fix multiple code paths

    Fixes https://github.com/FlineDev/BartyCrouch/issues/264

    Proposed Changes

    I have adjusted the logic of incrementalCodeUpdate method to properly handle extracting strings from source files specified via multiple entries in update.code.codePaths option.

    In the past, the logic was to walk all codePaths directories. For each directory create a temporary .strings file. Merge all entries from the temporary .strings file into output. Invoking this logic for multiple codePaths in additive=false mode would repeatedly overwrite the output Localized.strings file with only the entries extracted from currently processed directory and would remove everything else.

    The new logic uses only one temporary .strings file into which all entries from all codePaths are extracted by using extractLocStrings -a (the append mode) and only after that are all strings from the temporary .strings file merged into the output Localizable.strings.

    Changes

    • When invoking extractLocStrings specify the -a option to append extracted strings into temporary .strings file instead of replacing them.
    • Use just one temporary .strings file for all strings extracted during code.update

    Testing

    I have a testing project with the following .bartycrouch.toml Multiple entries via update.code.codePaths, and update.code.additive=false Each subdirectory contains one NSLocalizedString entry.

    [update]
    tasks = ["code", "normalize"]
    
    [update.code]
    codePaths = ["Sources/TestBartyCrouch", "Sources/TestBartyCrouch1"]
    localizablePaths = ["."]
    additive = false
    
    [update.normalize]
    paths = ["."]
    sourceLocale = "en"
    
    [lint]
    paths = ["."]
    subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
    duplicateKeys = true
    emptyValues = true
    

    Invoking published release against this project results in only one entry detected:

    € rm en.lproj/Localizable.strings && touch en.lproj/Localizable.strings
    
    € bartycrouch update -v                                                
    Starting Task 'Update Code' ...
    2022-10-11 16:37:39.523: ℹ️  Incrementally updated keys of file '/Users/mman/Developer/TestBartyCrouch/en.lproj/Localizable.strings'.
    2022-10-11 16:37:39.527: ✅  Sources/TestBartyCrouch:  Successfully updated strings file(s) of Code files.
    2022-10-11 16:37:39.596: ℹ️  Incrementally updated keys of file '/Users/mman/Developer/TestBartyCrouch/en.lproj/Localizable.strings'.
    2022-10-11 16:37:39.597: ✅  Sources/TestBartyCrouch1:  Successfully updated strings file(s) of Code files.
    Task 'Update Code' took 0.144 seconds.
    Starting Task 'Normalize' ...
    
    € cat en.lproj/Localizable.strings 
    /* Greeting from TestBartyCrouch1 target */
    "Hello, World, 1!" = "";
    

    Invoking version with the new logic results in:

    € rm en.lproj/Localizable.strings && touch en.lproj/Localizable.strings
    € ../BartyCrouch/.build/debug/bartycrouch update -v
    Starting Task 'Update Code' ...
    2022-10-11 16:38:53.051: ✅  Sources/TestBartyCrouch:  Successfully updated strings file(s) of Code files.
    2022-10-11 16:38:53.120: ✅  Sources/TestBartyCrouch1:  Successfully updated strings file(s) of Code files.
    2022-10-11 16:38:53.123: ℹ️  Incrementally updated keys of file '/Users/mman/Developer/TestBartyCrouch/en.lproj/Localizable.strings'.
    Task 'Update Code' took 0.141 seconds.
    Starting Task 'Normalize' ...
    
    € cat en.lproj/Localizable.strings 
    /* Greeting from TestBartyCrouch target */
    "Hello, World!" = "";
    
    /* Greeting from TestBartyCrouch1 target */
    "Hello, World, 1!" = "";
    
    opened by mman 1
  • [Bug] update.code with additive=false and code in multiple parent directories looses strings

    [Bug] update.code with additive=false and code in multiple parent directories looses strings

    Steps to Reproduce:

    I have my .bartycrouch.toml configured in a way that it looks up strings in multiple code directories referenced via ../ and combining them into one Localizable.strings file located in ./

    For example like this:

    [update]
    tasks = ["interfaces", "code", "normalize"]
    
    [update.interfaces]
    paths = ["../App"]
    defaultToBase = false
    ignoreEmptyStrings = false
    unstripped = false
    
    [update.code]
    codePaths = ["../App", "../Shared", "../Shared2"]
    subpathsToIgnore = ["Vendor"]
    localizablePaths = ["."]
    defaultToKeys = false
    additive = false
    unstripped = false
    plistArguments = true
    customFunction = "LocalizedStringResource"
    
    [update.normalize]
    paths = ["."]
    sourceLocale = "en"
    harmonizeWithSource = true
    sortByKeys = true
    
    [lint]
    paths = ["."]
    duplicateKeys = true
    emptyValues = true
    

    Expected Behavior:

    I expect bartycrouch update to combine all strings from all sources, clean them up and put them into one Localizable.strings file.

    Current Behavior:

    in additive=false mode strings from all directories but last specified via codePaths are lost and only strings for the last code directory are output.

    This means that all strings from ../App and ../Shared directories are lost and only strings found in ../Shared2 are actually output. Not sure if it is related to the fact that I use parent dir ../ references.

    Workaround:

    For now I have found a workaround to specify just one entry in codePaths and skip unwanted stuff via subpathsToIgnore.

    Environment

    Show environment details
    € bartycrouch --version
    Version: 4.11.0
    
    opened by mman 5
  • Remove empty lines from source files

    Remove empty lines from source files

    Proposed Changes

    When using the following options the empty lines was not removed in the source files

    [update.normalize]
    paths = ["./Sources"]
    sourceLocale = "sv"
    separateWithEmptyLine = false
    sortByKeys = false
    harmonizeWithSource = true
    

    This PR make sure to rewrite the source files without empty lines in all cases when separateWithEmptyLine is disabled

    opened by JohNan 4
  • Cocoapods executable doesn't work on x86 machines

    Cocoapods executable doesn't work on x86 machines

    Expected Behavior

    Running the executable distributed via cocoopods in a build phase works as expected. Example: ${PODS_ROOT}/BartyCrouch/bartycrouch lint -x --fail-on-warnings

    Actual Behavior

    An error is returned: bartycrouch: Bad CPU type in executable

    Steps to Reproduce the Problem

    1. Run the executable found at Pods/BartyCrouch/bartycrouch

    Specifications

    • Version: 4.9.0
    • Platform: iOS
    • IDE Version: Xcode 13.2.1
    bug Priority: Medium 
    opened by dtaylor1701 18
  • [Continuation] Add support for .intentDefinition files

    [Continuation] Add support for .intentDefinition files

    This is a rebase & continuation of https://github.com/Flinesoft/BartyCrouch/pull/207.

    Fixes #151.

    Unfortunately I can't merge as is, because I couldn't reproduce & check the behavior of this. See my comment here.


    This comment was written during my regular Open Source live stream on Twitch. Follow me there to support my work!

    opened by FlineDevPublic 0
Releases(4.14.1)
Owner
Flinesoft
Flinesoft
Swift friendly localization and i18n with in-app language switching

Localize-Swift Localize-Swift is a simple framework that improves i18n and localization in Swift iOS apps - providing cleaner syntax and in-app langua

Roy Marmelstein 2.9k Dec 29, 2022
Localizations is an OS X app that manages your Xcode project localization files (.strings)

Localizations 0.2 Localizations is an OS X app that manages your Xcode project localization files (.strings). It focuses on keeping .strings files in

Arnaud Thiercelin 129 Jul 19, 2022
Localize is a framework writed in swift to localize your projects easier improves i18n, including storyboards and strings.

Localize Localize is a framework written in swift to help you localize and pluralize your projects. It supports both storyboards and strings. Features

Andres Silva 279 Dec 24, 2022
A micro framework for integrating with the Google Translate api

GoogleTranslateSwift About This is a micro library for integrating with the Google Cloud Translation API. I currently only use it for personal project

Daniel Saidi 7 Dec 19, 2022
iOS localization swift code generation project

code-gen-library - localization-swift module code-gen-library - localization-swift module with Python bash script execute to localization swift files(

umut boz 0 Oct 26, 2021
Localization of the application with ability to change language "on the fly" and support for plural form in any language.

L10n-swift is a simple framework that improves localization in swift app, providing cleaner syntax and in-app language switching. Overview ?? Features

Adrian Bobrowski 287 Dec 24, 2022
transai is a localization tool on Android and iOS.

transai transai is a command line tool to help you do Android and iOS translation management. You can extract string files to csv format, or generate

Jintin 56 Nov 12, 2022
A CLI tool for localization resource management on Xcode. Built with Google Translator.

Supported by Jetbrains Open Source License Program Automatically translate and synchronize '.strings' files from the defined base language The basic c

gitmerge 164 May 4, 2022
Setting up application specific localized string within xib file.

LocalizedView ##What is this? LocalizedView is a helper class for setting up application specific localized string within Xib file. Here is a video de

darkcl 8 Oct 2, 2017
Localizable.strings files generator

Localizable.strings files generator When we want to internationalize our project always is a headache to maintain the Localizable.strings files. This

humdrum 30 Dec 18, 2022
Check Localizable.strings files of iOS Apps

Rubustrings Check the format and consistency of the Localizable.strings files of iOS Apps with multi-language support Rubustrings is also available fo

David Cordero 110 Nov 12, 2022
Lists missing keys from .strings files.

strings-check A simple command line utility to check if translation strings are missing, or if extra translations are present in a set of .strings fil

Dave Clayton-Wagner 3 Nov 22, 2022
The Swift code generator for your assets, storyboards, Localizable.strings, … — Get rid of all String-based APIs!

SwiftGen SwiftGen is a tool to automatically generate Swift code for resources of your projects (like images, localised strings, etc), to make them ty

null 8.3k Jan 3, 2023
Super lightweight library that helps you to localize strings, even directly in storyboards!

Translatio Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 9 or higher. Swi

Andrea Mario Lufino 19 Jan 29, 2022
Minification of localized strings

SmallStrings Reducing localized .strings file sizes by 80% How it works The library consists of two main components: A tool that converts the .strings

Emerge Tools 48 Jan 8, 2023
An application to convert strings to diffirent formats

Localized An application to convert strings to diffirent formats This app will help developers to convert strings from application in one platform to

null 16 Feb 12, 2021
Xcode plugin for quickly creating localized strings

Extractor Localizable Strings Extractor Localizable Strings is a open source plug-in for Xcode. It lets you extract localizable strings without openin

Vinícius Oliveira 220 Jun 29, 2022
Localize iOS apps in a smarter way using JSON files. Swift framework.

Swifternalization Swift library that helps in localizing apps in a different, better, simpler, more powerful way than system localization does. It use

Tomasz Szulc 575 Nov 3, 2022
Localize your views directly in Interface Builder with IBLocalizable

Localize your views easily in Interface Builder with IBLocalizable. With IBLocalizable, you can localize your views in Interface Builder easily. Simpl

Chris Jimenez 461 Dec 29, 2022