i18n_tools 0.0.1

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.
@@ -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
+