i18n-tasks 0.2.22 → 0.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +5 -1
  3. data/Gemfile +0 -1
  4. data/README.md +59 -49
  5. data/bin/i18n-tasks +38 -0
  6. data/i18n-tasks.gemspec +1 -0
  7. data/lib/i18n/tasks/commands.rb +121 -0
  8. data/lib/i18n/tasks/commands_base.rb +54 -0
  9. data/lib/i18n/tasks/configuration.rb +39 -1
  10. data/lib/i18n/tasks/data/storage/file_storage.rb +1 -1
  11. data/lib/i18n/tasks/data_traversal.rb +6 -7
  12. data/lib/i18n/tasks/fill_tasks.rb +20 -48
  13. data/lib/i18n/tasks/google_translation.rb +1 -1
  14. data/lib/i18n/tasks/key.rb +11 -26
  15. data/lib/i18n/tasks/key/key_group.rb +44 -0
  16. data/lib/i18n/tasks/key/match_pattern.rb +23 -0
  17. data/lib/i18n/tasks/key/usages.rb +11 -0
  18. data/lib/i18n/tasks/key_pattern_matching.rb +6 -2
  19. data/lib/i18n/tasks/missing_keys.rb +15 -12
  20. data/lib/i18n/tasks/plural_keys.rb +3 -3
  21. data/lib/i18n/tasks/reports/base.rb +3 -2
  22. data/lib/i18n/tasks/reports/spreadsheet.rb +2 -1
  23. data/lib/i18n/tasks/reports/terminal.rb +6 -6
  24. data/lib/i18n/tasks/scanners/base_scanner.rb +20 -14
  25. data/lib/i18n/tasks/scanners/pattern_scanner.rb +31 -5
  26. data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +75 -0
  27. data/lib/i18n/tasks/translation_data.rb +32 -11
  28. data/lib/i18n/tasks/unused_keys.rb +3 -2
  29. data/lib/i18n/tasks/used_keys.rb +14 -11
  30. data/lib/i18n/tasks/version.rb +1 -1
  31. data/lib/tasks/i18n-tasks.rake +34 -85
  32. data/spec/fixtures/app/controllers/events_controller.rb +23 -3
  33. data/spec/fixtures/app/views/index.html.slim +4 -1
  34. data/spec/fixtures/app/views/usages.html.slim +2 -0
  35. data/spec/fixtures/config/i18n-tasks.yml +1 -1
  36. data/spec/i18n_tasks_spec.rb +66 -38
  37. data/spec/pattern_scanner_spec.rb +1 -1
  38. data/spec/spec_helper.rb +2 -1
  39. data/spec/support/capture_std.rb +17 -0
  40. data/spec/support/fixtures.rb +9 -2
  41. data/spec/support/test_codebase.rb +5 -18
  42. data/spec/support/test_codebase_env.rake +4 -2
  43. data/spec/used_keys_spec.rb +1 -0
  44. metadata +31 -5
@@ -2,6 +2,9 @@ p #{t('ca.a')} #{t 'ca.b'} #{t "ca.c"}
2
2
  p #{t 'ca.d'} #{t 'ca.f', i: 'world'} #{t 'ca.e', i: 'world'}
3
3
  p #{t 'missing_in_es.a'} #{t 'same_in_es.a'} #{t 'blank_in_es.a'}
4
4
  p = t 'used_but_missing.a'
5
+ p = t 'x', scope: 'scoped'
6
+ p = t 'x', scope: [:very, :scoped]
7
+ p = t 'x', scope: [:scoped, code]
5
8
  p = t 'ignored_missing_key.a'
6
9
  p = t 'ignore.a'
7
10
  p = t 'ignored_pattern.some_key'
@@ -11,4 +14,4 @@ p = t 'numeric.a'
11
14
  p = t 'plural.a', count: 2
12
15
  p = t 'devise.a'
13
16
  p = t :missing_symbol_key
14
- p #{t :"missing_symbol.key_two"} #{t :'missing_symbol.key_three'}
17
+ p #{t :"missing_symbol.key_two"} #{t :'missing_symbol.key_three'}
@@ -0,0 +1,2 @@
1
+ p = t 'used.a'
2
+ b = t 'used.a'
@@ -37,7 +37,7 @@ ignore_unused:
37
37
 
38
38
  # do not report these keys as missing:
39
39
  ignore_missing:
40
- - ignored_missing_key.a # one key to ignore
40
+ - ignored_missing_key.a # one key t ignore
41
41
  - ignored_pattern.* # ignore the whole pattern
42
42
 
43
43
  # do not report these keys when they have the same value as the base locale version
@@ -1,13 +1,15 @@
1
1
  # coding: utf-8
2
2
  require 'spec_helper'
3
+ require 'fileutils'
3
4
 
4
5
  describe 'rake i18n' do
5
6
  describe 'missing' do
6
7
  it 'detects missing or identical' do
7
- TestCodebase.capture_stderr do
8
- TestCodebase.rake_result('i18n:missing').should be_i18n_keys %w(
8
+ capture_stderr do
9
+ expect(TestCodebase.rake_result('i18n:missing')).to be_i18n_keys %w(
9
10
  en.used_but_missing.a en.relative.index.missing
10
11
  es.missing_in_es.a es.blank_in_es.a es.same_in_es.a
12
+ en.hash.pattern_missing.a en.hash.pattern_missing.b
11
13
  en.missing_symbol_key en.missing_symbol.key_two en.missing_symbol.key_three
12
14
  )
13
15
  end
@@ -18,7 +20,7 @@ describe 'rake i18n' do
18
20
  let(:expected_unused_keys) { %w(unused.a unused.numeric unused.plural) }
19
21
 
20
22
  it 'detects unused' do
21
- TestCodebase.capture_stderr do
23
+ capture_stderr do
22
24
  out = TestCodebase.rake_result('i18n:unused')
23
25
  expect(out).to be_i18n_keys expected_unused_keys
24
26
  end
@@ -27,20 +29,18 @@ describe 'rake i18n' do
27
29
  it 'removes unused' do
28
30
  TestCodebase.in_test_app_dir do
29
31
  t = I18n::Tasks::BaseTask.new
30
-
31
32
  expected_unused_keys.each do |key|
32
- expect(t.t(t.data[:en], key)).to be_present
33
- expect(t.t(t.data[:es], key)).to be_present
33
+ expect(t.key_value?(key, :en)).to be_true
34
+ expect(t.key_value?(key, :es)).to be_true
34
35
  end
35
-
36
36
  ENV['CONFIRM'] = '1'
37
- TestCodebase.capture_stderr { TestCodebase.rake_result('i18n:remove_unused') }
38
-
37
+ capture_stderr {
38
+ TestCodebase.rake_result('i18n:remove_unused')
39
+ }
39
40
  t.data.reload
40
- # or save both to an xlsx file:
41
41
  expected_unused_keys.each do |key|
42
- expect(t.t(t.data[:en], key)).to be_nil
43
- expect(t.t(t.data[:es], key)).to be_nil
42
+ expect(t.key_value?(key, :en)).to be_false
43
+ expect(t.key_value?(key, :es)).to be_false
44
44
  end
45
45
  end
46
46
  end
@@ -49,9 +49,9 @@ describe 'rake i18n' do
49
49
  describe 'normalize' do
50
50
  it 'moves keys to the corresponding files as per data.write' do
51
51
  TestCodebase.in_test_app_dir {
52
- File.exists?('config/locales/devise.en.yml').should be_false
52
+ expect(File).to_not exist 'config/locales/devise.en.yml'
53
53
  TestCodebase.rake_result('i18n:normalize')
54
- YAML.load_file('config/locales/devise.en.yml')['en']['devise']['a'].should == 'EN_TEXT'
54
+ expect(YAML.load_file('config/locales/devise.en.yml')['en']['devise']['a']).to eq 'EN_TEXT'
55
55
  }
56
56
  end
57
57
  end
@@ -59,31 +59,59 @@ describe 'rake i18n' do
59
59
  describe 'spreadsheet report' do
60
60
  it 'saves' do
61
61
  TestCodebase.in_test_app_dir {
62
- TestCodebase.rake_result('i18n:spreadsheet_report')
63
- File.should exist 'tmp/i18n-report.xlsx'
62
+ capture_stderr { TestCodebase.rake_result('i18n:spreadsheet_report') }
63
+ expect(File).to exist 'tmp/i18n-report.xlsx'
64
+ FileUtils.cp('tmp/i18n-report.xlsx', '..')
64
65
  }
65
66
  end
66
67
 
67
68
  end
68
69
 
69
- describe 'fill:' do
70
- it 'add missing' do
71
- TestCodebase.in_test_app_dir { YAML.load_file('config/locales/en.yml')['en']['used_but_missing'].should be_nil }
72
- TestCodebase.rake_result('i18n:add_missing')
73
- TestCodebase.in_test_app_dir { YAML.load_file('config/locales/en.yml')['en']['used_but_missing']['a'].should == 'A' }
70
+ describe 'add_missing' do
71
+ it 'placeholder' do
72
+ TestCodebase.in_test_app_dir {
73
+ expect(YAML.load_file('config/locales/en.yml')['en']['used_but_missing']).to be_nil
74
+ }
75
+ TestCodebase.rake_result('i18n:add_missing:placeholder', 'base')
76
+ TestCodebase.in_test_app_dir {
77
+ expect(YAML.load_file('config/locales/en.yml')['en']['used_but_missing']['a']).to eq 'A'
78
+ }
74
79
  end
75
80
 
76
- it 'base_value' do
77
- TestCodebase.in_test_app_dir { YAML.load_file('config/locales/es.yml')['es']['missing_in_es'].should be_nil }
78
- TestCodebase.rake_result('i18n:fill:base_value')
81
+ it 'placeholder[VALUE]' do
82
+ TestCodebase.in_test_app_dir {
83
+ expect(YAML.load_file('config/locales/es.yml')['es']['missing_in_es']).to be_nil
84
+ }
85
+ TestCodebase.rake_result('i18n:add_missing:placeholder', 'all', 'TRME')
79
86
  TestCodebase.in_test_app_dir {
80
- YAML.load_file('config/locales/es.yml')['es']['missing_in_es']['a'].should == 'EN_TEXT'
81
- YAML.load_file('config/locales/devise.en.yml')['en']['devise']['a'].should == 'EN_TEXT'
82
- YAML.load_file('config/locales/devise.es.yml')['es']['devise']['a'].should == 'ES_TEXT'
87
+ expect(YAML.load_file('config/locales/es.yml')['es']['missing_in_es']['a']).to eq 'TRME'
88
+ # does not touch existing, but moves to the right file:
89
+ expect(YAML.load_file('config/locales/devise.es.yml')['es']['devise']['a']).to eq 'ES_TEXT'
83
90
  }
84
91
  end
85
92
  end
86
93
 
94
+ describe 'tasks_config' do
95
+ it 'prints config' do
96
+ expect(YAML.load(TestCodebase.rake_result('i18n:tasks_config'))).to(
97
+ eq TestCodebase.in_test_app_dir { I18n::Tasks::BaseTask.new.config_for_inspect }
98
+ )
99
+ end
100
+ end
101
+
102
+ describe 'usages' do
103
+ it 'prints usages' do
104
+ capture_stderr do
105
+ expect(TestCodebase.rake_result('i18n:usages', 'used.*')).to eq(<<-TXT)
106
+ used.a 2
107
+ app/views/usages.html.slim:1 p = t 'used.a'
108
+ app/views/usages.html.slim:2 b = t 'used.a'
109
+ TXT
110
+ end
111
+ end
112
+ end
113
+
114
+
87
115
  # --- setup ---
88
116
  BENCH_KEYS = 100
89
117
  before do
@@ -92,8 +120,10 @@ describe 'rake i18n' do
92
120
  {
93
121
  'ca' => {'a' => v, 'b' => v, 'c' => v, 'd' => v, 'e' => "#{v}%{i}", 'f' => "#{v}%{i}"},
94
122
  'cb' => {'a' => v, 'b' => "#{v}%{i}"},
95
- 'hash_pattern' => {'a' => v},
96
- 'hash_pattern2' => {'a' => v},
123
+ 'hash' => {
124
+ 'pattern' => {'a' => v},
125
+ 'pattern2' => {'a' => v},
126
+ },
97
127
  'unused' => {'a' => v, 'numeric' => v_num, 'plural' => {'one' => v, 'other' => v}},
98
128
  'ignore_unused' => {'a' => v},
99
129
  'missing_in_es' => {'a' => v},
@@ -110,7 +140,10 @@ describe 'rake i18n' do
110
140
  },
111
141
  'numeric' => {'a' => v_num},
112
142
  'plural' => {'a' => {'one' => v, 'other' => "%{count} #{v}s"}},
113
- 'devise' => {'a' => v}
143
+ 'devise' => {'a' => v},
144
+ 'scoped' => {'x' => v},
145
+ 'very' => {'scoped' => {'x' => v}},
146
+ 'used' => {'a' => v}
114
147
  }.tap { |r|
115
148
  gen = r["bench"] = {}
116
149
  BENCH_KEYS.times { |i| gen["key#{i}"] = v }
@@ -124,18 +157,13 @@ describe 'rake i18n' do
124
157
  es_data['ignore_eq_base_all']['a'] = 'EN_TEXT'
125
158
  es_data['ignore_eq_base_es']['a'] = 'EN_TEXT'
126
159
 
127
- fs = {
160
+ fs = fixtures_contents.merge(
128
161
  'config/locales/en.yml' => {'en' => en_data}.to_yaml,
129
162
  'config/locales/es.yml' => {'es' => es_data}.to_yaml,
130
- 'config/i18n-tasks.yml' => load_fixture('config/i18n-tasks.yml'),
131
- 'app/views/index.html.slim' => load_fixture('app/views/index.html.slim'),
132
- 'app/views/relative/index.html.slim' => load_fixture('app/views/relative/index.html.slim'),
133
- 'app/controllers/events_controller.rb' => load_fixture('app/controllers/events_controller.rb'),
134
- 'app/assets/javascripts/application.js' => load_fixture('app/assets/javascripts/application.js'),
135
-
136
163
  # test that our algorithms can scale to the order of {BENCH_KEYS} keys.
137
164
  'vendor/heavy.file' => BENCH_KEYS.times.map { |i| "t('bench.key#{i}') " }.join
138
- }
165
+ )
166
+
139
167
  TestCodebase.setup fs
140
168
  end
141
169
 
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe 'Pattern Scanner' do
4
4
  describe 'default pattern' do
5
- let!(:pattern) { I18n::Tasks::Scanners::PatternScanner::DEFAULT_PATTERN }
5
+ let!(:pattern) { I18n::Tasks::Scanners::PatternScanner.new.default_pattern }
6
6
 
7
7
  ['t "a.b"', "t 'a.b'", 't("a.b")', "t('a.b')",
8
8
  "t('a.b', :arg => val)", "t('a.b', arg: val)",
data/spec/spec_helper.rb CHANGED
@@ -21,4 +21,5 @@ Dir['spec/support/**/*.rb'].each { |f| require "./#{f}" }
21
21
 
22
22
  RSpec.configure do |config|
23
23
  config.include FixturesSupport
24
- end
24
+ config.include CaptureStd
25
+ end
@@ -0,0 +1,17 @@
1
+ module CaptureStd
2
+ def capture_stderr
3
+ err, $stderr = $stderr, StringIO.new
4
+ yield
5
+ $stderr.string
6
+ ensure
7
+ $stderr = err
8
+ end
9
+
10
+ def capture_stdout
11
+ out, $stdout = $stdout, StringIO.new
12
+ yield
13
+ $stdout.string
14
+ ensure
15
+ $stdout = out
16
+ end
17
+ end
@@ -1,7 +1,14 @@
1
1
  # quick'n'dirty fixture loader
2
2
  module FixturesSupport
3
- def load_fixture(path)
4
- Pathname.new('spec/fixtures').join(path).expand_path.read
3
+ def fixtures_contents
4
+ @fixtures_contents ||= begin
5
+ fixtures_path = 'spec/fixtures'
6
+ Dir.glob("#{fixtures_path}/**/*").inject({}) { |h, path|
7
+ next h if File.directory?(path)
8
+ h[path[fixtures_path.length + 1..-1]] = Pathname.new(path).read
9
+ h
10
+ }
11
+ end
5
12
  end
6
13
  end
7
14
 
@@ -1,11 +1,12 @@
1
1
  require 'fileutils'
2
2
  require 'yaml'
3
+ require_relative 'capture_std'
3
4
 
4
5
  module TestCodebase
6
+ include CaptureStd
5
7
  extend self
6
8
  AT = 'tmp/test_codebase'
7
9
 
8
-
9
10
  def setup(files = {})
10
11
  FileUtils.mkdir_p AT
11
12
  in_test_app_dir do
@@ -20,11 +21,11 @@ module TestCodebase
20
21
  FileUtils.rm_rf AT
21
22
  end
22
23
 
23
- def rake_result(task)
24
+ def rake_result(task, *args)
24
25
  in_test_app_dir {
25
26
  rake_task = Rake::Task[task]
26
27
  rake_task.reenable
27
- capture_stdout { rake_task.invoke }
28
+ capture_stdout { rake_task.invoke(*args) }
28
29
  }
29
30
  end
30
31
 
@@ -40,20 +41,6 @@ module TestCodebase
40
41
  @in_dir = false
41
42
  end
42
43
  end
44
+ end
43
45
 
44
- def capture_stderr
45
- err, $stderr = $stderr, StringIO.new
46
- yield
47
- $stderr.string
48
- ensure
49
- $stderr = err
50
- end
51
46
 
52
- def capture_stdout
53
- out, $stdout = $stdout, StringIO.new
54
- yield
55
- $stdout.string
56
- ensure
57
- $stdout = out
58
- end
59
- end
@@ -1,6 +1,8 @@
1
1
  task :environment do
2
- I18n.default_locale = 'en'
3
- I18n.available_locales = %w(en es)
2
+ Thread.exclusive do
3
+ I18n.default_locale = 'en'
4
+ I18n.available_locales = %w(en es)
5
+ end
4
6
  end
5
7
 
6
8
  namespace :i18n do
@@ -11,6 +11,7 @@ div = t 'a'
11
11
  h1 = t 'b'
12
12
  SLIM
13
13
  TestCodebase.in_test_app_dir { ex.run }
14
+ TestCodebase.teardown
14
15
  end
15
16
 
16
17
  it '#used_keys(true) finds usages' do
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.2.22
4
+ version: 0.3.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-25 00:00:00.000000000 Z
11
+ date: 2014-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: slop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: 3.4.7
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: 3.4.7
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: axlsx
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -184,7 +198,8 @@ description: |2
184
198
  and prefill missing keys. Supports relative and plural keys and Google Translate.
185
199
  email:
186
200
  - glex.spb@gmail.com
187
- executables: []
201
+ executables:
202
+ - i18n-tasks
188
203
  extensions: []
189
204
  extra_rdoc_files: []
190
205
  files:
@@ -196,9 +211,12 @@ files:
196
211
  - LICENSE.txt
197
212
  - README.md
198
213
  - Rakefile
214
+ - bin/i18n-tasks
199
215
  - i18n-tasks.gemspec
200
216
  - lib/i18n/tasks.rb
201
217
  - lib/i18n/tasks/base_task.rb
218
+ - lib/i18n/tasks/commands.rb
219
+ - lib/i18n/tasks/commands_base.rb
202
220
  - lib/i18n/tasks/configuration.rb
203
221
  - lib/i18n/tasks/data/adapter/json_adapter.rb
204
222
  - lib/i18n/tasks/data/adapter/yaml_adapter.rb
@@ -210,6 +228,9 @@ files:
210
228
  - lib/i18n/tasks/google_translation.rb
211
229
  - lib/i18n/tasks/ignore_keys.rb
212
230
  - lib/i18n/tasks/key.rb
231
+ - lib/i18n/tasks/key/key_group.rb
232
+ - lib/i18n/tasks/key/match_pattern.rb
233
+ - lib/i18n/tasks/key/usages.rb
213
234
  - lib/i18n/tasks/key_group.rb
214
235
  - lib/i18n/tasks/key_pattern_matching.rb
215
236
  - lib/i18n/tasks/missing_keys.rb
@@ -221,6 +242,7 @@ files:
221
242
  - lib/i18n/tasks/reports/terminal.rb
222
243
  - lib/i18n/tasks/scanners/base_scanner.rb
223
244
  - lib/i18n/tasks/scanners/pattern_scanner.rb
245
+ - lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb
224
246
  - lib/i18n/tasks/translation_data.rb
225
247
  - lib/i18n/tasks/unused_keys.rb
226
248
  - lib/i18n/tasks/used_keys.rb
@@ -231,6 +253,7 @@ files:
231
253
  - spec/fixtures/app/controllers/events_controller.rb
232
254
  - spec/fixtures/app/views/index.html.slim
233
255
  - spec/fixtures/app/views/relative/index.html.slim
256
+ - spec/fixtures/app/views/usages.html.slim
234
257
  - spec/fixtures/config/i18n-tasks.yml
235
258
  - spec/google_translate_spec.rb
236
259
  - spec/i18n_tasks_spec.rb
@@ -240,6 +263,7 @@ files:
240
263
  - spec/readme_spec.rb
241
264
  - spec/relative_keys_spec.rb
242
265
  - spec/spec_helper.rb
266
+ - spec/support/capture_std.rb
243
267
  - spec/support/fixtures.rb
244
268
  - spec/support/i18n_tasks_output_matcher.rb
245
269
  - spec/support/key_pattern_matcher.rb
@@ -262,9 +286,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
262
286
  version: '0'
263
287
  required_rubygems_version: !ruby/object:Gem::Requirement
264
288
  requirements:
265
- - - '>='
289
+ - - '>'
266
290
  - !ruby/object:Gem::Version
267
- version: '0'
291
+ version: 1.3.1
268
292
  requirements: []
269
293
  rubyforge_project:
270
294
  rubygems_version: 2.0.14
@@ -278,6 +302,7 @@ test_files:
278
302
  - spec/fixtures/app/controllers/events_controller.rb
279
303
  - spec/fixtures/app/views/index.html.slim
280
304
  - spec/fixtures/app/views/relative/index.html.slim
305
+ - spec/fixtures/app/views/usages.html.slim
281
306
  - spec/fixtures/config/i18n-tasks.yml
282
307
  - spec/google_translate_spec.rb
283
308
  - spec/i18n_tasks_spec.rb
@@ -287,6 +312,7 @@ test_files:
287
312
  - spec/readme_spec.rb
288
313
  - spec/relative_keys_spec.rb
289
314
  - spec/spec_helper.rb
315
+ - spec/support/capture_std.rb
290
316
  - spec/support/fixtures.rb
291
317
  - spec/support/i18n_tasks_output_matcher.rb
292
318
  - spec/support/key_pattern_matcher.rb