namespace :i18n do
desc 'Writes current default locale translations to a normalized file and deletes unused locale files' task :normalize => :environment do class Hash def to_hash_recursive result = self.to_hash result.each do |key, value| case value when Hash result[key] = value.to_hash_recursive when Array result[key] = value.to_hash_recursive end end result end def sort_by_key(recursive=false, &block) self.keys.sort(&block).reduce({}) do |seed, key| seed[key] = self[key] if recursive && seed[key].is_a?(Hash) seed[key] = seed[key].sort_by_key(true, &block) end seed end end end class Array def to_hash_recursive result = self result.each_with_index do |value,i| case value when Hash result[i] = value.to_hash_recursive when Array result[i] = value.to_hash_recursive end end result end end def current_i18n_yaml(locale) default_locale_translations = I18n.backend.send(:translations)[locale].with_indifferent_access.to_hash_recursive i18n_yaml = {locale.to_s => default_locale_translations}.sort_by_key(true).to_yaml process = i18n_yaml.split(/\n/).reject{|e| e == ''}[1..-1] # remove "---" from first line in yaml # add an empty line if yaml tree level changes by 2 or more tmp_ary = [] process.each_with_index do |line, idx| tmp_ary << line unless process[idx+1].nil? this_line_spcs = line.match(/\A\s*/)[0].length next_line_spcs = process[idx+1].match(/\A\s*/)[0].length tmp_ary << '' if next_line_spcs - this_line_spcs < -2 end end tmp_ary * "\n" end generated_locale_yaml = {} locales = (I18n.available_locales & I18n.backend.send(:translations).keys) if locales.empty? puts 'No locales found' exit 0 end locales.each do |locale| generated_locale_yaml[locale] = current_i18n_yaml(locale) end # delete unused locale files repo_root = %x(git rev-parse --show-toplevel).strip repo_locales = I18n.load_path.dup.keep_if{|p| p.include?(repo_root)} repo_locales.each do |locale_file| FileUtils.rm locale_file puts "removed \"#{locale_file}\"" end # write normalized locale to file generated_locale_yaml.keys.each do |locale| fn = File.join Rails.root, 'config', 'locales', locale.to_s + '.yml' f_size_before = File.exists?(fn) ? File.size(fn) : 0 File.open(fn, 'w') { |file| file.puts generated_locale_yaml[locale]} f_size_after = File.size fn puts "\n(re)generated #{fn}\n" if f_size_before == 0 puts "\"#{fn}\" created, file size: #{f_size_after} bytes.\n" elsif f_size_before != f_size_after puts "\"#{fn}\" changed from #{f_size_before} to #{f_size_after} bytes.\n" else puts "\"#{fn}\" is still #{f_size_after} bytes.\n" end end end
end