i18n-tasks 0.9.6 → 0.9.7

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 (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