i18n-youdao-tasks 0.9.37
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +448 -0
- data/Rakefile +13 -0
- data/bin/i18n-tasks +15 -0
- data/bin/i18n-tasks.cmd +2 -0
- data/config/locales/en.yml +129 -0
- data/config/locales/ru.yml +131 -0
- data/i18n-tasks.gemspec +58 -0
- data/lib/i18n/tasks/base_task.rb +52 -0
- data/lib/i18n/tasks/cli.rb +214 -0
- data/lib/i18n/tasks/command/collection.rb +21 -0
- data/lib/i18n/tasks/command/commander.rb +38 -0
- data/lib/i18n/tasks/command/commands/data.rb +107 -0
- data/lib/i18n/tasks/command/commands/eq_base.rb +22 -0
- data/lib/i18n/tasks/command/commands/health.rb +30 -0
- data/lib/i18n/tasks/command/commands/interpolations.rb +22 -0
- data/lib/i18n/tasks/command/commands/meta.rb +37 -0
- data/lib/i18n/tasks/command/commands/missing.rb +73 -0
- data/lib/i18n/tasks/command/commands/tree.rb +102 -0
- data/lib/i18n/tasks/command/commands/usages.rb +81 -0
- data/lib/i18n/tasks/command/dsl.rb +56 -0
- data/lib/i18n/tasks/command/option_parsers/enum.rb +57 -0
- data/lib/i18n/tasks/command/option_parsers/locale.rb +60 -0
- data/lib/i18n/tasks/command/options/common.rb +47 -0
- data/lib/i18n/tasks/command/options/data.rb +97 -0
- data/lib/i18n/tasks/command/options/locales.rb +44 -0
- data/lib/i18n/tasks/command_error.rb +15 -0
- data/lib/i18n/tasks/commands.rb +29 -0
- data/lib/i18n/tasks/concurrent/cache.rb +22 -0
- data/lib/i18n/tasks/concurrent/cached_value.rb +61 -0
- data/lib/i18n/tasks/configuration.rb +136 -0
- data/lib/i18n/tasks/console_context.rb +76 -0
- data/lib/i18n/tasks/data/adapter/json_adapter.rb +29 -0
- data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +27 -0
- data/lib/i18n/tasks/data/file_formats.rb +99 -0
- data/lib/i18n/tasks/data/file_system.rb +14 -0
- data/lib/i18n/tasks/data/file_system_base.rb +200 -0
- data/lib/i18n/tasks/data/router/conservative_router.rb +62 -0
- data/lib/i18n/tasks/data/router/pattern_router.rb +62 -0
- data/lib/i18n/tasks/data/tree/node.rb +206 -0
- data/lib/i18n/tasks/data/tree/nodes.rb +97 -0
- data/lib/i18n/tasks/data/tree/siblings.rb +333 -0
- data/lib/i18n/tasks/data/tree/traversal.rb +197 -0
- data/lib/i18n/tasks/data.rb +87 -0
- data/lib/i18n/tasks/html_keys.rb +14 -0
- data/lib/i18n/tasks/ignore_keys.rb +31 -0
- data/lib/i18n/tasks/interpolations.rb +30 -0
- data/lib/i18n/tasks/key_pattern_matching.rb +38 -0
- data/lib/i18n/tasks/locale_list.rb +19 -0
- data/lib/i18n/tasks/locale_pathname.rb +17 -0
- data/lib/i18n/tasks/logging.rb +35 -0
- data/lib/i18n/tasks/missing_keys.rb +185 -0
- data/lib/i18n/tasks/plural_keys.rb +67 -0
- data/lib/i18n/tasks/references.rb +103 -0
- data/lib/i18n/tasks/reports/base.rb +75 -0
- data/lib/i18n/tasks/reports/terminal.rb +243 -0
- data/lib/i18n/tasks/scanners/erb_ast_processor.rb +51 -0
- data/lib/i18n/tasks/scanners/erb_ast_scanner.rb +48 -0
- data/lib/i18n/tasks/scanners/file_scanner.rb +66 -0
- data/lib/i18n/tasks/scanners/files/caching_file_finder.rb +35 -0
- data/lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb +31 -0
- data/lib/i18n/tasks/scanners/files/caching_file_reader.rb +28 -0
- data/lib/i18n/tasks/scanners/files/file_finder.rb +61 -0
- data/lib/i18n/tasks/scanners/files/file_reader.rb +19 -0
- data/lib/i18n/tasks/scanners/local_ruby_parser.rb +74 -0
- data/lib/i18n/tasks/scanners/occurrence_from_position.rb +29 -0
- data/lib/i18n/tasks/scanners/pattern_mapper.rb +60 -0
- data/lib/i18n/tasks/scanners/pattern_scanner.rb +108 -0
- data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +100 -0
- data/lib/i18n/tasks/scanners/relative_keys.rb +70 -0
- data/lib/i18n/tasks/scanners/results/key_occurrences.rb +54 -0
- data/lib/i18n/tasks/scanners/results/occurrence.rb +69 -0
- data/lib/i18n/tasks/scanners/ruby_ast_call_finder.rb +63 -0
- data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +234 -0
- data/lib/i18n/tasks/scanners/ruby_key_literals.rb +30 -0
- data/lib/i18n/tasks/scanners/scanner.rb +17 -0
- data/lib/i18n/tasks/scanners/scanner_multiplexer.rb +43 -0
- data/lib/i18n/tasks/split_key.rb +72 -0
- data/lib/i18n/tasks/stats.rb +24 -0
- data/lib/i18n/tasks/string_interpolation.rb +17 -0
- data/lib/i18n/tasks/translation.rb +29 -0
- data/lib/i18n/tasks/translators/base_translator.rb +156 -0
- data/lib/i18n/tasks/translators/deepl_translator.rb +81 -0
- data/lib/i18n/tasks/translators/google_translator.rb +69 -0
- data/lib/i18n/tasks/translators/yandex_translator.rb +63 -0
- data/lib/i18n/tasks/translators/youdao_translator.rb +69 -0
- data/lib/i18n/tasks/unused_keys.rb +25 -0
- data/lib/i18n/tasks/used_keys.rb +184 -0
- data/lib/i18n/tasks/version.rb +7 -0
- data/lib/i18n/tasks.rb +69 -0
- data/templates/config/i18n-tasks.yml +142 -0
- data/templates/minitest/i18n_test.rb +36 -0
- data/templates/rspec/i18n_spec.rb +34 -0
- metadata +441 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: decea27417fe9009410ffdf1b00395d9982841369d4c86c10cb32bce0afec6ff
|
4
|
+
data.tar.gz: 2883bec42d018673d76724b81f1d1b0ff1b2c1ad3c6aba26873c64e20717c84a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 86b1a0f250f8e08f3814403bc8520e1c38e61ee2dc56d486f7af766fde844b74758fe4c47e9ad29516bd7a6cfc3d2a2a80ec915cffcf66c767b754be422d8131
|
7
|
+
data.tar.gz: dca4579f85c296e4b9e31339bf80e04d5065b3921724007f3134dfaa9672d9e6a37f63ad85221b8cf797df0aa83be6c1d937aab3edcd773e38445d592150cd93
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013-2014 Gleb Mazovetskiy
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,448 @@
|
|
1
|
+
# i18n-tasks [![Build Status][badge-ci]][ci] [![Coverage Status][badge-coverage]][coverage] [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/glebm/i18n-tasks?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
2
|
+
|
3
|
+
i18n-tasks helps you find and manage missing and unused translations.
|
4
|
+
|
5
|
+
<img width="539" height="331" src="https://i.imgur.com/XZBd8l7.png">
|
6
|
+
|
7
|
+
This gem analyses code statically for key usages, such as `I18n.t('some.key')`, in order to:
|
8
|
+
|
9
|
+
* Report keys that are missing or unused.
|
10
|
+
* Pre-fill missing keys, optionally from Google Translate or DeepL Pro.
|
11
|
+
* Remove unused keys.
|
12
|
+
|
13
|
+
Thus addressing the two main problems of [i18n gem][i18n-gem] design:
|
14
|
+
|
15
|
+
* Missing keys only blow up at runtime.
|
16
|
+
* Keys no longer in use may accumulate and introduce overhead, without you knowing it.
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
i18n-tasks can be used with any project using the ruby [i18n gem][i18n-gem] (default in Rails).
|
21
|
+
|
22
|
+
Add i18n-tasks to the Gemfile:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'i18n-tasks', '~> 0.9.37'
|
26
|
+
```
|
27
|
+
|
28
|
+
Copy the default [configuration file](#configuration):
|
29
|
+
|
30
|
+
```console
|
31
|
+
$ cp $(i18n-tasks gem-path)/templates/config/i18n-tasks.yml config/
|
32
|
+
```
|
33
|
+
|
34
|
+
Copy rspec test to test for missing and unused translations as part of the suite (optional):
|
35
|
+
|
36
|
+
```console
|
37
|
+
$ cp $(i18n-tasks gem-path)/templates/rspec/i18n_spec.rb spec/
|
38
|
+
```
|
39
|
+
|
40
|
+
Or for minitest:
|
41
|
+
|
42
|
+
```console
|
43
|
+
$ cp $(i18n-tasks gem-path)/templates/minitest/i18n_test.rb test/
|
44
|
+
```
|
45
|
+
|
46
|
+
## Usage
|
47
|
+
|
48
|
+
Run `bundle exec i18n-tasks` to get the list of all the tasks with short descriptions.
|
49
|
+
|
50
|
+
### Check health
|
51
|
+
|
52
|
+
`i18n-tasks health` checks if any keys are missing or not used,
|
53
|
+
that interpolations variables are consistent across locales,
|
54
|
+
and that all the locale files are normalized (auto-formatted):
|
55
|
+
|
56
|
+
```console
|
57
|
+
$ i18n-tasks health
|
58
|
+
```
|
59
|
+
|
60
|
+
### Add missing keys
|
61
|
+
|
62
|
+
Add missing keys with placeholders (base value or humanized key):
|
63
|
+
|
64
|
+
```console
|
65
|
+
$ i18n-tasks add-missing
|
66
|
+
```
|
67
|
+
|
68
|
+
This and other tasks accept arguments:
|
69
|
+
|
70
|
+
```console
|
71
|
+
$ i18n-tasks add-missing -v 'TRME %{value}' fr
|
72
|
+
```
|
73
|
+
|
74
|
+
Pass `--help` for more information:
|
75
|
+
|
76
|
+
```console
|
77
|
+
$ i18n-tasks add-missing --help
|
78
|
+
Usage: i18n-tasks add-missing [options] [locale ...]
|
79
|
+
-l, --locales Comma-separated list of locale(s) to process. Default: all. Special: base.
|
80
|
+
-f, --format Output format: terminal-table, yaml, json, keys, inspect. Default: terminal-table.
|
81
|
+
-v, --value Value. Interpolates: %{value}, %{human_key}, %{value_or_human_key}, %{key}. Default: %{value_or_human_key}.
|
82
|
+
-h, --help Display this help message.
|
83
|
+
```
|
84
|
+
|
85
|
+
### Google Translate missing keys
|
86
|
+
|
87
|
+
Translate missing values with Google Translate ([more below on the API key](#google-translation-config)).
|
88
|
+
|
89
|
+
```console
|
90
|
+
$ i18n-tasks translate-missing
|
91
|
+
|
92
|
+
# accepts from and locales options:
|
93
|
+
$ i18n-tasks translate-missing --from=base es fr
|
94
|
+
```
|
95
|
+
|
96
|
+
### DeepL Pro Translate missing keys
|
97
|
+
|
98
|
+
Translate missing values with DeepL Pro Translate ([more below on the API key](#deepl-translation-config)).
|
99
|
+
|
100
|
+
```console
|
101
|
+
$ i18n-tasks translate-missing --backend=deepl
|
102
|
+
|
103
|
+
# accepts from and locales options:
|
104
|
+
$ i18n-tasks translate-missing --backend=deepl --from=en fr nl
|
105
|
+
```
|
106
|
+
|
107
|
+
### Yandex Translate missing keys
|
108
|
+
|
109
|
+
Translate missing values with Yandex Translate ([more below on the API key](#yandex-translation-config)).
|
110
|
+
|
111
|
+
```console
|
112
|
+
$ i18n-tasks translate-missing --backend=yandex
|
113
|
+
|
114
|
+
# accepts from and locales options:
|
115
|
+
$ i18n-tasks translate-missing --from=en es fr
|
116
|
+
```
|
117
|
+
|
118
|
+
### Find usages
|
119
|
+
|
120
|
+
See where the keys are used with `i18n-tasks find`:
|
121
|
+
|
122
|
+
```bash
|
123
|
+
$ i18n-tasks find common.help
|
124
|
+
$ i18n-tasks find 'auth.*'
|
125
|
+
$ i18n-tasks find '{number,currency}.format.*'
|
126
|
+
```
|
127
|
+
|
128
|
+
<img width="437" height="129" src="https://i.imgur.com/VxBrSfY.png">
|
129
|
+
|
130
|
+
### Remove unused keys
|
131
|
+
|
132
|
+
```bash
|
133
|
+
$ i18n-tasks unused
|
134
|
+
$ i18n-tasks remove-unused
|
135
|
+
```
|
136
|
+
|
137
|
+
These tasks can infer [dynamic keys](#dynamic-keys) such as `t("category.\#{category.name}")` if you set
|
138
|
+
`search.strict` to false, or pass `--no-strict` on the command line.
|
139
|
+
|
140
|
+
If you want to keep the ordering from the original language file when using remove-unused, pass
|
141
|
+
`-k` or `--keep-order`.
|
142
|
+
|
143
|
+
### Normalize data
|
144
|
+
|
145
|
+
Sort the keys:
|
146
|
+
|
147
|
+
```console
|
148
|
+
$ i18n-tasks normalize
|
149
|
+
```
|
150
|
+
|
151
|
+
Sort the keys, and move them to the respective files as defined by [`config.write`](#multiple-locale-files):
|
152
|
+
|
153
|
+
```console
|
154
|
+
$ i18n-tasks normalize -p
|
155
|
+
```
|
156
|
+
|
157
|
+
### Move / rename / merge keys
|
158
|
+
|
159
|
+
`i18n-tasks mv <pattern> <target>` is a versatile task to move or delete keys matching the given pattern.
|
160
|
+
|
161
|
+
All nodes (leafs or subtrees) matching [`<pattern>`](#key-pattern-syntax) are merged together and moved to `<target>`.
|
162
|
+
|
163
|
+
Rename a node (leaf or subtree):
|
164
|
+
|
165
|
+
``` console
|
166
|
+
$ i18n-tasks mv user account
|
167
|
+
```
|
168
|
+
|
169
|
+
Move a node:
|
170
|
+
|
171
|
+
``` console
|
172
|
+
$ i18n-tasks mv user_alerts user.alerts
|
173
|
+
```
|
174
|
+
|
175
|
+
Move the children one level up:
|
176
|
+
|
177
|
+
``` console
|
178
|
+
$ i18n-tasks mv 'alerts.{:}' '\1'
|
179
|
+
```
|
180
|
+
|
181
|
+
Merge-move multiple nodes:
|
182
|
+
|
183
|
+
``` console
|
184
|
+
$ i18n-tasks mv '{user,profile}' account
|
185
|
+
```
|
186
|
+
|
187
|
+
Merge (non-leaf) nodes into parent:
|
188
|
+
|
189
|
+
``` console
|
190
|
+
$ i18n-tasks mv '{pages}.{a,b}' '\1'
|
191
|
+
```
|
192
|
+
|
193
|
+
### Delete keys
|
194
|
+
|
195
|
+
Delete the keys by using the `rm` task:
|
196
|
+
|
197
|
+
```console
|
198
|
+
$ i18n-tasks rm 'user.{old_profile,old_title}' another_key
|
199
|
+
```
|
200
|
+
|
201
|
+
### Compose tasks
|
202
|
+
|
203
|
+
`i18n-tasks` also provides composable tasks for reading, writing and manipulating locale data. Examples below.
|
204
|
+
|
205
|
+
`add-missing` implemented with `missing`, `tree-set-value` and `data-merge`:
|
206
|
+
```console
|
207
|
+
$ i18n-tasks missing -f yaml fr | i18n-tasks tree-set-value 'TRME %{value}' | i18n-tasks data-merge
|
208
|
+
```
|
209
|
+
|
210
|
+
`remove-unused` implemented with `unused` and `data-remove` (sans the confirmation):
|
211
|
+
```console
|
212
|
+
$ i18n-tasks unused -f yaml | i18n-tasks data-remove
|
213
|
+
```
|
214
|
+
|
215
|
+
Remove all keys from `fr` that do not exist in `en`. Do not change `en`:
|
216
|
+
```console
|
217
|
+
$ i18n-tasks missing -t diff -f yaml en | i18n-tasks tree-mv en fr | i18n-tasks data-remove
|
218
|
+
```
|
219
|
+
|
220
|
+
See the full list of tasks with `i18n-tasks --help`.
|
221
|
+
|
222
|
+
### Features and limitations
|
223
|
+
|
224
|
+
`i18n-tasks` uses an AST scanner for `.rb` files, and a regexp-based scanner for other files, such as `.haml`.
|
225
|
+
|
226
|
+
#### Relative keys
|
227
|
+
|
228
|
+
`i18n-tasks` offers support for relative keys, such as `t '.title'`.
|
229
|
+
|
230
|
+
✔ Keys relative to the file path they are used in (see [relative roots configuration](#usage-search)) are supported.
|
231
|
+
|
232
|
+
✔ Keys relative to `controller.action_name` in Rails controllers are supported. The closest `def` name is used.
|
233
|
+
|
234
|
+
#### Plural keys
|
235
|
+
|
236
|
+
✔ Plural keys, such as `key.{one,many,other,...}` are fully supported.
|
237
|
+
|
238
|
+
#### Reference keys
|
239
|
+
|
240
|
+
✔ Reference keys (keys with `:symbol` values) are fully supported. These keys are copied as-is in
|
241
|
+
`add/translate-missing`, and can be looked up by reference or value in `find`.
|
242
|
+
|
243
|
+
#### `t()` keyword arguments
|
244
|
+
|
245
|
+
✔ `scope` keyword argument is fully supported by the AST scanner, and also by the Regexp scanner but only when it is the first argument.
|
246
|
+
|
247
|
+
✔ `default` argument can be used to pre-fill locale files (AST scanner only).
|
248
|
+
|
249
|
+
#### Dynamic keys
|
250
|
+
|
251
|
+
By default, dynamic keys such as `t "cats.#{cat}.name"` are not recognized.
|
252
|
+
I encourage you to mark these with [i18n-tasks-use hints](#fine-tuning).
|
253
|
+
|
254
|
+
Alternatively, you can enable dynamic key inference by setting `search.strict` to `false` in the config. In this case,
|
255
|
+
all the dynamic parts of the key will be considered used, e.g. `cats.tenderlove.name` would not be reported as unused.
|
256
|
+
Note that only one section of the key is treated as a wildcard for each string interpolation; i.e. in this example,
|
257
|
+
`cats.tenderlove.special.name` *will* be reported as unused.
|
258
|
+
|
259
|
+
#### I18n.localize
|
260
|
+
|
261
|
+
`I18n.localize` is not supported, use [i18n-tasks-use hints](#fine-tuning).
|
262
|
+
This is because the key generated by `I18n.localize` depends on the type of the object passed in and thus cannot be inferred statically.
|
263
|
+
|
264
|
+
## Configuration
|
265
|
+
|
266
|
+
Configuration is read from `config/i18n-tasks.yml` or `config/i18n-tasks.yml.erb`.
|
267
|
+
Inspect the configuration with `i18n-tasks config`.
|
268
|
+
|
269
|
+
Install the [default config file][config] with:
|
270
|
+
|
271
|
+
```console
|
272
|
+
$ cp $(i18n-tasks gem-path)/templates/config/i18n-tasks.yml config/
|
273
|
+
```
|
274
|
+
|
275
|
+
Settings are compatible with Rails by default.
|
276
|
+
|
277
|
+
### Locales
|
278
|
+
|
279
|
+
By default, `base_locale` is set to `en` and `locales` are inferred from the paths to data files.
|
280
|
+
You can override these in the [config][config].
|
281
|
+
|
282
|
+
### Storage
|
283
|
+
|
284
|
+
The default data adapter supports YAML and JSON files.
|
285
|
+
|
286
|
+
#### Multiple locale files
|
287
|
+
|
288
|
+
i18n-tasks can manage multiple translation files and read translations from other gems.
|
289
|
+
To find out more see the `data` options in the [config][config].
|
290
|
+
NB: By default, only `%{locale}.yml` files are read, not `namespace.%{locale}.yml`. Make sure to check the config.
|
291
|
+
|
292
|
+
For writing to locale files i18n-tasks provides 2 options.
|
293
|
+
|
294
|
+
##### Pattern router
|
295
|
+
|
296
|
+
Pattern router organizes keys based on a list of key patterns, as in the example below:
|
297
|
+
|
298
|
+
```
|
299
|
+
data:
|
300
|
+
router: pattern_router
|
301
|
+
# a list of {key pattern => file} routes, matched top to bottom
|
302
|
+
write:
|
303
|
+
# write models.* and views.* keys to the respective files
|
304
|
+
- ['{models,views}.*', 'config/locales/\1.%{locale}.yml']
|
305
|
+
# or, write every top-level key namespace to its own file
|
306
|
+
- ['{:}.*', 'config/locales/\1.%{locale}.yml']
|
307
|
+
# default, sugar for ['*', path]
|
308
|
+
- 'config/locales/%{locale}.yml'
|
309
|
+
```
|
310
|
+
|
311
|
+
##### Conservative router
|
312
|
+
|
313
|
+
Conservative router keeps the keys where they are found, or infers the path from base locale.
|
314
|
+
If the key is completely new, conservative router will fall back to pattern router behaviour.
|
315
|
+
Conservative router is the **default** router.
|
316
|
+
|
317
|
+
```
|
318
|
+
data:
|
319
|
+
router: conservative_router
|
320
|
+
write:
|
321
|
+
- ['devise.*', 'config/locales/devise.%{locale}.yml']
|
322
|
+
- 'config/locales/%{locale}.yml'
|
323
|
+
```
|
324
|
+
|
325
|
+
If you want to have i18n-tasks reorganize your existing keys using `data.write`, either set the router to
|
326
|
+
`pattern_router` as above, or run `i18n-tasks normalize -p` (forcing the use of the pattern router for that run).
|
327
|
+
|
328
|
+
##### Key pattern syntax
|
329
|
+
|
330
|
+
A special syntax similar to file glob patterns is used throughout i18n-tasks to match translation keys:
|
331
|
+
|
332
|
+
| syntax | description |
|
333
|
+
|:------------:|:----------------------------------------------------------|
|
334
|
+
| `*` | matches everything |
|
335
|
+
| `:` | matches a single key |
|
336
|
+
| `{a, b.c}` | match any in set, can use `:` and `*`, match is captured |
|
337
|
+
|
338
|
+
Example of usage:
|
339
|
+
|
340
|
+
```sh
|
341
|
+
$ bundle exec i18n-tasks mv "{:}.contents.{*}_body" "\1.attributes.\2.body"
|
342
|
+
|
343
|
+
car.contents.name_body ⮕ car.attributes.name.body
|
344
|
+
car.contents.description_body ⮕ car.attributes.description.body
|
345
|
+
truck.contents.name_body ⮕ truck.attributes.name.body
|
346
|
+
truck.contents.description_body ⮕ truck.attributes.description.body
|
347
|
+
```
|
348
|
+
|
349
|
+
#### Custom adapters
|
350
|
+
|
351
|
+
If you store data somewhere but in the filesystem, e.g. in the database or mongodb, you can implement a custom adapter.
|
352
|
+
If you have implemented a custom adapter please share it on [the wiki][wiki].
|
353
|
+
|
354
|
+
### Usage search
|
355
|
+
|
356
|
+
i18n-tasks uses an AST scanner for `.rb` files, and a regexp scanner for all other files.
|
357
|
+
New scanners can be added easily: please refer to [this example](https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example).
|
358
|
+
|
359
|
+
See the `search` section in the [config file][config] for all available configuration options.
|
360
|
+
NB: By default, only the `app/` directory is searched.
|
361
|
+
|
362
|
+
### Fine-tuning
|
363
|
+
|
364
|
+
Add hints to static analysis with magic comment hints (lines starting with `(#|/) i18n-tasks-use` by default):
|
365
|
+
|
366
|
+
```ruby
|
367
|
+
# i18n-tasks-use t('activerecord.models.user') # let i18n-tasks know the key is used
|
368
|
+
User.model_name.human
|
369
|
+
```
|
370
|
+
|
371
|
+
You can also explicitly ignore keys appearing in locale files via `ignore*` settings.
|
372
|
+
|
373
|
+
If you have helper methods that generate translation keys, such as a `page_title` method that returns `t '.page_title'`,
|
374
|
+
or a `Spree.t(key)` method that returns `t "spree.#{key}"`, use the built-in `PatternMapper` to map these.
|
375
|
+
|
376
|
+
For more complex cases, you can implement a [custom scanner][custom-scanner-docs].
|
377
|
+
|
378
|
+
See the [config file][config] to find out more.
|
379
|
+
|
380
|
+
<a name="google-translation-config"></a>
|
381
|
+
### Google Translate
|
382
|
+
|
383
|
+
`i18n-tasks translate-missing` requires a Google Translate API key, get it at [Google API Console](https://code.google.com/apis/console).
|
384
|
+
|
385
|
+
Where this key is depends on your Google API console:
|
386
|
+
|
387
|
+
* Old console: API Access -> Simple API Access -> Key for server apps.
|
388
|
+
* New console: Nav Menu -> APIs & Services -> Credentials -> Create Credentials -> API Keys -> Restrict Key -> Cloud Translation API
|
389
|
+
|
390
|
+
In both cases, you may need to create the key if it doesn't exist.
|
391
|
+
|
392
|
+
Put the key in `GOOGLE_TRANSLATE_API_KEY` environment variable or in the config file.
|
393
|
+
|
394
|
+
```yaml
|
395
|
+
# config/i18n-tasks.yml
|
396
|
+
translation:
|
397
|
+
google_translate_api_key: <Google Translate API key>
|
398
|
+
```
|
399
|
+
|
400
|
+
<a name="deepl-translation-config"></a>
|
401
|
+
### DeepL Pro Translate
|
402
|
+
|
403
|
+
`i18n-tasks translate-missing` requires a DeepL Pro API key, get it at [DeepL](https://www.deepl.com/pro).
|
404
|
+
|
405
|
+
```yaml
|
406
|
+
# config/i18n-tasks.yml
|
407
|
+
translation:
|
408
|
+
deepl_api_key: <DeepL Pro API key>
|
409
|
+
deepl_host: <optional>
|
410
|
+
deepl_version: <optional>
|
411
|
+
```
|
412
|
+
|
413
|
+
<a name="yandex-translation-config"></a>
|
414
|
+
### Yandex Translate
|
415
|
+
|
416
|
+
`i18n-tasks translate-missing` requires a Yandex API key, get it at [Yandex](https://tech.yandex.com/translate).
|
417
|
+
|
418
|
+
```yaml
|
419
|
+
# config/i18n-tasks.yml
|
420
|
+
translation:
|
421
|
+
yandex_api_key: <Yandex API key>
|
422
|
+
```
|
423
|
+
|
424
|
+
## Interactive console
|
425
|
+
|
426
|
+
`i18n-tasks irb` starts an IRB session in i18n-tasks context. Type `guide` for more information.
|
427
|
+
|
428
|
+
## Import / export to a CSV spreadsheet
|
429
|
+
|
430
|
+
See [i18n-tasks wiki: CSV import and export tasks](https://github.com/glebm/i18n-tasks/wiki/Custom-CSV-import-and-export-tasks).
|
431
|
+
|
432
|
+
## Add new tasks
|
433
|
+
|
434
|
+
Tasks that come with the gem are defined in [lib/i18n/tasks/command/commands](lib/i18n/tasks/command/commands).
|
435
|
+
Custom tasks can be added easily, see the examples [on the wiki](https://github.com/glebm/i18n-tasks/wiki#custom-tasks).
|
436
|
+
|
437
|
+
[MIT license]: /LICENSE.txt
|
438
|
+
[ci]: https://github.com/glebm/i18n-tasks/actions/workflows/tests.yml
|
439
|
+
[badge-ci]: https://github.com/glebm/i18n-tasks/actions/workflows/tests.yml/badge.svg
|
440
|
+
[coverage]: https://codeclimate.com/github/glebm/i18n-tasks
|
441
|
+
[badge-coverage]: https://api.codeclimate.com/v1/badges/5d173e90ada8df07cedc/test_coverage
|
442
|
+
[config]: https://github.com/glebm/i18n-tasks/blob/master/templates/config/i18n-tasks.yml
|
443
|
+
[wiki]: https://github.com/glebm/i18n-tasks/wiki "i18n-tasks wiki"
|
444
|
+
[i18n-gem]: https://github.com/svenfuchs/i18n "svenfuchs/i18n on Github"
|
445
|
+
[screenshot-i18n-tasks]: https://i.imgur.com/XZBd8l7.png "i18n-tasks screenshot"
|
446
|
+
[screenshot-find]: https://i.imgur.com/VxBrSfY.png "i18n-tasks find output screenshot"
|
447
|
+
[adapter-example]: https://github.com/glebm/i18n-tasks/blob/master/lib/i18n/tasks/data/file_system_base.rb
|
448
|
+
[custom-scanner-docs]: https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
RSpec::Core::RakeTask.new(:rspec)
|
6
|
+
task default: :rspec
|
7
|
+
|
8
|
+
task :irb do
|
9
|
+
# $: << File.expand_path('lib', __FILE__)
|
10
|
+
require 'i18n/tasks'
|
11
|
+
require 'i18n/tasks/commands'
|
12
|
+
::I18n::Tasks::Commands.new(::I18n::Tasks::BaseTask.new).irb
|
13
|
+
end
|
data/bin/i18n-tasks
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../spec/bin_simplecov_helper' if ENV['I18N_TASKS_BIN_SIMPLECOV_COVERAGE']
|
5
|
+
|
6
|
+
# prevent i18n gem warning
|
7
|
+
require 'i18n'
|
8
|
+
i18n_gem_config = I18n.config
|
9
|
+
if i18n_gem_config.respond_to?(:enforce_available_locales=) && i18n_gem_config.enforce_available_locales.nil?
|
10
|
+
i18n_gem_config.enforce_available_locales = true
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'i18n/tasks/cli'
|
14
|
+
|
15
|
+
I18n::Tasks::CLI.start(ARGV)
|
data/bin/i18n-tasks.cmd
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
i18n_tasks:
|
4
|
+
add_missing:
|
5
|
+
added:
|
6
|
+
one: Added %{count} key
|
7
|
+
other: Added %{count} keys
|
8
|
+
cmd:
|
9
|
+
args:
|
10
|
+
default_text: 'Default: %{value}'
|
11
|
+
desc:
|
12
|
+
all_locales: Do not expect key patterns to start with a locale, instead apply them to all
|
13
|
+
locales implicitly.
|
14
|
+
config: Override config location
|
15
|
+
confirm: Confirm automatically
|
16
|
+
data_format: 'Data format: %{valid_text}.'
|
17
|
+
keep_order: Keep the order of the keys
|
18
|
+
key_pattern: Filter by key pattern (e.g. 'common.*')
|
19
|
+
key_pattern_to_rename: Full key (pattern) to rename. Required
|
20
|
+
locale: :i18n_tasks.common.locale
|
21
|
+
locale_to_translate_from: Locale to translate from
|
22
|
+
locales_filter: 'Locale(s) to process. Special: base'
|
23
|
+
missing_types: 'Filter by types: %{valid}'
|
24
|
+
new_key_name: New name, interpolates original name as %{key}. Required
|
25
|
+
nostdin: Do not read from stdin
|
26
|
+
out_format: 'Output format: %{valid_text}'
|
27
|
+
pattern_router: 'Use pattern router: keys moved per config data.write'
|
28
|
+
strict: >-
|
29
|
+
Avoid inferring dynamic key usages such as t("cats.#{cat}.name"). Takes precedence over
|
30
|
+
the config setting if set.
|
31
|
+
translation_backend: Translation backend (google or deepl)
|
32
|
+
value: >-
|
33
|
+
Value. Interpolates: %{value}, %{human_key}, %{key}, %{default}, %{value_or_human_key},
|
34
|
+
%{value_or_default_or_human_key}
|
35
|
+
desc:
|
36
|
+
add_missing: add missing keys to locale data
|
37
|
+
check_consistent_interpolations: verify that all translations use correct interpolation variables
|
38
|
+
check_normalized: verify that all translation data is normalized
|
39
|
+
config: display i18n-tasks configuration
|
40
|
+
data: show locale data
|
41
|
+
data_merge: merge locale data with trees
|
42
|
+
data_remove: remove keys present in tree from data
|
43
|
+
data_write: replace locale data with tree
|
44
|
+
eq_base: show translations equal to base value
|
45
|
+
find: show where keys are used in the code
|
46
|
+
gem_path: show path to the gem
|
47
|
+
health: is everything OK?
|
48
|
+
irb: start REPL session within i18n-tasks context
|
49
|
+
missing: show missing translations
|
50
|
+
mv: rename/merge the keys in locale data that match the given pattern
|
51
|
+
normalize: 'normalize translation data: sort and move to the right files'
|
52
|
+
remove_unused: remove unused keys
|
53
|
+
rm: remove the keys in locale data that match the given pattern
|
54
|
+
translate_missing: translate missing keys with Google Translate or DeepL Pro
|
55
|
+
tree_convert: convert tree between formats
|
56
|
+
tree_filter: filter tree by key pattern
|
57
|
+
tree_merge: merge trees
|
58
|
+
tree_mv_key: rename/merge/remove the keys matching the given pattern
|
59
|
+
tree_set_value: set values of keys, optionally match a pattern
|
60
|
+
tree_subtract: tree A minus the keys in tree B
|
61
|
+
tree_translate: Google Translate a tree to root locales
|
62
|
+
unused: show unused translations
|
63
|
+
encourage:
|
64
|
+
- Good job!
|
65
|
+
- Well done!
|
66
|
+
- Perfect!
|
67
|
+
enum_list_opt:
|
68
|
+
invalid: "%{invalid} is not in: %{valid}."
|
69
|
+
enum_opt:
|
70
|
+
invalid: "%{invalid} is not one of: %{valid}."
|
71
|
+
errors:
|
72
|
+
invalid_format: 'invalid format: %{invalid}. valid: %{valid}.'
|
73
|
+
invalid_locale: 'invalid locale: %{invalid}'
|
74
|
+
invalid_missing_type:
|
75
|
+
one: 'invalid type: %{invalid}. valid: %{valid}.'
|
76
|
+
other: 'unknown types: %{invalid}. valid: %{valid}.'
|
77
|
+
pass_forest: pass locale forest
|
78
|
+
common:
|
79
|
+
continue_q: Continue?
|
80
|
+
key: Key
|
81
|
+
locale: Locale
|
82
|
+
n_more: "%{count} more"
|
83
|
+
value: Value
|
84
|
+
data_stats:
|
85
|
+
text: >-
|
86
|
+
has %{key_count} keys across %{locale_count} locales. On average, values are %{value_chars_avg}
|
87
|
+
characters long, keys have %{key_segments_avg} segments, a locale has %{per_locale_avg} keys.
|
88
|
+
text_single_locale: >-
|
89
|
+
has %{key_count} keys in total. On average, values are %{value_chars_avg} characters long,
|
90
|
+
keys have %{key_segments_avg} segments.
|
91
|
+
title: Forest (%{locales})
|
92
|
+
deepl_translate:
|
93
|
+
errors:
|
94
|
+
no_api_key: >-
|
95
|
+
Setup DeepL Pro API key via DEEPL_AUTH_KEY environment variable or translation.deepl_api_key
|
96
|
+
in config/i18n-tasks.yml. Get the key at https://www.deepl.com/pro.
|
97
|
+
no_results: DeepL returned no results.
|
98
|
+
google_translate:
|
99
|
+
errors:
|
100
|
+
no_api_key: >-
|
101
|
+
Set Google API key via GOOGLE_TRANSLATE_API_KEY environment variable or translation.google_translate_api_key
|
102
|
+
in config/i18n-tasks.yml. Get the key at https://code.google.com/apis/console.
|
103
|
+
no_results: >-
|
104
|
+
Google Translate returned no results. Make sure billing information is set at https://code.google.com/apis/console.
|
105
|
+
health:
|
106
|
+
no_keys_detected: No keys detected. Check data.read in config/i18n-tasks.yml.
|
107
|
+
inconsistent_interpolations:
|
108
|
+
none: No inconsistent interpolations found.
|
109
|
+
missing:
|
110
|
+
details_title: Value in other locales or source
|
111
|
+
none: No translations are missing.
|
112
|
+
remove_unused:
|
113
|
+
confirm:
|
114
|
+
one: "%{count} translation will be removed from %{locales}."
|
115
|
+
other: "%{count} translation will be removed from %{locales}."
|
116
|
+
noop: No unused keys to remove
|
117
|
+
removed: Removed %{count} keys
|
118
|
+
translate_missing:
|
119
|
+
translated: Translated %{count} keys
|
120
|
+
unused:
|
121
|
+
none: Every translation is in use.
|
122
|
+
usages:
|
123
|
+
none: No key usages found.
|
124
|
+
yandex_translate:
|
125
|
+
errors:
|
126
|
+
no_api_key: >-
|
127
|
+
Set Yandex API key via YANDEX_API_KEY environment variable or translation.yandex_api_key
|
128
|
+
in config/i18n-tasks.yml. Get the key at https://tech.yandex.com/translate.
|
129
|
+
no_results: Yandex returned no results.
|