fastlane-plugin-translate 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d4b55852f8515ef6942b0bf6819379eb2c3cb81e20ef872a924470a2e9b6d886
4
+ data.tar.gz: 7d1d3b603837c68bd8fd548dca30b171ff074e42218956b910f9446109a3fea2
5
+ SHA512:
6
+ metadata.gz: 83b931afb04769b0d6bd57fe7b686a772e707d350239dbcef6d191633078d2cd205f5ebf2f0229a88aab838ef824dd078f3326b7489ed633bd6462af633d3e91
7
+ data.tar.gz: 1be7fd87de5af70a4ea87a8c05fc8900606e3fa07327c2f0694997a0f614163be7fdcec98c170ad7e4d2bee798d53b4d396838ec57fd398c603fcf7fec9f67a1
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Tijs Teulings <hello@tijs.org>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,318 @@
1
+ # fastlane-plugin-translate
2
+
3
+ <div align="center">
4
+ <img src="fastlane-action-translate-logo.png" alt="Fastlane Translate Plugin Logo" width="200"/>
5
+ </div>
6
+
7
+ [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-translate)
8
+ [![Buy Me A Coffee](https://img.shields.io/badge/Buy%20Me%20A%20Coffee-support-yellow.svg?style=flat)](https://buymeacoffee.com/xocrgwybbs)
9
+
10
+ ## About translate
11
+
12
+ Automatically translate iOS `Localizable.xcstrings` files using DeepL API. This plugin helps you efficiently manage app localization by translating untranslated strings while preserving your existing translations.
13
+
14
+ ## Features
15
+
16
+ - 🔍 **Auto-discovery**: Automatically finds your `Localizable.xcstrings` file
17
+ - 📊 **Translation analysis**: Shows translation progress for each language
18
+ - 🎯 **Smart targeting**: Only translates untranslated strings (state: "new" with empty values)
19
+ - 💾 **Progress tracking**: Saves progress between runs to avoid re-translating
20
+ - 🎭 **Formality support**: Automatically detects and offers formality options for supported languages
21
+ - 📝 **Context extraction**: Uses comments from xcstrings as translation context
22
+ - 🔄 **Batch processing**: Efficiently handles large numbers of strings
23
+ - 🛡️ **Error recovery**: Comprehensive error handling with user choices
24
+ - 📄 **Automatic backups**: Creates timestamped backups before translation
25
+ - ✅ **Validation**: Ensures output file is valid JSON
26
+
27
+ ## Getting Started
28
+
29
+ ### Install from RubyGems (Recommended)
30
+
31
+ ```bash
32
+ fastlane add_plugin translate
33
+ ```
34
+
35
+ ### Install from GitHub (Latest Development Version)
36
+
37
+ Add to your `Gemfile`:
38
+
39
+ ```ruby
40
+ gem "fastlane-plugin-translate", git: "https://github.com/tijs/fastlane-plugin-translate"
41
+ ```
42
+
43
+ Then run:
44
+
45
+ ```bash
46
+ bundle install
47
+ ```
48
+
49
+ ## Setup
50
+
51
+ 1. **Get a DeepL API key** from <https://www.deepl.com/pro#developer>
52
+ 2. **Set your API key** as an environment variable:
53
+
54
+ ```bash
55
+ export DEEPL_AUTH_KEY="your-deepl-api-key-here"
56
+ ```
57
+
58
+ ## Usage
59
+
60
+ ### Basic Usage
61
+
62
+ ```ruby
63
+ # Automatically detect xcstrings file and show language selection
64
+ translate_with_deepl
65
+ ```
66
+
67
+ ### Specify Target Language
68
+
69
+ ```ruby
70
+ # Translate to German
71
+ translate_with_deepl(target_language: "de")
72
+
73
+ # Translate to French with formal style
74
+ translate_with_deepl(
75
+ target_language: "fr",
76
+ formality: "more"
77
+ )
78
+ ```
79
+
80
+ ### Custom Configuration
81
+
82
+ ```ruby
83
+ # Full configuration example
84
+ translate_with_deepl(
85
+ xcstrings_path: "./MyApp/Localizable.xcstrings",
86
+ target_language: "es",
87
+ formality: "prefer_more",
88
+ batch_size: 15,
89
+ free_api: true
90
+ )
91
+ ```
92
+
93
+ ## Supported Languages
94
+
95
+ The plugin supports all languages available in both Apple's App Store Connect and DeepL API:
96
+
97
+ ### Full DeepL Support
98
+
99
+ - 🇩🇪 German (de) - *supports formality*
100
+ - 🇫🇷 French (fr) - *supports formality*
101
+ - 🇮🇹 Italian (it) - *supports formality*
102
+ - 🇪🇸 Spanish (es) - *supports formality*
103
+ - 🇳🇱 Dutch (nl) - *supports formality*
104
+ - 🇵🇱 Polish (pl) - *supports formality*
105
+ - 🇵🇹 Portuguese (pt-BR, pt-PT) - *supports formality*
106
+ - 🇯🇵 Japanese (ja) - *supports formality*
107
+ - 🇷🇺 Russian (ru) - *supports formality*
108
+ - 🇬🇧 English (en-US, en-GB)
109
+ - 🇨🇳 Chinese (zh-Hans, zh-Hant)
110
+ - 🇰🇷 Korean (ko)
111
+ - And many more...
112
+
113
+ *Languages marked with "supports formality" offer formal/informal translation options*
114
+
115
+ ## Parameters
116
+
117
+ | Parameter | Description | Default | Required |
118
+ |-----------|-------------|---------|----------|
119
+ | `api_token` | DeepL API authentication key | `ENV['DEEPL_AUTH_KEY']` | Yes |
120
+ | `xcstrings_path` | Path to Localizable.xcstrings file | Auto-detected | No |
121
+ | `target_language` | Target language code (e.g., "de", "fr") | User prompted | No |
122
+ | `batch_size` | Number of strings per API call | 20 | No |
123
+ | `free_api` | Use DeepL Free API endpoint | false | No |
124
+ | `formality` | Translation formality level | Auto-detected | No |
125
+
126
+ ### Formality Options
127
+
128
+ For supported languages, you can specify:
129
+
130
+ - `default` - Standard formality
131
+ - `more` - More formal language
132
+ - `less` - Less formal language
133
+ - `prefer_more` - Formal if available, otherwise default
134
+ - `prefer_less` - Informal if available, otherwise default
135
+
136
+ ## Example Output
137
+
138
+ ```
139
+ 🔍 Found xcstrings file: ./Kilowatt/Localizable.xcstrings
140
+ ✅ DeepL API key validated
141
+ 💾 Backup created: ./Kilowatt/Localizable.xcstrings.backup_20241201_143022
142
+
143
+ 📋 Available languages for translation:
144
+ 1. German (de): 45.2% translated (127 remaining) [supports formality]
145
+ 2. French (fr): 21.8% translated (220 remaining) [supports formality]
146
+ 3. Spanish (es): 18.1% translated (231 remaining) [supports formality]
147
+
148
+ 🎭 German supports formality options. Choose style:
149
+ → more (formal)
150
+
151
+ 🔄 Translating from EN to DE
152
+ 📝 Found 127 untranslated strings
153
+
154
+ 🔄 Translating batch 1/7 (20 strings)...
155
+ ✅ Batch 1 completed (20 strings)
156
+ 🔄 Translating batch 2/7 (20 strings)...
157
+ ✅ Batch 2 completed (20 strings)
158
+ ...
159
+
160
+ 📝 Updating xcstrings file with 127 translations...
161
+ 💾 Updated xcstrings file
162
+ ✅ Updated xcstrings file is valid JSON
163
+
164
+ 🎉 Translation completed!
165
+ 📊 Translated 127 strings for German (de)
166
+ 📄 Backup saved: ./Kilowatt/Localizable.xcstrings.backup_20241201_143022
167
+ 🗑️ You can delete the backup after verifying results
168
+ ```
169
+
170
+ ## Error Handling
171
+
172
+ The plugin provides comprehensive error recovery:
173
+
174
+ ### Rate Limiting
175
+
176
+ ```
177
+ ⚠️ Rate limit exceeded for batch 3/10
178
+ 1. Wait 60s and retry
179
+ 2. Skip this batch
180
+ 3. Abort translation
181
+ ```
182
+
183
+ ### Translation Errors
184
+
185
+ ```
186
+ ❌ Translation error for batch 2/10: Network timeout
187
+ 1. Skip this batch
188
+ 2. Retry batch
189
+ 3. Abort translation
190
+ ```
191
+
192
+ ### API Quota Issues
193
+
194
+ ```
195
+ ❌ DeepL quota exceeded. Upgrade your plan or wait for reset.
196
+ ```
197
+
198
+ ## Shared Values
199
+
200
+ The action sets the following shared values for use in other lanes:
201
+
202
+ - `TRANSLATE_WITH_DEEPL_TRANSLATED_COUNT` - Number of translated strings
203
+ - `TRANSLATE_WITH_DEEPL_TARGET_LANGUAGE` - Target language code
204
+ - `TRANSLATE_WITH_DEEPL_BACKUP_FILE` - Path to backup file
205
+
206
+ ```ruby
207
+ lane :translate_and_notify do
208
+ count = translate_with_deepl(target_language: "de")
209
+
210
+ slack(
211
+ message: "✅ Translated #{count} German strings!",
212
+ channel: "#localization"
213
+ )
214
+ end
215
+ ```
216
+
217
+ ## Progress Tracking
218
+
219
+ The plugin automatically saves translation progress:
220
+
221
+ ```
222
+ 📈 Found existing progress: 45 strings translated
223
+ Continue from where you left off?
224
+ 1. Yes, continue
225
+ 2. No, start fresh
226
+ ```
227
+
228
+ Progress files are automatically cleaned up after successful completion.
229
+
230
+ ## Context Support
231
+
232
+ When xcstrings files contain comments, they're used as translation context:
233
+
234
+ ```json
235
+ {
236
+ "Hello World": {
237
+ "comment": "Greeting message shown on app launch",
238
+ "localizations": { ... }
239
+ }
240
+ }
241
+ ```
242
+
243
+ This comment becomes context for better translation quality.
244
+
245
+ ## Requirements
246
+
247
+ - Ruby >= 2.6
248
+ - Fastlane >= 2.0.0
249
+ - DeepL API account (Free or Pro)
250
+
251
+ ## Development
252
+
253
+ ### Setup
254
+
255
+ 1. Clone the repository
256
+ 2. Run `bundle install`
257
+
258
+ ### Testing
259
+
260
+ #### Unit Tests (RSpec)
261
+
262
+ Run the full test suite:
263
+
264
+ ```bash
265
+ bundle exec rspec
266
+ ```
267
+
268
+ Run specific test files:
269
+
270
+ ```bash
271
+ bundle exec rspec spec/translate_with_deepl_action_spec.rb
272
+ bundle exec rspec spec/language_registry_spec.rb
273
+ bundle exec rspec spec/deepl_language_mapper_spec.rb
274
+ ```
275
+
276
+ #### Code Quality
277
+
278
+ Run RuboCop for style checking:
279
+
280
+ ```bash
281
+ bundle exec rubocop
282
+ ```
283
+
284
+ Auto-fix correctable issues:
285
+
286
+ ```bash
287
+ bundle exec rubocop -a
288
+ ```
289
+
290
+ #### Manual Testing
291
+
292
+ To test the plugin manually with a real project:
293
+
294
+ ```bash
295
+ # Export your DeepL API key
296
+ export DEEPL_AUTH_KEY="your-api-key-here"
297
+
298
+ # Test the plugin
299
+ bundle exec fastlane translate_with_deepl
300
+ ```
301
+
302
+ ### Requirements
303
+
304
+ - Ruby >= 3.4
305
+ - Fastlane >= 2.0.0
306
+ - DeepL API account (Free or Pro) for manual testing
307
+
308
+ ## Issues and Feedback
309
+
310
+ For bugs, feature requests, or questions, please [create an issue](https://github.com/yourusername/fastlane-plugin-translate/issues).
311
+
312
+ ## License
313
+
314
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
315
+
316
+ ## About fastlane
317
+
318
+ [fastlane](https://fastlane.tools) is the easiest way to automate beta deployments and releases for your iOS and Android apps. To get started with fastlane, check out [fastlane.tools](https://fastlane.tools).