i18n-tasks 0.9.37 → 1.0.13
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 +4 -4
- data/README.md +43 -5
- data/Rakefile +1 -1
- data/config/locales/en.yml +12 -3
- data/config/locales/ru.yml +8 -0
- data/i18n-tasks.gemspec +14 -7
- data/lib/i18n/tasks/cli.rb +8 -7
- data/lib/i18n/tasks/command/commander.rb +1 -0
- data/lib/i18n/tasks/command/commands/missing.rb +17 -5
- data/lib/i18n/tasks/command/options/common.rb +0 -1
- data/lib/i18n/tasks/command/options/data.rb +1 -1
- data/lib/i18n/tasks/concurrent/cached_value.rb +0 -2
- data/lib/i18n/tasks/configuration.rb +13 -7
- data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +15 -2
- data/lib/i18n/tasks/data/file_formats.rb +1 -1
- data/lib/i18n/tasks/data/router/pattern_router.rb +1 -1
- data/lib/i18n/tasks/data/tree/node.rb +1 -1
- data/lib/i18n/tasks/data/tree/nodes.rb +5 -7
- data/lib/i18n/tasks/data/tree/siblings.rb +1 -2
- data/lib/i18n/tasks/data/tree/traversal.rb +25 -11
- data/lib/i18n/tasks/html_keys.rb +2 -2
- data/lib/i18n/tasks/interpolations.rb +7 -3
- data/lib/i18n/tasks/key_pattern_matching.rb +2 -0
- data/lib/i18n/tasks/locale_pathname.rb +1 -1
- data/lib/i18n/tasks/plural_keys.rb +0 -6
- data/lib/i18n/tasks/references.rb +3 -3
- data/lib/i18n/tasks/reports/base.rb +2 -2
- data/lib/i18n/tasks/reports/terminal.rb +3 -3
- data/lib/i18n/tasks/scanners/ast_matchers/base_matcher.rb +118 -0
- data/lib/i18n/tasks/scanners/ast_matchers/message_receivers_matcher.rb +91 -0
- data/lib/i18n/tasks/scanners/ast_matchers/rails_model_matcher.rb +69 -0
- data/lib/i18n/tasks/scanners/erb_ast_processor.rb +74 -0
- data/lib/i18n/tasks/scanners/erb_ast_scanner.rb +48 -0
- data/lib/i18n/tasks/scanners/local_ruby_parser.rb +85 -0
- data/lib/i18n/tasks/scanners/pattern_mapper.rb +1 -1
- data/lib/i18n/tasks/scanners/pattern_scanner.rb +2 -2
- data/lib/i18n/tasks/scanners/relative_keys.rb +2 -2
- data/lib/i18n/tasks/scanners/results/occurrence.rb +17 -1
- data/lib/i18n/tasks/scanners/ruby_ast_call_finder.rb +9 -34
- data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +91 -156
- data/lib/i18n/tasks/scanners/ruby_key_literals.rb +2 -2
- data/lib/i18n/tasks/split_key.rb +1 -1
- data/lib/i18n/tasks/translation.rb +4 -1
- data/lib/i18n/tasks/translators/base_translator.rb +17 -12
- data/lib/i18n/tasks/translators/deepl_translator.rb +34 -11
- data/lib/i18n/tasks/translators/google_translator.rb +1 -1
- data/lib/i18n/tasks/translators/openai_translator.rb +100 -0
- data/lib/i18n/tasks/used_keys.rb +9 -6
- data/lib/i18n/tasks/version.rb +1 -1
- data/lib/i18n/tasks.rb +11 -0
- data/templates/config/i18n-tasks.yml +17 -4
- data/templates/minitest/i18n_test.rb +6 -6
- metadata +74 -16
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'i18n/tasks/translators/base_translator'
|
4
|
+
|
5
|
+
module I18n::Tasks::Translators
|
6
|
+
class OpenAiTranslator < BaseTranslator
|
7
|
+
# max allowed texts per request
|
8
|
+
BATCH_SIZE = 50
|
9
|
+
|
10
|
+
def initialize(*)
|
11
|
+
begin
|
12
|
+
require 'openai'
|
13
|
+
rescue LoadError
|
14
|
+
raise ::I18n::Tasks::CommandError, "Add gem 'ruby-openai' to your Gemfile to use this command"
|
15
|
+
end
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def options_for_translate_values(from:, to:, **options)
|
20
|
+
options.merge(
|
21
|
+
from: from,
|
22
|
+
to: to
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def options_for_html
|
27
|
+
{}
|
28
|
+
end
|
29
|
+
|
30
|
+
def options_for_plain
|
31
|
+
{}
|
32
|
+
end
|
33
|
+
|
34
|
+
def no_results_error_message
|
35
|
+
I18n.t('i18n_tasks.openai_translate.errors.no_results')
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def translator
|
41
|
+
@translator ||= OpenAI::Client.new(access_token: api_key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def api_key
|
45
|
+
@api_key ||= begin
|
46
|
+
key = @i18n_tasks.translation_config[:openai_api_key]
|
47
|
+
fail ::I18n::Tasks::CommandError, I18n.t('i18n_tasks.openai_translate.errors.no_api_key') if key.blank?
|
48
|
+
|
49
|
+
key
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def translate_values(list, from:, to:)
|
54
|
+
results = []
|
55
|
+
|
56
|
+
list.each_slice(BATCH_SIZE) do |batch|
|
57
|
+
translations = translate(batch, from, to)
|
58
|
+
|
59
|
+
results << JSON.parse(translations)
|
60
|
+
end
|
61
|
+
|
62
|
+
results.flatten
|
63
|
+
end
|
64
|
+
|
65
|
+
def translate(values, from, to) # rubocop:disable Metrics/MethodLength
|
66
|
+
messages = [
|
67
|
+
{
|
68
|
+
role: 'system',
|
69
|
+
content: "You are a helpful assistant that translates content from the #{from} to #{to} locale in an i18n
|
70
|
+
locale array. The array has a structured format and contains multiple strings. Your task is to translate
|
71
|
+
each of these strings and create a new array with the translated strings. Keep in mind the context of all
|
72
|
+
the strings for a more accurate translation.\n"
|
73
|
+
},
|
74
|
+
{
|
75
|
+
role: 'user',
|
76
|
+
content: "Translate this array: \n\n\n"
|
77
|
+
},
|
78
|
+
{
|
79
|
+
role: 'user',
|
80
|
+
content: values.to_json
|
81
|
+
}
|
82
|
+
]
|
83
|
+
|
84
|
+
response = translator.chat(
|
85
|
+
parameters: {
|
86
|
+
model: 'gpt-3.5-turbo',
|
87
|
+
messages: messages,
|
88
|
+
temperature: 0.7
|
89
|
+
}
|
90
|
+
)
|
91
|
+
|
92
|
+
translations = response.dig('choices', 0, 'message', 'content')
|
93
|
+
error = response['error']
|
94
|
+
|
95
|
+
fail "AI error: #{error}" if error.present?
|
96
|
+
|
97
|
+
translations
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/i18n/tasks/used_keys.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'find'
|
4
4
|
require 'i18n/tasks/scanners/pattern_with_scope_scanner'
|
5
5
|
require 'i18n/tasks/scanners/ruby_ast_scanner'
|
6
|
+
require 'i18n/tasks/scanners/erb_ast_scanner'
|
6
7
|
require 'i18n/tasks/scanners/scanner_multiplexer'
|
7
8
|
require 'i18n/tasks/scanners/files/caching_file_finder_provider'
|
8
9
|
require 'i18n/tasks/scanners/files/caching_file_reader'
|
@@ -20,14 +21,16 @@ module I18n::Tasks
|
|
20
21
|
relative_roots: %w[app/controllers app/helpers app/mailers app/presenters app/views].freeze,
|
21
22
|
scanners: [
|
22
23
|
['::I18n::Tasks::Scanners::RubyAstScanner', { only: %w[*.rb] }],
|
23
|
-
['::I18n::Tasks::Scanners::
|
24
|
+
['::I18n::Tasks::Scanners::ErbAstScanner', { only: %w[*.erb] }],
|
25
|
+
['::I18n::Tasks::Scanners::PatternWithScopeScanner', { exclude: %w[*.erb *.rb] }]
|
24
26
|
],
|
27
|
+
ast_matchers: [],
|
25
28
|
strict: true
|
26
29
|
}.freeze
|
27
30
|
|
28
|
-
ALWAYS_EXCLUDE = %w[*.jpg *.jpeg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss
|
29
|
-
*.yml *.json *.zip *.tar.gz *.swf *.flv *.mp3 *.wav *.flac *.webm *.mp4 *.ogg *.opus
|
30
|
-
*.webp *.map].freeze
|
31
|
+
ALWAYS_EXCLUDE = %w[*.jpg *.jpeg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss
|
32
|
+
*.less *.yml *.json *.zip *.tar.gz *.swf *.flv *.mp3 *.wav *.flac *.webm *.mp4 *.ogg *.opus
|
33
|
+
*.webp *.map *.xlsx].freeze
|
31
34
|
|
32
35
|
# Find all keys in the source and return a forest with the keys in absolute form and their occurrences.
|
33
36
|
#
|
@@ -139,7 +142,7 @@ module I18n::Tasks
|
|
139
142
|
|
140
143
|
# keys in the source that end with a ., e.g. t("category.#{ cat.i18n_key }") or t("category." + category.key)
|
141
144
|
# @param [String] replacement for interpolated values.
|
142
|
-
def expr_key_re(replacement: '
|
145
|
+
def expr_key_re(replacement: '*:')
|
143
146
|
@expr_key_re ||= begin
|
144
147
|
# disallow patterns with no keys
|
145
148
|
ignore_pattern_re = /\A[.#{replacement}]*\z/
|
@@ -175,7 +178,7 @@ module I18n::Tasks
|
|
175
178
|
braces << '{'
|
176
179
|
end
|
177
180
|
end
|
178
|
-
result << key[scanner.pos
|
181
|
+
result << key[scanner.pos..] unless scanner.eos?
|
179
182
|
result.join
|
180
183
|
end
|
181
184
|
end
|
data/lib/i18n/tasks/version.rb
CHANGED
data/lib/i18n/tasks.rb
CHANGED
@@ -34,6 +34,17 @@ module I18n
|
|
34
34
|
::I18n::Tasks::Commands.send :include, commands_module
|
35
35
|
self
|
36
36
|
end
|
37
|
+
|
38
|
+
# Add AST-matcher to i18n-tasks
|
39
|
+
#
|
40
|
+
# @param matcher_class_name
|
41
|
+
# @return self
|
42
|
+
def add_ast_matcher(matcher_class_name)
|
43
|
+
matchers = I18n::Tasks::Configuration::DEFAULTS[:search][:ast_matchers]
|
44
|
+
matchers << matcher_class_name
|
45
|
+
matchers.uniq!
|
46
|
+
self
|
47
|
+
end
|
37
48
|
end
|
38
49
|
|
39
50
|
@verbose = !ENV['VERBOSE'].nil?
|
@@ -13,7 +13,7 @@ data:
|
|
13
13
|
## Provide a custom adapter:
|
14
14
|
# adapter: I18n::Tasks::Data::FileSystem
|
15
15
|
|
16
|
-
# Locale files or `
|
16
|
+
# Locale files or `Find.find` patterns where translations are read from:
|
17
17
|
read:
|
18
18
|
## Default:
|
19
19
|
# - config/locales/%{locale}.yml
|
@@ -52,7 +52,7 @@ data:
|
|
52
52
|
|
53
53
|
# Find translate calls
|
54
54
|
search:
|
55
|
-
## Paths or `
|
55
|
+
## Paths or `Find.find` patterns to search in:
|
56
56
|
# paths:
|
57
57
|
# - app/
|
58
58
|
|
@@ -72,11 +72,13 @@ search:
|
|
72
72
|
# -
|
73
73
|
|
74
74
|
## Files or `File.fnmatch` patterns to exclude from search. Some files are always excluded regardless of this setting:
|
75
|
-
##
|
75
|
+
## *.jpg *.jpeg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less
|
76
|
+
## *.yml *.json *.zip *.tar.gz *.swf *.flv *.mp3 *.wav *.flac *.webm *.mp4 *.ogg *.opus *.webp *.map *.xlsx
|
76
77
|
exclude:
|
77
78
|
- app/assets/images
|
78
79
|
- app/assets/fonts
|
79
80
|
- app/assets/videos
|
81
|
+
- app/assets/builds
|
80
82
|
|
81
83
|
## Alternatively, the only files or `File.fnmatch patterns` to search in `paths`:
|
82
84
|
## If specified, this settings takes priority over `exclude`, but `exclude` still applies.
|
@@ -85,6 +87,15 @@ search:
|
|
85
87
|
## If `strict` is `false`, guess usages such as t("categories.#{category}.title"). The default is `true`.
|
86
88
|
# strict: true
|
87
89
|
|
90
|
+
## Allows adding ast_matchers for finding translations using the AST-scanners
|
91
|
+
## The available matchers are:
|
92
|
+
## - RailsModelMatcher
|
93
|
+
## Matches ActiveRecord translations like
|
94
|
+
## User.human_attribute_name(:email) and User.model_name.human
|
95
|
+
##
|
96
|
+
## To implement your own, please see `I18n::Tasks::Scanners::AstMatchers::BaseMatcher`.
|
97
|
+
# <%# I18n::Tasks.add_ast_matcher('I18n::Tasks::Scanners::AstMatchers::RailsModelMatcher') %>
|
98
|
+
|
88
99
|
## Multiple scanners can be used. Their results are merged.
|
89
100
|
## The options specified above are passed down to each scanner. Per-scanner options can be specified as well.
|
90
101
|
## See this example of a custom scanner: https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example
|
@@ -99,7 +110,9 @@ search:
|
|
99
110
|
# deepl_api_key: "48E92789-57A3-466A-9959-1A1A1A1A1A1A"
|
100
111
|
# # deepl_host: "https://api.deepl.com"
|
101
112
|
# # deepl_version: "v2"
|
102
|
-
|
113
|
+
# # add additional options to the DeepL.translate call: https://www.deepl.com/docs-api/translate-text/translate-text/
|
114
|
+
# deepl_options:
|
115
|
+
# formality: prefer_less
|
103
116
|
## Do not consider these keys missing:
|
104
117
|
# ignore_missing:
|
105
118
|
# - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
|
@@ -5,18 +5,18 @@ require 'i18n/tasks'
|
|
5
5
|
class I18nTest < ActiveSupport::TestCase
|
6
6
|
def setup
|
7
7
|
@i18n = I18n::Tasks::BaseTask.new
|
8
|
-
@missing_keys = @i18n.missing_keys
|
9
|
-
@unused_keys = @i18n.unused_keys
|
10
8
|
end
|
11
9
|
|
12
10
|
def test_no_missing_keys
|
13
|
-
|
14
|
-
|
11
|
+
missing_keys = @i18n.missing_keys
|
12
|
+
assert_empty missing_keys,
|
13
|
+
"Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them"
|
15
14
|
end
|
16
15
|
|
17
16
|
def test_no_unused_keys
|
18
|
-
|
19
|
-
|
17
|
+
unused_keys = @i18n.unused_keys
|
18
|
+
assert_empty unused_keys,
|
19
|
+
"#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_files_are_normalized
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- glebm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -38,6 +38,26 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 2.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: better_html
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '3.0'
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '1.0'
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.0'
|
41
61
|
- !ruby/object:Gem::Dependency
|
42
62
|
name: erubi
|
43
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +106,14 @@ dependencies:
|
|
86
106
|
requirements:
|
87
107
|
- - ">="
|
88
108
|
- !ruby/object:Gem::Version
|
89
|
-
version: 2.2.
|
109
|
+
version: 3.2.2.1
|
90
110
|
type: :runtime
|
91
111
|
prerelease: false
|
92
112
|
version_requirements: !ruby/object:Gem::Requirement
|
93
113
|
requirements:
|
94
114
|
- - ">="
|
95
115
|
- !ruby/object:Gem::Version
|
96
|
-
version: 2.2.
|
116
|
+
version: 3.2.2.1
|
97
117
|
- !ruby/object:Gem::Dependency
|
98
118
|
name: rails-i18n
|
99
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,12 +163,15 @@ dependencies:
|
|
143
163
|
- !ruby/object:Gem::Version
|
144
164
|
version: 1.5.1
|
145
165
|
- !ruby/object:Gem::Dependency
|
146
|
-
name:
|
166
|
+
name: bundler
|
147
167
|
requirement: !ruby/object:Gem::Requirement
|
148
168
|
requirements:
|
149
169
|
- - "~>"
|
150
170
|
- !ruby/object:Gem::Version
|
151
171
|
version: '2.0'
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 2.0.1
|
152
175
|
type: :development
|
153
176
|
prerelease: false
|
154
177
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -156,26 +179,23 @@ dependencies:
|
|
156
179
|
- - "~>"
|
157
180
|
- !ruby/object:Gem::Version
|
158
181
|
version: '2.0'
|
182
|
+
- - ">="
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: 2.0.1
|
159
185
|
- !ruby/object:Gem::Dependency
|
160
|
-
name:
|
186
|
+
name: overcommit
|
161
187
|
requirement: !ruby/object:Gem::Requirement
|
162
188
|
requirements:
|
163
189
|
- - "~>"
|
164
190
|
- !ruby/object:Gem::Version
|
165
|
-
version:
|
166
|
-
- - ">="
|
167
|
-
- !ruby/object:Gem::Version
|
168
|
-
version: 2.0.1
|
191
|
+
version: 0.58.0
|
169
192
|
type: :development
|
170
193
|
prerelease: false
|
171
194
|
version_requirements: !ruby/object:Gem::Requirement
|
172
195
|
requirements:
|
173
196
|
- - "~>"
|
174
197
|
- !ruby/object:Gem::Version
|
175
|
-
version:
|
176
|
-
- - ">="
|
177
|
-
- !ruby/object:Gem::Version
|
178
|
-
version: 2.0.1
|
198
|
+
version: 0.58.0
|
179
199
|
- !ruby/object:Gem::Dependency
|
180
200
|
name: rake
|
181
201
|
requirement: !ruby/object:Gem::Requirement
|
@@ -210,14 +230,42 @@ dependencies:
|
|
210
230
|
requirements:
|
211
231
|
- - "~>"
|
212
232
|
- !ruby/object:Gem::Version
|
213
|
-
version: 1.
|
233
|
+
version: 1.50.1
|
234
|
+
type: :development
|
235
|
+
prerelease: false
|
236
|
+
version_requirements: !ruby/object:Gem::Requirement
|
237
|
+
requirements:
|
238
|
+
- - "~>"
|
239
|
+
- !ruby/object:Gem::Version
|
240
|
+
version: 1.50.1
|
241
|
+
- !ruby/object:Gem::Dependency
|
242
|
+
name: rubocop-rake
|
243
|
+
requirement: !ruby/object:Gem::Requirement
|
244
|
+
requirements:
|
245
|
+
- - "~>"
|
246
|
+
- !ruby/object:Gem::Version
|
247
|
+
version: 0.6.0
|
248
|
+
type: :development
|
249
|
+
prerelease: false
|
250
|
+
version_requirements: !ruby/object:Gem::Requirement
|
251
|
+
requirements:
|
252
|
+
- - "~>"
|
253
|
+
- !ruby/object:Gem::Version
|
254
|
+
version: 0.6.0
|
255
|
+
- !ruby/object:Gem::Dependency
|
256
|
+
name: rubocop-rspec
|
257
|
+
requirement: !ruby/object:Gem::Requirement
|
258
|
+
requirements:
|
259
|
+
- - "~>"
|
260
|
+
- !ruby/object:Gem::Version
|
261
|
+
version: 2.19.0
|
214
262
|
type: :development
|
215
263
|
prerelease: false
|
216
264
|
version_requirements: !ruby/object:Gem::Requirement
|
217
265
|
requirements:
|
218
266
|
- - "~>"
|
219
267
|
- !ruby/object:Gem::Version
|
220
|
-
version:
|
268
|
+
version: 2.19.0
|
221
269
|
- !ruby/object:Gem::Dependency
|
222
270
|
name: simplecov
|
223
271
|
requirement: !ruby/object:Gem::Requirement
|
@@ -357,12 +405,18 @@ files:
|
|
357
405
|
- lib/i18n/tasks/references.rb
|
358
406
|
- lib/i18n/tasks/reports/base.rb
|
359
407
|
- lib/i18n/tasks/reports/terminal.rb
|
408
|
+
- lib/i18n/tasks/scanners/ast_matchers/base_matcher.rb
|
409
|
+
- lib/i18n/tasks/scanners/ast_matchers/message_receivers_matcher.rb
|
410
|
+
- lib/i18n/tasks/scanners/ast_matchers/rails_model_matcher.rb
|
411
|
+
- lib/i18n/tasks/scanners/erb_ast_processor.rb
|
412
|
+
- lib/i18n/tasks/scanners/erb_ast_scanner.rb
|
360
413
|
- lib/i18n/tasks/scanners/file_scanner.rb
|
361
414
|
- lib/i18n/tasks/scanners/files/caching_file_finder.rb
|
362
415
|
- lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb
|
363
416
|
- lib/i18n/tasks/scanners/files/caching_file_reader.rb
|
364
417
|
- lib/i18n/tasks/scanners/files/file_finder.rb
|
365
418
|
- lib/i18n/tasks/scanners/files/file_reader.rb
|
419
|
+
- lib/i18n/tasks/scanners/local_ruby_parser.rb
|
366
420
|
- lib/i18n/tasks/scanners/occurrence_from_position.rb
|
367
421
|
- lib/i18n/tasks/scanners/pattern_mapper.rb
|
368
422
|
- lib/i18n/tasks/scanners/pattern_scanner.rb
|
@@ -382,6 +436,7 @@ files:
|
|
382
436
|
- lib/i18n/tasks/translators/base_translator.rb
|
383
437
|
- lib/i18n/tasks/translators/deepl_translator.rb
|
384
438
|
- lib/i18n/tasks/translators/google_translator.rb
|
439
|
+
- lib/i18n/tasks/translators/openai_translator.rb
|
385
440
|
- lib/i18n/tasks/translators/yandex_translator.rb
|
386
441
|
- lib/i18n/tasks/unused_keys.rb
|
387
442
|
- lib/i18n/tasks/used_keys.rb
|
@@ -394,11 +449,14 @@ licenses:
|
|
394
449
|
- MIT
|
395
450
|
metadata:
|
396
451
|
issue_tracker: https://github.com/glebm/i18n-tasks
|
452
|
+
rubygems_mfa_required: 'true'
|
397
453
|
post_install_message: |
|
398
454
|
# Install default configuration:
|
399
455
|
cp $(bundle exec i18n-tasks gem-path)/templates/config/i18n-tasks.yml config/
|
400
456
|
# Add an RSpec for missing and unused keys:
|
401
457
|
cp $(bundle exec i18n-tasks gem-path)/templates/rspec/i18n_spec.rb spec/
|
458
|
+
# Or for minitest:
|
459
|
+
cp $(bundle exec i18n-tasks gem-path)/templates/minitest/i18n_test.rb test/
|
402
460
|
rdoc_options: []
|
403
461
|
require_paths:
|
404
462
|
- lib
|