i18n-tasks 0.0.1 → 0.0.2
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/.travis.yml +6 -0
- data/README.md +18 -11
- data/Rakefile +4 -0
- data/i18n-tasks.gemspec +3 -0
- data/lib/i18n/tasks/base_task.rb +9 -0
- data/lib/i18n/tasks/missing.rb +19 -0
- data/lib/i18n/tasks/prefill.rb +16 -0
- data/lib/i18n/tasks/task_helpers.rb +46 -0
- data/lib/i18n/tasks/unused.rb +18 -0
- data/lib/i18n/tasks/version.rb +1 -1
- data/lib/tasks/i18n-tasks.rake +8 -50
- data/spec/i18n_tasks_spec.rb +69 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/support/i18n_tasks_output_matcher.rb +5 -0
- data/spec/support/test_codebase.rb +50 -0
- data/spec/support/test_codebase_env.rake +4 -0
- metadata +61 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be5ef7d26c3df1ed7c2d3492c2ddbee544e561c0
|
4
|
+
data.tar.gz: c294aa392797e900e990defa0fbed3c5a7d7cafa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 783c897ba722831c9893301270e3a8dee8c7dd0775a32bb293c137a3b643f4fd50c9d05628e794891c72bbcfadce25f844da3d3846b750c495ea94bf8ee15d00
|
7
|
+
data.tar.gz: df5d3744b47f1ed0366cb6305823d6f38737e4b583af2ac586808ada0a9a2a0c7a7470db592871962ad1ff3e82a5e4d76790d41207445ca3080054c666573e9a
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,22 +1,29 @@
|
|
1
|
-
i18n-tasks
|
1
|
+
i18n-tasks [](https://travis-ci.org/glebm/i18n-tasks)
|
2
2
|
==========
|
3
3
|
|
4
|
-
I18n tasks to find missing / unused translations and more
|
4
|
+
Rails I18n tasks to find missing / unused translations and more. Works with slim / coffee / haml etc.
|
5
5
|
|
6
|
-
There are 3 tasks available
|
6
|
+
Use `rake -T i18n` to get the list of tasks with descriptions. There are 3 tasks available at the moment:
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
rake i18n:unused # find potentially unused translations
|
8
|
+
* `i18n:missing` task shows all the keys that have not been translated yet *([source](https://github.com/glebm/i18n-tasks/blob/master/lib/i18n/tasks/missing.rb))*
|
9
|
+
* `i18n:prefill` task normalizes locale files, and adds missing keys from base locale to others *([source](https://github.com/glebm/i18n-tasks/blob/master/lib/i18n/tasks/prefill.rb))*
|
10
|
+
* `i18n:unused` task shows potentially unused translations *([source](https://github.com/glebm/i18n-tasks/blob/master/lib/i18n/tasks/unused.rb))*
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
`i18n:unused` will detect pattern translations and not report them, e.g.:
|
13
|
+
|
14
|
+
t 'category.' + category.key # 'category.arts_and_crafts' considered used
|
15
|
+
t "category.#{category.key}" # also works
|
16
|
+
|
17
|
+
For more examples see [the tests](https://github.com/glebm/i18n-tasks/blob/master/spec/i18n_tasks_spec.rb#L43-L59).
|
16
18
|
|
17
19
|
Installation
|
18
|
-
|
20
|
+
------------
|
19
21
|
|
20
22
|
Simply add to Gemfile:
|
21
23
|
|
22
24
|
gem 'i18n-tasks', '~> 0.0.1'
|
25
|
+
|
26
|
+
Configuration
|
27
|
+
-------------
|
28
|
+
|
29
|
+
Currently i18n-tasks only reports / writes to locale data in `config/locales/{locale_code}.yml`. *PRs making this configurable welcome!*
|
data/Rakefile
CHANGED
data/i18n-tasks.gemspec
CHANGED
@@ -18,6 +18,9 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
+
spec.add_dependency 'rails'
|
22
|
+
spec.add_dependency 'rake'
|
21
23
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
24
|
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'rspec-rails'
|
23
26
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'i18n/tasks/base_task'
|
2
|
+
|
3
|
+
module I18n
|
4
|
+
module Tasks
|
5
|
+
class Missing < BaseTask
|
6
|
+
def perform
|
7
|
+
(I18n.available_locales.map(&:to_s) - [base_locale]).each do |locale|
|
8
|
+
trn = get_locale_data(locale)[locale]
|
9
|
+
traverse base[base_locale] do |key, base_value|
|
10
|
+
translated = t(trn, key)
|
11
|
+
if translated.blank? || translated == base_value
|
12
|
+
puts "#{locale}.#{key}: #{base_value}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'i18n/tasks/base_task'
|
2
|
+
|
3
|
+
module I18n
|
4
|
+
module Tasks
|
5
|
+
class Prefill < BaseTask
|
6
|
+
def perform
|
7
|
+
# Will also rewrite en, good for ordering
|
8
|
+
I18n.available_locales.map(&:to_s).each do |target_locale|
|
9
|
+
trn = get_locale_data(target_locale)
|
10
|
+
prefilled = { target_locale => base[base_locale] }.deep_merge(trn)
|
11
|
+
File.open(locale_file_path(target_locale), 'w'){ |f| f.write prefilled.to_yaml }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module I18n
|
4
|
+
module Tasks
|
5
|
+
module TaskHelpers
|
6
|
+
def run_command(*args)
|
7
|
+
_in, out, _err = Open3.popen3(*args)
|
8
|
+
out.gets nil
|
9
|
+
end
|
10
|
+
|
11
|
+
# locale data hash, with locale name as root
|
12
|
+
def get_locale_data(locale)
|
13
|
+
# todo multiple files, configuration option
|
14
|
+
YAML.load_file "config/locales/#{locale}.yml"
|
15
|
+
end
|
16
|
+
|
17
|
+
# main locale file path (for writing to)
|
18
|
+
def locale_file_path(locale)
|
19
|
+
"config/locales/#{locale}.yml"
|
20
|
+
end
|
21
|
+
|
22
|
+
# traverse hash, yielding with full key and value
|
23
|
+
def traverse(path = '', hash, &block)
|
24
|
+
hash.each do |k, v|
|
25
|
+
if v.is_a?(Hash)
|
26
|
+
traverse("#{path}.#{k}", v, &block)
|
27
|
+
else
|
28
|
+
block.call("#{path}.#{k}"[1..-1], v)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def t(hash, key)
|
34
|
+
key.split('.').inject(hash) { |r, seg| r.try(:[], seg) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def base_locale
|
38
|
+
I18n.default_locale.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
def base
|
42
|
+
@base ||= get_locale_data(base_locale)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'i18n/tasks/base_task'
|
2
|
+
|
3
|
+
module I18n
|
4
|
+
module Tasks
|
5
|
+
class Unused < BaseTask
|
6
|
+
def perform
|
7
|
+
grep_out = run_command 'grep', '-horI', %q{\\bt(\\?\\s*['"]\\([^'"]*\\)['"]}, 'app/'
|
8
|
+
used_keys = grep_out.split("\n").map { |r| r.match(/['"](.*?)['"]/)[1] }.uniq.to_set
|
9
|
+
pattern_prefixes = used_keys.select { |k| k =~ /\#{.*?}/ || k.ends_with?('.') }.map { |k| k.split(/\.?#/)[0] }
|
10
|
+
traverse base[base_locale] do |key, value|
|
11
|
+
if !used_keys.include?(key) && !pattern_prefixes.any? { |pp| key.start_with?(pp) }
|
12
|
+
puts "#{key}: #{value}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/i18n/tasks/version.rb
CHANGED
data/lib/tasks/i18n-tasks.rake
CHANGED
@@ -1,65 +1,23 @@
|
|
1
1
|
require 'set'
|
2
|
-
require '
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
require 'i18n/tasks/missing'
|
5
|
+
require 'i18n/tasks/prefill'
|
6
|
+
require 'i18n/tasks/unused'
|
3
7
|
|
4
8
|
namespace :i18n do
|
5
9
|
desc 'add keys from base locale to others'
|
6
10
|
task :prefill => :environment do
|
7
|
-
|
8
|
-
I18n.available_locales.map(&:to_s).each do |target_locale|
|
9
|
-
trn = YAML.load_file trn_path(target_locale)
|
10
|
-
prefilled = { target_locale => base[base_locale] }.deep_merge(trn)
|
11
|
-
File.open(trn_path(target_locale), 'w'){ |f| f.write prefilled.to_yaml }
|
12
|
-
end
|
11
|
+
I18n::Tasks::Prefill.new.perform
|
13
12
|
end
|
14
13
|
|
15
14
|
desc 'show keys with translation values identical to base'
|
16
15
|
task :missing => :environment do
|
17
|
-
|
18
|
-
trn = YAML.load_file(trn_path(locale))[locale]
|
19
|
-
traverse base[base_locale] do |key, base_value|
|
20
|
-
translated = t(trn, key)
|
21
|
-
if translated.blank? || translated == base_value
|
22
|
-
puts "#{locale}.#{key}: #{base_value}"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
16
|
+
I18n::Tasks::Missing.new.perform
|
26
17
|
end
|
27
18
|
|
28
19
|
desc 'find potentially unused translations'
|
29
20
|
task :unused => :environment do
|
30
|
-
|
31
|
-
used_keys = out.gets(nil).split("\n").map { |r| r.match(/['"](.*?)['"]/)[1] }.uniq.to_set
|
32
|
-
pattern_prefixes = used_keys.select { |key| key =~ /\#{.*?}/ || key.ends_with?('.') }.map { |key| key.split(/\.?#/)[0] }
|
33
|
-
traverse base[base_locale] do |key, value|
|
34
|
-
if !used_keys.include?(key) && !pattern_prefixes.any? { |pp| key.start_with?(pp) }
|
35
|
-
puts "#{key}: #{value}"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
define_method :trn_path do |locale|
|
41
|
-
"config/locales/#{locale}.yml"
|
42
|
-
end
|
43
|
-
|
44
|
-
define_method :traverse do |path = '', hash, &block|
|
45
|
-
hash.each do |k, v|
|
46
|
-
if v.is_a?(Hash)
|
47
|
-
traverse("#{path}.#{k}", v, &block)
|
48
|
-
else
|
49
|
-
block.call("#{path}.#{k}"[1..-1], v)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
define_method :t do |hash, key|
|
55
|
-
key.split('.').inject(hash) { |r, seg| r.try(:[], seg) }
|
56
|
-
end
|
57
|
-
|
58
|
-
define_method :base_locale do
|
59
|
-
I18n.default_locale.to_s
|
60
|
-
end
|
61
|
-
|
62
|
-
define_method :base do
|
63
|
-
@base ||= YAML.load_file trn_path(base_locale)
|
21
|
+
I18n::Tasks::Unused.new.perform
|
64
22
|
end
|
65
23
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'rake i18n' do
|
4
|
+
describe 'missing' do
|
5
|
+
it 'detects missing or identical' do
|
6
|
+
TestCodebase.rake_result('i18n:missing').should be_i18n_keys %w(es.missing_in_es.a es.blank_in_es.a es.same_in_es.a)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'unused' do
|
11
|
+
it 'detects unused' do
|
12
|
+
TestCodebase.rake_result('i18n:unused').should be_i18n_keys %w(unused.a)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'prefill' do
|
17
|
+
it 'detects unused' do
|
18
|
+
TestCodebase.in_test_app_dir { YAML.load_file('config/locales/es.yml')['es']['missing_in_es'].should be_nil }
|
19
|
+
TestCodebase.rake_result('i18n:prefill')
|
20
|
+
TestCodebase.in_test_app_dir { YAML.load_file('config/locales/es.yml')['es']['missing_in_es']['a'].should == 'EN_TEXT' }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# --- setup ---
|
25
|
+
before do
|
26
|
+
gen_data = ->(v) {
|
27
|
+
{
|
28
|
+
'ca' => {'a' => v, 'b' => v, 'c' => v, 'd' => v, 'e' => "#{v}%{i}", 'f' => "#{v}%{i}"},
|
29
|
+
'cb' => {'a' => v, 'b' => "#{v}%{i}"},
|
30
|
+
'hash_pattern' => {'a' => v},
|
31
|
+
'hash_pattern2' => {'a' => v},
|
32
|
+
'unused' => {'a' => v},
|
33
|
+
'missing_in_es' => {'a' => v},
|
34
|
+
'same_in_es' => {'a' => v},
|
35
|
+
'blank_in_es' => {'a' => v}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
en_data = gen_data.('EN_TEXT')
|
40
|
+
es_data = gen_data.('ES_TEXT').except('missing_in_es')
|
41
|
+
es_data['same_in_es']['a'] = 'EN_TEXT'
|
42
|
+
es_data['blank_in_es']['a'] = ''
|
43
|
+
|
44
|
+
fs = {
|
45
|
+
'config/locales/en.yml' => {'en' => en_data}.to_yaml,
|
46
|
+
'config/locales/es.yml' => {'es' => es_data}.to_yaml,
|
47
|
+
'app/views/index.html.slim' => <<-SLIM,
|
48
|
+
p \#{t('ca.a')} \#{t 'ca.b'} \#{t "ca.c"}
|
49
|
+
p \#{t 'ca.d'} \#{t 'ca.f', i: 'world'} \#{t 'ca.e', i: 'world'}
|
50
|
+
p \#{t 'missing_in_es.a'} \#{t 'same_in_es.a'} \#{t 'blank_in_es.a'}
|
51
|
+
SLIM
|
52
|
+
'app/controllers/events_controller.slim' => <<-RUBY,
|
53
|
+
class EventsController < ApplicationController
|
54
|
+
def show
|
55
|
+
redirect_to :edit, notice: I18n.t('cb.a')
|
56
|
+
I18n.t("cb.b", i: "Hello")
|
57
|
+
I18n.t("hash_pattern.\#{some_value}", i: "Hello")
|
58
|
+
I18n.t("hash_pattern2." + some_value, i: "Hello")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
RUBY
|
62
|
+
}
|
63
|
+
TestCodebase.setup fs
|
64
|
+
end
|
65
|
+
|
66
|
+
after do
|
67
|
+
TestCodebase.teardown
|
68
|
+
end
|
69
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
ENV['RAKE_ENV'] ||= 'test'
|
2
|
+
require 'rspec/autorun'
|
3
|
+
$: << File.expand_path('../lib', __FILE__)
|
4
|
+
require 'i18n/tasks'
|
5
|
+
require 'rake'
|
6
|
+
Rake.load_rakefile 'tasks/i18n-tasks.rake'
|
7
|
+
Rake.load_rakefile 'support/test_codebase_env.rake'
|
8
|
+
Dir['spec/support/**/*.rb'].each { |f| require "./#{f}" }
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
module TestCodebase
|
3
|
+
extend self
|
4
|
+
AT = 'tmp/test_codebase'
|
5
|
+
|
6
|
+
DEFAULTS = {
|
7
|
+
'config/locales/en.yml' => {'en' => {}}.to_yaml,
|
8
|
+
'config/locales/es.yml' => {'es' => {}}.to_yaml
|
9
|
+
}
|
10
|
+
|
11
|
+
def setup(files)
|
12
|
+
FileUtils.mkdir_p AT
|
13
|
+
in_test_app_dir do
|
14
|
+
DEFAULTS.merge(files).each do |path, content|
|
15
|
+
FileUtils.mkdir_p File.dirname(path)
|
16
|
+
File.open(path, 'w') { |f| f.write(content) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
FileUtils.rm_rf AT
|
23
|
+
end
|
24
|
+
|
25
|
+
def rake_result(task)
|
26
|
+
in_test_app_dir {
|
27
|
+
rake_task = Rake::Task[task]
|
28
|
+
rake_task.reenable
|
29
|
+
capture_stdout { rake_task.invoke }
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def in_test_app_dir(&block)
|
34
|
+
pwd = Dir.pwd
|
35
|
+
Dir.chdir AT
|
36
|
+
block.call
|
37
|
+
ensure
|
38
|
+
Dir.chdir pwd
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def capture_stdout
|
43
|
+
out = StringIO.new
|
44
|
+
$stdout = out
|
45
|
+
yield
|
46
|
+
out.string
|
47
|
+
ensure
|
48
|
+
$stdout = STDOUT
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- glebm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: bundler
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +66,20 @@ dependencies:
|
|
38
66
|
- - '>='
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
41
83
|
description: Rails I18n tasks to find missing / unused translations and more
|
42
84
|
email:
|
43
85
|
- glex.spb@gmail.com
|
@@ -48,15 +90,26 @@ files:
|
|
48
90
|
- .gitignore
|
49
91
|
- .ruby-gemset
|
50
92
|
- .ruby-version
|
93
|
+
- .travis.yml
|
51
94
|
- Gemfile
|
52
95
|
- LICENSE.txt
|
53
96
|
- README.md
|
54
97
|
- Rakefile
|
55
98
|
- i18n-tasks.gemspec
|
56
99
|
- lib/i18n/tasks.rb
|
100
|
+
- lib/i18n/tasks/base_task.rb
|
101
|
+
- lib/i18n/tasks/missing.rb
|
102
|
+
- lib/i18n/tasks/prefill.rb
|
57
103
|
- lib/i18n/tasks/railtie.rb
|
104
|
+
- lib/i18n/tasks/task_helpers.rb
|
105
|
+
- lib/i18n/tasks/unused.rb
|
58
106
|
- lib/i18n/tasks/version.rb
|
59
107
|
- lib/tasks/i18n-tasks.rake
|
108
|
+
- spec/i18n_tasks_spec.rb
|
109
|
+
- spec/spec_helper.rb
|
110
|
+
- spec/support/i18n_tasks_output_matcher.rb
|
111
|
+
- spec/support/test_codebase.rb
|
112
|
+
- spec/support/test_codebase_env.rake
|
60
113
|
homepage: https://github.com/glebm/i18n-tasks
|
61
114
|
licenses:
|
62
115
|
- MIT
|
@@ -81,4 +134,9 @@ rubygems_version: 2.0.3
|
|
81
134
|
signing_key:
|
82
135
|
specification_version: 4
|
83
136
|
summary: Rails I18n tasks to find missing / unused translations and more
|
84
|
-
test_files:
|
137
|
+
test_files:
|
138
|
+
- spec/i18n_tasks_spec.rb
|
139
|
+
- spec/spec_helper.rb
|
140
|
+
- spec/support/i18n_tasks_output_matcher.rb
|
141
|
+
- spec/support/test_codebase.rb
|
142
|
+
- spec/support/test_codebase_env.rake
|