i18n-verify 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- i18n-verify (0.0.4)
4
+ i18n-verify (0.0.5)
5
5
 
6
6
  GEM
7
7
  specs:
data/README.md CHANGED
@@ -24,6 +24,7 @@ i18n-verify is a set of rake tasks:
24
24
  * `rake i18n:find_key` for finding keys
25
25
  * `rake i18n:is_complete` for checking if translations are complete
26
26
  * `rake i18n:duplicates` for finding keys with more than one translation for any given locale
27
+ * `rake i18n:spell` for checking translation misspellings
27
28
 
28
29
  All of them will automatically pick up translation files configured for i18n (both yml and rb).
29
30
 
@@ -73,11 +74,27 @@ Examples:
73
74
  * `rake i18n:duplicates`
74
75
  * `rake i18n:duplicates locales=en`
75
76
 
77
+ i18n:spell
78
+ ----------
79
+
80
+ It checks for translation misspellings.
81
+
82
+ rake i18n:spell [locales=<list>]
83
+
84
+ `locales` defaults to all and should be a comma separated list with no spaces.
85
+
86
+ Please note that spelling requires aspell to be installed with all the dictionaries spelling is requested for.
87
+
88
+ Examples:
89
+
90
+ * `rake i18n:spell`
91
+ * `rake i18n:spell locales=en,fr`
92
+
76
93
  To do
77
94
  =====
78
95
 
79
- * Add spell checking support
80
96
  * Write tests (tests for rake tasks, that is!)
97
+ * More intelligent handling of spelling errors with a dictionary for accepted exceptions
81
98
  * ...
82
99
 
83
100
  Contributing to i18n-verify
@@ -94,4 +111,4 @@ Contributing to i18n-verify
94
111
  Copyright
95
112
  =========
96
113
 
97
- Copyright (c) 2011 fastcatch. See LICENSE.txt for further details.
114
+ Copyright (c) 2011 fastcatch. See the LICENSE file for further details.
data/Rakefile CHANGED
@@ -29,3 +29,8 @@ desc "Clean automatically generated files"
29
29
  task :clean do
30
30
  FileUtils.rm_rf "pkg"
31
31
  end
32
+
33
+ desc "Push to rubygems"
34
+ task :push do
35
+ system "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
36
+ end
data/i18n-verify.gemspec CHANGED
@@ -3,7 +3,7 @@
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "i18n-verify"
5
5
  s.homepage = "http://github.com/fastcatch/i18n-verify"
6
- s.version = "0.0.4"
6
+ s.version = "0.0.5"
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.summary = %Q{Tools to verify your Ruby on Rails localizations}
9
9
  s.description = %Q{It helps you find keys, undefined translations, duplicate keys, and more}
@@ -1,7 +1,57 @@
1
1
  module I18nVerify
2
+
3
+ class Translations < Array
4
+ def initialize(filenames)
5
+ # read files and store translations (similar to i18n's internals but include filenames)
6
+ filenames.each do |filename|
7
+ # puts "Loading: #{filename}"
8
+ type = File.extname(filename).tr('.', '').downcase.to_sym
9
+ case type
10
+ when :rb
11
+ data = eval IO.read(filename) # , binding, filename)
12
+ when :yml
13
+ data = YAML.load_file(filename)
14
+ else
15
+ raise I18n::UnknownFileType.new(type, filename)
16
+ end
17
+ raise I18n::InvalidLocaleData.new(filename) unless data.is_a?(Hash)
18
+ data.each_pair do |locale, d|
19
+ flatten_keys(d || {}) do |flat_key, translation|
20
+ self.push({ :filename => filename, :locale => locale.to_s, :key => flat_key, :translation => translation })
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ def select(*args, &block)
27
+ if block_given?
28
+ super &block
29
+ else
30
+ options = args.extract_options!
31
+ super {|h| options.all?{|key,value| h[key] == value} }
32
+ end
33
+ end
34
+
35
+ protected
36
+ # convert translations hash to flat keys
37
+ # i.e. from { :de => {:new => neue, :old => alt} } to [ ['de.new', 'neue'], ['de.old', 'alte'] ]
38
+ # and yields a flat key and the value to the block
39
+ def flatten_keys(hash, prev_key=nil, &block)
40
+ hash.each_pair do |key, value|
41
+ curr_key = [prev_key, key].compact.join('.')
42
+ if value.is_a?(Hash)
43
+ flatten_keys(value, curr_key, &block)
44
+ else
45
+ yield curr_key, value
46
+ end
47
+ end
48
+ end
49
+
50
+ end
51
+
2
52
  class Checker
3
53
  def initialize(filenames)
4
- @translations = load_files(filenames)
54
+ @translations = Translations.new(filenames)
5
55
  end
6
56
 
7
57
  def find_key(regexp=Regexp.new(''), group_by_filename=false)
@@ -66,43 +116,33 @@ module I18nVerify
66
116
  end
67
117
  end
68
118
 
69
- protected
70
- # convert translations hash to flat keys
71
- # i.e. from { :de => {:new => neue, :old => alt} } to [ ['de.new', 'neue'], ['de.old', 'alte'] ]
72
- # and yields a flat key and the value to the block
73
- def flatten_keys(hash, prev_key=nil, &block)
74
- hash.each_pair do |key, value|
75
- curr_key = [prev_key, key].compact.join('.')
76
- if value.is_a?(Hash)
77
- flatten_keys(value, curr_key, &block)
78
- else
79
- yield curr_key, value
80
- end
81
- end
82
- end
119
+ def spell(locales_requested = [])
120
+ locales = @translations.collect{|tr| tr[:locale]}.uniq
121
+ locales_to_check = locales_requested.empty? ? locales : (locales & locales_requested)
83
122
 
84
- # read files and store translations (similar to i18n's internals but include filenames)
85
- def load_files(filenames)
86
- translations = []
87
- filenames.each do |filename|
88
- # puts "Loading: #{filename}"
89
- type = File.extname(filename).tr('.', '').downcase.to_sym
90
- case type
91
- when :rb
92
- data = eval IO.read(filename) # , binding, filename)
93
- when :yml
94
- data = YAML.load_file(filename)
95
- else
96
- raise I18n::UnknownFileType.new(type, filename)
97
- end
98
- raise I18n::InvalidLocaleData.new(filename) unless data.is_a?(Hash)
99
- data.each_pair do |locale, d|
100
- flatten_keys(d || {}) do |flat_key, translation|
101
- translations.push({ :filename => filename, :locale => locale.to_s, :key => flat_key, :translation => translation })
123
+ puts "Checking spelling in locales #{locales_to_check.inspect} out of #{locales.inspect}"
124
+
125
+ # take each translation in turn and check spelling
126
+ @translations.each do |translation|
127
+ next unless locales_to_check.include? translation[:locale] # skip if in a locale not to be checked
128
+
129
+ text = translation[:translation]
130
+ next unless text.is_a? String # skip if not a string (perhaps an array?)
131
+ text.gsub!(/%\{[^}]*\}/, "") # remove translation params
132
+
133
+ # make aspell check the spelling
134
+ result = %x[echo "#{text}" | aspell -a --ignore-case --lang="#{translation[:locale]}" --dont-suggest]
135
+
136
+ # process result
137
+ # aspell returns lines in the format of '# <word> <position>' for each misspelled word
138
+ result.lines do |line|
139
+ parts = line.split(" ")
140
+ if parts[0]=='#' # misspelling found
141
+ # print: misspelled word | file | (full) key | position
142
+ puts "#{parts[1]} | #{translation[:filename]} | #{[translation[:locale],translation[:key]].join('.')} | #{parts[2]}"
102
143
  end
103
144
  end
104
145
  end
105
- translations
106
146
  end
107
147
 
108
148
  end
@@ -1,95 +1,108 @@
1
- namespace :i18n do
2
-
3
- #
4
- # find_key helps to find where certain (partial) keys have translations
5
- #
6
- # the first parameter is a regexp to look for (beware of period separators!)
7
- # the second parameter is a flag if results are to be grouped by file
8
- # (the default is one match per line with filename included)
9
- #
10
- # Examples:
11
- # rake find_key[/models/]
12
- # rake find_key[/\.models\.attributes/,true]
13
- #
14
- desc "Find translation keys matching a regexp"
15
- task :find_key, :regexp, :group_by_filename do |t, args|
16
- require "#{::Rails.root.to_s}/config/environment.rb"
17
- regexp = Regexp.new(args[:regexp] || "")
18
- group_by_filename = args[:group_by_filename]
19
- checker = I18nVerify::Checker.new(I18n.config.load_path)
20
- checker.find_key(regexp,group_by_filename)
21
- end
22
-
23
- #
24
- # is_complete helps in checking if all translations are set up in all directions
25
- # that is: verifies there are no missing keys in any of the trasnlations
26
- #
27
- # is_complete takes a command line rake param: the list of locales to check (all pairs)
28
- # omit for all
29
- #
30
- # Examples:
31
- # rake i18n:is_complete
32
- # rake i18n:is_complete locales=en,de
33
- #
34
- desc "Checks if translations are complete or there are missing ones"
35
- task :is_complete do |t, args|
36
- require "#{::Rails.root.to_s}/config/environment.rb"
37
- locales_requested = (ENV['locales'] || "").downcase.split(',')
38
- checker = I18nVerify::Checker.new(I18n.config.load_path)
39
- checker.is_complete?(locales_requested)
40
- end
41
-
42
- #
43
- # duplicates helps in finding keys with multiple translations to the same locale
44
- #
45
- # redundancies takes a command line rake param: the list of locales to check
46
- # omit for all
47
- #
48
- # Examples:
49
- # rake i18n:duplicates
50
- # rake i18n:duplicates locales=en,de
51
- #
52
- desc "Checks if any keys are translated multiple times"
53
- task :duplicates do |t, args|
54
- require "#{::Rails.root.to_s}/config/environment.rb"
55
- locales_requested = (ENV['locales'] || "").downcase.split(',')
56
- checker = I18nVerify::Checker.new(I18n.config.load_path)
57
- checker.duplicates(locales_requested)
58
- end
59
-
60
- =begin
61
- # TODO: write method
62
- desc "Checks translations spellings"
63
- task :spelling do |t, args|
64
- end
65
- =end
66
-
67
- desc "Run all checks"
68
- task :verify => [:is_complete, :duplicates] do
69
- end
70
-
71
- end
72
-
73
- #
74
- # BONUS :)
75
- #
76
- namespace :yaml do
77
- desc "Finds keys in yaml files; regexp to match keys; command line: rake yaml:find[config/locales/**/*.yml,/\.models\./]"
78
- task :find, :filename_pattern, :regexp, :group_by_filename do |t, args|
79
- filenames = Dir[args[:filename_pattern] || Rails.root.join('**', '*.{yaml,yml}').to_s]
80
- regexp = Regexp.new(args[:regexp] || "")
81
- group_by_filename = args[:group_by_filename]
82
-
83
- filenames.each do |filename|
84
- print filename + ":\n" if group_by_filename
85
-
86
- File.open( filename ) do |infile|
87
- yaml_hash = YAML::parse(infile).transform
88
- flatten_keys( yaml_hash ) do |key, value|
89
- puts "#{group_by_filename ? '' : (filename + ' #')} #{key}: #{value}\n" if key =~ regexp
90
- end
91
- end
92
-
93
- end
94
- end
1
+ namespace :i18n do
2
+
3
+ #
4
+ # find_key helps to find where certain (partial) keys have translations
5
+ #
6
+ # the first parameter is a regexp to look for (beware of period separators!)
7
+ # the second parameter is a flag if results are to be grouped by file
8
+ # (the default is one match per line with filename included)
9
+ #
10
+ # Examples:
11
+ # rake find_key[/models/]
12
+ # rake find_key[/\.models\.attributes/,true]
13
+ #
14
+ desc "Find translation keys matching a regexp"
15
+ task :find_key, :regexp, :group_by_filename do |t, args|
16
+ require "#{::Rails.root.to_s}/config/environment.rb"
17
+ regexp = Regexp.new(args[:regexp] || "")
18
+ group_by_filename = args[:group_by_filename]
19
+ checker = I18nVerify::Checker.new(I18n.config.load_path)
20
+ checker.find_key(regexp,group_by_filename)
21
+ end
22
+
23
+ #
24
+ # is_complete helps in checking if all translations are set up in all directions
25
+ # that is: verifies there are no missing keys in any of the trasnlations
26
+ #
27
+ # is_complete takes a command line rake param: the list of locales to check (all pairs)
28
+ # omit for all
29
+ #
30
+ # Examples:
31
+ # rake i18n:is_complete
32
+ # rake i18n:is_complete locales=en,de
33
+ #
34
+ desc "Checks if translations are complete or there are missing ones"
35
+ task :is_complete do |t, args|
36
+ require "#{::Rails.root.to_s}/config/environment.rb"
37
+ locales_requested = (ENV['locales'] || "").downcase.split(',')
38
+ checker = I18nVerify::Checker.new(I18n.config.load_path)
39
+ checker.is_complete?(locales_requested)
40
+ end
41
+
42
+ #
43
+ # duplicates helps in finding keys with multiple translations to the same locale
44
+ #
45
+ # duplicates takes a command line rake param: the list of locales to check
46
+ # omit for all
47
+ #
48
+ # Examples:
49
+ # rake i18n:duplicates
50
+ # rake i18n:duplicates locales=en,de
51
+ #
52
+ desc "Checks if any keys are translated multiple times"
53
+ task :duplicates do |t, args|
54
+ require "#{::Rails.root.to_s}/config/environment.rb"
55
+ locales_requested = (ENV['locales'] || "").downcase.split(',')
56
+ checker = I18nVerify::Checker.new(I18n.config.load_path)
57
+ checker.duplicates(locales_requested)
58
+ end
59
+
60
+ #
61
+ # spell helps checking translation spelling
62
+ #
63
+ # note: it requires aspell and the proper dictionaries installed
64
+ #
65
+ # spell takes a command line rake param: the list of locales to check
66
+ # omit for all
67
+ #
68
+ # Examples:
69
+ # rake i18n:spell
70
+ # rake i18n:spell locales=en,de
71
+ #
72
+ desc "Checks translations for spelling errors"
73
+ task :spell do |t, args|
74
+ require "#{::Rails.root.to_s}/config/environment.rb"
75
+ locales_requested = (ENV['locales'] || "").downcase.split(',')
76
+ checker = I18nVerify::Checker.new(I18n.config.load_path)
77
+ checker.spell(locales_requested)
78
+ end
79
+
80
+ desc "Run all checks"
81
+ task :verify => [:is_complete, :duplicates, :spell] do
82
+ end
83
+
84
+ end
85
+
86
+ #
87
+ # BONUS :)
88
+ #
89
+ namespace :yaml do
90
+ desc "Finds keys in yaml files; regexp to match keys; command line: rake yaml:find[config/locales/**/*.yml,/\.models\./]"
91
+ task :find, :filename_pattern, :regexp, :group_by_filename do |t, args|
92
+ filenames = Dir[args[:filename_pattern] || Rails.root.join('**', '*.{yaml,yml}').to_s]
93
+ regexp = Regexp.new(args[:regexp] || "")
94
+ group_by_filename = args[:group_by_filename]
95
+
96
+ filenames.each do |filename|
97
+ print filename + ":\n" if group_by_filename
98
+
99
+ File.open( filename ) do |infile|
100
+ yaml_hash = YAML::parse(infile).transform
101
+ flatten_keys( yaml_hash ) do |key, value|
102
+ puts "#{group_by_filename ? '' : (filename + ' #')} #{key}: #{value}\n" if key =~ regexp
103
+ end
104
+ end
105
+
106
+ end
107
+ end
95
108
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-verify
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - fastcatch
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-19 00:00:00 +02:00
18
+ date: 2011-07-20 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies: []
21
21