i18n-tasks 0.9.25 → 0.9.26

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