i18n-tasks 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/Rakefile +2 -1
  4. data/bin/i18n-tasks +1 -0
  5. data/config/locales/en.yml +15 -9
  6. data/config/locales/ru.yml +80 -74
  7. data/i18n-tasks.gemspec +9 -8
  8. data/lib/i18n/tasks.rb +2 -5
  9. data/lib/i18n/tasks/cli.rb +14 -18
  10. data/lib/i18n/tasks/command/commander.rb +2 -3
  11. data/lib/i18n/tasks/command/commands/health.rb +1 -1
  12. data/lib/i18n/tasks/command/commands/meta.rb +2 -2
  13. data/lib/i18n/tasks/command/commands/missing.rb +17 -19
  14. data/lib/i18n/tasks/command/commands/tree.rb +3 -3
  15. data/lib/i18n/tasks/command/commands/usages.rb +6 -5
  16. data/lib/i18n/tasks/command/commands/xlsx.rb +1 -1
  17. data/lib/i18n/tasks/command/dsl.rb +1 -2
  18. data/lib/i18n/tasks/command/option_parsers/enum.rb +6 -6
  19. data/lib/i18n/tasks/command/option_parsers/locale.rb +3 -1
  20. data/lib/i18n/tasks/command/options/data.rb +22 -21
  21. data/lib/i18n/tasks/command_error.rb +1 -3
  22. data/lib/i18n/tasks/configuration.rb +37 -27
  23. data/lib/i18n/tasks/console_context.rb +3 -2
  24. data/lib/i18n/tasks/data.rb +5 -4
  25. data/lib/i18n/tasks/data/adapter/json_adapter.rb +13 -12
  26. data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +13 -14
  27. data/lib/i18n/tasks/data/file_formats.rb +15 -10
  28. data/lib/i18n/tasks/data/file_system_base.rb +18 -22
  29. data/lib/i18n/tasks/data/router/conservative_router.rb +3 -6
  30. data/lib/i18n/tasks/data/router/pattern_router.rb +4 -5
  31. data/lib/i18n/tasks/data/tree/node.rb +20 -19
  32. data/lib/i18n/tasks/data/tree/nodes.rb +4 -3
  33. data/lib/i18n/tasks/data/tree/siblings.rb +36 -29
  34. data/lib/i18n/tasks/data/tree/traversal.rb +32 -35
  35. data/lib/i18n/tasks/google_translation.rb +22 -25
  36. data/lib/i18n/tasks/html_keys.rb +2 -0
  37. data/lib/i18n/tasks/ignore_keys.rb +3 -2
  38. data/lib/i18n/tasks/key_pattern_matching.rb +9 -8
  39. data/lib/i18n/tasks/locale_list.rb +4 -6
  40. data/lib/i18n/tasks/locale_pathname.rb +8 -8
  41. data/lib/i18n/tasks/logging.rb +3 -3
  42. data/lib/i18n/tasks/missing_keys.rb +29 -31
  43. data/lib/i18n/tasks/plural_keys.rb +6 -7
  44. data/lib/i18n/tasks/references.rb +72 -41
  45. data/lib/i18n/tasks/reports/base.rb +8 -7
  46. data/lib/i18n/tasks/reports/spreadsheet.rb +15 -16
  47. data/lib/i18n/tasks/reports/terminal.rb +32 -32
  48. data/lib/i18n/tasks/scanners/file_scanner.rb +6 -5
  49. data/lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb +1 -2
  50. data/lib/i18n/tasks/scanners/files/caching_file_reader.rb +0 -1
  51. data/lib/i18n/tasks/scanners/files/file_finder.rb +12 -15
  52. data/lib/i18n/tasks/scanners/files/file_reader.rb +0 -1
  53. data/lib/i18n/tasks/scanners/occurrence_from_position.rb +8 -7
  54. data/lib/i18n/tasks/scanners/pattern_mapper.rb +2 -2
  55. data/lib/i18n/tasks/scanners/pattern_scanner.rb +9 -7
  56. data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +1 -2
  57. data/lib/i18n/tasks/scanners/relative_keys.rb +11 -11
  58. data/lib/i18n/tasks/scanners/results/key_occurrences.rb +3 -4
  59. data/lib/i18n/tasks/scanners/results/occurrence.rb +8 -7
  60. data/lib/i18n/tasks/scanners/ruby_ast_call_finder.rb +2 -2
  61. data/lib/i18n/tasks/scanners/ruby_ast_scanner.rb +39 -31
  62. data/lib/i18n/tasks/scanners/scanner_multiplexer.rb +9 -3
  63. data/lib/i18n/tasks/split_key.rb +5 -6
  64. data/lib/i18n/tasks/stats.rb +10 -8
  65. data/lib/i18n/tasks/string_interpolation.rb +1 -1
  66. data/lib/i18n/tasks/unused_keys.rb +2 -2
  67. data/lib/i18n/tasks/used_keys.rb +47 -43
  68. data/lib/i18n/tasks/version.rb +1 -1
  69. data/templates/rspec/i18n_spec.rb +2 -2
  70. metadata +30 -3
@@ -2,8 +2,7 @@
2
2
  module I18n::Tasks
3
3
  module Data::Tree
4
4
  # Any Enumerable that yields nodes can mix in this module
5
- module Traversal
6
-
5
+ module Traversal # rubocop:disable Metrics/ModuleLength
7
6
  def nodes(&block)
8
7
  depth_first(&block)
9
8
  end
@@ -41,12 +40,13 @@ module I18n::Tasks
41
40
 
42
41
  def depth_first(&visitor)
43
42
  return to_enum(:depth_first) unless visitor
44
- each { |node|
43
+ each do |node|
45
44
  visitor.yield node
45
+ next unless node.children?
46
46
  node.children.each do |child|
47
47
  child.depth_first(&visitor)
48
- end if node.children?
49
- }
48
+ end
49
+ end
50
50
  self
51
51
  end
52
52
 
@@ -58,7 +58,6 @@ module I18n::Tasks
58
58
  self
59
59
  end
60
60
 
61
-
62
61
  def key_names(opts = {})
63
62
  opts[:root] = false unless opts.key?(:root)
64
63
  keys(opts).map { |key, _node| key }
@@ -88,12 +87,11 @@ module I18n::Tasks
88
87
  def select_nodes(&block)
89
88
  tree = Siblings.new
90
89
  each do |node|
91
- if block.yield(node)
92
- tree.append! node.derive(
93
- parent: tree.parent,
94
- children: (node.children.select_nodes(&block).to_a if node.children)
95
- )
96
- end
90
+ next unless block.yield(node)
91
+ tree.append! node.derive(
92
+ parent: tree.parent,
93
+ children: (node.children.select_nodes(&block).to_a if node.children)
94
+ )
97
95
  end
98
96
  tree
99
97
  end
@@ -117,56 +115,55 @@ module I18n::Tasks
117
115
  # @return Siblings
118
116
  def select_keys(opts = {}, &block)
119
117
  root = opts.key?(:root) ? opts[:root] : false
120
- ok = {}
118
+ ok = {}
121
119
  keys(root: root) do |full_key, node|
122
120
  if block.yield(full_key, node)
123
- node.walk_to_root { |p|
121
+ node.walk_to_root do |p|
124
122
  break if ok[p]
125
123
  ok[p] = true
126
- }
124
+ end
127
125
  end
128
126
  end
129
- select_nodes { |node|
127
+ select_nodes do |node|
130
128
  ok[node]
131
- }
129
+ end
132
130
  end
133
131
 
134
132
  # @return Siblings
135
133
  def intersect_keys(other_tree, key_opts = {}, &block)
136
134
  if block
137
- select_keys(key_opts) { |key, node|
135
+ select_keys(key_opts) do |key, node|
138
136
  other_node = other_tree[key]
139
- other_node && block.call(key, node, other_node)
140
- }
137
+ other_node && yield(key, node, other_node)
138
+ end
141
139
  else
142
- select_keys(key_opts) { |key, node| other_tree[key] }
140
+ select_keys(key_opts) { |key, _node| other_tree[key] }
143
141
  end
144
142
  end
145
143
 
146
144
  def grep_keys(match, opts = {})
147
145
  select_keys(opts) do |full_key, _node|
148
- match === full_key
146
+ match === full_key # rubocop:disable Style/CaseEquality
149
147
  end
150
148
  end
151
149
 
152
150
  def set_each_value!(val_pattern, key_pattern = nil, &value_proc)
153
- value_proc ||= proc { |node|
151
+ value_proc ||= proc do |node|
154
152
  node_value = node.value
155
153
  next node_value if node.reference?
156
- human_key = ActiveSupport::Inflector.humanize(node.key.to_s)
157
- full_key = node.full_key
154
+ human_key = ActiveSupport::Inflector.humanize(node.key.to_s)
155
+ full_key = node.full_key
156
+ default = (node.data[:occurrences] || []).detect { |o| o.default_arg.presence }.try(:default_arg)
158
157
  StringInterpolation.interpolate_soft(
159
- val_pattern,
160
- value: node_value,
161
- human_key: human_key,
162
- key: full_key,
163
- value_or_human_key: node_value.presence || human_key,
164
- value_or_default_or_human_key: node_value.presence ||
165
- (node.data[:occurrences] || []).detect { |o|
166
- o.default_arg.presence }.try(:default_arg) ||
167
- human_key
158
+ val_pattern,
159
+ value: node_value,
160
+ human_key: human_key,
161
+ key: full_key,
162
+ default: default,
163
+ value_or_human_key: node_value.presence || human_key,
164
+ value_or_default_or_human_key: node_value.presence || default || human_key
168
165
  )
169
- }
166
+ end
170
167
  if key_pattern.present?
171
168
  pattern_re = I18n::Tasks::KeyPatternMatching.compile_key_pattern(key_pattern)
172
169
  end
@@ -4,7 +4,6 @@ require 'i18n/tasks/html_keys'
4
4
 
5
5
  module I18n::Tasks
6
6
  module GoogleTranslation
7
-
8
7
  # @param [I18n::Tasks::Tree::Siblings] forest to translate to the locales of its root nodes
9
8
  # @param [String] from locale
10
9
  # @return [I18n::Tasks::Tree::Siblings] translated forest
@@ -17,18 +16,18 @@ module I18n::Tasks
17
16
 
18
17
  # @param [Array<[String, Object]>] list of key-value pairs
19
18
  # @return [Array<[String, Object]>] translated list
20
- def google_translate_list(list, opts)
19
+ def google_translate_list(list, opts) # rubocop:disable Metrics/AbcSize
21
20
  return [] if list.empty?
22
- opts = opts.dup
21
+ opts = opts.dup
23
22
  opts[:key] ||= translation_config[:api_key]
24
23
  validate_google_translate_api_key! opts[:key]
25
- key_pos = list.each_with_index.inject({}) { |idx, ((k, _v), i)| idx[k] = i; idx }
24
+ key_pos = list.each_with_index.inject({}) { |idx, ((k, _v), i)| idx.update(k => i) }
26
25
  # copy reference keys as is, instead of translating
27
26
  reference_key_vals = list.select { |_k, v| v.is_a? Symbol } || []
28
27
  list -= reference_key_vals
29
- result = list.group_by { |k_v| html_key? k_v[0], opts[:from] }.map { |is_html, list_slice|
30
- fetch_google_translations list_slice, opts.merge(is_html ? {html: true} : {format: 'text'})
31
- }.reduce(:+) || []
28
+ result = list.group_by { |k_v| html_key? k_v[0], opts[:from] }.map do |is_html, list_slice|
29
+ fetch_google_translations list_slice, opts.merge(is_html ? { html: true } : { format: 'text' })
30
+ end.reduce(:+) || []
32
31
  result.concat(reference_key_vals)
33
32
  result.sort! { |a, b| key_pos[a[0]] <=> key_pos[b[0]] }
34
33
  result
@@ -39,7 +38,7 @@ module I18n::Tasks
39
38
  def fetch_google_translations(list, opts)
40
39
  from_values(list, EasyTranslate.translate(to_values(list), opts)).tap do |result|
41
40
  if result.blank?
42
- raise CommandError.new(I18n.t('i18n_tasks.google_translate.errors.no_results'))
41
+ fail CommandError, I18n.t('i18n_tasks.google_translate.errors.no_results')
43
42
  end
44
43
  end
45
44
  end
@@ -48,7 +47,7 @@ module I18n::Tasks
48
47
 
49
48
  def validate_google_translate_api_key!(key)
50
49
  if key.blank?
51
- raise CommandError.new(I18n.t('i18n_tasks.google_translate.errors.no_api_key'))
50
+ fail CommandError, I18n.t('i18n_tasks.google_translate.errors.no_api_key')
52
51
  end
53
52
  end
54
53
 
@@ -71,13 +70,11 @@ module I18n::Tasks
71
70
  # @return [String, Array<String, nil>, nil] value for Google Translate or nil for non-string values
72
71
  def dump_value(value)
73
72
  case value
74
- when Array
75
- # dump recursively
76
- value.map { |v| dump_value v }
77
- when String
78
- replace_interpolations value
79
- else
80
- nil
73
+ when Array
74
+ # dump recursively
75
+ value.map { |v| dump_value v }
76
+ when String
77
+ replace_interpolations value
81
78
  end
82
79
  end
83
80
 
@@ -87,18 +84,18 @@ module I18n::Tasks
87
84
  # @return [Object] final translated value
88
85
  def parse_value(untranslated, each_translated)
89
86
  case untranslated
90
- when Array
91
- # implode array
92
- untranslated.map { |from| parse_value(from, each_translated) }
93
- when String
94
- restore_interpolations untranslated, each_translated.next
95
- else
96
- untranslated
87
+ when Array
88
+ # implode array
89
+ untranslated.map { |from| parse_value(from, each_translated) }
90
+ when String
91
+ restore_interpolations untranslated, each_translated.next
92
+ else
93
+ untranslated
97
94
  end
98
95
  end
99
96
 
100
- INTERPOLATION_KEY_RE = /%\{[^}]+\}/.freeze
101
- UNTRANSLATABLE_STRING = 'zxzxzx'.freeze
97
+ INTERPOLATION_KEY_RE = /%\{[^}]+\}/
98
+ UNTRANSLATABLE_STRING = 'zxzxzx'
102
99
 
103
100
  # @param [String] value
104
101
  # @return [String] 'hello, %{name}' => 'hello, <round-trippable string>'
@@ -5,9 +5,11 @@ module I18n::Tasks
5
5
  MAYBE_PLURAL_HTML_KEY_PATTERN = /[.\-_]html\.[^.]+\z/
6
6
 
7
7
  def html_key?(full_key, locale)
8
+ # rubocop:disable Style/DoubleNegation
8
9
  !!(full_key =~ HTML_KEY_PATTERN ||
9
10
  full_key =~ MAYBE_PLURAL_HTML_KEY_PATTERN &&
10
11
  depluralize_key(split_key(full_key, 2)[1], locale) =~ HTML_KEY_PATTERN)
12
+ # rubocop:enable Style/DoubleNegation
11
13
  end
12
14
  end
13
15
  end
@@ -14,13 +14,14 @@ module I18n::Tasks::IgnoreKeys
14
14
  @ignore_patterns ||= HashWithIndifferentAccess.new
15
15
  @ignore_patterns[type] ||= {}
16
16
  @ignore_patterns[type][locale] ||= begin
17
- global, type_ignore = ignore_config.presence || [], ignore_config(type).presence || []
17
+ global = ignore_config.presence || []
18
+ type_ignore = ignore_config(type).presence || []
18
19
  patterns = if type_ignore.is_a?(Array)
19
20
  global + type_ignore
20
21
  elsif type_ignore.is_a?(Hash)
21
22
  # ignore per locale
22
23
  global + (type_ignore['all'] || []) +
23
- type_ignore.select { |k, v| k.to_s =~ /\b#{locale}\b/ }.values.flatten(1).compact
24
+ type_ignore.select { |k, _v| k.to_s =~ /\b#{locale}\b/ }.values.flatten(1).compact
24
25
  end
25
26
  compile_patterns_re patterns
26
27
  end
@@ -2,8 +2,9 @@
2
2
  require 'strscan'
3
3
 
4
4
  module I18n::Tasks::KeyPatternMatching
5
- extend self
6
- MATCH_NOTHING = /\z\A/.freeze
5
+ extend self # rubocop:disable Style/ModuleFunction
6
+
7
+ MATCH_NOTHING = /\z\A/
7
8
 
8
9
  # one regex to match any
9
10
  def compile_patterns_re(key_patterns)
@@ -11,7 +12,7 @@ module I18n::Tasks::KeyPatternMatching
11
12
  # match nothing
12
13
  MATCH_NOTHING
13
14
  else
14
- /(?:#{ key_patterns.map { |p| compile_key_pattern p } * '|'.freeze })/m
15
+ /(?:#{ key_patterns.map { |p| compile_key_pattern p } * '|' })/m
15
16
  end
16
17
  end
17
18
 
@@ -26,10 +27,10 @@ module I18n::Tasks::KeyPatternMatching
26
27
  end
27
28
 
28
29
  def key_pattern_re_body(key_pattern)
29
- key_pattern.
30
- gsub(/\./, '\.'.freeze).
31
- gsub(/\*/, '.*'.freeze).
32
- gsub(/:/, '(?<=^|\.)[^.]+?(?=\.|$)'.freeze).
33
- gsub(/\{(.*?)}/) { "(#{$1.strip.gsub /\s*,\s*/, '|'.freeze})" }
30
+ key_pattern
31
+ .gsub(/\./, '\.')
32
+ .gsub(/\*/, '.*')
33
+ .gsub(/:/, '(?<=^|\.)[^.]+?(?=\.|$)')
34
+ .gsub(/\{(.*?)}/) { "(#{Regexp.last_match(1).strip.gsub(/\s*,\s*/, '|')})" }
34
35
  end
35
36
  end
@@ -1,19 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
  module I18n::Tasks
3
3
  module LocaleList
4
- extend self
4
+ module_function
5
5
 
6
6
  # @return locales converted to strings, with base locale first, the rest sorted alphabetically
7
7
  def normalize_locale_list(locales, base_locale, include_base = false)
8
8
  locales = Array(locales).map(&:to_s).sort
9
9
  if locales.include?(base_locale)
10
10
  [base_locale] + (locales - [base_locale])
11
+ elsif include_base
12
+ [base_locale] + locales
11
13
  else
12
- if include_base
13
- [base_locale] + locales
14
- else
15
- locales
16
- end
14
+ locales
17
15
  end
18
16
  end
19
17
  end
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
  module I18n::Tasks
3
3
  module LocalePathname
4
- extend self
4
+ class << self
5
+ def replace_locale(path, from, to)
6
+ path && path.gsub(path_locale_re(from), to)
7
+ end
5
8
 
6
- def replace_locale(path, from, to)
7
- path && path.gsub(path_locale_re(from), to)
8
- end
9
-
10
- private
9
+ private
11
10
 
12
- def path_locale_re(locale)
13
- (@path_locale_res ||= {})[locale] ||= /(?<=^|[\/.])#{locale}(?=[\/.])/.freeze
11
+ def path_locale_re(locale)
12
+ (@path_locale_res ||= {})[locale] ||= %r{(?<=^|[/.])#{locale}(?=[/.])}
13
+ end
14
14
  end
15
15
  end
16
16
  end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
  module I18n::Tasks::Logging
3
- extend self
3
+ module_function
4
4
 
5
5
  def warn_deprecated(message)
6
6
  log_stderr Term::ANSIColor.yellow Term::ANSIColor.bold "#{program_name}: [DEPRECATED] #{message}"
7
7
  end
8
8
 
9
- def log_verbose(message = nil, &block)
9
+ def log_verbose(message = nil)
10
10
  if ::I18n::Tasks.verbose?
11
- log_stderr Term::ANSIColor.bright_blue(message || block.call)
11
+ log_stderr Term::ANSIColor.bright_blue(message || yield)
12
12
  end
13
13
  end
14
14
 
@@ -2,11 +2,10 @@
2
2
  require 'set'
3
3
  module I18n::Tasks
4
4
  module MissingKeys
5
-
6
5
  MISSING_TYPES = {
7
- used: {glyph: '✗', summary: 'used in code but missing from base locale'},
8
- diff: {glyph: '∅', summary: 'translated in one locale but not in the other'}
9
- }
6
+ used: { glyph: '✗', summary: 'used in code but missing from base locale' },
7
+ diff: { glyph: '∅', summary: 'translated in one locale but not in the other' }
8
+ }.freeze
10
9
 
11
10
  def self.missing_keys_types
12
11
  @missing_keys_types ||= MISSING_TYPES.keys
@@ -19,9 +18,9 @@ module I18n::Tasks
19
18
  # @param types [:missing_used, :missing_diff] all if `nil`.
20
19
  # @return [Siblings]
21
20
  def missing_keys(locales: nil, types: nil, base_locale: nil)
22
- locales = locales.presence || self.locales
23
- types = types.presence || missing_keys_types
24
- base = base_locale || self.base_locale
21
+ locales ||= self.locales
22
+ types ||= missing_keys_types
23
+ base = base_locale || self.base_locale
25
24
  types.inject(empty_forest) do |f, type|
26
25
  f.merge! send(:"missing_#{type}_forest", locales, base)
27
26
  end
@@ -29,59 +28,59 @@ module I18n::Tasks
29
28
 
30
29
  def eq_base_keys(opts = {})
31
30
  locales = Array(opts[:locales]).presence || self.locales
32
- (locales - [base_locale]).inject(empty_forest) { |tree, locale|
31
+ (locales - [base_locale]).inject(empty_forest) do |tree, locale|
33
32
  tree.merge! equal_values_tree(locale, base_locale)
34
- }
33
+ end
35
34
  end
36
35
 
37
36
  def missing_diff_forest(locales, base = base_locale)
38
37
  tree = empty_forest
39
38
  # present in base but not locale
40
- (locales - [base]).each { |locale|
39
+ (locales - [base]).each do |locale|
41
40
  tree.merge! missing_diff_tree(locale, base)
42
- }
41
+ end
43
42
  if locales.include?(base)
44
43
  # present in locale but not base
45
- (self.locales - [base]).each { |locale|
44
+ (self.locales - [base]).each do |locale|
46
45
  tree.merge! missing_diff_tree(base, locale)
47
- }
46
+ end
48
47
  end
49
48
  tree
50
49
  end
51
50
 
52
51
  def missing_used_forest(locales, _base = base_locale)
53
- locales.inject(empty_forest) { |forest, locale|
52
+ locales.inject(empty_forest) do |forest, locale|
54
53
  forest.merge! missing_used_tree(locale)
55
- }
54
+ end
56
55
  end
57
56
 
58
57
  # keys present in compared_to, but not in locale
59
58
  def missing_diff_tree(locale, compared_to = base_locale)
60
- data[compared_to].select_keys { |key, _node|
59
+ data[compared_to].select_keys do |key, _node|
61
60
  locale_key_missing? locale, depluralize_key(key, compared_to)
62
- }.set_root_key!(locale, type: :missing_diff).keys { |_key, node|
61
+ end.set_root_key!(locale, type: :missing_diff).keys do |_key, node|
63
62
  # change path and locale to base
64
- data = {locale: locale, missing_diff_locale: node.data[:locale]}
63
+ data = { locale: locale, missing_diff_locale: node.data[:locale] }
65
64
  if node.data.key?(:path)
66
65
  data[:path] = LocalePathname.replace_locale(node.data[:path], node.data[:locale], locale)
67
66
  end
68
67
  node.data.update data
69
- }
68
+ end
70
69
  end
71
70
 
72
71
  # keys used in the code missing translations in locale
73
72
  def missing_used_tree(locale)
74
- used_tree(strict: true).select_keys { |key, _node|
73
+ used_tree(strict: true).select_keys do |key, _node|
75
74
  locale_key_missing?(locale, key)
76
- }.set_root_key!(locale, type: :missing_used)
75
+ end.set_root_key!(locale, type: :missing_used)
77
76
  end
78
77
 
79
78
  def equal_values_tree(locale, compare_to = base_locale)
80
79
  base = data[compare_to].first.children
81
- data[locale].select_keys(root: false) { |key, node|
80
+ data[locale].select_keys(root: false) do |key, node|
82
81
  other_node = base[key]
83
82
  other_node && !node.reference? && node.value == other_node.value && !ignore_key?(key, :eq_base, locale)
84
- }.set_root_key!(locale, type: :eq_base)
83
+ end.set_root_key!(locale, type: :eq_base)
85
84
  end
86
85
 
87
86
  def locale_key_missing?(locale, key)
@@ -96,7 +95,7 @@ module I18n::Tasks
96
95
  to_remove = []
97
96
  forest.each do |root|
98
97
  locale = root.key
99
- root.keys { |key, node|
98
+ root.keys do |key, node|
100
99
  next unless yield node
101
100
  if locales_and_node_by_key.key?(key)
102
101
  locales_and_node_by_key[key][0] << locale
@@ -104,17 +103,16 @@ module I18n::Tasks
104
103
  locales_and_node_by_key[key] = [[locale], node]
105
104
  end
106
105
  to_remove << node
107
- }
106
+ end
108
107
  end
109
108
  forest.remove_nodes_and_emptied_ancestors! to_remove
110
- locales_and_node_by_key.inject({}) { |inv, (key, (locales, node))|
109
+ locales_and_node_by_key.each_with_object({}) do |(key, (locales, node)), inv|
111
110
  (inv[locales.sort.join('+')] ||= []) << [key, node]
112
- inv
113
- }.map { |locales, keys_nodes|
114
- keys_nodes.each { |(key, node)|
111
+ end.map do |locales, keys_nodes|
112
+ keys_nodes.each do |(key, node)|
115
113
  forest["#{locales}.#{key}"] = node
116
- }
117
- }
114
+ end
115
+ end
118
116
  forest
119
117
  end
120
118
  end