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