i18n-tasks 0.9.16 → 0.9.17

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: d0cac577152584d62e48767e77416aa559bed589
4
- data.tar.gz: 5b981968e66f977fd24c8d2d16fc840614d88146
3
+ metadata.gz: ebc184ed8233c7a409de36ee6fd654fa4830e2f2
4
+ data.tar.gz: c846f15fa5b8e278d4b0dab8b3ec021759b8f603
5
5
  SHA512:
6
- metadata.gz: '09b634136cd5a68aa0f37c5b272cf55bda9880181e68c173d1247acb5c629c825317b0aea9e64f5a09387e1ae4c87813d4988c930dfa07f0d088f616b6da165d'
7
- data.tar.gz: 78d5153233fd8050e9394761010fb11344bdfc84f0d2f6786a2d016026e1027938a3b625a686e004f988bb6551aad3ae677ea8584c7356a09f01266807903e48
6
+ metadata.gz: 558d0ee6c04e5630c48f1e1c206f37931a38c60da5ff3392042940c814bfdbbab94ca0a51840f0b963fcd6adab4c9b3e2d4b5d15ee764670a4b49cd444194242
7
+ data.tar.gz: 8b955b0dd45d4761a9fde64ef0baa81fa3725d51f72ce136ebbac95c0bedb88a0a8392b1029253d780bf60a33fbaf7c1beb801f6430a9311dbe4d4cfe2a6aa9d
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.16'
27
+ gem 'i18n-tasks', '~> 0.9.17'
28
28
  ```
29
29
 
30
30
  Copy the default [configuration file](#configuration):
@@ -39,13 +39,20 @@ Copy rspec test to test for missing and unused translations as part of the suite
39
39
  $ cp $(i18n-tasks gem-path)/templates/rspec/i18n_spec.rb spec/
40
40
  ```
41
41
 
42
+ Or for minitest:
43
+
44
+ ```console
45
+ $ cp $(i18n-tasks gem-path)/templates/minitest/i18n_test.rb test/
46
+ ```
47
+
42
48
  ## Usage
43
49
 
44
50
  Run `i18n-tasks` to get the list of all the tasks with short descriptions.
45
51
 
46
52
  ### Check health
47
53
 
48
- `i18n-tasks health` checks if any keys are missing or not used:
54
+ `i18n-tasks health` checks if any keys are missing or not used,
55
+ and that all the locale files are normalized (auto-formatted):
49
56
 
50
57
  ```console
51
58
  $ i18n-tasks health
@@ -29,6 +29,7 @@ en:
29
29
  %{value_or_default_or_human_key}
30
30
  desc:
31
31
  add_missing: add missing keys to locale data
32
+ check_normalized: verify that all translation data is normalized
32
33
  config: display i18n-tasks configuration
33
34
  data: show locale data
34
35
  data_merge: merge locale data with trees
@@ -27,6 +27,7 @@ ru:
27
27
  %{value_or_default_or_human_key}
28
28
  desc:
29
29
  add_missing: добавить недостающие ключи к переводам
30
+ check_normalized: проверить, что все файлы переводов нормализованы
30
31
  config: показать конфигурацию
31
32
  data: показать данные переводов
32
33
  data_merge: добавить дерево к переводам
data/i18n-tasks.gemspec CHANGED
@@ -38,7 +38,7 @@ TEXT
38
38
  s.add_dependency 'activesupport', '>= 4.0.2'
39
39
  s.add_dependency 'ast', '>= 2.1.0'
40
40
  s.add_dependency 'easy_translate', '>= 0.5.0'
41
- s.add_dependency 'erubis'
41
+ s.add_dependency 'erubi'
42
42
  s.add_dependency 'highline', '>= 1.7.3'
43
43
  s.add_dependency 'i18n'
44
44
  s.add_dependency 'parser', '>= 2.2.3.0'
data/lib/i18n/tasks.rb CHANGED
@@ -57,7 +57,7 @@ rescue LoadError => _e
57
57
  require 'active_support/core_ext/try'
58
58
  end
59
59
  require 'rainbow'
60
- require 'erubis'
60
+ require 'erubi'
61
61
 
62
62
  require 'i18n/tasks/version'
63
63
  require 'i18n/tasks/base_task'
@@ -17,7 +17,19 @@ module I18n::Tasks
17
17
  args: %i[locales pattern_router]
18
18
 
19
19
  def normalize(opt = {})
20
- i18n.normalize_store! opt[:locales], opt[:pattern_router]
20
+ i18n.normalize_store! locales: opt[:locales],
21
+ force_pattern_router: opt[:pattern_router]
22
+ end
23
+
24
+ cmd :check_normalized,
25
+ pos: '[locale ...]',
26
+ desc: t('i18n_tasks.cmd.desc.check_normalized'),
27
+ args: %i[locales]
28
+
29
+ def check_normalized(opt)
30
+ non_normalized = i18n.non_normalized_paths locales: opt[:locales]
31
+ terminal_report.check_normalized_results(non_normalized)
32
+ :exit_1 unless non_normalized.empty?
21
33
  end
22
34
 
23
35
  cmd :mv,
@@ -18,7 +18,7 @@ module I18n::Tasks
18
18
  fail CommandError, t('i18n_tasks.health.no_keys_detected')
19
19
  end
20
20
  terminal_report.forest_stats forest, stats
21
- [missing(opt), unused(opt)].detect { |result| result == :exit_1 }
21
+ [missing(opt), unused(opt), check_normalized(opt)].detect { |result| result == :exit_1 }
22
22
  end
23
23
  end
24
24
  end
@@ -21,7 +21,9 @@ module I18n::Tasks::Configuration # rubocop:disable Metrics/ModuleLength
21
21
 
22
22
  def file_config
23
23
  file = CONFIG_FILES.detect { |f| File.exist?(f) }
24
- config = file && YAML.load(Erubis::Eruby.new(File.read(file, encoding: 'UTF-8')).result)
24
+ # rubocop:disable Security/Eval
25
+ config = file && YAML.load(eval(Erubi::Engine.new(File.read(file, encoding: 'UTF-8')).src))
26
+ # rubocop:enable Security/Eval
25
27
  if config.present?
26
28
  config.with_indifferent_access.tap do |c|
27
29
  if c[:relative_roots]
@@ -59,16 +59,25 @@ module I18n::Tasks
59
59
  !t(key, locale).nil?
60
60
  end
61
61
 
62
- # write to store, normalizing all data
63
- def normalize_store!(from = nil, pattern_router = false)
64
- from = locales unless from
65
- router = pattern_router ? ::I18n::Tasks::Data::Router::PatternRouter.new(data, data.config) : data.router
62
+ # Normalize all the locale data in the store (by writing to the store).
63
+ #
64
+ # @param [Array<String>] locales locales to normalize. Default: all.
65
+ # @param [Boolean] force_pattern_router Whether to use pattern router regardless of the config.
66
+ def normalize_store!(locales: nil, force_pattern_router: false)
67
+ locales = self.locales unless locales
68
+ router = force_pattern_router ? ::I18n::Tasks::Data::Router::PatternRouter.new(data, data.config) : data.router
66
69
  data.with_router(router) do
67
- Array(from).each do |target_locale|
68
- # store handles normalization
70
+ Array(locales).each do |target_locale|
71
+ # The store handles actual normalization:
69
72
  data[target_locale] = data[target_locale]
70
73
  end
71
74
  end
72
75
  end
76
+
77
+ # @param [Array<String>] locales locales to check. Default: all.
78
+ # @return [Array<String>] paths to data that requires normalization
79
+ def non_normalized_paths(locales: nil)
80
+ Array(locales || self.locales).flat_map { |locale| data.non_normalized_paths(locale) }
81
+ end
73
82
  end
74
83
  end
@@ -14,6 +14,7 @@ module I18n
14
14
  adapter_op :dump, format, tree, write_config(format)
15
15
  end
16
16
 
17
+ # @return [Hash]
17
18
  def adapter_parse(tree, format)
18
19
  adapter_op :parse, format, tree, read_config(format)
19
20
  end
@@ -34,8 +35,14 @@ module I18n
34
35
  (config[format] || {})[:read]
35
36
  end
36
37
 
38
+ # @return [Hash]
37
39
  def load_file(path)
38
- adapter_parse ::File.read(path, encoding: 'UTF-8'), self.class.adapter_name_for_path(path)
40
+ adapter_parse read_file(path), self.class.adapter_name_for_path(path)
41
+ end
42
+
43
+ # @return [String]
44
+ def read_file(path)
45
+ ::File.read(path, encoding: 'UTF-8')
39
46
  end
40
47
 
41
48
  def write_tree(path, tree)
@@ -43,14 +50,16 @@ module I18n
43
50
  adapter = self.class.adapter_name_for_path(path)
44
51
  content = adapter_dump(hash, adapter)
45
52
  # Ignore unchanged data
46
- return if File.file?(path) &&
47
- # Comparing hashes for equality directly would ignore key order.
48
- # Round-trip through the adapter and compare the strings instead:
49
- content == adapter_dump(load_file(path), adapter)
53
+ return if File.file?(path) && content == read_file(path)
50
54
  ::FileUtils.mkpath(File.dirname(path))
51
55
  ::File.open(path, 'w') { |f| f.write content }
52
56
  end
53
57
 
58
+ def normalized?(path, tree)
59
+ return false unless File.file?(path)
60
+ read_file(path) == adapter_dump(tree.to_hash(true), self.class.adapter_name_for_path(path))
61
+ end
62
+
54
63
  module ClassMethods
55
64
  # @param pattern [String] File.fnmatch pattern
56
65
  # @param adapter [responds to parse(string)->hash and dump(hash)->string]
@@ -53,6 +53,14 @@ module I18n::Tasks
53
53
  @available_locales = nil
54
54
  end
55
55
 
56
+ # @param [String] locale
57
+ # @return [Array<String>] paths to files that are not normalized
58
+ def non_normalized_paths(locale)
59
+ router.route(locale, get(locale))
60
+ .reject { |path, tree_slice| normalized?(path, tree_slice) }
61
+ .map(&:first)
62
+ end
63
+
56
64
  def write(forest)
57
65
  forest.each { |root| set(root.key, root) }
58
66
  end
@@ -90,6 +90,16 @@ module I18n
90
90
  end
91
91
  end
92
92
 
93
+ def check_normalized_results(non_normalized)
94
+ if non_normalized.empty?
95
+ print_success 'All data is normalized'
96
+ return
97
+ end
98
+ log_stderr Rainbow('The following data requires normalization:').yellow
99
+ puts non_normalized
100
+ log_stderr Rainbow('Run `i18n-tasks normalize` to fix').yellow
101
+ end
102
+
93
103
  private
94
104
 
95
105
  def missing_key_info(leaf)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module I18n
4
4
  module Tasks
5
- VERSION = '0.9.16'
5
+ VERSION = '0.9.17'
6
6
  end
7
7
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'i18n/tasks'
4
+
5
+ class I18nTest < ActiveSupport::TestCase
6
+ def setup
7
+ @i18n = I18n::Tasks::BaseTask.new
8
+ @missing_keys = @i18n.missing_keys
9
+ @unused_keys = @i18n.unused_keys
10
+ end
11
+
12
+ def test_no_missing_keys
13
+ assert_empty @missing_keys,
14
+ "Missing #{@missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them"
15
+ end
16
+
17
+ def test_no_unused_keys
18
+ assert_empty @unused_keys,
19
+ "#{@unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
20
+ end
21
+
22
+ def test_files_are_normalized
23
+ non_normalized = @i18n.non_normalized_paths
24
+ error_message = "The following files need to be normalized:\n" \
25
+ "#{non_normalized.map { |path| " #{path}" }.join("\n")}\n" \
26
+ 'Please run `i18n-tasks normalize` to fix'
27
+ assert_empty non_normalized, error_message
28
+ end
29
+ end
@@ -16,4 +16,12 @@ RSpec.describe 'I18n' do
16
16
  expect(unused_keys).to be_empty,
17
17
  "#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
18
18
  end
19
+
20
+ it 'files are normalized' do
21
+ non_normalized = i18n.non_normalized_paths
22
+ error_message = "The following files need to be normalized:\n" \
23
+ "#{non_normalized.map { |path| " #{path}" }.join("\n")}\n" \
24
+ 'Please run `i18n-tasks normalize` to fix'
25
+ expect(non_normalized).to be_empty, error_message
26
+ end
19
27
  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.16
4
+ version: 0.9.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-21 00:00:00.000000000 Z
11
+ date: 2017-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.5.0
55
55
  - !ruby/object:Gem::Dependency
56
- name: erubis
56
+ name: erubi
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -328,6 +328,7 @@ files:
328
328
  - lib/i18n/tasks/used_keys.rb
329
329
  - lib/i18n/tasks/version.rb
330
330
  - templates/config/i18n-tasks.yml
331
+ - templates/minitest/i18n_test.rb
331
332
  - templates/rspec/i18n_spec.rb
332
333
  homepage: https://github.com/glebm/i18n-tasks
333
334
  licenses: