i18n-tasks 1.0.14 → 1.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.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +138 -39
  3. data/Rakefile +4 -4
  4. data/bin/i18n-tasks +3 -3
  5. data/config/locales/en.yml +17 -1
  6. data/config/locales/ru.yml +18 -1
  7. data/i18n-tasks.gemspec +28 -38
  8. data/lib/i18n/tasks/base_task.rb +19 -19
  9. data/lib/i18n/tasks/cli.rb +37 -30
  10. data/lib/i18n/tasks/command/collection.rb +4 -4
  11. data/lib/i18n/tasks/command/commander.rb +5 -5
  12. data/lib/i18n/tasks/command/commands/check_prism.rb +126 -0
  13. data/lib/i18n/tasks/command/commands/data.rb +33 -33
  14. data/lib/i18n/tasks/command/commands/eq_base.rb +3 -3
  15. data/lib/i18n/tasks/command/commands/health.rb +6 -5
  16. data/lib/i18n/tasks/command/commands/interpolations.rb +14 -3
  17. data/lib/i18n/tasks/command/commands/meta.rb +6 -6
  18. data/lib/i18n/tasks/command/commands/missing.rb +28 -26
  19. data/lib/i18n/tasks/command/commands/tree.rb +33 -33
  20. data/lib/i18n/tasks/command/commands/usages.rb +24 -24
  21. data/lib/i18n/tasks/command/dsl.rb +1 -1
  22. data/lib/i18n/tasks/command/option_parsers/enum.rb +8 -7
  23. data/lib/i18n/tasks/command/option_parsers/locale.rb +4 -4
  24. data/lib/i18n/tasks/command/options/common.rb +16 -16
  25. data/lib/i18n/tasks/command/options/data.rb +18 -18
  26. data/lib/i18n/tasks/command/options/locales.rb +33 -24
  27. data/lib/i18n/tasks/commands.rb +14 -12
  28. data/lib/i18n/tasks/concurrent/cache.rb +1 -1
  29. data/lib/i18n/tasks/concurrent/cached_value.rb +1 -1
  30. data/lib/i18n/tasks/configuration.rb +26 -20
  31. data/lib/i18n/tasks/console_context.rb +11 -11
  32. data/lib/i18n/tasks/data/adapter/json_adapter.rb +1 -1
  33. data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +5 -5
  34. data/lib/i18n/tasks/data/file_formats.rb +3 -3
  35. data/lib/i18n/tasks/data/file_system.rb +5 -5
  36. data/lib/i18n/tasks/data/file_system_base.rb +26 -26
  37. data/lib/i18n/tasks/data/language_names.rb +202 -0
  38. data/lib/i18n/tasks/data/router/conservative_router.rb +3 -3
  39. data/lib/i18n/tasks/data/router/isolating_router.rb +19 -19
  40. data/lib/i18n/tasks/data/router/pattern_router.rb +5 -5
  41. data/lib/i18n/tasks/data/tree/node.rb +27 -27
  42. data/lib/i18n/tasks/data/tree/nodes.rb +10 -10
  43. data/lib/i18n/tasks/data/tree/siblings.rb +20 -20
  44. data/lib/i18n/tasks/data/tree/traversal.rb +5 -5
  45. data/lib/i18n/tasks/data.rb +4 -4
  46. data/lib/i18n/tasks/html_keys.rb +2 -2
  47. data/lib/i18n/tasks/ignore_keys.rb +9 -9
  48. data/lib/i18n/tasks/interpolations.rb +21 -1
  49. data/lib/i18n/tasks/key_pattern_matching.rb +8 -8
  50. data/lib/i18n/tasks/logging.rb +2 -1
  51. data/lib/i18n/tasks/missing_keys.rb +24 -8
  52. data/lib/i18n/tasks/plural_keys.rb +6 -4
  53. data/lib/i18n/tasks/references.rb +4 -4
  54. data/lib/i18n/tasks/reports/base.rb +18 -14
  55. data/lib/i18n/tasks/reports/terminal.rb +64 -47
  56. data/lib/i18n/tasks/scanners/ast_matchers/base_matcher.rb +3 -3
  57. data/lib/i18n/tasks/scanners/ast_matchers/default_i18n_subject_matcher.rb +3 -3
  58. data/lib/i18n/tasks/scanners/ast_matchers/message_receivers_matcher.rb +10 -10
  59. data/lib/i18n/tasks/scanners/ast_matchers/rails_model_matcher.rb +2 -2
  60. data/lib/i18n/tasks/scanners/erb_ast_scanner.rb +69 -10
  61. data/lib/i18n/tasks/scanners/file_scanner.rb +5 -5
  62. data/lib/i18n/tasks/scanners/files/caching_file_finder.rb +3 -3
  63. data/lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb +3 -3
  64. data/lib/i18n/tasks/scanners/files/caching_file_reader.rb +2 -2
  65. data/lib/i18n/tasks/scanners/files/file_finder.rb +8 -8
  66. data/lib/i18n/tasks/scanners/files/file_reader.rb +1 -1
  67. data/lib/i18n/tasks/scanners/local_ruby_parser.rb +9 -9
  68. data/lib/i18n/tasks/scanners/occurrence_from_position.rb +1 -1
  69. data/lib/i18n/tasks/scanners/pattern_mapper.rb +7 -7
  70. data/lib/i18n/tasks/scanners/pattern_scanner.rb +20 -20
  71. data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +8 -8
  72. data/lib/i18n/tasks/scanners/prism_scanners/arguments_visitor.rb +48 -0
  73. data/lib/i18n/tasks/scanners/prism_scanners/nodes.rb +374 -0
  74. data/lib/i18n/tasks/scanners/prism_scanners/visitor.rb +337 -0
  75. data/lib/i18n/tasks/scanners/relative_keys.rb +8 -8
  76. data/lib/i18n/tasks/scanners/results/key_occurrences.rb +3 -3
  77. data/lib/i18n/tasks/scanners/results/occurrence.rb +14 -10
  78. data/lib/i18n/tasks/scanners/ruby_ast_call_finder.rb +1 -1
  79. data/lib/i18n/tasks/scanners/ruby_key_literals.rb +6 -6
  80. data/lib/i18n/tasks/scanners/ruby_parser_factory.rb +27 -0
  81. data/lib/i18n/tasks/scanners/ruby_scanner.rb +225 -0
  82. data/lib/i18n/tasks/scanners/scanner.rb +2 -2
  83. data/lib/i18n/tasks/scanners/scanner_multiplexer.rb +1 -1
  84. data/lib/i18n/tasks/split_key.rb +4 -4
  85. data/lib/i18n/tasks/stats.rb +3 -3
  86. data/lib/i18n/tasks/translation.rb +8 -5
  87. data/lib/i18n/tasks/translators/base_translator.rb +43 -13
  88. data/lib/i18n/tasks/translators/deepl_translator.rb +22 -14
  89. data/lib/i18n/tasks/translators/google_translator.rb +178 -26
  90. data/lib/i18n/tasks/translators/openai_translator.rb +56 -31
  91. data/lib/i18n/tasks/translators/watsonx_translator.rb +155 -0
  92. data/lib/i18n/tasks/translators/yandex_translator.rb +13 -9
  93. data/lib/i18n/tasks/unused_keys.rb +1 -1
  94. data/lib/i18n/tasks/used_keys.rb +32 -32
  95. data/lib/i18n/tasks/version.rb +1 -1
  96. data/lib/i18n/tasks.rb +17 -16
  97. data/templates/config/i18n-tasks.yml +14 -2
  98. data/templates/minitest/i18n_test.rb +3 -3
  99. data/templates/rspec/i18n_spec.rb +7 -7
  100. metadata +38 -172
  101. data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +0 -145
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd61ceb254dc1c44768bd40672b3f31635c9d42fb237950cbdfe64fef642a850
4
- data.tar.gz: ae6981dd739636ddb5f1bae1ca9e5cf05ba991fd1345a5488e1cfa8561833877
3
+ metadata.gz: 3231dd8c4f3772a49ed9db6862f6d34c9fabed656a1ba3588f2a0d24be158d50
4
+ data.tar.gz: b5db9e81af6eff9256acf3b84bbbcea4a738c987f0485e04e127eba0236f01fd
5
5
  SHA512:
6
- metadata.gz: 1312910139411cc4695bea0f0de8624d49958efac33c8c7b7bd99fb3f351d408d0a6980789ec81a43452bc29a15292f6de9719ace0e3b902866d63c02f5cab79
7
- data.tar.gz: e782f1bc1f1ad68cc33583d014c879b3d121ba2e0990db8cc109f864aeb0e98f0a97030300294e31e9041899b131b2b677fe6917f705d09bda6bf07aed588b42
6
+ metadata.gz: 601af6d9cf98382b36cb7eebec4672c8918440f63899ef8e91cda798de0685971e331e352420c0f7d3c2f4a5dc056d80f7b0feb1b04e7aa847c69ebd273ff214
7
+ data.tar.gz: d8e0c5b7bb14a6ab061f60360e869f293b2c608fde5a02f7ebb90495f8c0d0adec69d4665818bd96b2fe6f3c590434aa94ad35462e2777bd9925ac3150aa4273
data/README.md CHANGED
@@ -24,7 +24,7 @@ i18n-tasks can be used with any project using the ruby [i18n gem][i18n-gem] (def
24
24
  Add i18n-tasks to the Gemfile:
25
25
 
26
26
  ```ruby
27
- gem 'i18n-tasks', '~> 1.0.14', group: :development
27
+ gem 'i18n-tasks', '~> 1.1.0', group: :development
28
28
  ```
29
29
 
30
30
  Copy the default [configuration file](#configuration):
@@ -84,49 +84,23 @@ Usage: i18n-tasks add-missing [options] [locale ...]
84
84
  -h, --help Display this help message.
85
85
  ```
86
86
 
87
- ### Google Translate missing keys
87
+ ### Translate Missing Keys
88
88
 
89
- Translate missing values with Google Translate ([more below on the API key](#google-translation-config)).
89
+ Translate missing keys using a backend service of your choice.
90
90
 
91
91
  ```console
92
92
  $ i18n-tasks translate-missing
93
93
 
94
- # accepts from and locales options:
95
- $ i18n-tasks translate-missing --from=base es fr
94
+ # accepts backend, from and locales options
95
+ $ i18n-tasks translate-missing --from=base es fr --backend=google
96
96
  ```
97
97
 
98
- ### DeepL Pro Translate missing keys
99
-
100
- Translate missing values with DeepL Pro Translate ([more below on the API key](#deepl-translation-config)).
101
-
102
- ```console
103
- $ i18n-tasks translate-missing --backend=deepl
104
-
105
- # accepts from and locales options:
106
- $ i18n-tasks translate-missing --backend=deepl --from=en fr nl
107
- ```
108
-
109
- ### Yandex Translate missing keys
110
-
111
- Translate missing values with Yandex Translate ([more below on the API key](#yandex-translation-config)).
112
-
113
- ```console
114
- $ i18n-tasks translate-missing --backend=yandex
115
-
116
- # accepts from and locales options:
117
- $ i18n-tasks translate-missing --from=en es fr
118
- ```
119
-
120
- ### OpenAI Translate missing keys
121
-
122
- Translate missing values with OpenAI ([more below on the API key](#openai-translation-config)).
123
-
124
- ```console
125
- $ i18n-tasks translate-missing --backend=openai
126
-
127
- # accepts from and locales options:
128
- $ i18n-tasks translate-missing --from=en es fr
129
- ```
98
+ Available backends:
99
+ - `google` - [Google Translate](#google-translation-config)
100
+ - `deepl` - [DeepL Pro](#deepl-translation-config)
101
+ - `yandex` - [Yandex Translate](#yandex-translation-config)
102
+ - `openai` - [OpenAI](#openai-translation-config)
103
+ - `watsonx` - [watsonx](#watsonx-translation-config)
130
104
 
131
105
  ### Find usages
132
106
 
@@ -253,6 +227,27 @@ See the full list of tasks with `i18n-tasks --help`.
253
227
  ✔ Reference keys (keys with `:symbol` values) are fully supported. These keys are copied as-is in
254
228
  `add/translate-missing`, and can be looked up by reference or value in `find`.
255
229
 
230
+ #### Unexpected normalization
231
+ `i18n-tasks` uses a yaml parser and emitter called `Psych` under the hood. `Psych` has it's own heuristic on when
232
+ to use `|`, `>`, or `""` for multi-line strings. This can have some unexpected consequences, eg when normalizing:
233
+ ```yaml
234
+ a: |
235
+ Lorem ipsum dolor sit amet, consectetur
236
+ Lorem ipsum dolor sit amet, consectetur
237
+ b: |
238
+ Lorem ipsum dolor sit amet, consectetur
239
+ Lorem ipsum dolor sit amet, consectetur
240
+ ```
241
+ we get the result
242
+ ```yaml
243
+ a: |
244
+ Lorem ipsum dolor sit amet, consectetur
245
+ Lorem ipsum dolor sit amet, consectetur
246
+ b: "Lorem ipsum dolor sit amet, consectetur \nLorem ipsum dolor sit amet, consectetur\n"
247
+ ```
248
+ The only difference between `a` and `b` is that `b` has an extra trailing space in each line.
249
+ This is an unfortunate side effect of `i18n-tasks` using `Psych`.
250
+
256
251
  #### `t()` keyword arguments
257
252
 
258
253
  ✔ `scope` keyword argument is fully supported by the AST scanner, and also by the Regexp scanner but only when it is the first argument.
@@ -392,6 +387,22 @@ truck.contents.description_body ⮕ truck.attributes.description.body
392
387
  If you store data somewhere but in the filesystem, e.g. in the database or mongodb, you can implement a custom adapter.
393
388
  If you have implemented a custom adapter please share it on [the wiki][wiki].
394
389
 
390
+ #### Rails credentials
391
+
392
+ If you use Rails credentials and want to load e.g. credentials for translation backends, convert your `i18n-tasks.yml`to `i18n-tasks.yml.erb` and add
393
+ a `require "./config/application"` line to load Rails.
394
+
395
+ ```yaml
396
+ # config/i18n-tasks.yml.erb
397
+ <% require "./config/application" %>
398
+
399
+ # ...
400
+
401
+ translation:
402
+ backend: google
403
+ google_translate_api_key: <%= Rails.application.credentials.google_translate_api_key %>
404
+ ```
405
+
395
406
  ### Usage search
396
407
 
397
408
  i18n-tasks uses an AST scanner for `.rb` and `.html.erb` files, and a regexp scanner for all other files.
@@ -418,6 +429,24 @@ For more complex cases, you can implement a [custom scanner][custom-scanner-docs
418
429
 
419
430
  See the [config file][config] to find out more.
420
431
 
432
+ ### Environment Variables and Dotenv
433
+
434
+ i18n-tasks supports loading environment variables from `.env` files using the [dotenv](https://github.com/bkeepers/dotenv) gem.
435
+ This is particularly useful for storing translation API keys and other sensitive configuration.
436
+
437
+ If you have `dotenv` in your Gemfile, i18n-tasks will automatically load environment variables from `.env` files
438
+ before executing commands. This means you can store your API keys in a `.env` file:
439
+
440
+ ```bash
441
+ # .env
442
+ GOOGLE_TRANSLATE_API_KEY=your_google_api_key
443
+ DEEPL_AUTH_KEY=your_deepl_api_key
444
+ OPENAI_API_KEY=your_openai_api_key
445
+ ```
446
+
447
+ The dotenv integration works seamlessly - no additional configuration is required. If `dotenv` is not available,
448
+ i18n-tasks will continue to work normally using system environment variables.
449
+
421
450
  <a name="google-translation-config"></a>
422
451
  ### Google Translate
423
452
 
@@ -435,6 +464,7 @@ Put the key in `GOOGLE_TRANSLATE_API_KEY` environment variable or in the config
435
464
  ```yaml
436
465
  # config/i18n-tasks.yml
437
466
  translation:
467
+ backend: google
438
468
  google_translate_api_key: <Google Translate API key>
439
469
  ```
440
470
 
@@ -447,11 +477,12 @@ GOOGLE_TRANSLATE_API_KEY=<Google Translate API key>
447
477
  <a name="deepl-translation-config"></a>
448
478
  ### DeepL Pro Translate
449
479
 
450
- `i18n-tasks translate-missing` requires a DeepL Pro API key, get it at [DeepL](https://www.deepl.com/pro).
480
+ `i18n-tasks translate-missing` requires a DeepL Pro API key, get it at [DeepL](https://www.deepl.com/pro). You can specify alias locales if you only use the simple locales internally.
451
481
 
452
482
  ```yaml
453
483
  # config/i18n-tasks.yml
454
484
  translation:
485
+ backend: deepl
455
486
  deepl_api_key: <DeepL Pro API key>
456
487
  deepl_host: <optional>
457
488
  deepl_version: <optional>
@@ -460,12 +491,15 @@ translation:
460
491
  - 2c6415be-1852-4f54-9e1b-d800463496b4
461
492
  deepl_options:
462
493
  formality: prefer_less
494
+ deepl_locale_aliases:
495
+ en: en-us
496
+ pt: pt-br
463
497
  ```
464
498
 
465
499
  or via environment variables:
466
500
 
467
501
  ```bash
468
- DEEPL_API_KEY=<DeepL Pro API key>
502
+ DEEPL_AUTH_KEY=<DeepL Pro API key>
469
503
  DEEPL_HOST=<optional>
470
504
  DEEPL_VERSION=<optional>
471
505
  ```
@@ -478,6 +512,7 @@ DEEPL_VERSION=<optional>
478
512
  ```yaml
479
513
  # config/i18n-tasks.yml
480
514
  translation:
515
+ backend: yandex
481
516
  yandex_api_key: <Yandex API key>
482
517
  ```
483
518
 
@@ -495,6 +530,7 @@ YANDEX_API_KEY=<Yandex API key>
495
530
  ```yaml
496
531
  # config/i18n-tasks.yml
497
532
  translation:
533
+ backend: openai
498
534
  openai_api_key: <OpenAI API key>
499
535
  openai_model: <optional>
500
536
  ```
@@ -506,6 +542,69 @@ OPENAI_API_KEY=<OpenAI API key>
506
542
  OPENAI_MODEL=<optional>
507
543
  ```
508
544
 
545
+ <a name="watsonx-translation-config"></a>
546
+ ### watsonx Translate
547
+
548
+ `i18n-tasks translate-missing` requires a watsonx project and api key, get it at [IBM watsonx](https://www.ibm.com/watsonx/).
549
+
550
+ ```yaml
551
+ # config/i18n-tasks.yml
552
+ translation:
553
+ backend: watsonx
554
+ watsonx_api_key: <watsonx API key>
555
+ watsonx_project_id: <watsonx project id>
556
+ watsonx_model: <optional>
557
+ ```
558
+
559
+ or via environment variable:
560
+
561
+ ```bash
562
+ WATSONX_API_KEY=<watsonx API key>
563
+ WATSONX_PROJECT_ID=<watsonx project id>
564
+ WATSONX_MODEL=<optional>
565
+ ```
566
+
567
+ ### Prism-based scanner for Ruby and ERB files
568
+
569
+ There is a scanner based on [Prism](https://github.com/ruby/prism) usable in two different modes.
570
+
571
+ - `rails` mode parses Rails code and handles context such as controllers, before_actions, model translations and more.
572
+ - `ruby` mode parses Ruby code only, and works similar to the existing whitequark/parser-implementation.
573
+ - The parser is used for both ruby and ERB files.
574
+
575
+ #### `rails` mode
576
+
577
+ It handles the following cases:
578
+ - Translations called in `before_actions`
579
+ - Translations called in nested methods
580
+ - `Model.human_attribute_name` calls
581
+ - `Model.model_name.human` calls
582
+
583
+ Enabled it by adding:
584
+ ```yaml
585
+ search:
586
+ prism: "rails"
587
+ ```
588
+
589
+ to your `config/i18n-tasks.yml` file.
590
+
591
+ #### `ruby` mode
592
+
593
+ It finds all `I18n.t`, `I18n.translate`, `t` and `translate` calls in Ruby code. Enabled it by adding:
594
+
595
+ ```yaml
596
+ search:
597
+ prism: "ruby"
598
+ ```
599
+
600
+ The goal is to replace the whitequark/parser-based scanner with this one in the future.
601
+
602
+ #### Help us out with testing
603
+
604
+ Please install the latest version of the gem and run `i18n-tasks check-prism` which will parse everything with the whitequark/parser-based scanner and then everything with the Prism-scanner and try to compare the results.
605
+
606
+ Open up issues with any parser crashes, missed translations or false positives.
607
+
509
608
  ## Interactive console
510
609
 
511
610
  `i18n-tasks irb` starts an IRB session in i18n-tasks context. Type `guide` for more information.
data/Rakefile CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
5
  RSpec::Core::RakeTask.new(:rspec)
6
6
  task default: :rspec
7
7
 
8
8
  task :irb do
9
9
  # $: << File.expand_path('lib', __FILE__)
10
- require 'i18n/tasks'
11
- require 'i18n/tasks/commands'
10
+ require "i18n/tasks"
11
+ require "i18n/tasks/commands"
12
12
  I18n::Tasks::Commands.new(I18n::Tasks::BaseTask.new).irb
13
13
  end
data/bin/i18n-tasks CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative '../spec/bin_simplecov_helper' if ENV['I18N_TASKS_BIN_SIMPLECOV_COVERAGE']
4
+ require_relative "../spec/bin_simplecov_helper" if ENV["I18N_TASKS_BIN_SIMPLECOV_COVERAGE"]
5
5
 
6
6
  # prevent i18n gem warning
7
- require 'i18n'
7
+ require "i18n"
8
8
  i18n_gem_config = I18n.config
9
9
  if i18n_gem_config.respond_to?(:enforce_available_locales=) && i18n_gem_config.enforce_available_locales.nil?
10
10
  i18n_gem_config.enforce_available_locales = true
11
11
  end
12
12
 
13
- require 'i18n/tasks/cli'
13
+ require "i18n/tasks/cli"
14
14
 
15
15
  I18n::Tasks::CLI.start(ARGV)
@@ -26,7 +26,7 @@ en:
26
26
  strict: >-
27
27
  Avoid inferring dynamic key usages such as t("cats.#{cat}.name"). Takes precedence over
28
28
  the config setting if set.
29
- translation_backend: Translation backend (google or deepl)
29
+ translation_backend: Translation backend [google, deepl, yandex, openai])
30
30
  value: >-
31
31
  Value. Interpolates: %%{value}, %%{human_key}, %%{key}, %%{default}, %%{value_or_human_key},
32
32
  %%{value_or_default_or_human_key}
@@ -34,6 +34,9 @@ en:
34
34
  add_missing: add missing keys to locale data, optionally match a pattern
35
35
  check_consistent_interpolations: verify that all translations use correct interpolation variables
36
36
  check_normalized: verify that all translation data is normalized
37
+ check_prism: verify that Prism-scanner produces the same (or better) results as the default
38
+ parser
39
+ check_reserved_interpolations: verify that all translations avoid reserved interpolation variables
37
40
  config: display i18n-tasks configuration
38
41
  cp: copy the keys in locale data that match the given pattern
39
42
  data: show locale data
@@ -69,6 +72,7 @@ en:
69
72
  enum_opt:
70
73
  invalid: "%{invalid} is not one of: %{valid}."
71
74
  errors:
75
+ invalid_backend: 'Invalid backend: %{invalid}. Must be one of %{valid}.'
72
76
  invalid_format: 'invalid format: %{invalid}. valid: %{valid}.'
73
77
  invalid_locale: 'invalid locale: %{invalid}'
74
78
  invalid_missing_type:
@@ -123,12 +127,24 @@ en:
123
127
  other: "%{count} translation will be removed from %{locales}."
124
128
  noop: No unused keys to remove
125
129
  removed: Removed %{count} keys
130
+ reserved_interpolations:
131
+ details_title: Reserved interpolation keys
132
+ none: No reserved interpolations found.
126
133
  translate_missing:
127
134
  translated: Translated %{count} keys
128
135
  unused:
129
136
  none: Every translation is in use.
130
137
  usages:
131
138
  none: No key usages found.
139
+ watsonx_translate:
140
+ errors:
141
+ no_api_key: >-
142
+ Set watsonx API key via WATSONX_API_KEY environment variable or translation.watsonx_api_key
143
+ in config/i18n-tasks.yml. Get the key at https://www.ibm.com/products/watsonx-ai.
144
+ no_project_id: >-
145
+ Set watsonx Project ID via WATSONX_PROJECT_ID environment variable or translation.watsonx_api_key
146
+ in config/i18n-tasks.yml. Get the key at https://www.ibm.com/products/watsonx-ai.
147
+ no_results: watsonx returned no results.
132
148
  yandex_translate:
133
149
  errors:
134
150
  no_api_key: >-
@@ -23,7 +23,7 @@ ru:
23
23
  out_format: 'Формат вывода: %{valid_text}.'
24
24
  pattern_router: 'Использовать pattern_router: ключи распределятся по файлам согласно data.write'
25
25
  strict: Не угадывать динамические использования ключей, например `t("category.#{category.key}")`
26
- translation_backend: Движок перевода (google или deepl)
26
+ translation_backend: Движок перевода [google, deepl, yandex, openai]
27
27
  value: >-
28
28
  Значение, интерполируется с %%{value}, %%{human_key}, %%{key}, %%{default}, %%{value_or_human_key},
29
29
  %%{value_or_default_or_human_key}
@@ -32,6 +32,10 @@ ru:
32
32
  check_consistent_interpolations: убедитесь, что во всех переводах используются правильные
33
33
  интерполяционные переменные
34
34
  check_normalized: проверить, что все файлы переводов нормализованы
35
+ check_prism: убедитесь, что Prism-scanner выдает те же (или лучшие) результаты, что и анализатор
36
+ по умолчанию
37
+ check_reserved_interpolations: проверьте, что все переводы обходятся без зарезервированных
38
+ интерполяционных переменных
35
39
  config: показать конфигурацию
36
40
  cp: скопируйте ключи в данных локали, соответствующие заданному шаблону
37
41
  data: показать данные переводов
@@ -66,6 +70,7 @@ ru:
66
70
  enum_opt:
67
71
  invalid: "%{invalid} не является одним из: %{valid}."
68
72
  errors:
73
+ invalid_backend: 'Недопустимый источник данных: %{invalid}. Должен быть одним из %{valid}.'
69
74
  invalid_format: 'Неизвестный формат %{invalid}. Форматы: %{valid}.'
70
75
  invalid_locale: Неверный язык %{invalid}
71
76
  invalid_missing_type:
@@ -124,12 +129,24 @@ ru:
124
129
  other: Переводы (%{count}) будут удалены из %{locales}.
125
130
  noop: Нет неиспользуемых ключей
126
131
  removed: Удалены ключи (%{count})
132
+ reserved_interpolations:
133
+ details_title: Зарезервированные ключи интерполяции
134
+ none: NЗарезервированных интерполяций не обнаружено.
127
135
  translate_missing:
128
136
  translated: Переведены ключи (%{count})
129
137
  unused:
130
138
  none: Все переводы используются.
131
139
  usages:
132
140
  none: Не найдено использований.
141
+ watsonx_translate:
142
+ errors:
143
+ no_api_key: >-
144
+ Установите ключ API watsonx через переменную среды WATSONX_API_KEY или translation.watsonx_api_key
145
+ в config/i18n-tasks.yml. Получите ключ на https://www.ibm.com/products/watsonx-ai.
146
+ no_project_id: >-
147
+ Установите идентификатор проекта watsonx через переменную среды WATSONX_PROJECT_ID или translation.watsonx_api_key
148
+ в config/i18n-tasks.yml. Получите ключ на https://www.ibm.com/products/watsonx-ai.
149
+ no_results: watsonx не вернул результатов.
133
150
  yandex_translate:
134
151
  errors:
135
152
  no_api_key: |-
data/i18n-tasks.gemspec CHANGED
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('lib', __dir__)
3
+ lib = File.expand_path("lib", __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'i18n/tasks/version'
5
+ require "i18n/tasks/version"
6
6
 
7
7
  Gem::Specification.new do |s|
8
- s.name = 'i18n-tasks'
9
- s.version = I18n::Tasks::VERSION
10
- s.authors = ['glebm']
11
- s.email = ['glex.spb@gmail.com']
12
- s.license = 'MIT'
13
- s.summary = 'Manage localization and translation with the awesome power of static analysis'
14
- s.description = <<~TEXT
8
+ s.name = "i18n-tasks"
9
+ s.version = I18n::Tasks::VERSION
10
+ s.authors = ["glebm"]
11
+ s.email = ["glex.spb@gmail.com"]
12
+ s.license = "MIT"
13
+ s.summary = "Manage localization and translation with the awesome power of static analysis"
14
+ s.description = <<~TEXT
15
15
  i18n-tasks helps you find and manage missing and unused translations.
16
16
 
17
17
  It analyses code statically for key usages, such as `I18n.t('some.key')`, in order to report keys that are missing or unused,
@@ -25,39 +25,29 @@ Gem::Specification.new do |s|
25
25
  # Or for minitest:
26
26
  cp $(bundle exec i18n-tasks gem-path)/templates/minitest/i18n_test.rb test/
27
27
  TEXT
28
- s.homepage = 'https://github.com/glebm/i18n-tasks'
28
+ s.homepage = "https://github.com/glebm/i18n-tasks"
29
29
  s.metadata = {
30
- 'issue_tracker' => 'https://github.com/glebm/i18n-tasks',
31
- 'rubygems_mfa_required' => 'true'
30
+ "changelog_uri" => "https://github.com/glebm/i18n-tasks/blob/main/CHANGES.md",
31
+ "issue_tracker" => "https://github.com/glebm/i18n-tasks",
32
+ "rubygems_mfa_required" => "true",
33
+ "source_code_uri" => "https://github.com/glebm/i18n-tasks"
32
34
  }
33
- s.required_ruby_version = '>= 2.6', '< 4.0'
35
+ s.required_ruby_version = ">= 3.1"
34
36
 
35
37
  s.files = `git ls-files`.split($/)
36
38
  s.files -= s.files.grep(%r{^(doc/|\.|spec/)}) + %w[CHANGES.md config/i18n-tasks.yml Gemfile]
37
- s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } - %w[i18n-tasks.cmd]
38
- s.require_paths = ['lib']
39
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } - %w[i18n-tasks.cmd]
40
+ s.require_paths = ["lib"]
39
41
 
40
- s.add_dependency 'activesupport', '>= 4.0.2'
41
- s.add_dependency 'ast', '>= 2.1.0'
42
- s.add_dependency 'erubi'
43
- s.add_dependency 'highline', '>= 2.0.0'
44
- s.add_dependency 'i18n'
45
- s.add_dependency 'parser', '>= 3.2.2.1'
46
- s.add_dependency 'rails-i18n'
47
- s.add_dependency 'rainbow', '>= 2.2.2', '< 4.0'
48
- s.add_dependency 'terminal-table', '>= 1.5.1'
49
- s.add_development_dependency 'bundler', '~> 2.0', '>= 2.0.1'
50
- s.add_development_dependency 'overcommit', '~> 0.58.0'
51
- s.add_development_dependency 'rake'
52
- s.add_development_dependency 'rspec', '~> 3.3'
53
- s.add_development_dependency 'rubocop', '~> 1.50.1'
54
- s.add_development_dependency 'rubocop-rake', '~> 0.6.0'
55
- s.add_development_dependency 'rubocop-rspec', '~> 2.19.0'
56
- s.add_development_dependency 'simplecov'
57
- s.add_development_dependency 'yard'
58
-
59
- # Translation backends
60
- s.add_development_dependency 'deepl-rb', '>= 2.1.0'
61
- s.add_development_dependency 'easy_translate', '>= 0.5.1' # Google Translate
62
- s.add_development_dependency 'yandex-translator', '>= 0.3.3'
42
+ s.add_dependency "activesupport", ">= 4.0.2"
43
+ s.add_dependency "ast", ">= 2.1.0"
44
+ s.add_dependency "erubi"
45
+ s.add_dependency "highline", ">= 3.0.0"
46
+ s.add_dependency "i18n"
47
+ s.add_dependency "parser", ">= 3.2.2.1"
48
+ s.add_dependency "prism"
49
+ s.add_dependency "rails-i18n"
50
+ s.add_dependency "rainbow", ">= 2.2.2", "< 4.0"
51
+ s.add_dependency "ruby-progressbar", "~> 1.8", ">= 1.8.1"
52
+ s.add_dependency "terminal-table", ">= 1.5.1"
63
53
  end
@@ -1,24 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'i18n/tasks/command_error'
4
- require 'i18n/tasks/split_key'
5
- require 'i18n/tasks/key_pattern_matching'
6
- require 'i18n/tasks/logging'
7
- require 'i18n/tasks/plural_keys'
8
- require 'i18n/tasks/references'
9
- require 'i18n/tasks/html_keys'
10
- require 'i18n/tasks/used_keys'
11
- require 'i18n/tasks/ignore_keys'
12
- require 'i18n/tasks/missing_keys'
13
- require 'i18n/tasks/interpolations'
14
- require 'i18n/tasks/unused_keys'
15
- require 'i18n/tasks/translation'
16
- require 'i18n/tasks/locale_pathname'
17
- require 'i18n/tasks/locale_list'
18
- require 'i18n/tasks/string_interpolation'
19
- require 'i18n/tasks/data'
20
- require 'i18n/tasks/configuration'
21
- require 'i18n/tasks/stats'
3
+ require "i18n/tasks/command_error"
4
+ require "i18n/tasks/split_key"
5
+ require "i18n/tasks/key_pattern_matching"
6
+ require "i18n/tasks/logging"
7
+ require "i18n/tasks/plural_keys"
8
+ require "i18n/tasks/references"
9
+ require "i18n/tasks/html_keys"
10
+ require "i18n/tasks/used_keys"
11
+ require "i18n/tasks/ignore_keys"
12
+ require "i18n/tasks/missing_keys"
13
+ require "i18n/tasks/interpolations"
14
+ require "i18n/tasks/unused_keys"
15
+ require "i18n/tasks/translation"
16
+ require "i18n/tasks/locale_pathname"
17
+ require "i18n/tasks/locale_list"
18
+ require "i18n/tasks/string_interpolation"
19
+ require "i18n/tasks/data"
20
+ require "i18n/tasks/configuration"
21
+ require "i18n/tasks/stats"
22
22
 
23
23
  module I18n
24
24
  module Tasks