Skip to content

Instantly share code, notes, and snippets.

@m-basov
Last active July 18, 2016 09:35
Show Gist options
  • Save m-basov/e6e739148c023d06f2a552d937d58606 to your computer and use it in GitHub Desktop.
Save m-basov/e6e739148c023d06f2a552d937d58606 to your computer and use it in GitHub Desktop.
Convert old VSU config to new
# rubocop:disable Metrics/LineLength
require 'json'
require 'optparse'
# Parse CLI options
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: ruby converter.rb [options]. \n
If arguments are not provided will try to convert files in current directory."
opts.on('-f', '--file=path', 'Convert file and replace it content') { |f| options[:file] = f }
opts.on('-s', '--string=string', 'Convert string and output to stdout') { |s| options[:string] = s }
opts.on('-d', '--dir=path', 'Convert all files at given directory and replace it content') { |d| options[:dir] = d }
end.parse!
# String helpers
# underscrore("email-field") #=> "email_field"
def underscore(str = '')
new_string = str.gsub('::', '/')
new_string.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
new_string.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
new_string.gsub!(/[[:space:]]|\-/, '\1_\2')
new_string.downcase!
new_string
end
# titleize("padding-bottom") #=> "Padding Bottom"
def titleize(str = '')
underscore(str).split('_').map(&:capitalize).join(' ')
end
# Convert old configs format to new one
class ConfigConverter
def initialize(hash)
fields = hash['content']
styles = hash['styles']
@styles = styles.map { |style| create_section(style, fields) }
end
def to_json
JSON.pretty_generate(Hash[@styles])
end
private
def create_section(style, fields = [])
section_key = underscore(style['key'])
[section_key, {
name: style['name'],
screen: style.fetch('screen', 'cta'),
fields: create_fields(fields, style['related-fields'] || [style['key']]),
styles: create_styles(style['data'], section_key)
}]
end
def create_fields(fields, keys)
map = fields.map do |field|
next unless keys.include?(field['key'])
[underscore(field['key']), {
name: field['name'],
val: field['value']
}]
end.compact
Hash[map]
end
def create_styles(styles, section_key = nil)
map = styles.map do |style|
[style['key'], {
name: titleize(style['key'].sub(/^\:/, '')),
val: style['value']
}]
end
map.concat add_missing_styles(section_key)
# Convert array to hash
Hash[map]
end
def add_missing_styles(section_key)
case section_key
when 'general'
[
['background-image', {
name: 'Form Background Image',
val: 'none'
}]
]
else
[]
end
end
end
# Convert give files and replace it's content with new config
def convert_files!(files)
files.each do |file|
content = File.read(file)
json = JSON.parse(content)
File.open(file, 'w') { |f| f.write(ConfigConverter.new(json).to_json) }
end
end
# Convert given JSON string and output to stdio
def convert_string!(string)
puts ConfigConverter.new(JSON.parse(string)).to_json
end
# Choose command
convert_files!([File.expand_path(options[:file])]) unless options[:file].nil?
convert_string!(options[:string]) unless options[:string].nil?
convert_files!(Dir["#{options[:dir]}/**/*.json"]) unless options[:dir].nil?
convert_files!(Dir["#{Dir.pwd}/**/*.json"]) if options.empty?
# rubocop:disable Metrics/LineLength
require 'json'
require 'optparse'
# Parse CLI options
options = {}
OptionParser.new do |opts|
opts.banner = 'Usage: ruby updater.rb [options].'
opts.on('-d', '--dir=path', 'Path to directory with configs, by default is pwd') { |d| options[:dir] = d }
opts.on('-t', '--type=form-type', 'Form type in format trigger/template. Ex: hero/1') { |t| options[:type] = t }
opts.on('-s', '--str=config-string', 'Config to need updates') { |s| options[:str] = s }
end.parse!
# Hash deep merge
def deep_merge(current_hash, other_hash)
result_hash = current_hash.clone
current_hash.each_pair do |current_key, current_value|
other_value = other_hash[current_key]
result_hash[current_key] = if other_value.is_a?(Hash) && current_value.is_a?(Hash)
deep_merge(current_value, other_value)
else
other_value || current_value
end
end
result_hash
end
# Update old config to new one
class ConfigUpdater
def initialize(old_conf, new_conf)
@conf = update_config(old_conf, new_conf)
end
def to_json
JSON.pretty_generate(@conf)
end
private
def update_config(old_conf, new_conf)
old_hash = JSON.parse(old_conf)
new_hash = JSON.parse(new_conf)
deep_merge(new_hash, old_hash)
end
end
def process_config!(opts = {})
dir = opts[:dir] || Dir.pwd
type = opts[:type]
str = opts[:str]
file = File.read(File.join(dir, "#{type}.json"))
updater = ConfigUpdater.new(str, file)
puts updater.to_json
end
process_config!(options)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment