1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
desc 'Updates and checks locales against en.yml'
task :locales do
%w(locales:update locales:check_interpolation).collect do |task|
Rake::Task[task].invoke
end
end
namespace :locales do
desc 'Updates language files based on en.yml content (only works for new top level keys).'
task :update do
dir = ENV['DIR'] || './config/locales'
en_strings = YAML.load(File.read(File.join(dir,'en.yml')))['en']
files = Dir.glob(File.join(dir,'*.{yaml,yml}'))
files.sort.each do |file|
puts "Updating file #{file}"
file_strings = YAML.load(File.read(file))
file_strings = file_strings[file_strings.keys.first]
missing_keys = en_strings.keys - file_strings.keys
next if missing_keys.empty?
puts "==> Missing #{missing_keys.size} keys (#{missing_keys.join(', ')})"
lang = File.open(file, 'a')
missing_keys.each do |key|
{key => en_strings[key]}.to_yaml.each_line do |line|
next if line =~ /^---/ || line.empty?
puts " #{line}"
lang << " #{line}"
end
end
lang.close
end
end
desc 'Checks interpolation arguments in locals against en.yml'
task :check_interpolation do
dir = ENV['DIR'] || './config/locales'
en_strings = YAML.load(File.read(File.join(dir,'en.yml')))['en']
files = Dir.glob(File.join(dir,'*.{yaml,yml}'))
files.sort.each do |file|
puts "parsing #{file}..."
file_strings = YAML.load_file(file)
unless file_strings.is_a?(Hash)
puts "#{file}: content is not a Hash (#{file_strings.class.name})"
next
end
unless file_strings.keys.size == 1
puts "#{file}: content has multiple keys (#{file_strings.keys.size})"
next
end
file_strings = file_strings[file_strings.keys.first]
file_strings.each do |key, string|
next unless string.is_a?(String)
string.scan /%\{\w+\}/ do |match|
unless en_strings[key].nil? || en_strings[key].include?(match)
puts "#{file}: #{key} uses #{match} not found in en.yml"
end
end
end
end
end
desc <<-END_DESC
Removes a translation string from all locale file (only works for top-level childless non-multiline keys, probably doesn\'t work on windows).
Options:
key=key_1,key_2 Comma-separated list of keys to delete
skip=en,de Comma-separated list of locale files to ignore (filename without extension)
END_DESC
task :remove_key do
dir = ENV['DIR'] || './config/locales'
files = Dir.glob(File.join(dir,'*.yml'))
skips = ENV['skip'] ? Regexp.union(ENV['skip'].split(',')) : nil
deletes = ENV['key'] ? Regexp.union(ENV['key'].split(',')) : nil
# Ignore multiline keys (begin with | or >) and keys with children (nothing meaningful after :)
delete_regex = /\A #{deletes}: +[^\|>\s#].*\z/
files.each do |path|
# Skip certain locales
(puts "Skipping #{path}"; next) if File.basename(path, ".yml") =~ skips
puts "Deleting selected keys from #{path}"
orig_content = File.open(path, 'r') {|file| file.read}
File.open(path, 'w') {|file| orig_content.each_line {|line| file.puts line unless line.chomp =~ delete_regex}}
end
end
desc <<-END_DESC
Adds a new top-level translation string to all locale file (only works for childless keys, probably doesn\'t work on windows, doesn't check for duplicates).
Options:
key="some_key=foo"
key1="another_key=bar"
key_fb="foo=bar" Keys to add in the form key=value, every option of the form key[,\\d,_*] will be recognised
skip=en,de Comma-separated list of locale files to ignore (filename without extension)
END_DESC
task :add_key do
dir = ENV['DIR'] || './config/locales'
files = Dir.glob(File.join(dir,'*.yml'))
skips = ENV['skip'] ? Regexp.union(ENV['skip'].split(',')) : nil
keys_regex = /\Akey(\d+|_.+)?\z/
adds = ENV.reject {|k,v| !(k =~ keys_regex)}.values.collect {|v| Array.new v.split("=",2)}
key_list = adds.collect {|v| v[0]}.join(", ")
files.each do |path|
# Skip certain locales
(puts "Skipping #{path}"; next) if File.basename(path, ".yml") =~ skips
# TODO: Check for duplicate/existing keys
puts "Adding #{key_list} to #{path}"
File.open(path, 'a') do |file|
adds.each do |kv|
Hash[*kv].to_yaml.each_line do |line|
file.puts " #{line}" unless (line =~ /^---/ || line.empty?)
end
end
end
end
end
desc 'Duplicates a key. Exemple rake locales:dup key=foo new_key=bar'
task :dup do
dir = ENV['DIR'] || './config/locales'
files = Dir.glob(File.join(dir,'*.yml'))
skips = ENV['skip'] ? Regexp.union(ENV['skip'].split(',')) : nil
key = ENV['key']
new_key = ENV['new_key']
abort "Missing key argument" if key.blank?
abort "Missing new_key argument" if new_key.blank?
files.each do |path|
# Skip certain locales
(puts "Skipping #{path}"; next) if File.basename(path, ".yml") =~ skips
puts "Adding #{new_key} to #{path}"
strings = File.read(path)
unless strings =~ /^( #{key}: .+)$/
puts "Key not found in #{path}"
next
end
line = $1
File.open(path, 'a') do |file|
file.puts(line.sub(key, new_key))
end
end
end
desc 'Check parsing yaml by psych library on Ruby 1.9.'
# On Fedora 12 and 13, if libyaml-devel is available,
# in case of installing by rvm,
# Ruby 1.9 default yaml library is psych.
task :check_parsing_by_psych do
begin
require 'psych'
parser = Psych::Parser.new
dir = ENV['DIR'] || './config/locales'
files = Dir.glob(File.join(dir,'*.yml'))
files.sort.each do |filename|
next if File.directory? filename
puts "parsing #{filename}..."
begin
parser.parse File.open(filename)
rescue => e1
puts(e1.message)
puts("")
end
end
rescue => e
puts(e.message)
end
end
end
|