i18n-tasks 0.3.5 → 0.3.6
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 +4 -4
- data/CHANGES.md +4 -0
- data/README.md +6 -3
- data/i18n-tasks.gemspec +5 -2
- data/lib/i18n/tasks.rb +3 -5
- data/lib/i18n/tasks/commands_base.rb +5 -0
- data/lib/i18n/tasks/fill_tasks.rb +1 -3
- data/lib/i18n/tasks/key_pattern_matching.rb +0 -16
- data/lib/i18n/tasks/missing_keys.rb +0 -5
- data/lib/i18n/tasks/translation_data.rb +0 -3
- data/lib/i18n/tasks/version.rb +1 -1
- data/spec/google_translate_spec.rb +34 -5
- data/spec/i18n_tasks_spec.rb +11 -15
- data/spec/support/test_codebase.rb +18 -0
- metadata +6 -4
- data/lib/i18n/tasks/data/yaml.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b81678a0e44f5c7593956fbe37f122aff4cdb7fc
|
4
|
+
data.tar.gz: e5bbc6aa629d379ab04551f00d706e714b2b845c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5151ef672fedd86b317900c2621b03a09748e3275efd39221626f101dd895a53336c76ef73e2e973287c40af6d38130323cc89fa178fe0e2bce92fc3d705120
|
7
|
+
data.tar.gz: ec27bed50ae7691827b57619437ce3e3b943a0b01b658e7d350a12ef0af5fa20b921209534ec766e46a8e9864f90fbc67f909c3f15d097263bd0a35845378997
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
# i18n-tasks [![Build Status][badge-travis]][travis] [![Coverage Status][badge-coveralls]][coveralls] [![Code Climate][badge-code-climate]][code-climate] [![Flattr this][badge-flattr]][flattr]
|
2
2
|
|
3
|
+
i18n-tasks finds and manages missing and unused translations in your application.
|
4
|
+
|
3
5
|
The basic approach to i18n key management in frameworks such as Rails is far from perfect.
|
4
6
|
If you use a key that does not exist, this will only blow up at runtime. Keys left over from removed code accumulate
|
5
7
|
in the resource files, introducing unnecessary overhead on the translators. Translation files can quickly turn to disarray.
|
6
8
|
|
7
|
-
i18n-tasks improves this by using static analysis. It
|
8
|
-
|
9
|
+
i18n-tasks improves this by using static analysis. It scans calls such as `I18n.t('some.key')` and uses this information to
|
10
|
+
provide reports on key usage, missing and unused keys, and can prefill missing keys, including from Google Translate,
|
11
|
+
and can also remove unused keys.
|
9
12
|
|
10
13
|
<img width="534" height="288" src="https://raw.github.com/glebm/i18n-tasks/master/doc/img/i18n-tasks.png">
|
11
14
|
|
@@ -14,7 +17,7 @@ This information is inferred based on the keys the gem detects used with calls s
|
|
14
17
|
Add to Gemfile:
|
15
18
|
|
16
19
|
```ruby
|
17
|
-
gem 'i18n-tasks', '~> 0.3.
|
20
|
+
gem 'i18n-tasks', '~> 0.3.5'
|
18
21
|
```
|
19
22
|
|
20
23
|
## Usage
|
data/i18n-tasks.gemspec
CHANGED
@@ -10,12 +10,15 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.email = ['glex.spb@gmail.com']
|
11
11
|
s.summary = %q{Manage translations in ruby applications with the awesome power of static analysis — Edit}
|
12
12
|
s.description = %q{
|
13
|
+
i18n-tasks finds and manages missing and unused translations in your application.
|
14
|
+
|
13
15
|
The basic approach to i18n key management in frameworks such as Rails is far from perfect.
|
14
16
|
If you use a key that does not exist, this will only blow up at runtime. Keys left over from removed code accumulate
|
15
17
|
in the resource files, introducing unnecessary overhead on the translators. Translation files can quickly turn to disarray.
|
16
18
|
|
17
|
-
i18n-tasks improves this by using static analysis. It
|
18
|
-
|
19
|
+
i18n-tasks improves this by using static analysis. It scans calls such as `I18n.t('some.key')` and uses this information to
|
20
|
+
provide reports on key usage, missing and unused keys, and can prefill missing keys, including from Google Translate,
|
21
|
+
and can also remove unused keys.
|
19
22
|
}
|
20
23
|
s.homepage = 'https://github.com/glebm/i18n-tasks'
|
21
24
|
if s.respond_to?(:metadata=)
|
data/lib/i18n/tasks.rb
CHANGED
@@ -19,11 +19,9 @@ module I18n
|
|
19
19
|
)
|
20
20
|
class << self
|
21
21
|
def config
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
HashWithIndifferentAccess.new.merge(file.presence || {})
|
26
|
-
end
|
22
|
+
file = CONFIG_FILES.detect { |f| File.exists?(f) }
|
23
|
+
file = YAML.load(Erubis::Eruby.new(File.read(file)).result) if file
|
24
|
+
HashWithIndifferentAccess.new.merge(file.presence || {})
|
27
25
|
end
|
28
26
|
include ::I18n::Tasks::Logging
|
29
27
|
end
|
@@ -2,6 +2,11 @@ require 'ostruct'
|
|
2
2
|
module I18n::Tasks
|
3
3
|
class CommandsBase
|
4
4
|
include ::I18n::Tasks::Logging
|
5
|
+
|
6
|
+
def initialize(i18n_task = nil)
|
7
|
+
@i18n_task = i18n_task
|
8
|
+
end
|
9
|
+
|
5
10
|
def locales_opt(locales)
|
6
11
|
return i18n_task.locales if locales == ['all'] || locales == 'all'
|
7
12
|
if locales.present?
|
@@ -13,9 +13,7 @@ module I18n::Tasks::FillTasks
|
|
13
13
|
locales: non_base_locales(opts[:locales]),
|
14
14
|
keys: proc { |locale| keys_to_fill(locale).select(&t_proc(from)).select { |k| t(k).is_a?(String) } },
|
15
15
|
values: proc { |keys, locale|
|
16
|
-
google_translate
|
17
|
-
to: locale,
|
18
|
-
from: from
|
16
|
+
google_translate(keys.zip(keys.map(&t_proc(from))), to: locale, from: from).map(&:last)
|
19
17
|
}
|
20
18
|
)
|
21
19
|
update_data opts
|
@@ -28,20 +28,4 @@ module I18n::Tasks::KeyPatternMatching
|
|
28
28
|
gsub(/:/, '(?<=^|\.)[^.]+?(?=\.|$)').
|
29
29
|
gsub(/\{(.*?)}/) { "(#{$1.strip.gsub /\s*,\s*/, '|'})" }
|
30
30
|
end
|
31
|
-
|
32
|
-
# @return [Array<String>] keys sans passed patterns
|
33
|
-
def exclude_patterns(keys, patterns)
|
34
|
-
pattern_re = compile_patterns_re patterns.select { |p| p.end_with?('.') }
|
35
|
-
(keys - patterns).reject { |k| k =~ pattern_re }
|
36
|
-
end
|
37
|
-
|
38
|
-
# compile prefix matching Regexp from the list of prefixes
|
39
|
-
# @return [Regexp] regexp matching any of the prefixes
|
40
|
-
def compile_start_with_re(prefixes)
|
41
|
-
if prefixes.blank?
|
42
|
-
MATCH_NOTHING # match nothing
|
43
|
-
else
|
44
|
-
/^(?:#{prefixes.map { |p| Regexp.escape(p) }.join('|')})/
|
45
|
-
end
|
46
|
-
end
|
47
31
|
end
|
@@ -25,11 +25,6 @@ module I18n::Tasks
|
|
25
25
|
@missing_keys_types ||= [:missing_from_base, :eq_base, :missing_from_locale]
|
26
26
|
end
|
27
27
|
|
28
|
-
def untranslated_keys(locales = nil)
|
29
|
-
warn_deprecated '#untranslated_keys. Please use #missing_keys instead'
|
30
|
-
missing_keys(locales: locales)
|
31
|
-
end
|
32
|
-
|
33
28
|
# @return [KeyGroup] missing keys, i.e. key that are in the code but are not in the base locale data
|
34
29
|
def keys_missing_from_base
|
35
30
|
@keys_missing_from_base ||= begin
|
data/lib/i18n/tasks/version.rb
CHANGED
@@ -1,14 +1,43 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'i18n/tasks/commands'
|
2
3
|
|
3
4
|
describe 'Google Translation' do
|
4
5
|
include I18n::Tasks::GoogleTranslation
|
5
6
|
|
7
|
+
TEST_STRING = 'Hello, %{user}!'
|
8
|
+
TEST_RESULT = 'Hola, %{user}!'
|
9
|
+
|
6
10
|
if ENV['GOOGLE_TRANSLATE_API_KEY']
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
describe 'real world test' do
|
12
|
+
delegate :i18n_cmd, :i18n_task, :in_test_app_dir, to: :TestCodebase
|
13
|
+
|
14
|
+
context 'API' do
|
15
|
+
it 'works' do
|
16
|
+
google_translate(
|
17
|
+
[['common.hello', TEST_STRING]], from: :en, to: :es, key: ENV['GOOGLE_TRANSLATE_API_KEY']
|
18
|
+
).should == [['common.hello', TEST_RESULT]]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
before do
|
23
|
+
TestCodebase.setup('config/locales/en.yml' => '', 'config/locales/es.yml' => '')
|
24
|
+
end
|
25
|
+
|
26
|
+
after do
|
27
|
+
TestCodebase.teardown
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'command' do
|
31
|
+
let(:task) { i18n_task }
|
32
|
+
let(:cmd) { i18n_cmd(task) }
|
33
|
+
|
34
|
+
it 'works' do
|
35
|
+
in_test_app_dir do
|
36
|
+
task.data[:en] = {'common' => {'hello' => TEST_STRING}}
|
37
|
+
cmd.translate_missing
|
38
|
+
expect(task.data[:es]['common']['hello']).to eq(TEST_RESULT)
|
39
|
+
end
|
40
|
+
end
|
12
41
|
end
|
13
42
|
end
|
14
43
|
end
|
data/spec/i18n_tasks_spec.rb
CHANGED
@@ -4,11 +4,7 @@ require 'i18n/tasks/commands'
|
|
4
4
|
require 'fileutils'
|
5
5
|
|
6
6
|
describe 'i18n-tasks' do
|
7
|
-
|
8
|
-
TestCodebase.in_test_app_dir do
|
9
|
-
capture_stdout { ::I18n::Tasks::Commands.new.send(name, *args, &block) }
|
10
|
-
end
|
11
|
-
end
|
7
|
+
delegate :run_cmd, :i18n_task, :in_test_app_dir, to: :TestCodebase
|
12
8
|
|
13
9
|
describe 'missing' do
|
14
10
|
let (:expected_missing_keys) {
|
@@ -39,8 +35,8 @@ describe 'i18n-tasks' do
|
|
39
35
|
|
40
36
|
describe 'remove_unused' do
|
41
37
|
it 'removes unused' do
|
42
|
-
|
43
|
-
t =
|
38
|
+
in_test_app_dir do
|
39
|
+
t = i18n_task
|
44
40
|
expected_unused_keys.each do |key|
|
45
41
|
expect(t.key_value?(key, :en)).to be_true
|
46
42
|
expect(t.key_value?(key, :es)).to be_true
|
@@ -60,7 +56,7 @@ describe 'i18n-tasks' do
|
|
60
56
|
|
61
57
|
describe 'normalize' do
|
62
58
|
it 'moves keys to the corresponding files as per data.write' do
|
63
|
-
|
59
|
+
in_test_app_dir {
|
64
60
|
expect(File).to_not exist 'config/locales/devise.en.yml'
|
65
61
|
run_cmd :normalize
|
66
62
|
expect(YAML.load_file('config/locales/devise.en.yml')['en']['devise']['a']).to eq 'EN_TEXT'
|
@@ -70,7 +66,7 @@ describe 'i18n-tasks' do
|
|
70
66
|
|
71
67
|
describe 'xlsx_report' do
|
72
68
|
it 'saves' do
|
73
|
-
|
69
|
+
in_test_app_dir {
|
74
70
|
capture_stderr { run_cmd :xlsx_report }
|
75
71
|
expect(File).to exist 'tmp/i18n-report.xlsx'
|
76
72
|
FileUtils.cp('tmp/i18n-report.xlsx', '..')
|
@@ -81,21 +77,21 @@ describe 'i18n-tasks' do
|
|
81
77
|
|
82
78
|
describe 'add_missing' do
|
83
79
|
it 'default placeholder' do
|
84
|
-
|
80
|
+
in_test_app_dir {
|
85
81
|
expect(YAML.load_file('config/locales/en.yml')['en']['used_but_missing']).to be_nil
|
86
82
|
}
|
87
83
|
run_cmd :add_missing, locales: 'base'
|
88
|
-
|
84
|
+
in_test_app_dir {
|
89
85
|
expect(YAML.load_file('config/locales/en.yml')['en']['used_but_missing']['a']).to eq 'A'
|
90
86
|
}
|
91
87
|
end
|
92
88
|
|
93
89
|
it 'placeholder: value' do
|
94
|
-
|
90
|
+
in_test_app_dir {
|
95
91
|
expect(YAML.load_file('config/locales/es.yml')['es']['missing_in_es']).to be_nil
|
96
92
|
}
|
97
93
|
run_cmd :add_missing, locales: 'all', placeholder: 'TRME'
|
98
|
-
|
94
|
+
in_test_app_dir {
|
99
95
|
expect(YAML.load_file('config/locales/es.yml')['es']['missing_in_es']['a']).to eq 'TRME'
|
100
96
|
# does not touch existing, but moves to the right file:
|
101
97
|
expect(YAML.load_file('config/locales/devise.es.yml')['es']['devise']['a']).to eq 'ES_TEXT'
|
@@ -106,7 +102,7 @@ describe 'i18n-tasks' do
|
|
106
102
|
describe 'config' do
|
107
103
|
it 'prints config' do
|
108
104
|
expect(YAML.load(run_cmd :config)).to(
|
109
|
-
eq
|
105
|
+
eq(in_test_app_dir { i18n_task.config_for_inspect })
|
110
106
|
)
|
111
107
|
end
|
112
108
|
end
|
@@ -126,7 +122,7 @@ TXT
|
|
126
122
|
|
127
123
|
# --- setup ---
|
128
124
|
BENCH_KEYS = 100
|
129
|
-
before do
|
125
|
+
before(:each) do
|
130
126
|
gen_data = ->(v) {
|
131
127
|
v_num = v.chars.map(&:ord).join('').to_i
|
132
128
|
{
|
@@ -7,6 +7,24 @@ module TestCodebase
|
|
7
7
|
extend self
|
8
8
|
AT = 'tmp/test_codebase'
|
9
9
|
|
10
|
+
def i18n_task(*args)
|
11
|
+
TestCodebase.in_test_app_dir do
|
12
|
+
::I18n::Tasks::BaseTask.new(*args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def i18n_cmd(*args)
|
17
|
+
TestCodebase.in_test_app_dir do
|
18
|
+
::I18n::Tasks::Commands.new(*args)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def run_cmd(name, *args, &block)
|
23
|
+
in_test_app_dir do
|
24
|
+
capture_stdout { i18n_cmd.send(name, *args, &block) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
10
28
|
def setup(files = {})
|
11
29
|
FileUtils.mkdir_p AT
|
12
30
|
in_test_app_dir do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- glebm
|
@@ -180,12 +180,15 @@ dependencies:
|
|
180
180
|
version: '0'
|
181
181
|
description: |2
|
182
182
|
|
183
|
+
i18n-tasks finds and manages missing and unused translations in your application.
|
184
|
+
|
183
185
|
The basic approach to i18n key management in frameworks such as Rails is far from perfect.
|
184
186
|
If you use a key that does not exist, this will only blow up at runtime. Keys left over from removed code accumulate
|
185
187
|
in the resource files, introducing unnecessary overhead on the translators. Translation files can quickly turn to disarray.
|
186
188
|
|
187
|
-
i18n-tasks improves this by using static analysis. It
|
188
|
-
|
189
|
+
i18n-tasks improves this by using static analysis. It scans calls such as `I18n.t('some.key')` and uses this information to
|
190
|
+
provide reports on key usage, missing and unused keys, and can prefill missing keys, including from Google Translate,
|
191
|
+
and can also remove unused keys.
|
189
192
|
email:
|
190
193
|
- glex.spb@gmail.com
|
191
194
|
executables:
|
@@ -212,7 +215,6 @@ files:
|
|
212
215
|
- lib/i18n/tasks/data/adapter/yaml_adapter.rb
|
213
216
|
- lib/i18n/tasks/data/file_system.rb
|
214
217
|
- lib/i18n/tasks/data/storage/file_storage.rb
|
215
|
-
- lib/i18n/tasks/data/yaml.rb
|
216
218
|
- lib/i18n/tasks/data_traversal.rb
|
217
219
|
- lib/i18n/tasks/fill_tasks.rb
|
218
220
|
- lib/i18n/tasks/google_translation.rb
|
data/lib/i18n/tasks/data/yaml.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'i18n/tasks/data/file_system'
|
2
|
-
|
3
|
-
module I18n::Tasks
|
4
|
-
module Data
|
5
|
-
class Yaml < FileSystem
|
6
|
-
def initialize(*args)
|
7
|
-
super
|
8
|
-
I18n::Tasks.warn_deprecated "data.adapter set to 'yaml'. please use 'file_system' instead"
|
9
|
-
end
|
10
|
-
register_adapter '*.yml', Adapter::YamlAdapter
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|