Giter VIP home page Giter VIP logo

bartycrouch's Introduction

CI Status Version: 4.14.0 Swift: 5.7 License: MIT
PayPal: Donate GitHub: Become a sponsor Patreon: Become a patron

InstallationConfigurationUsageBuild ScriptDonationMigration GuidesIssuesContributingLicense

Important Notice

Apple introduced String Catalogs in Xcode 15 which implements many aspects of BartyCrouch like the incremental auto-extraction, or warning against empty translations. It's also fully backward-compatible with all iOS versions. Migrating is as simple as right-clicking a .strings file and choosing "Migrate to String Catalog...". I wrote a detailed FAQ about String Catalogs if you want to learn more. It's really awesome, everybody should migrate to it!

The only feature it's missing is machine translation, but I wrote an app to fill the gap and it supports even more translation services than BartyCrouch. Use TranslateKit in the future by simply drag & dropping the String Catalog file and letting it handle the translation, it's really easy.

Note that TranslateKit is being actively worked on. In comparison, BartyCrouch is kept up-to-date only by volunteers in the community.

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 14+ & Swift 5.7+
  • Xcode Command Line Tools (see here for installation instructions)
  • In Xcode 15 or later: Set "User Script Sandboxing" to NO in your target's "Build Settings" tab

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 FlineDev/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 = ["."]
subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
defaultToBase = false
ignoreEmptyStrings = false
unstripped = false
ignoreKeys = ["#bartycrouch-ignore!", "#bc-ignore!", "#i!"]

[update.code]
codePaths = ["."]
subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
localizablePaths = ["."]
defaultToKeys = false
additive = true
unstripped = false
ignoreKeys = ["#bartycrouch-ignore!", "#bc-ignore!", "#i!"]

[update.transform]
codePaths = ["."]
subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
localizablePaths = ["."]
transformer = "foundation"
supportedLanguageEnumPath = "."
typeName = "BartyCrouch"
translateMethodName = "translate"

[update.normalize]
paths = ["."]
subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
sourceLocale = "en"
harmonizeWithSource = true
sortByKeys = true

[lint]
paths = ["."]
subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
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/FlineDev/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 = "."
translator = "microsoftTranslator"
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.
  • subpathsToIgnore: The subpaths to be ignored inside the directories found via the paths option.
  • 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.
  • ignoreKeys: Keys (e.g. in the comment) indicating that specific translation entries should be ignored when generating String files. Useful to ignore strings that are gonna be translated in code.
Options for code
  • codePaths: The directory / directories to search for Swift code files.
  • subpathsToIgnore: The subpaths to be ignored inside the directories found via the paths option.
  • 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 search for strings to localize, in addition to NSLocalizedString, and CFCopyLocalizedString. Defaults to LocalizedStringResource.
  • 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.)
  • ignoreKeys: Keys (e.g. in the comment) indicating that specific translation entries should be ignored when generating String files.
  • overrideComments: Always overrides the comment with the keys new translation, useful for IB files.
Options for transform
  • codePaths: The directory / directories to search for Swift code files.
  • subpathsToIgnore: The subpaths to be ignored inside the directories found via the paths option.
  • 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.
  • separateWithEmptyLine: Set to false if you don't want to have empty lines between Strings entries. Defaults to `true.
Options for translate
  • paths: The directory / directories to search for Strings files.
  • subpathsToIgnore: The subpaths to be ignored inside the directories found via the paths option.
  • translator: Specifies the translation API. Use microsoftTranslator or deepL.
  • secret: Your Microsoft Translator Text API Subscription Key or Authentication Key for DeepL API.
  • sourceLocale: The source language to translate from.
  • separateWithEmptyLine: Set to false if you don't want to have empty lines between Strings entries. Defaults to `true.
Options for normalize
  • paths: The directory / directories to search for Strings files.
  • subpathsToIgnore: The subpaths to be ignored inside the directories found via the paths option.
  • sourceLocale: The source language to harmonize keys of other languages with.
  • harmonizeWithSource: Synchronizes keys with source language.
  • sortByKeys: Alphabetically sorts translations by their keys.
  • separateWithEmptyLine: Set to false if you don't want to have empty lines between Strings entries. Defaults to `true.

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.

Localizing strings of LocalizableStringResource type (AppIntents, ...)

Historically, Apple platforms used CFCopyLocalizedString, and NSLocalizedString macros and their variants, to mark strings used in code to be localized, and to load their localized versions during runtime from Localizable.strings file.

Since introduction of the AppIntents framework, the localized strings in code can also be typed as LocalizedStringResource, and are no longer marked explicitly.

Let's examine this snippet of AppIntents code:

struct ExportAllTransactionsIntent: AppIntent {
    static var title: LocalizedStringResource = "Export all transactions"

    static var description =
        IntentDescription("Exports your transaction history as CSV data.")
}

In the example above, both the "Export all transactions", and "Exports your transaction history as CSV data." are actually StaticString instances that will be converted during compilation into LocalizedStringResource instances, and will lookup their respective localizations during runtime from Localized.strings file the same way as when using NSLocalizedString in the past. The only exception being that such strings are not marked explicitly, and require swift compiler to parse and extract such strings for localization. This is what Xcode does from version 13 when using Product -> Export Localizations... option.

In order to continue translating these strings with bartycrouch it is required to mark them explicitely with LocalizedStringResource(_: String, comment: String) call, and specify customFunction="LocalizedStringResource" in code task options.

The example AppIntents code that can be localized with bartycrouch will look like this:

struct ExportAllTransactionsIntent: AppIntent {
    static var title = LocalizedStringResource("Export all transactions", comment: "")

    static var description =
        IntentDescription(LocalizedStringResource("Exports your transaction history as CSV data.", comment: ""))
}

Note that you must use the full form of LocalizedStringResource(_: StaticString, comment: StaticString) for the bartycrouch, or more specifically for the extractLocStrings (see xcrun extractLocStrings) to properly parse the strings.

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:

export PATH="$PATH:/opt/homebrew/bin"

if which bartycrouch > /dev/null; then
    bartycrouch update -x
    bartycrouch lint -x
else
    echo "warning: BartyCrouch not installed, download it from https://github.com/FlineDev/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.

In order for the tests to run build issues, you need to run – also add an API key in the new file to run the translations tests, too:

cp Tests/BartyCrouchTranslatorTests/Secrets/secrets.json.sample Tests/BartyCrouchTranslatorTests/Secrets/secrets.json

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.

bartycrouch's People

Contributors

alexdeem avatar bmironer avatar clementpadovani avatar crazytonyli avatar crystalstorm avatar csknns avatar diederich avatar divinedominion avatar djbe avatar econa77 avatar flinedevpublic avatar fredpi avatar hactar avatar jamiegough avatar jeehut avatar kondamon avatar ludvigeriksson avatar mathebox avatar mman avatar moogle19 avatar mshibanami avatar nickatgit avatar noppefoxwolf avatar rebe1one avatar robnadin avatar romanr avatar tladesignz avatar vinceplusplus avatar zjx20 avatar zufuliu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bartycrouch's Issues

#bc-ignore! for NSLocalizedString

Is it possible to exclude NSLocalizedStrings that have #bc-ignore! in comment? The use case is that when we use .stringsdict to handle pluralization, we don't need to add these keys into Localizable.strings file.

Example

String.localizedStringWithFormat(NSLocalizedString("%d minute(s) ago", comment: "x minute(s) ago"), components.minute)

The %d minute(s) ago key will be taken from Localizable.stringsdict file, not from Localizable.strings.

Another possible solution is to scan Localizable.stringsdict file for keys and exclude them from Localizable.strings file.

Automatically find all localized Storyboards/XIBs

Currently paths to the Storyboard or XIB files need to be specified explicitly. This is bad in terms of adding the script once and not thinking about it any more when new Interface Builder files are added over time. Currently the script would need to be updated each time a new files was created.

When there is no input file specified BartyCrouch could assume that all localized Storyboard and XIB files are meant and find them recursively in the current directory. The recommended build script would then also become much shorter.

Error! No `Localizable.strings` file found for output.

Hello,

Why am i getting "Error! No Localizable.strings file found for output." ?

I use

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
else
    echo "warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch"
fi

Incrementally updated keys of file '/Users/utkudalmaz/Developer/Jemiyet/Jemiyett/tr-TR.lproj/LaunchScreen.strings'.
BartyCrouch: Successfully updated strings file(s) of Storyboard or XIB file.
Incrementally updated keys of file '/Users/utkudalmaz/Developer/Jemiyet/Jemiyett/tr-TR.lproj/Main.strings'.
BartyCrouch: Successfully updated strings file(s) of Storyboard or XIB file.
Error! No Localizable.strings file found for output.
Command /bin/sh failed with exit code 64

Support custom function names (genstrings option)

The genstrings command line tool which BartyCrouch uses also accepts an alternative function name than NSLocalizedString. There was a first attempt in #14 to support this feature in BartyCrouch, too.

This should be implement sooner or later. Currently I'm waiting for @crystalstorm to write a simple test to ensure this feature continues to work in the future.

Improve automatic machine-translation Strings files detection

Currently when the machine translation feature is used each Storyboard or Strings file needs to be listed explicitly even when the goal is to list all existing Storyboards, XIBs and Strings files. For that case there should be an automatic finding algorithm with only a source language specified.

Add --default-to-base option for code command?

Hi, thanks for releasing this tool, it's very helpful.

At present, when running the code command, BartyCrouch adds blank strings to the target locale files, which results in blank strings in the app until translations are provided. It would be nice if it provided a --default-to-base options (like the interfacecommand provides), that copies the base language string to the target files instead, so the UI at lease has some text. Is there a specific reason why this option is only available for interface?

Many thanks.

How to work with multiple strings files

I have multiple string files in my project and I use them using

NSLocalizedString("Please add description.", tableName: "SellForm", bundle: NSBundle.mainBundle(), value: "", comment: "")

but BC doesn't seem to recognize my SellForm.strings file

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

Use CommandLine library

Consider communicating with the command line using CommandLine. That would both provide handy features like help and make the code cleaner and more manageable.

Support for ".localized" String extension in Swift

In my project I have the following String extension which I use to localize strings:

extension String {

    var localized: String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
    }
}

Could something like this be supported by BartyCrouch?

Fails completely if a single translation file is missing

BartyCrouch isn't doing anything if any of the Storyboard files is missing a translation. For example if English, Polish and Russian are specified as the projects supported languages, and there are Main.storyboard and LaunchScreen.storyboard, both base-internationalized but only for Russian and Polish, not for English, then BartyCrouch currently fails completely with "Error! No input files found." which is too general.

We could do one of the following:

  1. make BartyCrouch more resilient against missing files (so that the existing ones work)
  2. improve the error by stating that all specified project languages must be met by all IB files
  3. combine both by introducing a check for each IB file, listing the missing ones as a warning but processing the existing

Crashes with 'Range or index out of bounds'

I have 11 languages in my project and I added the bartycrouch to my build phases and get the following error when building:
BartyCrouch: Successfully updated strings file(s) of Storyboard or XIB file.
2016-06-21 15:04:01.669 genstrings[26695:5181041] *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString characterAtIndex:]: Range or index out of bounds'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff93f904f2 __exceptionPreprocess + 178
1 libobjc.A.dylib 0x00007fff8f111f7e objc_exception_throw + 48
2 CoreFoundation 0x00007fff93ff74bd +[NSException raise:format:] + 205
3 CoreFoundation 0x00007fff93f05cf6 -[__NSCFString characterAtIndex:] + 102
4 genstrings 0x0000000104d3296b genstrings + 10603
5 genstrings 0x0000000104d318d1 genstrings + 6353
6 genstrings 0x0000000104d3150c genstrings + 5388
7 libdyld.dylib 0x00007fff882125ad start + 1
8 ??? 0x000000000000024f 0x0 + 591
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Error! Could not extract strings from Code in directory '/Users/Arie/Developer/multilock-ios'.
Command /bin/sh failed with exit code 69

Please help

Add option to retrieve new String keys from Code

BartyCrouch currently recognizes changes in Storyboards and XIBs and updates their localization strings appropriately. Adding basic support for Code files (written in Swift or ObjC) using the NSLocalizedString macro shouldn't be too hard so an addition should be considered.

The details could be more complicated of course, so maybe an alternative to NSLocalizedString may be introduced simplifying an automated update of the strings files.

Microsoft Translators "unescaped double quotes" issue

The Microsoft Translator translates some Strings that contain a single quoted substring so that the result replaces the single quoted substrings with double quotes. This happens for some languages like Hungarian or Slovakian.

BartyCrouch could try prevent issues in these cases by simply adding a backslash in front of each double quoted translation result. It could also be that the right place to tackle this is in the Polyglot dependency, but it needs to be solved.

Example:
An english sentence like "She said: 'Stop!'" becomes "She said: "Stop"" for some languages. BartyCrouch should automatically escape the double quotes so that the result looks like this: "She said: "Stop!"".

Localizing Info.plist

Hello,

Is it possible to use BartyCrouch in order to localize the Info.plist file?
If not, do you have any plan to support this?

Missing Support of Generating Multiple Comments of Same Key?

Suppose I have the following code:

let s1 = NSLocalizedString("test", comment: "test comment 1")
let s2 = NSLocalizedString("test", comment: "test comment 2")

BC generated .strings file becomes:

"test" = "test";

However, with the original genstrings, the generated file would become:

/* test comment 1
   test comment 2 */
"test" = "test";

Keep generated contents in sync with Base localization values

For example, there is one generated comment:

/* Class = "UITableViewSection"; headerTitle = "Foo"; ObjectID = "HQs-Z9-d7P"; */
"HQs-Z9-d7P.headerTitle" = "Foo";

If the base localization "Foo" was changed to "Bar" in the base Main.storyboard, can .strings files be also updated to reflect the change? To become:

/* Class = "UITableViewSection"; headerTitle = "Bar"; ObjectID = "HQs-Z9-d7P"; */
"HQs-Z9-d7P.headerTitle" = "Bar";  /* gets the update too if it wasn't a translated value */

Looking for a video tutorial.

Looking for a video tutorial. Anybody wanna take a shot at this? I'm confused on how to set bartycrouch up with Xcode 8.3 with the default preexisting localized procedures.

Installing bartycrouch isn't the problem. Its integrating bartycrouch with current existing Xcode project with a prior Localized strings.

Also I've also been arriving at a Sementation fault: 11 but it doesn't show where the fault is coming from when I run the following command.

bartycrouch code -p "localization1" -l "localization1/" -a

Also, does BartyCrouch allow or enable user to switch between languages of the user choosing without through device settings?

Thanks!

Specify output languages

Currently it is only possible to pass output file paths, choose all or choose all with some excluded paths. When passing output file paths OR the excluded paths there should be an option to simply specify the locale code like so and it should use the paths found by -a to determine the full paths:

bartycrouch -i "path/to/Main.storyboard" -o en de ja zh-Hans
bartycrouch -i "path/to/Main.storyboard" -e en-GB es zh-Hant

This can be done by using a regex like this one: /\A[a-z]{2}[-]{0,1}\w*\z/

Removes translations with emoji

I have a UILabel in a storyboard with 😀 as the text. I added a new locale through Xcode which gives me in the .strings file:

/* Class = "UILabel"; text = "😀"; ObjectID = "hi9-mx-Y1T"; */
"hi9-mx-Y1T.text" = "😀";

However, when I run BartyCrouch, it removes those two lines.

Homebrew issue

Today when updating homebrew repositories I receive the following:

> brew up
fatal: could not read Username for 'https://github.com': terminal prompts disabled
Error: Fetching /usr/local/Homebrew/Library/Taps/flinesoft/homebrew-bartycrouch failed!

Translations with newlines are moved and replaced with empty string

Example

Command: bartycrouch interfaces -p ./

Several translations, all with newlines, are affected. The original has \n but the translations contain actual newlines, which BartyCrouch does not seem to like very much.

Example:

-/* Class = "UILabel"; text = "LIVE RECORDING\n00:00:00"; ObjectID = "y9M-C2-74f"; */
-"y9M-C2-74f.text" = "实时录制
-00:00:00";
-

******* some other translations ***********

+/* Class = "UILabel"; text = "LIVE RECORDING\n00:00:00"; ObjectID = "y9M-C2-74f"; */
+"y9M-C2-74f.text" = "";

So the problem is two-fold:

  1. The translation goes from working to translation to empty (should not be touched by BartyCrouch)
  2. Is relocated to another place in the file

How do I handle this properly?

Support install via CocoaPods

Thank you for creating a great tool 👍

Is it possible to install via CocoaPods like SwiftLint?
By version control via CocoaPods, it makes it easier for multiple people to develop, oss development and more.

findFiles() hanging indefinitely

In 3.9, w/ changing of the order of reading the standard output/error, /usr/bin/find is now hanging indefinitely for me.

If I swap the order so standardOutput is read first, it works as expected with ~1000 files found and 0 errors:

(lldb) po errdata.isEmpty
true

Reproducing

The magic number (on my machine, at least. macOS 10.12.6, Xcode 9.0 9A235) seems to be 983 files, anything over that and it seems to hang. I've attached a zip file with a file hierarchy that reproduced the bug on my machine. It is just a bunch of empty .swift/h/m files in folders.

files.zip

Terminating app due to uncaught exception 'NSInternalInconsistencyException'

Help, latest xcode keep getting this no matter what I do. Runs fine if i disable the script?

BartyCrouch: Successfully updated strings file(s) of Storyboard or XIB file.
2016-10-30 21:21:49.855 bartycrouch[32900:1074407] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't posix_spawn: error 7'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff7d0e952b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fff917c1cad objc_exception_throw + 48
2 CoreFoundation 0x00007fff7d167a0d +[NSException raise:format:] + 205
3 Foundation 0x00007fff7eafcc7e -[NSConcreteTask launchWithDictionary:] + 3134
4 bartycrouch 0x000000010f5c504b bartycrouch + 192587
5 bartycrouch 0x000000010f5ccb57 bartycrouch + 224087
6 bartycrouch 0x000000010f5c6e77 bartycrouch + 200311
7 bartycrouch 0x000000010f5c7a8d bartycrouch + 203405
8 bartycrouch 0x000000010f5ca365 bartycrouch + 213861
9 bartycrouch 0x000000010f5ae54c bartycrouch + 99660
10 bartycrouch 0x000000010f597ef9 bartycrouch + 7929
11 libdyld.dylib 0x00007fff9209f255 start + 1
12 ??? 0x0000000000000007 0x0 + 7
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Error! No `Localizable.strings` file found for output.

Hi,
i cannot make "code" command work.
I tried both from build script and from terminal.

Code from build script gives me no error but code is not working (while interface works properly):

if which bartycrouch > /dev/null; then
bartycrouch interfaces -p "$PROJECT_DIR"
bartycrouch code -p "$PROJECT_DIR" -l "$PROJECT_DIR" -a
else
echo "warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch"
fi

and from terminal I open a new terminal inside the folder containing my code files and my *.lproj folders and write:
bartycrouch code -p "/" -l "/" -a
here terminal writes

Error! No Localizable.strings file found for output.

The only way to make "code" working is open a new terminal inside one of my *lproj folder and then bartycrouch code -p "../" -l "../" -a

Thank's for Your help

infinite with xcode 9 GM

Hello,

I tried my project with the new xcode 9 GM today, the BartyCrouch script never stops.
So I tried launching command :
bartycrouch interfaces -p [My Project Path] -v
The script is working for some files and then stops for one.
I tried launching with the source file and found that the problem comes from the file : Commander.swift , the line let outdata = outpipe.fileHandleForReading.readDataToEndOfFile() never stops.

I reproduced the same issue with a second project.

My XCode version is : 9.0 (9A235).

Error! No file exists at output path '<path><file>.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?

Fails to parse comments containing bracket characters

If I have the following code:

let s1 = NSLocalizedString("test", comment: "test comment containing ()")

The generated .strings file becomes:

"test" = "";

There seems to be a bug in the comment matching pattern in the recent multiline comment support. I took the solution from http://blog.ostermiller.org/find-comment and adapted it a bit (removed newline characters thanks to .dotMatchesLineSeparators and added extra brackets to keep the third last capture group pointing to the comment), now it seems to work fine:

let translationRegexString = "(?:\\s*/\\*(((?:[^*]|(?:\\*+(?:[^*/])))*))\\*+/\\s*)?\\s*(?:^\\s*\"([\\S ]*)\"\\s*=\\s*\"([\\S ]*)\"\\s*;\\s*$)"

Option to Exclude path to avoid picking up localisation from Pods and imported libs

Would be great to have --exclude path option, to avoid picking up localisation from Pods and imported libraries

For example project has this structure:

  • Module1
  • Module2
  • Module3
  • Pods

running bartycrouch code -p . will include localization from Pods or any third party libraries happen to be relative to project root. It mixes those 3rd party strings into your Localizable.strings.

Yes, the sources can be organized under something like /src in root of project, but that never happens. Sources are never in their own separate subtree.

As workaround paths can be included by running command multiple times. bartycrouch code -p Module1 , bartycrouch code -p Module2 etc. but that is not sustainable.

Error! Could not extract strings from Storyboard or XIB at path

Hello,

I don't understand why I have this error message. I have a storyboard with 2 strings files in the project.

Error! Could not extract strings from Storyboard or XIB at path '/Users/Axel/Developer/Skipper/Skipper/Base.lproj/Activities.storyboard

screenshot 2016-08-02 10 41 37

screenshot 2016-08-02 10 44 32

Can you help please?
Thanks
Axel

Empty title?

hello,

When I run BartyCrouch it nicely adds new UIElements in interface files to the strings file, but the title is always empty. For example, when I add a new label and run BartyCrouch the strings file reads

/* Class = "UILabel"; text = "New Label"; ObjectID = "6F2-Kl-Hfp"; */
"6F2-Kl-Hfp.text" = "";

The same happens with new buttons. What could be the reason for this?

Thanks and regards,
Sebastian Mecklenburg

Slow builds with high number of unchanged Localizables

When using the full automatic build style builds with unchanged IB files can take 5-10 seconds longer than without BartyCrouch even when nothing is changed with many files (say thousand translation target files) to check. This should be fixed, for example by using a build artifact file that keeps track of the last time BartyCrouch was run and skip files that didn't change since then.

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

Question on correct use of #bc-ignore!

I'd like to use #bc-ignore! in Interface Builder. For mostly personal preference, I'd rather put it in the comment section, rather then the actual value of a label.

screen shot 2017-03-02 at 3 37 56 pm

This works, and looking at StringsFileUpdater.swift, it doesn't seem to make a difference between keys and comments when looking for the special ignore strings.

I just want to confirm this is expected behavior. I don't want to depend on anything undocumented that might break in the future.

Thanks for all the work on this library, it is exactly what we needed.

Build script fails with only interfaces subcommand

Hi,

I don't want incrementally updates localizable.string but this code return "Command /bin/sh failed with exit code 78"

if which bartycrouch > /dev/null; then bartycrouch interfaces -p "$PROJECT_DIR" -b else echo "warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch" fi

What's wrong ?

Thanks in advance :D

Add default to comment option to code sub-command

First, thank you for creating this great tool!

In our workflow we usually add the default localization in comments, there is a possibility to add keys as a default value to the localized files. I think option -c or --default-to-comment to add comments as default values for code sub-command would be a great complement to the --default-to-keys option.

What do you think about it?

Add unstripped option to keep newlines at beginning/end

Currently using the combination of BartyCrouch and PhraseApp results to some issues with newlines. The problem is that PhraseApp keeps no newline at the top of the file and two newlines instead at the bottom of it. BartyCrouch currently keeps each one newline at the top and bottom.

The requested feature would be a new command line option to keep the surrounding newlines (and other whitespace characters) the the top and bottom of the file. It could be called unstripped or -u as strip is typically a method on Strings that removes whitespaces from the beginning and end.

Add option to sort translations by keys in resulting Strings files

Currently when a Strings file is saved the order of the translations isn't changed, new translations are simply added at the end of the list. There should be an option to sort them by keys which is especially useful for the code sub command when using structured keys like 'SETTINGS.USER_SECTION.LOGOUT'.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.