i18n_tools 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/i18n_tools/missing_scanner.rb +28 -0
- data/lib/i18n_tools/scanner.rb +54 -0
- data/lib/i18n_tools/tasks.rb +21 -0
- data/lib/i18n_tools/unused_scanner.rb +24 -0
- data/lib/i18n_tools.rb +19 -0
- metadata +71 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module I18nTools
|
2
|
+
class MissingScanner < Scanner
|
3
|
+
def initialize(locale)
|
4
|
+
@locale = locale
|
5
|
+
end
|
6
|
+
|
7
|
+
def results
|
8
|
+
missing_ones = []
|
9
|
+
|
10
|
+
scan do |key|
|
11
|
+
missing_ones << key unless I18n.backend.send(:lookup, @locale, key)
|
12
|
+
end
|
13
|
+
|
14
|
+
result = {}
|
15
|
+
|
16
|
+
missing_ones.each do |key|
|
17
|
+
current_hash = result
|
18
|
+
parts = key.split(".")
|
19
|
+
parts[0..-2].each do |part|
|
20
|
+
current_hash[part] ||= {}
|
21
|
+
current_hash = current_hash[part]
|
22
|
+
end
|
23
|
+
|
24
|
+
current_hash[parts.last] = ""
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module I18nTools
|
2
|
+
class Scanner
|
3
|
+
VIEW_REGEXPS = [/[^\w]t\(\"(.*?)\".*?\)/, /[^\w]t\(\'(.*?)\'.*?\)/]
|
4
|
+
CODE_REGEXPS = [/I18n\.t\(\"(.*?)\".*?\)/, /I18n\.t\(\'(.*?)\'.*?\)/]
|
5
|
+
|
6
|
+
cattr_accessor :file_types
|
7
|
+
self.file_types = ['controllers', 'helpers', 'models']
|
8
|
+
|
9
|
+
protected
|
10
|
+
def scan(&block)
|
11
|
+
scan_views(&block)
|
12
|
+
scan_code(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def scan_views(&block)
|
17
|
+
Dir['app/views/**/*.erb', 'app/views/**/*.rhtml'].each do |filename|
|
18
|
+
next if ignores.any? { |r| filename =~ r }
|
19
|
+
|
20
|
+
content = File.read(filename)
|
21
|
+
VIEW_REGEXPS.each do |view_regexp|
|
22
|
+
content.scan(view_regexp) do |match|
|
23
|
+
key = match.first
|
24
|
+
next if key =~ /\#\{/
|
25
|
+
if key =~ /^\./
|
26
|
+
namespace = filename.gsub('app/views/', '').gsub('.html.erb', '').gsub('/', '.')
|
27
|
+
key = (namespace + key).split('.').collect { |part| part.gsub(/^\_/, '') }.join('.')
|
28
|
+
end
|
29
|
+
yield key
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def scan_code(&block)
|
36
|
+
Dir["lib/**/*.rb", *self.class.file_types.collect { |t| "app/#{t}/**/*.rb" }].each do |filename|
|
37
|
+
next if ignores.any? { |r| filename =~ r }
|
38
|
+
|
39
|
+
content = File.read(filename)
|
40
|
+
CODE_REGEXPS.each do |code_regexp|
|
41
|
+
content.scan(code_regexp) do |match|
|
42
|
+
key = match.first
|
43
|
+
next if key =~ /\#\{/
|
44
|
+
yield key
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def ignores
|
51
|
+
@ignores ||= File.read(".i18nignore").split("\n").reject { |e| e.strip.blank? || e =~ /^#/ }.collect { |i| Regexp.new(i) } rescue []
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
namespace :translations do
|
2
|
+
task :setup => :environment do
|
3
|
+
require 'i18n_tools'
|
4
|
+
|
5
|
+
@locale = (ENV['LOCALE'] || 'en').to_sym
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'Detect missing translations'
|
9
|
+
task :missing => :setup do
|
10
|
+
require 'ya2yaml'
|
11
|
+
|
12
|
+
results = I18nTools::MissingScanner.new(@locale).results
|
13
|
+
puts({ @locale.to_s => results }.ya2yaml)
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Detect translations that are not used in code'
|
17
|
+
task :unused => :setup do
|
18
|
+
unused = I18nTools::UnusedScanner.new(@locale).results
|
19
|
+
puts unused
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module I18nTools
|
2
|
+
class UnusedScanner < Scanner
|
3
|
+
def initialize(locale)
|
4
|
+
@locale = locale
|
5
|
+
end
|
6
|
+
|
7
|
+
def results
|
8
|
+
used_ones = []
|
9
|
+
|
10
|
+
scan do |key|
|
11
|
+
used_ones << [@locale, key].join('.')
|
12
|
+
end
|
13
|
+
|
14
|
+
defined_ones = I18nTools.extract_i18n_keys(@locale.to_s, I18n.backend.send(:lookup, @locale, ''))
|
15
|
+
|
16
|
+
unused = (defined_ones - used_ones).reject { |key| ignore_keys.any? { |rx| rx =~ key } }.sort
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
def ignore_keys
|
21
|
+
@ignore_keys ||= File.read(".i18nignore_unused").split("\n").reject { |e| e.strip.blank? || e =~ /^#/ }.collect { |key| Regexp.new(Regexp.escape("#{@locale}.#{key}")) } rescue []
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/i18n_tools.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# require all necessary files here
|
2
|
+
|
3
|
+
module I18nTools
|
4
|
+
def self.extract_i18n_keys(prefix, object)
|
5
|
+
case object
|
6
|
+
when Hash
|
7
|
+
return prefix if object.keys.include?(:one) && object.keys.include?(:other)
|
8
|
+
object.collect do |key, value|
|
9
|
+
extract_i18n_keys([prefix, key].join('.'), value)
|
10
|
+
end.flatten.compact
|
11
|
+
when String
|
12
|
+
prefix
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require File.dirname(__FILE__) + '/i18n_tools/scanner'
|
18
|
+
require File.dirname(__FILE__) + '/i18n_tools/missing_scanner'
|
19
|
+
require File.dirname(__FILE__) + '/i18n_tools/unused_scanner'
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: i18n_tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Thomas Kadauke
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-17 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description:
|
23
|
+
email: tkadauke@imedo.de
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- lib/i18n_tools/missing_scanner.rb
|
32
|
+
- lib/i18n_tools/scanner.rb
|
33
|
+
- lib/i18n_tools/tasks.rb
|
34
|
+
- lib/i18n_tools/unused_scanner.rb
|
35
|
+
- lib/i18n_tools.rb
|
36
|
+
has_rdoc: true
|
37
|
+
homepage:
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
hash: 3
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 1.3.7
|
67
|
+
signing_key:
|
68
|
+
specification_version: 3
|
69
|
+
summary: Tasks for extracting missing and unused translations from Rails projects
|
70
|
+
test_files: []
|
71
|
+
|