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.
- checksums.yaml +4 -4
- data/README.md +138 -39
- data/Rakefile +4 -4
- data/bin/i18n-tasks +3 -3
- data/config/locales/en.yml +17 -1
- data/config/locales/ru.yml +18 -1
- data/i18n-tasks.gemspec +28 -38
- data/lib/i18n/tasks/base_task.rb +19 -19
- data/lib/i18n/tasks/cli.rb +37 -30
- data/lib/i18n/tasks/command/collection.rb +4 -4
- data/lib/i18n/tasks/command/commander.rb +5 -5
- data/lib/i18n/tasks/command/commands/check_prism.rb +126 -0
- data/lib/i18n/tasks/command/commands/data.rb +33 -33
- data/lib/i18n/tasks/command/commands/eq_base.rb +3 -3
- data/lib/i18n/tasks/command/commands/health.rb +6 -5
- data/lib/i18n/tasks/command/commands/interpolations.rb +14 -3
- data/lib/i18n/tasks/command/commands/meta.rb +6 -6
- data/lib/i18n/tasks/command/commands/missing.rb +28 -26
- data/lib/i18n/tasks/command/commands/tree.rb +33 -33
- data/lib/i18n/tasks/command/commands/usages.rb +24 -24
- data/lib/i18n/tasks/command/dsl.rb +1 -1
- data/lib/i18n/tasks/command/option_parsers/enum.rb +8 -7
- data/lib/i18n/tasks/command/option_parsers/locale.rb +4 -4
- data/lib/i18n/tasks/command/options/common.rb +16 -16
- data/lib/i18n/tasks/command/options/data.rb +18 -18
- data/lib/i18n/tasks/command/options/locales.rb +33 -24
- data/lib/i18n/tasks/commands.rb +14 -12
- data/lib/i18n/tasks/concurrent/cache.rb +1 -1
- data/lib/i18n/tasks/concurrent/cached_value.rb +1 -1
- data/lib/i18n/tasks/configuration.rb +26 -20
- data/lib/i18n/tasks/console_context.rb +11 -11
- data/lib/i18n/tasks/data/adapter/json_adapter.rb +1 -1
- data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +5 -5
- data/lib/i18n/tasks/data/file_formats.rb +3 -3
- data/lib/i18n/tasks/data/file_system.rb +5 -5
- data/lib/i18n/tasks/data/file_system_base.rb +26 -26
- data/lib/i18n/tasks/data/language_names.rb +202 -0
- data/lib/i18n/tasks/data/router/conservative_router.rb +3 -3
- data/lib/i18n/tasks/data/router/isolating_router.rb +19 -19
- data/lib/i18n/tasks/data/router/pattern_router.rb +5 -5
- data/lib/i18n/tasks/data/tree/node.rb +27 -27
- data/lib/i18n/tasks/data/tree/nodes.rb +10 -10
- data/lib/i18n/tasks/data/tree/siblings.rb +20 -20
- data/lib/i18n/tasks/data/tree/traversal.rb +5 -5
- data/lib/i18n/tasks/data.rb +4 -4
- data/lib/i18n/tasks/html_keys.rb +2 -2
- data/lib/i18n/tasks/ignore_keys.rb +9 -9
- data/lib/i18n/tasks/interpolations.rb +21 -1
- data/lib/i18n/tasks/key_pattern_matching.rb +8 -8
- data/lib/i18n/tasks/logging.rb +2 -1
- data/lib/i18n/tasks/missing_keys.rb +24 -8
- data/lib/i18n/tasks/plural_keys.rb +6 -4
- data/lib/i18n/tasks/references.rb +4 -4
- data/lib/i18n/tasks/reports/base.rb +18 -14
- data/lib/i18n/tasks/reports/terminal.rb +64 -47
- data/lib/i18n/tasks/scanners/ast_matchers/base_matcher.rb +3 -3
- data/lib/i18n/tasks/scanners/ast_matchers/default_i18n_subject_matcher.rb +3 -3
- data/lib/i18n/tasks/scanners/ast_matchers/message_receivers_matcher.rb +10 -10
- data/lib/i18n/tasks/scanners/ast_matchers/rails_model_matcher.rb +2 -2
- data/lib/i18n/tasks/scanners/erb_ast_scanner.rb +69 -10
- data/lib/i18n/tasks/scanners/file_scanner.rb +5 -5
- data/lib/i18n/tasks/scanners/files/caching_file_finder.rb +3 -3
- data/lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb +3 -3
- data/lib/i18n/tasks/scanners/files/caching_file_reader.rb +2 -2
- data/lib/i18n/tasks/scanners/files/file_finder.rb +8 -8
- data/lib/i18n/tasks/scanners/files/file_reader.rb +1 -1
- data/lib/i18n/tasks/scanners/local_ruby_parser.rb +9 -9
- data/lib/i18n/tasks/scanners/occurrence_from_position.rb +1 -1
- data/lib/i18n/tasks/scanners/pattern_mapper.rb +7 -7
- data/lib/i18n/tasks/scanners/pattern_scanner.rb +20 -20
- data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +8 -8
- data/lib/i18n/tasks/scanners/prism_scanners/arguments_visitor.rb +48 -0
- data/lib/i18n/tasks/scanners/prism_scanners/nodes.rb +374 -0
- data/lib/i18n/tasks/scanners/prism_scanners/visitor.rb +337 -0
- data/lib/i18n/tasks/scanners/relative_keys.rb +8 -8
- data/lib/i18n/tasks/scanners/results/key_occurrences.rb +3 -3
- data/lib/i18n/tasks/scanners/results/occurrence.rb +14 -10
- data/lib/i18n/tasks/scanners/ruby_ast_call_finder.rb +1 -1
- data/lib/i18n/tasks/scanners/ruby_key_literals.rb +6 -6
- data/lib/i18n/tasks/scanners/ruby_parser_factory.rb +27 -0
- data/lib/i18n/tasks/scanners/ruby_scanner.rb +225 -0
- data/lib/i18n/tasks/scanners/scanner.rb +2 -2
- data/lib/i18n/tasks/scanners/scanner_multiplexer.rb +1 -1
- data/lib/i18n/tasks/split_key.rb +4 -4
- data/lib/i18n/tasks/stats.rb +3 -3
- data/lib/i18n/tasks/translation.rb +8 -5
- data/lib/i18n/tasks/translators/base_translator.rb +43 -13
- data/lib/i18n/tasks/translators/deepl_translator.rb +22 -14
- data/lib/i18n/tasks/translators/google_translator.rb +178 -26
- data/lib/i18n/tasks/translators/openai_translator.rb +56 -31
- data/lib/i18n/tasks/translators/watsonx_translator.rb +155 -0
- data/lib/i18n/tasks/translators/yandex_translator.rb +13 -9
- data/lib/i18n/tasks/unused_keys.rb +1 -1
- data/lib/i18n/tasks/used_keys.rb +32 -32
- data/lib/i18n/tasks/version.rb +1 -1
- data/lib/i18n/tasks.rb +17 -16
- data/templates/config/i18n-tasks.yml +14 -2
- data/templates/minitest/i18n_test.rb +3 -3
- data/templates/rspec/i18n_spec.rb +7 -7
- metadata +38 -172
- data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +0 -145
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "i18n/tasks/translators/base_translator"
|
|
4
4
|
|
|
5
5
|
module I18n::Tasks::Translators
|
|
6
6
|
class YandexTranslator < BaseTranslator
|
|
7
7
|
def initialize(*)
|
|
8
8
|
begin
|
|
9
|
-
require
|
|
9
|
+
require "yandex-translator"
|
|
10
10
|
rescue LoadError
|
|
11
11
|
raise ::I18n::Tasks::CommandError, "Add gem 'yandex-translator' to your Gemfile to use this command"
|
|
12
12
|
end
|
|
@@ -16,7 +16,11 @@ module I18n::Tasks::Translators
|
|
|
16
16
|
protected
|
|
17
17
|
|
|
18
18
|
def translate_values(list, **options)
|
|
19
|
-
list.map { |item| translator.translate(item, options) }
|
|
19
|
+
result = list.map { |item| translator.translate(item, options) }
|
|
20
|
+
|
|
21
|
+
@progress_bar.progress += result.size
|
|
22
|
+
|
|
23
|
+
result
|
|
20
24
|
end
|
|
21
25
|
|
|
22
26
|
def options_for_translate_values(from:, to:, **options)
|
|
@@ -27,24 +31,24 @@ module I18n::Tasks::Translators
|
|
|
27
31
|
end
|
|
28
32
|
|
|
29
33
|
def options_for_html
|
|
30
|
-
{
|
|
34
|
+
{format: "html"}
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
def options_for_plain
|
|
34
|
-
{
|
|
38
|
+
{format: "plain"}
|
|
35
39
|
end
|
|
36
40
|
|
|
37
41
|
def no_results_error_message
|
|
38
|
-
I18n.t(
|
|
42
|
+
I18n.t("i18n_tasks.yandex_translate.errors.no_results")
|
|
39
43
|
end
|
|
40
44
|
|
|
41
45
|
private
|
|
42
46
|
|
|
43
47
|
# Convert 'es-ES' to 'es'
|
|
44
48
|
def to_yandex_compatible_locale(locale)
|
|
45
|
-
return locale unless locale.include?(
|
|
49
|
+
return locale unless locale.include?("-")
|
|
46
50
|
|
|
47
|
-
locale.split(
|
|
51
|
+
locale.split("-", 2).first
|
|
48
52
|
end
|
|
49
53
|
|
|
50
54
|
def translator
|
|
@@ -54,7 +58,7 @@ module I18n::Tasks::Translators
|
|
|
54
58
|
def api_key
|
|
55
59
|
@api_key ||= begin
|
|
56
60
|
key = @i18n_tasks.translation_config[:yandex_api_key]
|
|
57
|
-
fail ::I18n::Tasks::CommandError, I18n.t(
|
|
61
|
+
fail ::I18n::Tasks::CommandError, I18n.t("i18n_tasks.yandex_translate.errors.no_api_key") if key.blank?
|
|
58
62
|
|
|
59
63
|
key
|
|
60
64
|
end
|
data/lib/i18n/tasks/used_keys.rb
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
3
|
+
require "find"
|
|
4
|
+
require "i18n/tasks/scanners/pattern_with_scope_scanner"
|
|
5
|
+
require "i18n/tasks/scanners/ruby_scanner"
|
|
6
|
+
require "i18n/tasks/scanners/erb_ast_scanner"
|
|
7
|
+
require "i18n/tasks/scanners/scanner_multiplexer"
|
|
8
|
+
require "i18n/tasks/scanners/files/caching_file_finder_provider"
|
|
9
|
+
require "i18n/tasks/scanners/files/caching_file_reader"
|
|
10
10
|
|
|
11
11
|
# Require the pattern mapper even though it's not used by i18n-tasks directly.
|
|
12
12
|
# This allows the user to use it in config/i18n-tasks.yml without having to require it.
|
|
13
13
|
# See https://github.com/glebm/i18n-tasks/issues/204.
|
|
14
|
-
require
|
|
14
|
+
require "i18n/tasks/scanners/pattern_mapper"
|
|
15
15
|
|
|
16
16
|
module I18n::Tasks
|
|
17
17
|
module UsedKeys # rubocop:disable Metrics/ModuleLength
|
|
@@ -20,17 +20,17 @@ module I18n::Tasks
|
|
|
20
20
|
relative_exclude_method_name_paths: [],
|
|
21
21
|
relative_roots: %w[app/controllers app/helpers app/mailers app/presenters app/views].freeze,
|
|
22
22
|
scanners: [
|
|
23
|
-
[
|
|
24
|
-
[
|
|
25
|
-
[
|
|
23
|
+
["::I18n::Tasks::Scanners::RubyScanner", {only: %w[*.rb]}],
|
|
24
|
+
["::I18n::Tasks::Scanners::ErbAstScanner", {only: %w[*.erb]}],
|
|
25
|
+
["::I18n::Tasks::Scanners::PatternWithScopeScanner", {exclude: %w[*.erb *.rb]}]
|
|
26
26
|
],
|
|
27
27
|
ast_matchers: [],
|
|
28
28
|
strict: true
|
|
29
29
|
}.freeze
|
|
30
30
|
|
|
31
31
|
ALWAYS_EXCLUDE = %w[*.jpg *.jpeg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
*.less *.yml *.json *.zip *.tar.gz *.swf *.flv *.mp3 *.wav *.flac *.webm *.mp4 *.ogg *.opus
|
|
33
|
+
*.webp *.map *.xlsx].freeze
|
|
34
34
|
|
|
35
35
|
# Find all keys in the source and return a forest with the keys in absolute form and their occurrences.
|
|
36
36
|
#
|
|
@@ -40,12 +40,12 @@ module I18n::Tasks
|
|
|
40
40
|
# @return [Data::Tree::Siblings]
|
|
41
41
|
def used_tree(key_filter: nil, strict: nil, include_raw_references: false)
|
|
42
42
|
src_tree = used_in_source_tree(key_filter: key_filter, strict: strict)
|
|
43
|
-
raw_refs, resolved_refs, used_refs = process_references(src_tree[
|
|
43
|
+
raw_refs, resolved_refs, used_refs = process_references(src_tree["used"].children)
|
|
44
44
|
raw_refs.leaves { |node| node.data[:ref_type] = :reference_usage }
|
|
45
45
|
resolved_refs.leaves { |node| node.data[:ref_type] = :reference_usage_resolved }
|
|
46
46
|
used_refs.leaves { |node| node.data[:ref_type] = :reference_usage_key }
|
|
47
47
|
src_tree.tap do |result|
|
|
48
|
-
tree = result[
|
|
48
|
+
tree = result["used"].children
|
|
49
49
|
tree.subtract_by_key!(raw_refs)
|
|
50
50
|
tree.merge!(raw_refs) if include_raw_references
|
|
51
51
|
tree.merge!(used_refs).merge!(resolved_refs)
|
|
@@ -57,11 +57,11 @@ module I18n::Tasks
|
|
|
57
57
|
scanner(strict: strict).keys.freeze)
|
|
58
58
|
if key_filter
|
|
59
59
|
key_filter_re = compile_key_pattern(key_filter)
|
|
60
|
-
keys
|
|
60
|
+
keys = keys.select { |k| k.key =~ key_filter_re }
|
|
61
61
|
end
|
|
62
62
|
Data::Tree::Node.new(
|
|
63
|
-
key:
|
|
64
|
-
data: {
|
|
63
|
+
key: "used",
|
|
64
|
+
data: {key_filter: key_filter},
|
|
65
65
|
children: Data::Tree::Siblings.from_key_occurrences(keys)
|
|
66
66
|
).to_siblings
|
|
67
67
|
end
|
|
@@ -71,11 +71,11 @@ module I18n::Tasks
|
|
|
71
71
|
shared_options = search_config.dup
|
|
72
72
|
shared_options.delete(:scanners)
|
|
73
73
|
shared_options[:strict] = strict unless strict.nil?
|
|
74
|
-
log_verbose
|
|
74
|
+
log_verbose "Scanners: "
|
|
75
75
|
Scanners::ScannerMultiplexer.new(
|
|
76
76
|
scanners: search_config[:scanners].map do |(class_name, args)|
|
|
77
77
|
if args && args[:strict]
|
|
78
|
-
fail CommandError,
|
|
78
|
+
fail CommandError, "the strict option is global and cannot be applied on the scanner level"
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
ActiveSupport::Inflector.constantize(class_name).new(
|
|
@@ -92,15 +92,15 @@ module I18n::Tasks
|
|
|
92
92
|
@search_config ||= begin
|
|
93
93
|
conf = (config[:search] || {}).deep_symbolize_keys
|
|
94
94
|
if conf[:scanner]
|
|
95
|
-
warn_deprecated
|
|
95
|
+
warn_deprecated "search.scanner is now search.scanners, an array of [ScannerClass, options]"
|
|
96
96
|
conf[:scanners] = [[conf.delete(:scanner)]]
|
|
97
97
|
end
|
|
98
98
|
if conf[:ignore_lines]
|
|
99
|
-
warn_deprecated
|
|
99
|
+
warn_deprecated "search.ignore_lines is no longer a global setting: pass it directly to the pattern scanner."
|
|
100
100
|
conf.delete(:ignore_lines)
|
|
101
101
|
end
|
|
102
102
|
if conf[:include]
|
|
103
|
-
warn_deprecated
|
|
103
|
+
warn_deprecated "search.include is now search.only"
|
|
104
104
|
conf[:only] = conf.delete(:include)
|
|
105
105
|
end
|
|
106
106
|
merge_scanner_configs(SEARCH_DEFAULTS, conf).freeze
|
|
@@ -142,19 +142,19 @@ module I18n::Tasks
|
|
|
142
142
|
|
|
143
143
|
# keys in the source that end with a ., e.g. t("category.#{ cat.i18n_key }") or t("category." + category.key)
|
|
144
144
|
# @param [String] replacement for interpolated values.
|
|
145
|
-
def expr_key_re(replacement:
|
|
145
|
+
def expr_key_re(replacement: "*:")
|
|
146
146
|
@expr_key_re ||= begin
|
|
147
147
|
# disallow patterns with no keys
|
|
148
148
|
ignore_pattern_re = /\A[.#{replacement}]*\z/
|
|
149
|
-
patterns
|
|
150
|
-
k.end_with?(
|
|
149
|
+
patterns = used_in_source_tree(strict: false).key_names.select do |k|
|
|
150
|
+
k.end_with?(".") || k =~ /\#{/
|
|
151
151
|
end.map do |k|
|
|
152
|
-
pattern = "#{replace_key_exp(k, replacement)}#{replacement if k.end_with?(
|
|
152
|
+
pattern = "#{replace_key_exp(k, replacement)}#{replacement if k.end_with?(".")}"
|
|
153
153
|
next if pattern =~ ignore_pattern_re
|
|
154
154
|
|
|
155
155
|
pattern
|
|
156
156
|
end.compact
|
|
157
|
-
compile_key_pattern "{#{patterns *
|
|
157
|
+
compile_key_pattern "{#{patterns * ","}}"
|
|
158
158
|
end
|
|
159
159
|
end
|
|
160
160
|
|
|
@@ -164,18 +164,18 @@ module I18n::Tasks
|
|
|
164
164
|
# @return [String]
|
|
165
165
|
def replace_key_exp(key, replacement)
|
|
166
166
|
scanner = StringScanner.new(key)
|
|
167
|
-
braces
|
|
168
|
-
result
|
|
167
|
+
braces = []
|
|
168
|
+
result = []
|
|
169
169
|
while (match_until = scanner.scan_until(/(?:#?\{|})/))
|
|
170
170
|
case scanner.matched
|
|
171
171
|
when '#{'
|
|
172
172
|
braces << scanner.matched
|
|
173
173
|
result << match_until[0..-3] if braces.length == 1
|
|
174
|
-
when
|
|
174
|
+
when "}"
|
|
175
175
|
prev_brace = braces.pop
|
|
176
176
|
result << replacement if braces.empty? && prev_brace == '#{'
|
|
177
177
|
else
|
|
178
|
-
braces <<
|
|
178
|
+
braces << "{"
|
|
179
179
|
end
|
|
180
180
|
end
|
|
181
181
|
result << key[scanner.pos..] unless scanner.eos?
|
data/lib/i18n/tasks/version.rb
CHANGED
data/lib/i18n/tasks.rb
CHANGED
|
@@ -5,7 +5,7 @@ module I18n
|
|
|
5
5
|
module Tasks
|
|
6
6
|
class << self
|
|
7
7
|
def gem_path
|
|
8
|
-
File.expand_path(File.join(File.dirname(__FILE__),
|
|
8
|
+
File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def verbose?
|
|
@@ -47,7 +47,7 @@ module I18n
|
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
@verbose = !ENV[
|
|
50
|
+
@verbose = !ENV["VERBOSE"].nil?
|
|
51
51
|
|
|
52
52
|
module Data
|
|
53
53
|
end
|
|
@@ -56,25 +56,26 @@ end
|
|
|
56
56
|
|
|
57
57
|
# Per https://github.com/rails/rails/commit/0181f0edd57a2149278bd59c3519233ca1e0a413#commitcomment-60940992
|
|
58
58
|
# 'active_support' must be required first even if we only use parts of it.
|
|
59
|
-
require
|
|
59
|
+
require "active_support"
|
|
60
60
|
|
|
61
|
-
require
|
|
62
|
-
require
|
|
63
|
-
require
|
|
64
|
-
require
|
|
65
|
-
require
|
|
66
|
-
require
|
|
67
|
-
require
|
|
61
|
+
require "active_support/inflector"
|
|
62
|
+
require "active_support/core_ext/hash"
|
|
63
|
+
require "active_support/core_ext/array/access"
|
|
64
|
+
require "active_support/core_ext/array/extract_options"
|
|
65
|
+
require "active_support/core_ext/module/delegation"
|
|
66
|
+
require "active_support/core_ext/object/blank"
|
|
67
|
+
require "active_support/core_ext/object/try"
|
|
68
68
|
|
|
69
|
-
require
|
|
70
|
-
require
|
|
69
|
+
require "ruby-progressbar"
|
|
70
|
+
require "rainbow"
|
|
71
|
+
require "erubi"
|
|
71
72
|
|
|
72
|
-
require
|
|
73
|
-
require
|
|
73
|
+
require "i18n/tasks/version"
|
|
74
|
+
require "i18n/tasks/base_task"
|
|
74
75
|
|
|
75
76
|
# Add internal locale data to i18n gem load path
|
|
76
|
-
require
|
|
77
|
+
require "i18n"
|
|
77
78
|
|
|
78
|
-
Dir[File.join(I18n::Tasks.gem_path,
|
|
79
|
+
Dir[File.join(I18n::Tasks.gem_path, "config", "locales", "*.yml")].each do |locale_file|
|
|
79
80
|
I18n.config.load_path << locale_file
|
|
80
81
|
end
|
|
@@ -34,7 +34,7 @@ data:
|
|
|
34
34
|
## Example (replace %#= with %=):
|
|
35
35
|
# - "<%#= %x[bundle info vagrant --path].chomp %>/templates/locales/%{locale}.yml"
|
|
36
36
|
|
|
37
|
-
## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
|
|
37
|
+
## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, isolating_router, or a custom class.
|
|
38
38
|
# router: conservative_router
|
|
39
39
|
|
|
40
40
|
yaml:
|
|
@@ -122,12 +122,24 @@ search:
|
|
|
122
122
|
# formality: prefer_less
|
|
123
123
|
# # OpenAI
|
|
124
124
|
# openai_api_key: "sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
|
125
|
-
# # openai_model: "gpt-
|
|
125
|
+
# # openai_model: "gpt-4o-mini" # see https://platform.openai.com/docs/models
|
|
126
|
+
# # openai_temperature: 0.0 # Controls randomness in responses (0.0-2.0), default: 0.0
|
|
126
127
|
# # may contain `%{from}` and `%{to}`, which will be replaced by source and target locale codes, respectively (using `Kernel.format`)
|
|
127
128
|
# # openai_system_prompt: >-
|
|
128
129
|
# # You are a professional translator that translates content from the %{from} locale
|
|
129
130
|
# # to the %{to} locale in an i18n locale array.
|
|
130
131
|
# #
|
|
132
|
+
# # Per-locale prompts override the default prompt for specific target locales
|
|
133
|
+
# # openai_locale_prompts:
|
|
134
|
+
# # es: >-
|
|
135
|
+
# # You are a professional translator specializing in Latin American Spanish.
|
|
136
|
+
# # Translate content from the %{from} locale to the %{to} locale, using informal language
|
|
137
|
+
# # and regional expressions common in Mexico.
|
|
138
|
+
# # ja: >-
|
|
139
|
+
# # You are a professional translator specializing in business Japanese.
|
|
140
|
+
# # Translate content from the %{from} locale to the %{to} locale using formal, professional
|
|
141
|
+
# # language appropriate for business contexts.
|
|
142
|
+
# #
|
|
131
143
|
# # The array has a structured format and contains multiple strings. Your task is to translate
|
|
132
144
|
# # each of these strings and create a new array with the translated strings.
|
|
133
145
|
# #
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "i18n/tasks"
|
|
4
4
|
|
|
5
5
|
class I18nTest < ActiveSupport::TestCase
|
|
6
6
|
def setup
|
|
@@ -10,13 +10,13 @@ class I18nTest < ActiveSupport::TestCase
|
|
|
10
10
|
def test_no_missing_keys
|
|
11
11
|
missing_keys = @i18n.missing_keys
|
|
12
12
|
assert_empty missing_keys,
|
|
13
|
-
|
|
13
|
+
"Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them"
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def test_no_unused_keys
|
|
17
17
|
unused_keys = @i18n.unused_keys
|
|
18
18
|
assert_empty unused_keys,
|
|
19
|
-
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "i18n/tasks"
|
|
4
4
|
|
|
5
5
|
RSpec.describe I18n do
|
|
6
6
|
let(:i18n) { I18n::Tasks::BaseTask.new }
|
|
@@ -8,17 +8,17 @@ RSpec.describe I18n do
|
|
|
8
8
|
let(:unused_keys) { i18n.unused_keys }
|
|
9
9
|
let(:inconsistent_interpolations) { i18n.inconsistent_interpolations }
|
|
10
10
|
|
|
11
|
-
it
|
|
11
|
+
it "does not have missing keys" do
|
|
12
12
|
expect(missing_keys).to be_empty,
|
|
13
|
-
|
|
13
|
+
"Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them"
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
it
|
|
16
|
+
it "does not have unused keys" do
|
|
17
17
|
expect(unused_keys).to be_empty,
|
|
18
|
-
|
|
18
|
+
"#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
it
|
|
21
|
+
it "files are normalized" do
|
|
22
22
|
non_normalized = i18n.non_normalized_paths
|
|
23
23
|
error_message = "The following files need to be normalized:\n" \
|
|
24
24
|
"#{non_normalized.map { |path| " #{path}" }.join("\n")}\n" \
|
|
@@ -26,7 +26,7 @@ RSpec.describe I18n do
|
|
|
26
26
|
expect(non_normalized).to be_empty, error_message
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
it
|
|
29
|
+
it "does not have inconsistent interpolations" do
|
|
30
30
|
error_message = "#{inconsistent_interpolations.leaves.count} i18n keys have inconsistent interpolations.\n" \
|
|
31
31
|
"Run `i18n-tasks check-consistent-interpolations' to show them"
|
|
32
32
|
expect(inconsistent_interpolations).to be_empty, error_message
|