i18n-tasks 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b5b15ad428fdc29cc404d033f363c08708f5b815
4
- data.tar.gz: c5aaaecace6c6024d544ff552c06097b9ec2f252
3
+ metadata.gz: 4807ae41e4ea2c7274b08bc55c2a2286a6e601d5
4
+ data.tar.gz: bdc921c3485e004c0e395a79afde8a5cfcfa888c
5
5
  SHA512:
6
- metadata.gz: 54586d8f4fb14861a755a75325ccf73230b9e180bc590f2f7fd383dc6c10c3529943179709d1d8045873148530684625c92a53d9b997281b9078acac51c40699
7
- data.tar.gz: 693ff45562b53f09a0c5baf81b0d5418227e35d182f81e51cdff99c740b2a4666c39bbf3ea84f9d64daafb5ce34b454a59410b3c73a03fadf35c3b9ee98244bb
6
+ metadata.gz: 3b58817464f4c4878f822606dda7ae226b33f53b6542b938a272864d1d4a92806a72d81f4d16571e8176e04687784861a7c541f1ac0e92b6ce055ed46a93b8da
7
+ data.tar.gz: 276c9a94d0575d383ea163a8e20d56b26248cf0c16da4caa2efd53f7530ed4632f3f264e9dcf747013db063cd19c984cd218cb60829ace938f79b6c97db7130f
data/README.md CHANGED
@@ -24,7 +24,7 @@ i18n-tasks can be used with any project using the ruby [i18n gem][i18n-gem] (def
24
24
  Add i18n-tasks to the Gemfile:
25
25
 
26
26
  ```ruby
27
- gem 'i18n-tasks', '~> 0.9.3'
27
+ gem 'i18n-tasks', '~> 0.9.4'
28
28
  ```
29
29
 
30
30
  Copy the default [configuration file](#configuration):
@@ -13,7 +13,7 @@ en:
13
13
  data_format: 'Data format: %{valid_text}.'
14
14
  key_pattern: Filter by key pattern (e.g. 'common.*')
15
15
  key_pattern_to_rename: Full key (pattern) to rename. Required
16
- locale: Locale
16
+ locale: :i18n_tasks.common.locale
17
17
  locale_to_translate_from: Locale to translate from
18
18
  locales_filter: 'Locale(s) to process. Special: base'
19
19
  missing_types: 'Filter by types: %{valid}'
@@ -159,12 +159,20 @@ module I18n::Tasks::Data::Tree
159
159
  Term::ANSIColor.dark '∅'
160
160
  else
161
161
  [Term::ANSIColor.color(1 + level % 15, key),
162
- (": #{Term::ANSIColor.cyan(value.to_s)}" if leaf?),
162
+ (": #{format_value_for_inspect(value)}" if leaf?),
163
163
  (" #{data}" if data?)].compact.join
164
164
  end
165
165
  [' ' * level, label, ("\n" + children.map { |c| c.inspect(level + 1) }.join("\n") if children?)].compact.join
166
166
  end
167
167
 
168
+ def format_value_for_inspect(value)
169
+ if value.is_a?(Symbol)
170
+ "#{Term::ANSIColor.bold(Term::ANSIColor.yellow '⮕ ')}#{Term::ANSIColor.yellow value.to_s}"
171
+ else
172
+ Term::ANSIColor.cyan(value.to_s)
173
+ end
174
+ end
175
+
168
176
  protected
169
177
 
170
178
  def dirty!
@@ -123,21 +123,11 @@ module I18n::Tasks::Data::Tree
123
123
  end
124
124
 
125
125
  def subtract_keys(keys)
126
- to_remove = Set.new
127
- keys.each do |full_key|
128
- node = get full_key
129
- to_remove << node if node
130
- end
131
- remove_nodes_collapsing_emptied_ancestors to_remove
126
+ remove_nodes_and_emptied_ancestors(keys.inject(Set.new) { |set, key| (node = get(key)) ? set << node : set })
132
127
  end
133
128
 
134
129
  def subtract_keys!(keys)
135
- to_remove = Set.new
136
- keys.each do |full_key|
137
- node = get full_key
138
- to_remove << node if node
139
- end
140
- remove_nodes_collapsing_emptied_ancestors! to_remove
130
+ remove_nodes_and_emptied_ancestors!(keys.inject(Set.new) { |set, key| (node = get(key)) ? set << node : set })
141
131
  end
142
132
 
143
133
  def subtract_by_key(other)
@@ -179,19 +169,20 @@ module I18n::Tasks::Data::Tree
179
169
  end
180
170
 
181
171
  # @param nodes [Enumerable] Modified in-place.
182
- def remove_nodes_collapsing_emptied_ancestors(nodes)
172
+ def remove_nodes_and_emptied_ancestors(nodes)
183
173
  add_ancestors_that_only_contain_nodes! nodes
184
174
  select_nodes { |node| !nodes.include?(node) }
185
175
  end
186
176
 
187
177
  # @param nodes [Enumerable] Modified in-place.
188
- def remove_nodes_collapsing_emptied_ancestors!(nodes)
178
+ def remove_nodes_and_emptied_ancestors!(nodes)
189
179
  add_ancestors_that_only_contain_nodes! nodes
190
180
  select_nodes! { |node| !nodes.include?(node) }
191
181
  end
192
182
 
193
183
  private
194
184
 
185
+ # Adds all the ancestors that only contain the given nodes as descendants to the given nodes.
195
186
  # @param nodes [Set] Modified in-place.
196
187
  def add_ancestors_that_only_contain_nodes!(nodes)
197
188
  levels.reverse_each do |level_nodes|
@@ -75,6 +75,12 @@ module I18n::Tasks
75
75
  result
76
76
  end
77
77
 
78
+ def root_key_value_data(sort = false)
79
+ result = keys(root: false).map { |key, node| [node.root.key, key, node.value, node.data] }
80
+ result.sort! { |a, b| a[0] != b[0] ? a[0] <=> b[0] : a[1] <=> b[1] } if sort
81
+ result
82
+ end
83
+
78
84
  #-- modify / derive
79
85
 
80
86
  # Select the nodes for which the block returns true. Pre-order traversal.
@@ -89,25 +89,28 @@ module I18n::Tasks
89
89
  end
90
90
 
91
91
  # @param [::I18n::Tasks::Data::Tree::Siblings] forest
92
- def collapse_missing_used_locales!(forest)
93
- locales_and_nodes_by_key = {}
94
- to_remove = []
92
+ # @yield [::I18n::Tasks::Data::Tree::Node]
93
+ # @yieldreturn [Boolean] whether to collapse the node
94
+ def collapse_same_key_in_locales!(forest)
95
+ locales_and_node_by_key = {}
96
+ to_remove = []
95
97
  forest.each do |root|
96
98
  locale = root.key
97
- root.leaves { |node|
98
- if node.data[:type] == :missing_used
99
- (locales_and_nodes_by_key[node.full_key(root: false)] ||= []) << [locale, node]
100
- to_remove << node
99
+ root.keys { |key, node|
100
+ next unless yield node
101
+ if locales_and_node_by_key.key?(key)
102
+ locales_and_node_by_key[key][0] << locale
103
+ else
104
+ locales_and_node_by_key[key] = [[locale], node]
101
105
  end
106
+ to_remove << node
102
107
  }
103
108
  end
104
- forest.remove_nodes_collapsing_emptied_ancestors! to_remove
105
- keys_and_nodes_by_locale = {}
106
- locales_and_nodes_by_key.each { |key, locales_and_nodes|
107
- locales = locales_and_nodes.map(&:first).sort.join('+')
108
- (keys_and_nodes_by_locale[locales] ||= []) << [key, locales_and_nodes[0][1]]
109
- }
110
- keys_and_nodes_by_locale.map { |locales, keys_nodes|
109
+ forest.remove_nodes_and_emptied_ancestors! to_remove
110
+ locales_and_node_by_key.inject({}) { |inv, (key, (locales, node))|
111
+ (inv[locales.sort.join('+')] ||= []) << [key, node]
112
+ inv
113
+ }.map { |locales, keys_nodes|
111
114
  keys_nodes.each { |(key, node)|
112
115
  forest["#{locales}.#{key}"] = node
113
116
  }
@@ -26,6 +26,7 @@ module I18n::Tasks
26
26
  else
27
27
  resolved_node.children = usage_node.children
28
28
  end
29
+ resolved_node.leaves { |node| node.data[:ref_info] = [ref_node.full_key, ref_node.value.to_s] }
29
30
  }.tap { |new_resolved_refs|
30
31
  refs.key_to_node[ref_node.key].data.tap { |ref_data|
31
32
  ref_data[:occurrences] ||= []
@@ -58,5 +58,11 @@ module I18n::Tasks::Reports
58
58
  locale.tr '+', ' '
59
59
  end
60
60
  end
61
+
62
+ def collapse_missing_tree!(forest)
63
+ forest = task.collapse_plural_nodes!(forest)
64
+ forest = task.collapse_same_key_in_locales!(forest) { |node| node.data[:type] == :missing_used }
65
+ forest
66
+ end
61
67
  end
62
68
  end
@@ -20,9 +20,7 @@ module I18n::Tasks::Reports
20
20
  private
21
21
 
22
22
  def add_missing_sheet(wb)
23
- forest = task.missing_keys
24
- forest = task.collapse_plural_nodes!(forest)
25
- forest = task.collapse_missing_used_locales!(forest)
23
+ forest = collapse_missing_tree! task.missing_keys
26
24
  wb.styles do |s|
27
25
  type_cell = s.add_style :alignment => {:horizontal => :center}
28
26
  locale_cell = s.add_style :alignment => {:horizontal => :center}
@@ -8,15 +8,16 @@ module I18n
8
8
  include Term::ANSIColor
9
9
 
10
10
  def missing_keys(forest = task.missing_keys)
11
- forest = task.collapse_plural_nodes!(forest)
12
- forest = task.collapse_missing_used_locales!(forest)
11
+ forest = collapse_missing_tree! forest
13
12
  if forest.present?
14
13
  print_title missing_title(forest)
15
14
  print_table headings: [cyan(bold(I18n.t('i18n_tasks.common.locale'))),
16
15
  cyan(bold I18n.t('i18n_tasks.common.key')),
17
16
  I18n.t('i18n_tasks.missing.details_title')] do |t|
18
17
  t.rows = sort_by_attr!(forest_to_attr(forest)).map do |a|
19
- [{value: cyan(format_locale(a[:locale])), alignment: :center}, cyan(a[:key]), missing_key_info(a)]
18
+ [{value: cyan(format_locale(a[:locale])), alignment: :center},
19
+ format_key(a[:key], a[:data]),
20
+ missing_key_info(a)]
20
21
  end
21
22
  end
22
23
  else
@@ -46,27 +47,27 @@ module I18n
46
47
  end
47
48
 
48
49
  def unused_keys(tree = task.unused_keys)
49
- keys = tree.root_key_values(true)
50
+ keys = tree.root_key_value_data(true)
50
51
  if keys.present?
51
52
  print_title unused_title(keys)
52
- print_locale_key_value_table keys
53
+ print_locale_key_value_data_table keys
53
54
  else
54
55
  print_success I18n.t('i18n_tasks.unused.none')
55
56
  end
56
57
  end
57
58
 
58
59
  def eq_base_keys(tree = task.eq_base_keys)
59
- keys = tree.root_key_values(true)
60
+ keys = tree.root_key_value_data(true)
60
61
  if keys.present?
61
62
  print_title eq_base_title(keys)
62
- print_locale_key_value_table keys
63
+ print_locale_key_value_data_table keys
63
64
  else
64
65
  print_info cyan('No translations are the same as base value')
65
66
  end
66
67
  end
67
68
 
68
69
  def show_tree(tree)
69
- print_locale_key_value_table tree.root_key_values(true)
70
+ print_locale_key_value_data_table tree.root_key_value_data(true)
70
71
  end
71
72
 
72
73
  def forest_stats(forest, stats = task.forest_stats(forest))
@@ -89,25 +90,37 @@ module I18n
89
90
  end
90
91
  end
91
92
 
93
+ def format_key(key, data)
94
+ if data[:ref_info]
95
+ from, to = data[:ref_info]
96
+ resolved = key[0...to.length]
97
+ after = key[to.length..-1]
98
+ " #{yellow from}#{cyan after}\n#{bold(yellow('⮕'))} #{bold yellow resolved}"
99
+ else
100
+ cyan(key)
101
+ end
102
+ end
103
+
92
104
  def format_value(val)
93
105
  val.is_a?(Symbol) ? "#{bold(yellow('⮕ '))}#{yellow(val.to_s)}" : val.to_s.strip
94
106
  end
95
107
 
96
- def format_reference_desc(node)
97
- case node.data[:type]
108
+ def format_reference_desc(node_data)
109
+ return nil unless node_data
110
+ case node_data[:ref_type]
98
111
  when :reference_usage
99
- bold(yellow('(reference)'))
112
+ bold(yellow('(ref)'))
100
113
  when :reference_usage_resolved
101
- bold(yellow('(resolved reference)'))
114
+ bold(yellow('(resolved ref)'))
102
115
  when :reference_usage_key
103
- bold(yellow('(reference key)'))
116
+ bold(yellow('(ref key)'))
104
117
  end
105
118
  end
106
119
 
107
120
  def print_occurrences(node, full_key = node.full_key)
108
121
  occurrences = node.data[:occurrences]
109
122
  puts [bold("#{full_key}"),
110
- format_reference_desc(node),
123
+ format_reference_desc(node.data),
111
124
  (green(occurrences.size.to_s) if occurrences.size > 1)
112
125
  ].compact.join ' '
113
126
  occurrences.each do |occurrence|
@@ -115,13 +128,13 @@ module I18n
115
128
  end
116
129
  end
117
130
 
118
- def print_locale_key_value_table(locale_key_values)
119
- if locale_key_values.present?
131
+ def print_locale_key_value_data_table(locale_key_value_datas)
132
+ if locale_key_value_datas.present?
120
133
  print_table headings: [bold(cyan(I18n.t('i18n_tasks.common.locale'))),
121
134
  bold(cyan(I18n.t('i18n_tasks.common.key'))),
122
135
  I18n.t('i18n_tasks.common.value')] do |t|
123
- t.rows = locale_key_values.map { |(locale, k, v)|
124
- [{value: cyan(locale), alignment: :center}, cyan(k), format_value(v)]
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)]
125
138
  }
126
139
  end
127
140
  else
@@ -12,9 +12,7 @@ module I18n
12
12
  # @param [String] locale
13
13
  # @param [Boolean] strict if true, do not match dynamic keys
14
14
  def unused_tree(locale: base_locale, strict: nil)
15
- used_key_names = used_tree(strict: true).keys.reject {|_key, node|
16
- node.data[:type] == :used_reference_key_raw
17
- }.map(&:first)
15
+ used_key_names = used_tree(strict: true).key_names
18
16
  collapse_plural_nodes! data[locale].select_keys { |key, _node|
19
17
  !ignore_key?(key, :unused) &&
20
18
  (strict || !used_in_expr?(key)) &&
@@ -30,14 +30,14 @@ module I18n::Tasks
30
30
  #
31
31
  # @param key_filter [String] only return keys matching this pattern.
32
32
  # @param strict [Boolean] if true, dynamic keys are excluded (e.g. `t("category.#{ category.key }")`)
33
+ # @param include_raw_references [Boolean] if true, includes reference usages as they appear in the source
33
34
  # @return [Data::Tree::Siblings]
34
35
  def used_tree(key_filter: nil, strict: nil, include_raw_references: false)
35
36
  src_tree = used_in_source_tree(key_filter: key_filter, strict: strict)
36
-
37
37
  raw_refs, resolved_refs, used_refs = process_references(src_tree['used'].children)
38
- raw_refs.leaves { |node| node.data[:type] = :reference_usage }
39
- resolved_refs.leaves { |node| node.data[:type] = :reference_usage_resolved }
40
- used_refs.leaves { |node| node.data[:type] = :reference_usage_key }
38
+ raw_refs.leaves { |node| node.data[:ref_type] = :reference_usage }
39
+ resolved_refs.leaves { |node| node.data[:ref_type] = :reference_usage_resolved }
40
+ used_refs.leaves { |node| node.data[:ref_type] = :reference_usage_key }
41
41
  src_tree.tap do |result|
42
42
  tree = result['used'].children
43
43
  tree.subtract_by_key!(raw_refs)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module I18n
3
3
  module Tasks
4
- VERSION = '0.9.3'
4
+ VERSION = '0.9.4'
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-04 00:00:00.000000000 Z
11
+ date: 2016-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport