Skip to content

Instantly share code, notes, and snippets.

@bhalash
Last active June 6, 2016 15:27
Show Gist options
  • Select an option

  • Save bhalash/26e6f4ef010d55a65c6c0ff8f9d594be to your computer and use it in GitHub Desktop.

Select an option

Save bhalash/26e6f4ef010d55a65c6c0ff8f9d594be to your computer and use it in GitHub Desktop.
Add Locale Strings
#!/usr/bin/env ruby
require 'yaml'
#
# Consts
#
PROG_VERSION = '1.0.0'
PROG_NAME = 'add_locale_string'
#
# Lesser Variables
#
@error_messages = {
key: "Error: invalid key '#{ARGV[1]}' supplied. Keys may contain only lowercase letters and periods, and must begin and end with a letter."
}
#
# Methods
#
# Recursively merge hashes.
#
# This operates in a different manner to the normal Hash.merge method!
#
# 1. It is recursive, unlike Hash.merge.
# 2. Data in the existing hash is preferentially saved in all cases.
#
# @param [Hash] hash - Hash to merge into this.
# @return [Hash] self
class Hash
def recursive_merge(hash)
self.merge(hash) do |key, self_val, hash_val|
self_val.is_a?(Hash) ? self_val.recursive_merge(hash_val) : self_val
end
end
end
# Return list of files in given directory.
#
# @return [Array] - List of files.
class Dir
def self.files(dir, regex = //)
files = Dir.entries(dir).select do |file|
!File.directory?(file) && file =~ regex
end
end
end
# Print application help message, and exit the application.
def print_help
puts "\n#{PROG_NAME}, version #{PROG_VERSION}"
puts "\n#{PROG_NAME} inserts a new locale English string into project YAML language files. A placeholder value will be inserted into non-English files."
puts "\nIn all cases existing values will be preserved. This tool will _not_ overwrite any existing values."
puts "\nusage:\t#{PROG_NAME} [folder] [key] [string]"
puts "\t#{PROG_NAME} controller happy.lego.man 'Everything is awesome!'"
exit
end
# Print error message, and exit the application
#
# @param [Symbol] error - Error to print.
def print_error(error)
puts @error_messages[error] || 'Generic error oh my.'
print_help
end
# Recursively convert an array in to a hash with a value at the end.
#
# @see http://stackoverflow.com/a/5095149/1433400
# @param [Array] keys - Array of keys to convert.
# @param [String] message - Message to insert at the end.
# @return [Hash] - Recursively nested hash.
def locale_hash(keys, message)
keys.split('.').reverse.inject(message) do |sum, element|
{ element => sum }
end
end
# Return locale message for given file.
#
# This script only adds messages to English files. Placeholder values are
# inserted for other languages.
#
# @param [String] file - Filename to open.
# @return [String] - Locale string.
def locale_message(file)
return @message_string if file == 'en.yml'
'[NYI] TRANSLATION MISSING'
end
#
# Validations
#
# 1. Test for empty arguments.
# 2. Validate folder name against whitelist.
# 3. Test that key matches regex. See: https://regex101.com/r/fA1vN2/1
#
print_help if ARGV.empty? || ARGV[0] == 'help'
# print_error :folder if !LOCALE_FOLDERS.include? ARGV[0]
print_error :key if ARGV[1] !~ /\A[a-z][a-z.]+[a-z]\z/
#
# Assignations
#
@target_folder = ARGV.shift
@yaml_key = ARGV.shift
@message_string = ARGV.join(' ')
#
# Happy Goodness
#
# FIXME: Change @target_folder to some sort of whitelisted app path.
Dir.chdir @target_folder
Dir.files('.', /\A.+\.yml\z/).each do |file_name|
# 1. Generate hashes to merge.
new_locale_data = locale_hash @yaml_key, locale_message(file_name)
locale_data = YAML.load_file(file_name)
if locale_data
# 2a. Read file and recursively merge it's contents with the new string.
# 2b. Existing strings will be preserved in all cases.
locale_data = locale_data.recursive_merge new_locale_data
# locale_data = locale_data.merge new_locale_data
# 3. Write to file.
File.open(file_name, 'w') { |file| file.write locale_data.to_yaml }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment