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
@@ -7,22 +7,21 @@ module I18n::Tasks::PluralKeys
7
7
  def collapse_plural_nodes!(tree)
8
8
  tree.leaves.map(&:parent).compact.uniq.each do |node|
9
9
  children = node.children
10
- if plural_forms?(children)
11
- node.value = children.to_hash
12
- node.children = nil
13
- node.data.merge! children.first.data
14
- end
10
+ next unless plural_forms?(children)
11
+ node.value = children.to_hash
12
+ node.children = nil
13
+ node.data.merge! children.first.data
15
14
  end
16
15
  tree
17
16
  end
18
17
 
19
18
  # @param [String] key i18n key
20
19
  # @param [String] locale to pull key data from
21
- # @return the base form if the key is a specific plural form (e.g. apple for apple.many), and the key as passed otherwise
20
+ # @return [String] the base form if the key is a specific plural form (e.g. apple for apple.many), the key otherwise.
22
21
  def depluralize_key(key, locale = base_locale)
23
22
  return key if key !~ PLURAL_KEY_RE
24
23
  key_name = last_key_part(key)
25
- parent_key = key[0 .. - (key_name.length + 2)]
24
+ parent_key = key[0..- (key_name.length + 2)]
26
25
  nodes = tree("#{locale}.#{parent_key}").presence || (locale != base_locale && tree("#{base_locale}.#{parent_key}"))
27
26
  if nodes && plural_forms?(nodes)
28
27
  parent_key
@@ -5,64 +5,95 @@ module I18n::Tasks
5
5
  # 1. Raw references -- a subset of the usages tree with keys that are reference key usages.
6
6
  # 2. Resolved references -- all the used references in their fully resolved form.
7
7
  # 3. Reference keys -- all the used reference keys.
8
- def process_references(usages, data_references = merge_reference_trees(data_forest.select_keys { |_, node| node.reference? }))
9
- fail ArgumentError.new('usages must be a Data::Tree::Instance') unless usages.is_a?(Data::Tree::Siblings)
10
- fail ArgumentError.new('all_references must be a Data::Tree::Instance') unless data_references.is_a?(Data::Tree::Siblings)
11
- raw_refs = empty_forest
8
+ def process_references(usages,
9
+ data_refs = merge_reference_trees(data_forest.select_keys { |_, node| node.reference? }))
10
+ fail ArgumentError, 'usages must be a Data::Tree::Instance' unless usages.is_a?(Data::Tree::Siblings)
11
+ fail ArgumentError, 'all_references must be a Data::Tree::Instance' unless data_refs.is_a?(Data::Tree::Siblings)
12
+ raw_refs = empty_forest
12
13
  resolved_refs = empty_forest
13
- refs = empty_forest
14
- data_references.key_to_node.each do |ref_key_part, ref_node|
14
+ refs = empty_forest
15
+ data_refs.key_to_node.each do |ref_key_part, ref_node|
15
16
  usages.each do |usage_node|
16
17
  next unless usage_node.key == ref_key_part
17
18
  if ref_node.leaf?
18
- unless refs.key_to_node.key?(ref_node.key)
19
- refs.merge_node!(Data::Tree::Node.new(key: ref_node.key, data: usage_node.data))
20
- end
21
- resolved_refs.merge!(
22
- Data::Tree::Siblings.from_key_names([ref_node.value.to_s]) { |_, resolved_node|
23
- raw_refs.merge_node!(usage_node)
24
- if usage_node.leaf?
25
- resolved_node.data.merge!(usage_node.data)
26
- else
27
- resolved_node.children = usage_node.children
28
- end
29
- resolved_node.leaves { |node| node.data[:ref_info] = [ref_node.full_key, ref_node.value.to_s] }
30
- }.tap { |new_resolved_refs|
31
- refs.key_to_node[ref_node.key].data.tap { |ref_data|
32
- ref_data[:occurrences] ||= []
33
- new_resolved_refs.leaves { |leaf| ref_data[:occurrences].concat(leaf.data[:occurrences] || []) }
34
- ref_data[:occurrences].sort_by!(&:path)
35
- ref_data[:occurrences].uniq!
36
- }
37
- })
19
+ process_leaf!(ref_node, usage_node, raw_refs, resolved_refs, refs)
38
20
  else
39
- child_raw_refs, child_resolved_refs, child_refs = process_references(usage_node.children, ref_node.children)
40
- raw_refs.merge_node! Data::Tree::Node.new(key: ref_node.key, children: child_raw_refs) unless child_raw_refs.empty?
41
- resolved_refs.merge! child_resolved_refs
42
- refs.merge_node! Data::Tree::Node.new(key: ref_node.key, children: child_refs) unless child_refs.empty?
21
+ process_non_leaf!(ref_node, usage_node, raw_refs, resolved_refs, refs)
43
22
  end
44
23
  end
45
24
  end
46
25
  [raw_refs, resolved_refs, refs]
47
26
  end
48
27
 
28
+ private
29
+
30
+ # @param [I18n::Tasks::Data::Tree::Node] ref
31
+ # @param [I18n::Tasks::Data::Tree::Node] usage
32
+ # @param [I18n::Tasks::Data::Tree::Siblings] raw_refs
33
+ # @param [I18n::Tasks::Data::Tree::Siblings] resolved_refs
34
+ # @param [I18n::Tasks::Data::Tree::Siblings] refs
35
+ def process_leaf!(ref, usage, raw_refs, resolved_refs, refs)
36
+ refs.merge_node!(Data::Tree::Node.new(key: ref.key, data: usage.data)) unless refs.key_to_node.key?(ref.key)
37
+ new_resolved_refs = Data::Tree::Siblings.from_key_names([ref.value.to_s]) do |_, resolved_node|
38
+ raw_refs.merge_node!(usage)
39
+ if usage.leaf?
40
+ resolved_node.data.merge!(usage.data)
41
+ else
42
+ resolved_node.children = usage.children
43
+ end
44
+ resolved_node.leaves { |node| node.data[:ref_info] = [ref.full_key, ref.value.to_s] }
45
+ end
46
+ add_occurences! refs.key_to_node[ref.key].data, new_resolved_refs
47
+ resolved_refs.merge! new_resolved_refs
48
+ end
49
+
50
+ # @param [Hash] ref_data
51
+ # @param [I18n::Tasks::Data::Tree::Siblings] new_resolved_refs
52
+ def add_occurences!(ref_data, new_resolved_refs)
53
+ ref_data[:occurrences] ||= []
54
+ new_resolved_refs.leaves do |leaf|
55
+ ref_data[:occurrences].concat(leaf.data[:occurrences] || [])
56
+ end
57
+ ref_data[:occurrences].sort_by!(&:path)
58
+ ref_data[:occurrences].uniq!
59
+ end
60
+
61
+ # @param [I18n::Tasks::Data::Tree::Node] ref
62
+ # @param [I18n::Tasks::Data::Tree::Node] usage
63
+ # @param [I18n::Tasks::Data::Tree::Siblings] raw_refs
64
+ # @param [I18n::Tasks::Data::Tree::Siblings] resolved_refs
65
+ # @param [I18n::Tasks::Data::Tree::Siblings] refs
66
+ def process_non_leaf!(ref, usage, raw_refs, resolved_refs, refs)
67
+ child_raw_refs, child_resolved_refs, child_refs = process_references(usage.children, ref.children)
68
+ raw_refs.merge_node! Data::Tree::Node.new(key: ref.key, children: child_raw_refs) unless child_raw_refs.empty?
69
+ resolved_refs.merge! child_resolved_refs
70
+ refs.merge_node! Data::Tree::Node.new(key: ref.key, children: child_refs) unless child_refs.empty?
71
+ end
72
+
49
73
  # Given a forest of references, merge trees into one tree, ensuring there are no conflicting references.
50
- # @param roots [Data::Tree::Siblings]
51
- # @return [Data::Tree::Siblings]
74
+ # @param roots [I18n::Tasks::Data::Tree::Siblings]
75
+ # @return [I18n::Tasks::Data::Tree::Siblings]
52
76
  def merge_reference_trees(roots)
53
77
  roots.inject(empty_forest) do |forest, root|
54
- root.keys { |full_key, node|
55
- log_warn(
78
+ root.keys do |full_key, node|
79
+ if full_key == node.value.to_s
80
+ log_warn(
56
81
  "Self-referencing key #{node.full_key(root: false).inspect} in #{node.data[:locale].inspect}"
57
- ) if full_key == node.value.to_s
58
- }
82
+ )
83
+ end
84
+ end
59
85
  forest.merge!(
60
- root.children,
61
- on_leaves_merge: -> (node, other) {
86
+ root.children,
87
+ on_leaves_merge: lambda do |node, other|
88
+ if node.value != other.value
62
89
  log_warn(
63
- "Conflicting references: #{node.full_key(root: false)} ⮕ #{node.value} in #{node.data[:locale]}, but ⮕ #{other.value} in #{other.data[:locale]}"
64
- ) if node.value != other.value
65
- })
90
+ 'Conflicting references: '\
91
+ "#{node.full_key(root: false)} #{node.value} in #{node.data[:locale]},"\
92
+ " but ⮕ #{other.value} in #{other.data[:locale]}"
93
+ )
94
+ end
95
+ end
96
+ )
66
97
  end
67
98
  end
68
99
  end
@@ -30,24 +30,25 @@ module I18n::Tasks::Reports
30
30
 
31
31
  def used_title(keys_nodes, filter)
32
32
  used_n = keys_nodes.map { |_k, node| node.data[:occurrences].size }.reduce(:+).to_i
33
- "#{keys_nodes.size} key#{'s' if keys_nodes.size != 1}#{" matching '#{filter}'" if filter}#{" (#{used_n} usage#{'s' if used_n != 1})" if used_n > 0}"
33
+ "#{keys_nodes.size} key#{'s' if keys_nodes.size != 1}#{" matching '#{filter}'" if filter}"\
34
+ "#{" (#{used_n} usage#{'s' if used_n != 1})" if used_n > 0}"
34
35
  end
35
36
 
36
37
  # Sort keys by their attributes in order
37
38
  # @param [Hash] order e.g. {locale: :asc, type: :desc, key: :asc}
38
- def sort_by_attr!(objects, order = {locale: :asc, key: :asc})
39
+ def sort_by_attr!(objects, order = { locale: :asc, key: :asc })
39
40
  order_keys = order.keys
40
- objects.sort! { |a, b|
41
+ objects.sort! do |a, b|
41
42
  by = order_keys.detect { |k| a[k] != b[k] }
42
43
  order[by] == :desc ? b[by] <=> a[by] : a[by] <=> b[by]
43
- }
44
+ end
44
45
  objects
45
46
  end
46
47
 
47
48
  def forest_to_attr(forest)
48
- forest.keys(root: false).map { |key, node|
49
- {key: key, value: node.value, type: node.data[:type], locale: node.root.key, data: node.data}
50
- }
49
+ forest.keys(root: false).map do |key, node|
50
+ { key: key, value: node.value, type: node.data[:type], locale: node.root.key, data: node.data }
51
+ end
51
52
  end
52
53
 
53
54
  def format_locale(locale)
@@ -4,8 +4,7 @@ require 'fileutils'
4
4
 
5
5
  module I18n::Tasks::Reports
6
6
  class Spreadsheet < Base
7
-
8
- def save_report(path, opts)
7
+ def save_report(path, _opts)
9
8
  path = path.presence || 'tmp/i18n-report.xlsx'
10
9
  p = Axlsx::Package.new
11
10
  p.use_shared_strings = true # see #159
@@ -19,22 +18,24 @@ module I18n::Tasks::Reports
19
18
 
20
19
  private
21
20
 
22
- def add_missing_sheet(wb)
21
+ def add_missing_sheet(wb) # rubocop:disable Metrics/AbcSize
23
22
  forest = collapse_missing_tree! task.missing_keys
24
23
  wb.styles do |s|
25
- type_cell = s.add_style :alignment => {:horizontal => :center}
26
- locale_cell = s.add_style :alignment => {:horizontal => :center}
24
+ type_cell = s.add_style alignment: { horizontal: :center }
25
+ locale_cell = s.add_style alignment: { horizontal: :center }
27
26
  regular_style = s.add_style
28
- wb.add_worksheet(name: missing_title(forest)) { |sheet|
29
- sheet.page_setup.fit_to :width => 1
30
- sheet.add_row [I18n.t('i18n_tasks.common.type'), I18n.t('i18n_tasks.common.locale'), I18n.t('i18n_tasks.common.key'), I18n.t('i18n_tasks.common.base_value')]
27
+ wb.add_worksheet(name: missing_title(forest)) do |sheet|
28
+ sheet.page_setup.fit_to width: 1
29
+ sheet.add_row [I18n.t('i18n_tasks.common.type'), I18n.t('i18n_tasks.common.locale'),
30
+ I18n.t('i18n_tasks.common.key'), I18n.t('i18n_tasks.common.base_value')]
31
31
  style_header sheet
32
32
  forest.keys do |key, node|
33
- locale, type = format_locale(node.root.data[:locale]), node.data[:type]
33
+ locale = format_locale(node.root.data[:locale])
34
+ type = node.data[:type]
34
35
  sheet.add_row [missing_type_info(type)[:summary], locale, key, task.t(key)],
35
- styles: [type_cell, locale_cell, regular_style, regular_style]
36
+ styles: [type_cell, locale_cell, regular_style, regular_style]
36
37
  end
37
- }
38
+ end
38
39
  end
39
40
  end
40
41
 
@@ -48,11 +49,10 @@ module I18n::Tasks::Reports
48
49
  add_locale_key_value_table wb, keys, name: unused_title(keys)
49
50
  end
50
51
 
51
- private
52
-
53
52
  def add_locale_key_value_table(wb, keys, worksheet_opts = {})
54
53
  wb.add_worksheet worksheet_opts do |sheet|
55
- sheet.add_row [I18n.t('i18n_tasks.common.locale'), I18n.t('i18n_tasks.common.key'), I18n.t('i18n_tasks.common.value')]
54
+ sheet.add_row [I18n.t('i18n_tasks.common.locale'), I18n.t('i18n_tasks.common.key'),
55
+ I18n.t('i18n_tasks.common.value')]
56
56
  style_header sheet
57
57
  keys.each do |locale_k_v|
58
58
  sheet.add_row locale_k_v
@@ -60,9 +60,8 @@ module I18n::Tasks::Reports
60
60
  end
61
61
  end
62
62
 
63
-
64
63
  def style_header(sheet)
65
- border_bottom = sheet.workbook.styles.add_style(border: {style: :thin, color: '000000', edges: [:bottom]})
64
+ border_bottom = sheet.workbook.styles.add_style(border: { style: :thin, color: '000000', edges: [:bottom] })
66
65
  sheet.rows.first.style = border_bottom
67
66
  end
68
67
  end
@@ -4,7 +4,7 @@ require 'terminal-table'
4
4
  module I18n
5
5
  module Tasks
6
6
  module Reports
7
- class Terminal < Base
7
+ class Terminal < Base # rubocop:disable Metrics/ClassLength
8
8
  include Term::ANSIColor
9
9
 
10
10
  def missing_keys(forest = task.missing_keys)
@@ -12,10 +12,10 @@ module I18n
12
12
  if forest.present?
13
13
  print_title missing_title(forest)
14
14
  print_table headings: [cyan(bold(I18n.t('i18n_tasks.common.locale'))),
15
- cyan(bold I18n.t('i18n_tasks.common.key')),
15
+ cyan(bold(I18n.t('i18n_tasks.common.key'))),
16
16
  I18n.t('i18n_tasks.missing.details_title')] do |t|
17
17
  t.rows = sort_by_attr!(forest_to_attr(forest)).map do |a|
18
- [{value: cyan(format_locale(a[:locale])), alignment: :center},
18
+ [{ value: cyan(format_locale(a[:locale])), alignment: :center },
19
19
  format_key(a[:key], a[:data]),
20
20
  missing_key_info(a)]
21
21
  end
@@ -27,14 +27,14 @@ module I18n
27
27
 
28
28
  def icon(type)
29
29
  glyph = missing_type_info(type)[:glyph]
30
- {missing_used: red(glyph), missing_diff: yellow(glyph)}[type]
30
+ { missing_used: red(glyph), missing_diff: yellow(glyph) }[type]
31
31
  end
32
32
 
33
33
  def used_keys(used_tree = task.used_tree)
34
34
  # For the used tree we may have usage nodes that are not leaves as references.
35
- keys_nodes = used_tree.nodes.select { |node| !!node.data[:occurrences] }.map { |node|
35
+ keys_nodes = used_tree.nodes.select { |node| node.data[:occurrences].present? }.map do |node|
36
36
  [node.full_key(root: false), node]
37
- }
37
+ end
38
38
  print_title used_title(keys_nodes, used_tree.first.root.data[:key_filter])
39
39
  # Group multiple nodes
40
40
  if keys_nodes.present?
@@ -86,7 +86,8 @@ module I18n
86
86
  if leaf[:type] == :missing_used
87
87
  first_occurrence leaf
88
88
  else
89
- "#{cyan leaf[:data][:missing_diff_locale]} #{format_value(leaf[:value].is_a?(String) ? leaf[:value].strip : leaf[:value])}"
89
+ "#{cyan leaf[:data][:missing_diff_locale]} "\
90
+ "#{format_value(leaf[:value].is_a?(String) ? leaf[:value].strip : leaf[:value])}"
90
91
  end
91
92
  end
92
93
 
@@ -106,23 +107,22 @@ module I18n
106
107
  end
107
108
 
108
109
  def format_reference_desc(node_data)
109
- return nil unless node_data
110
- case node_data[:ref_type]
111
- when :reference_usage
112
- bold(yellow('(ref)'))
113
- when :reference_usage_resolved
114
- bold(yellow('(resolved ref)'))
115
- when :reference_usage_key
116
- bold(yellow('(ref key)'))
117
- end
110
+ return nil unless node_data
111
+ case node_data[:ref_type]
112
+ when :reference_usage
113
+ bold(yellow('(ref)'))
114
+ when :reference_usage_resolved
115
+ bold(yellow('(resolved ref)'))
116
+ when :reference_usage_key
117
+ bold(yellow('(ref key)'))
118
+ end
118
119
  end
119
120
 
120
121
  def print_occurrences(node, full_key = node.full_key)
121
122
  occurrences = node.data[:occurrences]
122
- puts [bold("#{full_key}"),
123
+ puts [bold(full_key.to_s),
123
124
  format_reference_desc(node.data),
124
- (green(occurrences.size.to_s) if occurrences.size > 1)
125
- ].compact.join ' '
125
+ (green(occurrences.size.to_s) if occurrences.size > 1)].compact.join ' '
126
126
  occurrences.each do |occurrence|
127
127
  puts " #{key_occurrence full_key, occurrence}"
128
128
  end
@@ -134,7 +134,7 @@ module I18n
134
134
  bold(cyan(I18n.t('i18n_tasks.common.key'))),
135
135
  I18n.t('i18n_tasks.common.value')] do |t|
136
136
  t.rows = locale_key_value_datas.map { |(locale, k, v, data)|
137
- [{value: cyan(locale), alignment: :center}, format_key(k, data), format_value(v)]
137
+ [{ value: cyan(locale), alignment: :center }, format_key(k, data), format_value(v)]
138
138
  }
139
139
  end
140
140
  else
@@ -143,15 +143,15 @@ module I18n
143
143
  end
144
144
 
145
145
  def print_title(title)
146
- log_stderr "#{bold title.strip} #{dark "|"} #{"i18n-tasks v#{I18n::Tasks::VERSION}"}"
146
+ log_stderr "#{bold title.strip} #{dark '|'} #{"i18n-tasks v#{I18n::Tasks::VERSION}"}"
147
147
  end
148
148
 
149
149
  def print_success(message)
150
- log_stderr bold(green "✓ #{I18n.t('i18n_tasks.cmd.encourage').sample} #{message}")
150
+ log_stderr bold(green("✓ #{I18n.t('i18n_tasks.cmd.encourage').sample} #{message}"))
151
151
  end
152
152
 
153
153
  def print_error(message)
154
- log_stderr(bold red message)
154
+ log_stderr(bold(red(message)))
155
155
  end
156
156
 
157
157
  def print_info(message)
@@ -159,8 +159,7 @@ module I18n
159
159
  end
160
160
 
161
161
  def indent(txt, n = 2)
162
- spaces = ' ' * n
163
- txt.gsub /^/, spaces
162
+ txt.gsub(/^/, ' ' * n)
164
163
  end
165
164
 
166
165
  def print_table(opts, &block)
@@ -177,18 +176,19 @@ module I18n
177
176
  # @type [I18n::Tasks::Scanners::KeyOccurrences]
178
177
  occurrences = leaf[:data][:occurrences]
179
178
  # @type [I18n::Tasks::Scanners::Occurrence]
180
- first = occurrences.first
181
- [green("#{first.path}:#{first.line_num}"),
182
- ("(#{I18n.t 'i18n_tasks.common.n_more', count: occurrences.length - 1})" if occurrences.length > 1)
179
+ first = occurrences.first
180
+ [
181
+ green("#{first.path}:#{first.line_num}"),
182
+ ("(#{I18n.t 'i18n_tasks.common.n_more', count: occurrences.length - 1})" if occurrences.length > 1)
183
183
  ].compact.join(' ')
184
184
  end
185
185
 
186
186
  def highlight_key(full_key, line, range = (0..-1))
187
- line.dup.tap { |s|
188
- s[range] = s[range].sub(full_key) { |m|
187
+ line.dup.tap do |s|
188
+ s[range] = s[range].sub(full_key) do |m|
189
189
  highlight_string m
190
- }
191
- }
190
+ end
191
+ end
192
192
  end
193
193
 
194
194
  module HighlightUnderline
@@ -12,7 +12,8 @@ module I18n::Tasks::Scanners
12
12
  def initialize(
13
13
  config: {},
14
14
  file_finder_provider: Files::CachingFileFinderProvider.new,
15
- file_reader: Files::CachingFileReader.new)
15
+ file_reader: Files::CachingFileReader.new
16
+ )
16
17
  @config = config
17
18
  @file_reader = file_reader
18
19
  @file_finder = file_finder_provider.get(**config.slice(:paths, :only, :exclude))
@@ -20,11 +21,11 @@ module I18n::Tasks::Scanners
20
21
 
21
22
  # @return (see Scanner#keys)
22
23
  def keys
23
- (traverse_files { |path|
24
+ (traverse_files do |path|
24
25
  scan_file(path)
25
- }.reduce(:+) || []).group_by(&:first).map { |key, keys_occurrences|
26
+ end.reduce(:+) || []).group_by(&:first).map do |key, keys_occurrences|
26
27
  Results::KeyOccurrences.new(key: key, occurrences: keys_occurrences.map(&:second))
27
- }
28
+ end
28
29
  end
29
30
 
30
31
  protected
@@ -32,7 +33,7 @@ module I18n::Tasks::Scanners
32
33
  # Extract all occurrences of translate calls from the file at the given path.
33
34
  #
34
35
  # @return [Array<[key, Results::KeyOccurrence]>] each occurrence found in the file
35
- def scan_file(path)
36
+ def scan_file(_path)
36
37
  fail 'Unimplemented'
37
38
  end
38
39