i18n-tasks 0.9.25 → 0.9.26

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c701c96d03c3226bb8c9a6e2bed8477c7846645ee384a93c569c090cfe9b76ae
4
- data.tar.gz: 5209c23392064c0d0a15cc61f2a82d0a08294e58afd7b1466b433295ae861e98
3
+ metadata.gz: c5c06b9d6d4187eda97fce4acb55c31c8c01534814e8770ed64d3f0f052dbb26
4
+ data.tar.gz: ec0198e22e8c9b55fd87f386467cb94400a400263405efc42fc5d3696c610e21
5
5
  SHA512:
6
- metadata.gz: 4a573608dff03c12f15920a84ed5c01d2377c593e43ed1cf27c0f9a1951b75fa4211be678b1ad150df7a129365f09a77e398c45d6260c87213f62985dbad58d9
7
- data.tar.gz: 9bf7f845ef28e04b87bbbdc9b0e293ef7187b808ce7a7b690434441a725d6b61ef74759f77e26d5df756d49220f04ff6d0a716581cda040979c41d2d1d374b4c
6
+ metadata.gz: 89296743377a8207fa571d82c23c1ec36e71b8209f2f949cf8d541ea0ef4db87b1f69e5c28796ee6ebeeddad1c352a2d1b2f14bf685593e828c715dc74a24b18
7
+ data.tar.gz: b66aaea9115ee5015e9696d562666dbcfeae6f770f4e8558e59257557e9d138249639bdf6a9b9e73ee1acadb88b1ae386f0d1dde1e7b655ff816f15e0a229fc9
data/README.md CHANGED
@@ -22,7 +22,7 @@ i18n-tasks can be used with any project using the ruby [i18n gem][i18n-gem] (def
22
22
  Add i18n-tasks to the Gemfile:
23
23
 
24
24
  ```ruby
25
- gem 'i18n-tasks', '~> 0.9.25'
25
+ gem 'i18n-tasks', '~> 0.9.26'
26
26
  ```
27
27
 
28
28
  Copy the default [configuration file](#configuration):
@@ -33,6 +33,7 @@ en:
33
33
  %{value_or_default_or_human_key}
34
34
  desc:
35
35
  add_missing: add missing keys to locale data
36
+ check_consistent_interpolations: verify that all translations use correct interpolation variables
36
37
  check_normalized: verify that all translation data is normalized
37
38
  config: display i18n-tasks configuration
38
39
  data: show locale data
@@ -102,6 +103,8 @@ en:
102
103
  Google Translate returned no results. Make sure billing information is set at https://code.google.com/apis/console.
103
104
  health:
104
105
  no_keys_detected: No keys detected. Check data.read in config/i18n-tasks.yml.
106
+ inconsistent_interpolations:
107
+ none: No inconsistent interpolations found.
105
108
  missing:
106
109
  details_title: Value in other locales or source
107
110
  none: No translations are missing.
@@ -9,7 +9,7 @@ ru:
9
9
  desc:
10
10
  all_locales: Не ожидать, что маски ключа начинаются с локали. Применять маски ко всем локалям.
11
11
  confirm: Подтвердить автоматом
12
- data_format: 'Формат данных: %{valid_text}. %{default_text}.'
12
+ data_format: 'Формат данных: %{valid_text}.'
13
13
  keep_order: Keep the order of the keys
14
14
  key_pattern: Маска ключа (например, common.*)
15
15
  key_pattern_to_rename: Полный ключ (шаблон) для переименования. Необходимый параметр.
@@ -21,7 +21,7 @@ ru:
21
21
  missing_types: 'Типы недостающих переводов: %{valid}. По умолчанию: все'
22
22
  new_key_name: Новое имя, интерполирует оригинальное название как %{key}. Необходимый параметр.
23
23
  nostdin: Не читать дерево из стандартного ввода
24
- out_format: 'Формат вывода: %{valid_text}. %{default_text}.'
24
+ out_format: 'Формат вывода: %{valid_text}.'
25
25
  pattern_router: 'Использовать pattern_router: ключи распределятся по файлам согласно data.write'
26
26
  strict: Не угадывать динамические использования ключей, например `t("category.#{category.key}")`
27
27
  translation_backend: Движок перевода (google или deepl)
@@ -30,6 +30,8 @@ ru:
30
30
  %{value_or_default_or_human_key}
31
31
  desc:
32
32
  add_missing: добавить недостающие ключи к переводам
33
+ check_consistent_interpolations: убедитесь, что во всех переводах используются правильные
34
+ интерполяционные переменные
33
35
  check_normalized: проверить, что все файлы переводов нормализованы
34
36
  config: показать конфигурацию
35
37
  data: показать данные переводов
@@ -99,12 +101,14 @@ ru:
99
101
  в https://code.google.com/apis/console.
100
102
  health:
101
103
  no_keys_detected: Ключи не обнаружены. Проверьте data.read в config/i18n-tasks.yml.
104
+ inconsistent_interpolations:
105
+ none: Не найдено несогласованных интерполяций.
102
106
  missing:
103
107
  details_title: На других языках или в коде
104
108
  none: Всё переведено.
105
109
  remove_unused:
106
110
  confirm:
107
- one: Один перевод будут удалён из %{locales}.
111
+ one: "%{count} перевод будут удалён из %{locales}."
108
112
  other: Переводы (%{count}) будут удалены из %{locales}.
109
113
  noop: Нет неиспользуемых ключей
110
114
  removed: Удалены ключи (%{count})
@@ -10,6 +10,7 @@ require 'i18n/tasks/html_keys'
10
10
  require 'i18n/tasks/used_keys'
11
11
  require 'i18n/tasks/ignore_keys'
12
12
  require 'i18n/tasks/missing_keys'
13
+ require 'i18n/tasks/interpolations'
13
14
  require 'i18n/tasks/unused_keys'
14
15
  require 'i18n/tasks/translation'
15
16
  require 'i18n/tasks/locale_pathname'
@@ -30,6 +31,7 @@ module I18n
30
31
  include UsedKeys
31
32
  include IgnoreKeys
32
33
  include MissingKeys
34
+ include Interpolations
33
35
  include UnusedKeys
34
36
  include Translation
35
37
  include Logging
@@ -12,7 +12,9 @@ module I18n::Tasks
12
12
  args: %i[locales out_format]
13
13
 
14
14
  def eq_base(opt = {})
15
- print_forest i18n.eq_base_keys(opt), opt, :eq_base_keys
15
+ forest = i18n.eq_base_keys(opt)
16
+ print_forest forest, opt, :eq_base_keys
17
+ :exit_1 unless forest.empty?
16
18
  end
17
19
  end
18
20
  end
@@ -16,7 +16,12 @@ module I18n::Tasks
16
16
  stats = i18n.forest_stats(forest)
17
17
  fail CommandError, t('i18n_tasks.health.no_keys_detected') if stats[:key_count].zero?
18
18
  terminal_report.forest_stats forest, stats
19
- [missing(opt), unused(opt), check_normalized(opt)].detect { |result| result == :exit_1 }
19
+ [
20
+ missing(opt),
21
+ unused(opt),
22
+ check_consistent_interpolations(opt),
23
+ check_normalized(opt)
24
+ ].detect { |result| result == :exit_1 }
20
25
  end
21
26
  end
22
27
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module I18n::Tasks
4
+ module Command
5
+ module Commands
6
+ module Interpolations
7
+ include Command::Collection
8
+
9
+ cmd :check_consistent_interpolations,
10
+ pos: '[locale ...]',
11
+ desc: t('i18n_tasks.cmd.desc.check_consistent_interpolations'),
12
+ args: %i[locales out_format]
13
+
14
+ def check_consistent_interpolations(opt = {})
15
+ forest = i18n.inconsistent_interpolations(opt.slice(:locales, :base_locale))
16
+ print_forest forest, opt, :inconsistent_interpolations
17
+ :exit_1 unless forest.empty?
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -5,6 +5,7 @@ require 'i18n/tasks/command/collection'
5
5
  require 'i18n/tasks/command/commands/health'
6
6
  require 'i18n/tasks/command/commands/missing'
7
7
  require 'i18n/tasks/command/commands/usages'
8
+ require 'i18n/tasks/command/commands/interpolations'
8
9
  require 'i18n/tasks/command/commands/eq_base'
9
10
  require 'i18n/tasks/command/commands/data'
10
11
  require 'i18n/tasks/command/commands/tree'
@@ -17,6 +18,7 @@ module I18n::Tasks
17
18
  include Command::Commands::Health
18
19
  include Command::Commands::Missing
19
20
  include Command::Commands::Usages
21
+ include Command::Commands::Interpolations
20
22
  include Command::Commands::EqBase
21
23
  include Command::Commands::Data
22
24
  include Command::Commands::Tree
@@ -18,10 +18,42 @@ module I18n::Tasks::Concurrent
18
18
 
19
19
  # @return [Object] Result of the computation.
20
20
  def get
21
- return @result unless @result == NULL
21
+ return get_result_volatile unless get_result_volatile == NULL
22
22
  @mutex.synchronize do
23
- @result = @computation.call
23
+ next unless get_result_volatile == NULL
24
+ set_result_volatile @computation.call
25
+ @computation = nil
24
26
  end
27
+ get_result_volatile
25
28
  end
29
+
30
+ private
31
+
32
+ # Ruby instance variable volatility is currently unspecified:
33
+ # https://bugs.ruby-lang.org/issues/11539
34
+ #
35
+ # Below are the implementations for major ruby engines, based on concurrent-ruby.
36
+ # rubocop:disable Lint/DuplicateMethods,Naming/AccessorMethodName
37
+ case RUBY_ENGINE
38
+ when 'rbx'
39
+ def get_result_volatile
40
+ Rubinius.memory_barrier
41
+ @result
42
+ end
43
+
44
+ def set_result_volatile(value)
45
+ @result = value
46
+ Rubinius.memory_barrier
47
+ end
48
+ else
49
+ def get_result_volatile
50
+ @result
51
+ end
52
+
53
+ def set_result_volatile(value)
54
+ @result = value
55
+ end
56
+ end
57
+ # rubocop:enable Lint/DuplicateMethods,Naming/AccessorMethodName
26
58
  end
27
59
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module I18n::Tasks
4
+ module Interpolations
5
+ VARIABLE_REGEX = /%{[^}]+}/
6
+
7
+ def inconsistent_interpolations(locales: nil, base_locale: nil) # rubocop:disable Metrics/AbcSize
8
+ locales ||= self.locales
9
+ base_locale ||= self.base_locale
10
+ result = empty_forest
11
+
12
+ data[base_locale].key_values.each do |key, value|
13
+ next if !value.is_a?(String) || ignore_key?(key, :inconsistent_interpolations)
14
+ base_vars = Set.new(value.scan(VARIABLE_REGEX))
15
+ (locales - [base_locale]).each do |current_locale|
16
+ node = data[current_locale].first.children[key]
17
+ next unless node&.value&.is_a?(String)
18
+ vars = node.value.scan(VARIABLE_REGEX)
19
+ unless vars.size == base_vars.size && vars.all? { |v| base_vars.include?(v) }
20
+ result.merge!(node.walk_to_root.reduce(nil) { |c, p| [p.derive(children: c)] })
21
+ end
22
+ end
23
+ end
24
+
25
+ result.each { |root| root.data[:type] = :inconsistent_interpolations }
26
+ result
27
+ end
28
+ end
29
+ end
@@ -21,6 +21,10 @@ module I18n::Tasks::Reports
21
21
  "Missing translations (#{forest.leaves.count || '∅'})"
22
22
  end
23
23
 
24
+ def inconsistent_interpolations_title(forest)
25
+ "Inconsistent interpolations (#{forest.leaves.count || '∅'})"
26
+ end
27
+
24
28
  def unused_title(key_values)
25
29
  "Unused keys (#{key_values.count || '∅'})"
26
30
  end
@@ -25,6 +25,15 @@ module I18n
25
25
  end
26
26
  end
27
27
 
28
+ def inconsistent_interpolations(forest = task.inconsistent_interpolations)
29
+ if forest.present?
30
+ print_title inconsistent_interpolations_title(forest)
31
+ show_tree(forest)
32
+ else
33
+ print_success I18n.t('i18n_tasks.inconsistent_interpolations.none')
34
+ end
35
+ end
36
+
28
37
  def icon(type)
29
38
  glyph = missing_type_info(type)[:glyph]
30
39
  { missing_used: Rainbow(glyph).red, missing_diff: Rainbow(glyph).yellow }[type]
@@ -61,7 +61,7 @@ module I18n::Tasks::Translators
61
61
 
62
62
  def configure_api_key!
63
63
  api_key = @i18n_tasks.translation_config[:deepl_api_key]
64
- fail CommandError, I18n.t('i18n_tasks.deepl_translate.errors.no_api_key') if api_key.blank?
64
+ fail ::I18n::Tasks::CommandError, I18n.t('i18n_tasks.deepl_translate.errors.no_api_key') if api_key.blank?
65
65
  DeepL.configure { |config| config.auth_key = api_key }
66
66
  end
67
67
  end
@@ -59,7 +59,7 @@ module I18n::Tasks::Translators
59
59
  )
60
60
  key ||= translation_config[:api_key]
61
61
  end
62
- fail CommandError, I18n.t('i18n_tasks.google_translate.errors.no_api_key') if key.blank?
62
+ fail ::I18n::Tasks::CommandError, I18n.t('i18n_tasks.google_translate.errors.no_api_key') if key.blank?
63
63
  key
64
64
  end
65
65
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module I18n
4
4
  module Tasks
5
- VERSION = '0.9.25'
5
+ VERSION = '0.9.26'
6
6
  end
7
7
  end
@@ -111,6 +111,10 @@ search:
111
111
  # fr,es:
112
112
  # - common.brand
113
113
 
114
+ ## Exclude these keys from the `i18n-tasks check-consistent-interpolations` report:
115
+ # ignore_inconsistent_interpolations:
116
+ # - 'activerecord.attributes.*'
117
+
114
118
  ## Ignore these keys completely:
115
119
  # ignore:
116
120
  # - kaminari.*
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.25
4
+ version: 0.9.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-18 00:00:00.000000000 Z
11
+ date: 2018-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -282,6 +282,7 @@ files:
282
282
  - lib/i18n/tasks/command/commands/data.rb
283
283
  - lib/i18n/tasks/command/commands/eq_base.rb
284
284
  - lib/i18n/tasks/command/commands/health.rb
285
+ - lib/i18n/tasks/command/commands/interpolations.rb
285
286
  - lib/i18n/tasks/command/commands/meta.rb
286
287
  - lib/i18n/tasks/command/commands/missing.rb
287
288
  - lib/i18n/tasks/command/commands/tree.rb
@@ -312,6 +313,7 @@ files:
312
313
  - lib/i18n/tasks/data/tree/traversal.rb
313
314
  - lib/i18n/tasks/html_keys.rb
314
315
  - lib/i18n/tasks/ignore_keys.rb
316
+ - lib/i18n/tasks/interpolations.rb
315
317
  - lib/i18n/tasks/key_pattern_matching.rb
316
318
  - lib/i18n/tasks/locale_list.rb
317
319
  - lib/i18n/tasks/locale_pathname.rb