Skip to content

Commit

Permalink
Merge branch 'release/4.14.0' into versions
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeehut committed Dec 14, 2022
2 parents 36cc463 + 2f12a53 commit 03c3816
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 45 deletions.
2 changes: 1 addition & 1 deletion BartyCrouch.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "BartyCrouch"
s.version = "4.13.0"
s.version = "4.14.0"
s.summary = "Localization/I18n: Incrementally update/translate your Strings files from .swift, .h, .m(m), .storyboard or .xib files."

s.description = <<-DESC
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ If needed, pluralize to `Tasks`, `PRs` or `Authors` and list multiple entries se
### Security
- None.

## [4.14.0] - 2022-12-14
### Added
- Support for Swift 5.7 and Xcode 14, dropping support for older versions and fixing the 'could not parse syntax tree' issue.
- BartyCrouch now recognizes `LocalizedStringResource` entries by default (unless you override the `customFunction` option). This helps support localization in newer APIs like the AppIntents framework. See README for more info.
### Fixed
- Updated DeepL API to a POST request according to the documentation to fix issues.

## [4.13.0] - 2022-10-07
### Added
- Re-implement option `overrideComments` for code update (see README).
Expand Down
2 changes: 1 addition & 1 deletion Formula/bartycrouch.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Bartycrouch < Formula
desc "Incrementally update/translate your Strings files"
homepage "https://github.com/Flinesoft/BartyCrouch"
url "https://github.com/Flinesoft/BartyCrouch.git", :tag => "4.12.1", :revision => "f2515c0e78b35681602a7b48bc6b08a8d19bf864"
url "https://github.com/Flinesoft/BartyCrouch.git", :tag => "4.13.0", :revision => "36cc46399abe717986cda40ccd6d6eb34c6ff70d"
head "https://github.com/Flinesoft/BartyCrouch.git"

depends_on :xcode => ["14.0", :build]
Expand Down
19 changes: 13 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SHELL = /bin/bash

prefix ?= /usr/local
prefix ?= /opt/homebrew
bindir ?= $(prefix)/bin
libdir ?= $(prefix)/lib
srcdir = Sources
Expand All @@ -18,26 +18,33 @@ bartycrouch: $(SOURCES)
@swift build \
-c release \
--disable-sandbox \
--scratch-path "$(BUILDDIR)" \
-Xlinker -dead_strip_dylibs
--scratch-path "$(BUILDDIR)"

bartycrouch_universal: $(SOURCES)
@swift build \
-c release \
--arch arm64 --arch x86_64 \
--disable-sandbox \
--scratch-path "$(BUILDDIR)" \
-Xlinker -dead_strip_dylibs
--scratch-path "$(BUILDDIR)"

.PHONY: install
install: bartycrouch
@install -d "$(bindir)" "$(libdir)"
@install "$(BUILDDIR)/release/bartycrouch" "$(bindir)"
@install ".build/artifacts/swift-syntax/_InternalSwiftSyntaxParser.xcframework/macos-arm64_x86_64/lib_InternalSwiftSyntaxParser.dylib" \
"$(libdir)"
@install_name_tool -change \
"@rpath/lib_InternalSwiftSyntaxParser.dylib" \
"$(libdir)/lib_InternalSwiftSyntaxParser.dylib" \
"$(bindir)/bartycrouch"

.PHONY: portable_zip
portable_zip: bartycrouch_universal
rm -f "$(BUILDDIR)/Apple/Products/Release/portable_bartycrouch.zip"
zip -j "$(BUILDDIR)/Apple/Products/Release/portable_bartycrouch.zip" "$(BUILDDIR)/Apple/Products/Release/bartycrouch" "$(REPODIR)/LICENSE"
zip -j "$(BUILDDIR)/Apple/Products/Release/portable_bartycrouch.zip" \
"$(BUILDDIR)/Apple/Products/Release/bartycrouch" \
"$(REPODIR)/LICENSE" \
".build/artifacts/swift-syntax/_InternalSwiftSyntaxParser.xcframework/macos-arm64_x86_64/lib_InternalSwiftSyntaxParser.dylib"
echo "Portable ZIP created at: $(BUILDDIR)/Apple/Products/Release/portable_bartycrouch.zip"

.PHONY: uninstall
Expand Down
6 changes: 0 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@ let package = Package(
.package(url: "https://github.com/pointfreeco/swift-custom-dump.git", from: "0.3.0"),
],
targets: [
.binaryTarget(
name: "lib_InternalSwiftSyntaxParser",
url: "https://github.com/keith/StaticInternalSwiftSyntaxParser/releases/download/5.7/lib_InternalSwiftSyntaxParser.xcframework.zip",
checksum: "99803975d10b2664fc37cc223a39b4e37fe3c79d3d6a2c44432007206d49db15"
),
.executableTarget(
name: "BartyCrouch",
dependencies: ["BartyCrouchKit"]
Expand All @@ -43,7 +38,6 @@ let package = Package(
"SwiftCLI",
.product(name: "SwiftSyntaxParser", package: "swift-syntax"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
"lib_InternalSwiftSyntaxParser",
"BartyCrouchUtility",
]
),
Expand Down
57 changes: 52 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
<img src="https://api.codacy.com/project/badge/Coverage/7b34ad9193c2438aa32aa29a0490451f"/>
</a>
<a href="https://github.com/FlineDev/BartyCrouch/releases">
<img src="https://img.shields.io/badge/Version-4.13.0-blue.svg"
alt="Version: 4.13.0">
<img src="https://img.shields.io/badge/Version-4.14.0-blue.svg"
alt="Version: 4.14.0">
</a>
<img src="https://img.shields.io/badge/Swift-5.7-FFAC45.svg"
alt="Swift: 5.7">
Expand Down Expand Up @@ -50,6 +50,14 @@
• <a href="#license">License</a>
</p>

> :sparkles: **Important Notice** :sparkles:
>
> There's [**now a new Mac app called RemafoX**](https://remafox.app?source=github.aaakk.us.kg.BartyCrouch) which is the _successor_ to BartyCrouch. It improves upon several aspects of BartyCrouch, such as having **no flaky dependencies**, adding **pluralization** support, **smart** machine translation, a built-in SwiftUI-compatible **enum generator**, built-in **step-by-step instructions** for easier setup, **detailed explanations** of all config options, and even [**a set of video guides**](https://www.youtube.com/watch?v=ObGIiWARjmw&list=PLvkAveYAfY4TLPtPd5jnqMwpAzY_pdxs5) for things like setup, key naming best practices and team onboarding. Get it for free [here](https://apps.apple.com/app/apple-store/id1605635026?pt=549314&ct=github.aaakk.us.kg.BartyCrouch&mt=8).
>
> Note that RemafoX is being **actively worked on**, you can even [vote for or request new features here](https://github.com/FlineDev/RemafoX/issues?q=is%3Aissue+label%3A%22Feature+Request%22+sort%3Areactions-%2B1-desc).
> In comparison, BartyCrouch is kept up-to-date mostly by 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](#build-script)** within your project.
Expand All @@ -58,7 +66,7 @@ Checkout [this blog post](https://jeehut.medium.com/localization-in-swift-like-a

## Requirements

- Xcode 13.3+ & Swift 5.6+
- Xcode 14+ & Swift 5.7+
- Xcode Command Line Tools (see [here](http://stackoverflow.com/a/9329325/3451975) for installation instructions)

## Getting Started
Expand Down Expand Up @@ -258,12 +266,12 @@ tasks = ["interfaces", "code", "transform", "normalize"]
- `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`.
- `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.
- `overrideComments`: Always overrides the comment with the keys new translation, useful for IB files.

</details>

Expand Down Expand Up @@ -355,6 +363,40 @@ self.title = L10n.Onboarding.FirstPage.headerTitle

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:
Expand Down Expand Up @@ -426,6 +468,11 @@ See the file [MIGRATION_GUIDES.md](https://github.com/FlineDev/BartyCrouch/blob/

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](http://chris.beams.io/posts/git-commit/)). 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 an API key in the new file to run the translations tests, too:
```shell
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`
Expand Down
2 changes: 1 addition & 1 deletion Sources/BartyCrouch/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SwiftCLI
// MARK: - CLI
let cli = CLI(
name: "bartycrouch",
version: "4.13.0",
version: "4.14.0",
description: "Incrementally update & translate your Strings files from code or interface files."
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extension CodeOptions: TomlCodable {
localizablePaths: toml.filePaths(update, code, singularKey: "localizablePath", pluralKey: "localizablePaths"),
defaultToKeys: toml.bool(update, code, "defaultToKeys") ?? false,
additive: toml.bool(update, code, "additive") ?? true,
customFunction: toml.string(update, code, "customFunction"),
customFunction: toml.string(update, code, "customFunction") ?? "LocalizedStringResource",
customLocalizableName: toml.string(update, code, "customLocalizableName"),
unstripped: toml.bool(update, code, "unstripped") ?? false,
plistArguments: toml.bool(update, code, "plistArguments") ?? true,
Expand Down
35 changes: 13 additions & 22 deletions Sources/BartyCrouchTranslator/DeeplApi/DeepLApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ enum DeepLApi {

for text in texts {
if currentBatch.count < maximumTextsPerRequest
&& text.count + currentBatchTotalLength < maximumTextsLengthPerRequest
&& text.count + currentBatchTotalLength < maximumTextsLengthPerRequest
{
currentBatch.append(text)
currentBatchTotalLength += text.count
Expand Down Expand Up @@ -47,10 +47,6 @@ extension DeepLApi: Endpoint {
return decoder
}

var encoder: JSONEncoder {
JSONEncoder()
}

var subpath: String {
switch self {
case .translate:
Expand All @@ -59,25 +55,20 @@ extension DeepLApi: Endpoint {
}

var method: HttpMethod {
.get
}

var queryParameters: [String: QueryParameterValue] {
var urlParameters: [String: QueryParameterValue] = [:]

switch self {
case let .translate(texts, sourceLanguage, targetLanguage, apiKey):
urlParameters["text"] = .array(texts)
urlParameters["source_lang"] = sourceLanguage.deepLParameterValue
urlParameters["target_lang"] = targetLanguage.deepLParameterValue
urlParameters["auth_key"] = .string(apiKey)
case .translate(let texts, let sourceLanguage, let targetLanguage, let authKey):
let textEntries = texts.map { "text=\($0.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)" }
.joined(separator: "&")
let authKeyEntry = "auth_key=\(authKey)"
let sourceLanguageEntry = "source_lang=\(sourceLanguage.deepLParameterValue)"
let targetLanguageEntry = "target_lang=\(targetLanguage.deepLParameterValue)"
let bodyString = [authKeyEntry, sourceLanguageEntry, targetLanguageEntry, textEntries].joined(separator: "&")
return .post(body: bodyString.data(using: .utf8)!)
}

return urlParameters
}

var headers: [String: String] {
["Content-Type": "application/json"]
["Content-Type": "application/x-www-form-urlencoded"]
}

static func baseUrl(for apiType: ApiType) -> URL {
Expand All @@ -92,13 +83,13 @@ extension DeepLApi: Endpoint {
}

private extension Language {
var deepLParameterValue: QueryParameterValue {
var deepLParameterValue: String {
switch self {
case .chineseSimplified:
return .string("ZH")
return "ZH"

default:
return .string(rawValue.uppercased())
return rawValue.uppercased()
}
}
}
2 changes: 1 addition & 1 deletion Sources/SupportingFiles/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.13.0</string>
<string>4.14.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
Expand Down
4 changes: 3 additions & 1 deletion Tests/BartyCrouchConfigurationTests/ConfigurationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ConfigurationTests: XCTestCase {
XCTAssertEqual(configuration.updateOptions.code.codePaths, ["."])
XCTAssertEqual(configuration.updateOptions.code.localizablePaths, ["."])
XCTAssertEqual(configuration.updateOptions.code.additive, true)
XCTAssertEqual(configuration.updateOptions.code.customFunction, nil)
XCTAssertEqual(configuration.updateOptions.code.customFunction, "LocalizedStringResource")
XCTAssertEqual(configuration.updateOptions.code.customLocalizableName, nil)
XCTAssertEqual(configuration.updateOptions.code.defaultToKeys, false)
XCTAssertEqual(configuration.updateOptions.code.unstripped, false)
Expand Down Expand Up @@ -117,6 +117,7 @@ class ConfigurationTests: XCTestCase {
XCTAssertEqual(configuration.updateOptions.code.customLocalizableName, "MyOwnLocalizable")
XCTAssertEqual(configuration.updateOptions.code.defaultToKeys, true)
XCTAssertEqual(configuration.updateOptions.code.unstripped, true)
XCTAssertEqual(configuration.updateOptions.code.overrideComments, false)

XCTAssertEqual(configuration.updateOptions.transform.codePaths, ["Sources"])
XCTAssertEqual(configuration.updateOptions.transform.localizablePaths, ["Sources/SupportingFiles"])
Expand Down Expand Up @@ -168,6 +169,7 @@ class ConfigurationTests: XCTestCase {
unstripped = true
plistArguments = true
ignoreKeys = ["#bartycrouch-ignore!", "#bc-ignore!", "#i!"]
overrideComments = false
[update.transform]
codePaths = ["."]
Expand Down

0 comments on commit 03c3816

Please sign in to comment.