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 +4 -4
- data/README.md +9 -2
- data/config/locales/en.yml +1 -0
- data/config/locales/ru.yml +1 -0
- data/i18n-tasks.gemspec +1 -1
- data/lib/i18n/tasks.rb +1 -1
- data/lib/i18n/tasks/command/commands/data.rb +13 -1
- data/lib/i18n/tasks/command/commands/health.rb +1 -1
- data/lib/i18n/tasks/configuration.rb +3 -1
- data/lib/i18n/tasks/data.rb +15 -6
- data/lib/i18n/tasks/data/file_formats.rb +14 -5
- data/lib/i18n/tasks/data/file_system_base.rb +8 -0
- data/lib/i18n/tasks/reports/terminal.rb +10 -0
- data/lib/i18n/tasks/version.rb +1 -1
- data/templates/minitest/i18n_test.rb +29 -0
- data/templates/rspec/i18n_spec.rb +8 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebc184ed8233c7a409de36ee6fd654fa4830e2f2
|
4
|
+
data.tar.gz: c846f15fa5b8e278d4b0dab8b3ec021759b8f603
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
data/config/locales/en.yml
CHANGED
@@ -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
|
data/config/locales/ru.yml
CHANGED
@@ -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 '
|
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
@@ -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],
|
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
|
-
|
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]
|
data/lib/i18n/tasks/data.rb
CHANGED
@@ -59,16 +59,25 @@ module I18n::Tasks
|
|
59
59
|
!t(key, locale).nil?
|
60
60
|
end
|
61
61
|
|
62
|
-
#
|
63
|
-
|
64
|
-
|
65
|
-
|
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(
|
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
|
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)
|
data/lib/i18n/tasks/version.rb
CHANGED
@@ -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.
|
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-
|
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:
|
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:
|