i18n-tasks 1.0.15 → 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 +85 -13
- data/Rakefile +4 -4
- data/bin/i18n-tasks +3 -3
- data/config/locales/en.yml +6 -0
- data/config/locales/ru.yml +7 -0
- data/i18n-tasks.gemspec +28 -41
- 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 +25 -25
- 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 +5 -5
- 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 +32 -32
- 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 +22 -21
- 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 +1 -1
- 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 +8 -8
- 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 +8 -1
- data/lib/i18n/tasks/scanners/prism_scanners/nodes.rb +101 -61
- data/lib/i18n/tasks/scanners/prism_scanners/visitor.rb +169 -105
- 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 +1 -1
- 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 +5 -5
- data/lib/i18n/tasks/translators/base_translator.rb +40 -14
- data/lib/i18n/tasks/translators/deepl_translator.rb +17 -14
- data/lib/i18n/tasks/translators/google_translator.rb +169 -25
- data/lib/i18n/tasks/translators/openai_translator.rb +34 -23
- data/lib/i18n/tasks/translators/watsonx_translator.rb +16 -16
- data/lib/i18n/tasks/translators/yandex_translator.rb +8 -8
- data/lib/i18n/tasks/unused_keys.rb +1 -1
- data/lib/i18n/tasks/used_keys.rb +32 -33
- data/lib/i18n/tasks/version.rb +1 -1
- data/lib/i18n/tasks.rb +17 -17
- data/templates/config/i18n-tasks.yml +12 -0
- data/templates/minitest/i18n_test.rb +3 -3
- data/templates/rspec/i18n_spec.rb +7 -7
- metadata +25 -185
- data/lib/i18n/tasks/scanners/prism_scanner.rb +0 -83
- data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +0 -145
data/lib/i18n/tasks/used_keys.rb
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
10
|
-
require 'i18n/tasks/scanners/files/caching_file_reader'
|
|
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"
|
|
11
10
|
|
|
12
11
|
# Require the pattern mapper even though it's not used by i18n-tasks directly.
|
|
13
12
|
# This allows the user to use it in config/i18n-tasks.yml without having to require it.
|
|
14
13
|
# See https://github.com/glebm/i18n-tasks/issues/204.
|
|
15
|
-
require
|
|
14
|
+
require "i18n/tasks/scanners/pattern_mapper"
|
|
16
15
|
|
|
17
16
|
module I18n::Tasks
|
|
18
17
|
module UsedKeys # rubocop:disable Metrics/ModuleLength
|
|
@@ -21,17 +20,17 @@ module I18n::Tasks
|
|
|
21
20
|
relative_exclude_method_name_paths: [],
|
|
22
21
|
relative_roots: %w[app/controllers app/helpers app/mailers app/presenters app/views].freeze,
|
|
23
22
|
scanners: [
|
|
24
|
-
[
|
|
25
|
-
[
|
|
26
|
-
[
|
|
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]}]
|
|
27
26
|
],
|
|
28
27
|
ast_matchers: [],
|
|
29
28
|
strict: true
|
|
30
29
|
}.freeze
|
|
31
30
|
|
|
32
31
|
ALWAYS_EXCLUDE = %w[*.jpg *.jpeg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
*.less *.yml *.json *.zip *.tar.gz *.swf *.flv *.mp3 *.wav *.flac *.webm *.mp4 *.ogg *.opus
|
|
33
|
+
*.webp *.map *.xlsx].freeze
|
|
35
34
|
|
|
36
35
|
# Find all keys in the source and return a forest with the keys in absolute form and their occurrences.
|
|
37
36
|
#
|
|
@@ -41,12 +40,12 @@ module I18n::Tasks
|
|
|
41
40
|
# @return [Data::Tree::Siblings]
|
|
42
41
|
def used_tree(key_filter: nil, strict: nil, include_raw_references: false)
|
|
43
42
|
src_tree = used_in_source_tree(key_filter: key_filter, strict: strict)
|
|
44
|
-
raw_refs, resolved_refs, used_refs = process_references(src_tree[
|
|
43
|
+
raw_refs, resolved_refs, used_refs = process_references(src_tree["used"].children)
|
|
45
44
|
raw_refs.leaves { |node| node.data[:ref_type] = :reference_usage }
|
|
46
45
|
resolved_refs.leaves { |node| node.data[:ref_type] = :reference_usage_resolved }
|
|
47
46
|
used_refs.leaves { |node| node.data[:ref_type] = :reference_usage_key }
|
|
48
47
|
src_tree.tap do |result|
|
|
49
|
-
tree = result[
|
|
48
|
+
tree = result["used"].children
|
|
50
49
|
tree.subtract_by_key!(raw_refs)
|
|
51
50
|
tree.merge!(raw_refs) if include_raw_references
|
|
52
51
|
tree.merge!(used_refs).merge!(resolved_refs)
|
|
@@ -58,11 +57,11 @@ module I18n::Tasks
|
|
|
58
57
|
scanner(strict: strict).keys.freeze)
|
|
59
58
|
if key_filter
|
|
60
59
|
key_filter_re = compile_key_pattern(key_filter)
|
|
61
|
-
keys
|
|
60
|
+
keys = keys.select { |k| k.key =~ key_filter_re }
|
|
62
61
|
end
|
|
63
62
|
Data::Tree::Node.new(
|
|
64
|
-
key:
|
|
65
|
-
data: {
|
|
63
|
+
key: "used",
|
|
64
|
+
data: {key_filter: key_filter},
|
|
66
65
|
children: Data::Tree::Siblings.from_key_occurrences(keys)
|
|
67
66
|
).to_siblings
|
|
68
67
|
end
|
|
@@ -72,11 +71,11 @@ module I18n::Tasks
|
|
|
72
71
|
shared_options = search_config.dup
|
|
73
72
|
shared_options.delete(:scanners)
|
|
74
73
|
shared_options[:strict] = strict unless strict.nil?
|
|
75
|
-
log_verbose
|
|
74
|
+
log_verbose "Scanners: "
|
|
76
75
|
Scanners::ScannerMultiplexer.new(
|
|
77
76
|
scanners: search_config[:scanners].map do |(class_name, args)|
|
|
78
77
|
if args && args[:strict]
|
|
79
|
-
fail CommandError,
|
|
78
|
+
fail CommandError, "the strict option is global and cannot be applied on the scanner level"
|
|
80
79
|
end
|
|
81
80
|
|
|
82
81
|
ActiveSupport::Inflector.constantize(class_name).new(
|
|
@@ -93,15 +92,15 @@ module I18n::Tasks
|
|
|
93
92
|
@search_config ||= begin
|
|
94
93
|
conf = (config[:search] || {}).deep_symbolize_keys
|
|
95
94
|
if conf[:scanner]
|
|
96
|
-
warn_deprecated
|
|
95
|
+
warn_deprecated "search.scanner is now search.scanners, an array of [ScannerClass, options]"
|
|
97
96
|
conf[:scanners] = [[conf.delete(:scanner)]]
|
|
98
97
|
end
|
|
99
98
|
if conf[:ignore_lines]
|
|
100
|
-
warn_deprecated
|
|
99
|
+
warn_deprecated "search.ignore_lines is no longer a global setting: pass it directly to the pattern scanner."
|
|
101
100
|
conf.delete(:ignore_lines)
|
|
102
101
|
end
|
|
103
102
|
if conf[:include]
|
|
104
|
-
warn_deprecated
|
|
103
|
+
warn_deprecated "search.include is now search.only"
|
|
105
104
|
conf[:only] = conf.delete(:include)
|
|
106
105
|
end
|
|
107
106
|
merge_scanner_configs(SEARCH_DEFAULTS, conf).freeze
|
|
@@ -143,19 +142,19 @@ module I18n::Tasks
|
|
|
143
142
|
|
|
144
143
|
# keys in the source that end with a ., e.g. t("category.#{ cat.i18n_key }") or t("category." + category.key)
|
|
145
144
|
# @param [String] replacement for interpolated values.
|
|
146
|
-
def expr_key_re(replacement:
|
|
145
|
+
def expr_key_re(replacement: "*:")
|
|
147
146
|
@expr_key_re ||= begin
|
|
148
147
|
# disallow patterns with no keys
|
|
149
148
|
ignore_pattern_re = /\A[.#{replacement}]*\z/
|
|
150
|
-
patterns
|
|
151
|
-
k.end_with?(
|
|
149
|
+
patterns = used_in_source_tree(strict: false).key_names.select do |k|
|
|
150
|
+
k.end_with?(".") || k =~ /\#{/
|
|
152
151
|
end.map do |k|
|
|
153
|
-
pattern = "#{replace_key_exp(k, replacement)}#{replacement if k.end_with?(
|
|
152
|
+
pattern = "#{replace_key_exp(k, replacement)}#{replacement if k.end_with?(".")}"
|
|
154
153
|
next if pattern =~ ignore_pattern_re
|
|
155
154
|
|
|
156
155
|
pattern
|
|
157
156
|
end.compact
|
|
158
|
-
compile_key_pattern "{#{patterns *
|
|
157
|
+
compile_key_pattern "{#{patterns * ","}}"
|
|
159
158
|
end
|
|
160
159
|
end
|
|
161
160
|
|
|
@@ -165,18 +164,18 @@ module I18n::Tasks
|
|
|
165
164
|
# @return [String]
|
|
166
165
|
def replace_key_exp(key, replacement)
|
|
167
166
|
scanner = StringScanner.new(key)
|
|
168
|
-
braces
|
|
169
|
-
result
|
|
167
|
+
braces = []
|
|
168
|
+
result = []
|
|
170
169
|
while (match_until = scanner.scan_until(/(?:#?\{|})/))
|
|
171
170
|
case scanner.matched
|
|
172
171
|
when '#{'
|
|
173
172
|
braces << scanner.matched
|
|
174
173
|
result << match_until[0..-3] if braces.length == 1
|
|
175
|
-
when
|
|
174
|
+
when "}"
|
|
176
175
|
prev_brace = braces.pop
|
|
177
176
|
result << replacement if braces.empty? && prev_brace == '#{'
|
|
178
177
|
else
|
|
179
|
-
braces <<
|
|
178
|
+
braces << "{"
|
|
180
179
|
end
|
|
181
180
|
end
|
|
182
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,26 +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
|
|
71
|
-
require
|
|
69
|
+
require "ruby-progressbar"
|
|
70
|
+
require "rainbow"
|
|
71
|
+
require "erubi"
|
|
72
72
|
|
|
73
|
-
require
|
|
74
|
-
require
|
|
73
|
+
require "i18n/tasks/version"
|
|
74
|
+
require "i18n/tasks/base_task"
|
|
75
75
|
|
|
76
76
|
# Add internal locale data to i18n gem load path
|
|
77
|
-
require
|
|
77
|
+
require "i18n"
|
|
78
78
|
|
|
79
|
-
Dir[File.join(I18n::Tasks.gem_path,
|
|
79
|
+
Dir[File.join(I18n::Tasks.gem_path, "config", "locales", "*.yml")].each do |locale_file|
|
|
80
80
|
I18n.config.load_path << locale_file
|
|
81
81
|
end
|
|
@@ -123,11 +123,23 @@ search:
|
|
|
123
123
|
# # OpenAI
|
|
124
124
|
# openai_api_key: "sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
|
125
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
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: i18n-tasks
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- glebm
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-14 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: activesupport
|
|
@@ -57,14 +58,14 @@ dependencies:
|
|
|
57
58
|
requirements:
|
|
58
59
|
- - ">="
|
|
59
60
|
- !ruby/object:Gem::Version
|
|
60
|
-
version:
|
|
61
|
+
version: 3.0.0
|
|
61
62
|
type: :runtime
|
|
62
63
|
prerelease: false
|
|
63
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
65
|
requirements:
|
|
65
66
|
- - ">="
|
|
66
67
|
- !ruby/object:Gem::Version
|
|
67
|
-
version:
|
|
68
|
+
version: 3.0.0
|
|
68
69
|
- !ruby/object:Gem::Dependency
|
|
69
70
|
name: i18n
|
|
70
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -93,6 +94,20 @@ dependencies:
|
|
|
93
94
|
- - ">="
|
|
94
95
|
- !ruby/object:Gem::Version
|
|
95
96
|
version: 3.2.2.1
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: prism
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
96
111
|
- !ruby/object:Gem::Dependency
|
|
97
112
|
name: rails-i18n
|
|
98
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -161,180 +176,6 @@ dependencies:
|
|
|
161
176
|
- - ">="
|
|
162
177
|
- !ruby/object:Gem::Version
|
|
163
178
|
version: 1.5.1
|
|
164
|
-
- !ruby/object:Gem::Dependency
|
|
165
|
-
name: bundler
|
|
166
|
-
requirement: !ruby/object:Gem::Requirement
|
|
167
|
-
requirements:
|
|
168
|
-
- - "~>"
|
|
169
|
-
- !ruby/object:Gem::Version
|
|
170
|
-
version: '2.0'
|
|
171
|
-
- - ">="
|
|
172
|
-
- !ruby/object:Gem::Version
|
|
173
|
-
version: 2.0.1
|
|
174
|
-
type: :development
|
|
175
|
-
prerelease: false
|
|
176
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
-
requirements:
|
|
178
|
-
- - "~>"
|
|
179
|
-
- !ruby/object:Gem::Version
|
|
180
|
-
version: '2.0'
|
|
181
|
-
- - ">="
|
|
182
|
-
- !ruby/object:Gem::Version
|
|
183
|
-
version: 2.0.1
|
|
184
|
-
- !ruby/object:Gem::Dependency
|
|
185
|
-
name: overcommit
|
|
186
|
-
requirement: !ruby/object:Gem::Requirement
|
|
187
|
-
requirements:
|
|
188
|
-
- - "~>"
|
|
189
|
-
- !ruby/object:Gem::Version
|
|
190
|
-
version: 0.58.0
|
|
191
|
-
type: :development
|
|
192
|
-
prerelease: false
|
|
193
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
194
|
-
requirements:
|
|
195
|
-
- - "~>"
|
|
196
|
-
- !ruby/object:Gem::Version
|
|
197
|
-
version: 0.58.0
|
|
198
|
-
- !ruby/object:Gem::Dependency
|
|
199
|
-
name: rake
|
|
200
|
-
requirement: !ruby/object:Gem::Requirement
|
|
201
|
-
requirements:
|
|
202
|
-
- - ">="
|
|
203
|
-
- !ruby/object:Gem::Version
|
|
204
|
-
version: '0'
|
|
205
|
-
type: :development
|
|
206
|
-
prerelease: false
|
|
207
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
208
|
-
requirements:
|
|
209
|
-
- - ">="
|
|
210
|
-
- !ruby/object:Gem::Version
|
|
211
|
-
version: '0'
|
|
212
|
-
- !ruby/object:Gem::Dependency
|
|
213
|
-
name: rspec
|
|
214
|
-
requirement: !ruby/object:Gem::Requirement
|
|
215
|
-
requirements:
|
|
216
|
-
- - "~>"
|
|
217
|
-
- !ruby/object:Gem::Version
|
|
218
|
-
version: '3.3'
|
|
219
|
-
type: :development
|
|
220
|
-
prerelease: false
|
|
221
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
222
|
-
requirements:
|
|
223
|
-
- - "~>"
|
|
224
|
-
- !ruby/object:Gem::Version
|
|
225
|
-
version: '3.3'
|
|
226
|
-
- !ruby/object:Gem::Dependency
|
|
227
|
-
name: rubocop
|
|
228
|
-
requirement: !ruby/object:Gem::Requirement
|
|
229
|
-
requirements:
|
|
230
|
-
- - "~>"
|
|
231
|
-
- !ruby/object:Gem::Version
|
|
232
|
-
version: 1.50.1
|
|
233
|
-
type: :development
|
|
234
|
-
prerelease: false
|
|
235
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
236
|
-
requirements:
|
|
237
|
-
- - "~>"
|
|
238
|
-
- !ruby/object:Gem::Version
|
|
239
|
-
version: 1.50.1
|
|
240
|
-
- !ruby/object:Gem::Dependency
|
|
241
|
-
name: rubocop-rake
|
|
242
|
-
requirement: !ruby/object:Gem::Requirement
|
|
243
|
-
requirements:
|
|
244
|
-
- - "~>"
|
|
245
|
-
- !ruby/object:Gem::Version
|
|
246
|
-
version: 0.6.0
|
|
247
|
-
type: :development
|
|
248
|
-
prerelease: false
|
|
249
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
250
|
-
requirements:
|
|
251
|
-
- - "~>"
|
|
252
|
-
- !ruby/object:Gem::Version
|
|
253
|
-
version: 0.6.0
|
|
254
|
-
- !ruby/object:Gem::Dependency
|
|
255
|
-
name: rubocop-rspec
|
|
256
|
-
requirement: !ruby/object:Gem::Requirement
|
|
257
|
-
requirements:
|
|
258
|
-
- - "~>"
|
|
259
|
-
- !ruby/object:Gem::Version
|
|
260
|
-
version: 2.19.0
|
|
261
|
-
type: :development
|
|
262
|
-
prerelease: false
|
|
263
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
264
|
-
requirements:
|
|
265
|
-
- - "~>"
|
|
266
|
-
- !ruby/object:Gem::Version
|
|
267
|
-
version: 2.19.0
|
|
268
|
-
- !ruby/object:Gem::Dependency
|
|
269
|
-
name: simplecov
|
|
270
|
-
requirement: !ruby/object:Gem::Requirement
|
|
271
|
-
requirements:
|
|
272
|
-
- - ">="
|
|
273
|
-
- !ruby/object:Gem::Version
|
|
274
|
-
version: '0'
|
|
275
|
-
type: :development
|
|
276
|
-
prerelease: false
|
|
277
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
278
|
-
requirements:
|
|
279
|
-
- - ">="
|
|
280
|
-
- !ruby/object:Gem::Version
|
|
281
|
-
version: '0'
|
|
282
|
-
- !ruby/object:Gem::Dependency
|
|
283
|
-
name: yard
|
|
284
|
-
requirement: !ruby/object:Gem::Requirement
|
|
285
|
-
requirements:
|
|
286
|
-
- - ">="
|
|
287
|
-
- !ruby/object:Gem::Version
|
|
288
|
-
version: '0'
|
|
289
|
-
type: :development
|
|
290
|
-
prerelease: false
|
|
291
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
292
|
-
requirements:
|
|
293
|
-
- - ">="
|
|
294
|
-
- !ruby/object:Gem::Version
|
|
295
|
-
version: '0'
|
|
296
|
-
- !ruby/object:Gem::Dependency
|
|
297
|
-
name: deepl-rb
|
|
298
|
-
requirement: !ruby/object:Gem::Requirement
|
|
299
|
-
requirements:
|
|
300
|
-
- - ">="
|
|
301
|
-
- !ruby/object:Gem::Version
|
|
302
|
-
version: 2.1.0
|
|
303
|
-
type: :development
|
|
304
|
-
prerelease: false
|
|
305
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
306
|
-
requirements:
|
|
307
|
-
- - ">="
|
|
308
|
-
- !ruby/object:Gem::Version
|
|
309
|
-
version: 2.1.0
|
|
310
|
-
- !ruby/object:Gem::Dependency
|
|
311
|
-
name: easy_translate
|
|
312
|
-
requirement: !ruby/object:Gem::Requirement
|
|
313
|
-
requirements:
|
|
314
|
-
- - ">="
|
|
315
|
-
- !ruby/object:Gem::Version
|
|
316
|
-
version: 0.5.1
|
|
317
|
-
type: :development
|
|
318
|
-
prerelease: false
|
|
319
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
320
|
-
requirements:
|
|
321
|
-
- - ">="
|
|
322
|
-
- !ruby/object:Gem::Version
|
|
323
|
-
version: 0.5.1
|
|
324
|
-
- !ruby/object:Gem::Dependency
|
|
325
|
-
name: yandex-translator
|
|
326
|
-
requirement: !ruby/object:Gem::Requirement
|
|
327
|
-
requirements:
|
|
328
|
-
- - ">="
|
|
329
|
-
- !ruby/object:Gem::Version
|
|
330
|
-
version: 0.3.3
|
|
331
|
-
type: :development
|
|
332
|
-
prerelease: false
|
|
333
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
334
|
-
requirements:
|
|
335
|
-
- - ">="
|
|
336
|
-
- !ruby/object:Gem::Version
|
|
337
|
-
version: 0.3.3
|
|
338
179
|
description: |
|
|
339
180
|
i18n-tasks helps you find and manage missing and unused translations.
|
|
340
181
|
|
|
@@ -360,6 +201,7 @@ files:
|
|
|
360
201
|
- lib/i18n/tasks/cli.rb
|
|
361
202
|
- lib/i18n/tasks/command/collection.rb
|
|
362
203
|
- lib/i18n/tasks/command/commander.rb
|
|
204
|
+
- lib/i18n/tasks/command/commands/check_prism.rb
|
|
363
205
|
- lib/i18n/tasks/command/commands/data.rb
|
|
364
206
|
- lib/i18n/tasks/command/commands/eq_base.rb
|
|
365
207
|
- lib/i18n/tasks/command/commands/health.rb
|
|
@@ -386,6 +228,7 @@ files:
|
|
|
386
228
|
- lib/i18n/tasks/data/file_formats.rb
|
|
387
229
|
- lib/i18n/tasks/data/file_system.rb
|
|
388
230
|
- lib/i18n/tasks/data/file_system_base.rb
|
|
231
|
+
- lib/i18n/tasks/data/language_names.rb
|
|
389
232
|
- lib/i18n/tasks/data/router/conservative_router.rb
|
|
390
233
|
- lib/i18n/tasks/data/router/isolating_router.rb
|
|
391
234
|
- lib/i18n/tasks/data/router/pattern_router.rb
|
|
@@ -421,7 +264,6 @@ files:
|
|
|
421
264
|
- lib/i18n/tasks/scanners/pattern_mapper.rb
|
|
422
265
|
- lib/i18n/tasks/scanners/pattern_scanner.rb
|
|
423
266
|
- lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb
|
|
424
|
-
- lib/i18n/tasks/scanners/prism_scanner.rb
|
|
425
267
|
- lib/i18n/tasks/scanners/prism_scanners/arguments_visitor.rb
|
|
426
268
|
- lib/i18n/tasks/scanners/prism_scanners/nodes.rb
|
|
427
269
|
- lib/i18n/tasks/scanners/prism_scanners/visitor.rb
|
|
@@ -429,9 +271,9 @@ files:
|
|
|
429
271
|
- lib/i18n/tasks/scanners/results/key_occurrences.rb
|
|
430
272
|
- lib/i18n/tasks/scanners/results/occurrence.rb
|
|
431
273
|
- lib/i18n/tasks/scanners/ruby_ast_call_finder.rb
|
|
432
|
-
- lib/i18n/tasks/scanners/ruby_ast_scanner.rb
|
|
433
274
|
- lib/i18n/tasks/scanners/ruby_key_literals.rb
|
|
434
275
|
- lib/i18n/tasks/scanners/ruby_parser_factory.rb
|
|
276
|
+
- lib/i18n/tasks/scanners/ruby_scanner.rb
|
|
435
277
|
- lib/i18n/tasks/scanners/scanner.rb
|
|
436
278
|
- lib/i18n/tasks/scanners/scanner_multiplexer.rb
|
|
437
279
|
- lib/i18n/tasks/split_key.rb
|
|
@@ -472,17 +314,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
472
314
|
requirements:
|
|
473
315
|
- - ">="
|
|
474
316
|
- !ruby/object:Gem::Version
|
|
475
|
-
version: '
|
|
476
|
-
- - "<"
|
|
477
|
-
- !ruby/object:Gem::Version
|
|
478
|
-
version: '4.0'
|
|
317
|
+
version: '3.1'
|
|
479
318
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
480
319
|
requirements:
|
|
481
320
|
- - ">="
|
|
482
321
|
- !ruby/object:Gem::Version
|
|
483
322
|
version: '0'
|
|
484
323
|
requirements: []
|
|
485
|
-
rubygems_version: 3.
|
|
324
|
+
rubygems_version: 3.2.3
|
|
325
|
+
signing_key:
|
|
486
326
|
specification_version: 4
|
|
487
327
|
summary: Manage localization and translation with the awesome power of static analysis
|
|
488
328
|
test_files: []
|