Skip to content

Commit

Permalink
phuonglm@:~/Projects/iorad/iorad-dev$ git log --oneline
Browse files Browse the repository at this point in the history
6ac70b3 #321 #314 #302 should implement project specific config support feature
  • Loading branch information
phuonglm committed Jul 14, 2017
1 parent d1bec25 commit 8576641
Show file tree
Hide file tree
Showing 8 changed files with 471 additions and 61 deletions.
71 changes: 64 additions & 7 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,85 @@ require 'json'
load File.dirname(__FILE__) + '/lib/utility.rb'
load File.dirname(__FILE__) + '/lib/provisioner.rb'


# Load default setting
file = File.read(File.dirname(__FILE__) + '/vagrant_config.json')
data_hash = JSON.parse(file)
override_hash = nil

# Check and override if exist any match JSON object from vagrant_config_override.json
if File.exist? (File.dirname(__FILE__) + '/vagrant_config_override.json')
override_file = File.read(File.dirname(__FILE__) + '/vagrant_config_override.json')

if File.exist?(File.dirname(__FILE__) + '/workspace/dev-setuo/vagrant_config_default.json')
begin
override_hash = JSON.parse(override_file)
data_hash = overrides(data_hash, override_hash)
parsing_file = File.dirname(__FILE__) + '/vagrant_config_override.json'
rescue Exception => msg
puts red(msg)
puts red('from vagrant_config_override.json')
ans = prompt yellow("some errors have occured and 'vagrant_config_override.json' file will not be used, do you want to continue? [y/N]: ")
puts red('from ' + parsing_file)
ans = prompt yellow("some errors have occured and '" + parsing_file + "' file will not be used, do you want to continue? [y/N]: ")
if ans.downcase != 'y'
exit!
end
end
end
begin
if File.exist?(File.dirname(__FILE__) + '/vagrant_config_override.json')
parsing_file = File.dirname(__FILE__) + '/vagrant_config_override.json'
override_file = File.read(parsing_file)
override_hash = JSON.parse(override_file)

data_hash = overrides(data_hash, override_hash)
end

if File.exist?(File.dirname(__FILE__) + '/workspace/dev-setup/vagrant_config_default.json')
parsing_file = File.dirname(__FILE__) + '/workspace/dev-setup/vagrant_config_default.json'
org_config_file = File.read(parsing_file)
org_config_hash = JSON.parse(org_config_file)

overide_config_file_path = parsing_file.gsub(/default\.json$/, "overide.json")
if File.exist?(overide_config_file_path)
override_config_file = File.read(overide_config_file_path)
parsing_file = overide_config_file_path
overide_config_hash = JSON.parse(override_config_file)
org_config_hash = overrides(org_config_hash, overide_config_hash)
end
if !org_config_hash.nil?
overrides(data_hash, org_config_hash)
end
end


if data_hash.key?('config_paths')
data_hash['config_paths'].each do |default_config_file_path, value|
overide_config_file_path = default_config_file_path.gsub(/default\.json$/, "overide.json")
if File.exist?(default_config_file_path)
default_config_file = File.read(default_config_file_path)
parsing_file = default_config_file_path
project_config_hash = JSON.parse(default_config_file)
else
puts red('Error read file ' + default_config_file_path + '. Please check if that file exist. Exiting.' )
exit!
end

if File.exist?(overide_config_file_path)
override_config_file = File.read(overide_config_file_path)
parsing_file = overide_config_file_path
overide_config_hash = JSON.parse(override_config_file)
project_config_hash = overrides(project_config_hash, overide_config_hash)
end
if !project_config_hash.nil?
overrides(data_hash, project_config_hash)
end
end
end
rescue Exception => msg
puts red(msg)
puts red('from ' + parsing_file)
ans = prompt yellow("some errors have occured and '" + parsing_file + "' file will not be used, do you want to continue? [y/N]: ")
if ans.downcase != 'y'
exit!
end
end
puts JSON.pretty_generate(data_hash)

Vagrant.configure("2") do |config|

Expand Down Expand Up @@ -125,7 +183,6 @@ Vagrant.configure("2") do |config|
end
when 'public_network'
options[:ip] = vm_network['ip'] unless vm_network['ip'].nil? or vm_network['ip'].strip().empty?
options[:bridge] = vm_network['bridge'] unless vm_network['bridge'].nil? or vm_network['bridge'].empty?
end

config.vm.network vm_network['mode'], options
Expand Down
132 changes: 78 additions & 54 deletions lib/utility.rb
Original file line number Diff line number Diff line change
@@ -1,73 +1,97 @@
# Utility functions
def overrides(obj1, obj2)
obj2.each do |key, value|
replaced_key = key.to_s.sub(/_u?[ra]_/, '')

if !obj1.has_key?(replaced_key)
if value.class.name == 'Hash'
obj1[key] = {}
elsif value.class.name == 'Array'
obj1[replaced_key] = []
end
end

# replace
replaced_key = key.sub(/_r_/, '')
if key.start_with?('_r_') and obj1.has_key?(replaced_key) and value.class.name == 'Array'
obj1[replaced_key] = []
key = replaced_key
if value.class.name == 'Array'
if (key.start_with?('_r_') || key.start_with?('_a_') || key.start_with?('_ua_')) && obj1.has_key?(key)
obj1[replaced_key] = obj1[key].clone
obj1.delete(key)
end

if (key.start_with?('_r_') || key.start_with?('_a_') || key.start_with?('_ua_')) && !obj1.has_key?(replaced_key)
obj1[replaced_key] = []
key = replaced_key
else
if key.start_with?('_r_')
obj1[replaced_key] = []
key = replaced_key
elsif key.start_with?('_a_')
value = obj1[replaced_key].concat(obj2[key])
key = replaced_key
elsif key.start_with?('_ua_')
value = (obj1[replaced_key].concat(obj2[key])).uniq
key = replaced_key
end
end
end

if obj1.has_key?(key)
if value.class.name == 'Hash'
obj1[key] = overrides(obj1[key], obj2[key])
elsif value.class.name == 'Array'
obj1_value = obj1[key].clone
if value[0].class.name != 'Hash'
obj1_value = value
else
value.map! do |val|
if val.class.name == 'Hash'
id_existing = false
obj1[key].each do |val1|
if val1['_id'] == val['_id']
id_existing = true
break
end
if value.class.name == 'Hash'
obj1[key] = overrides(obj1[key], obj2[key])
elsif value.class.name == 'Array'
obj1_value = obj1[key].clone
if value[0].class.name != 'Hash'
obj1_value = value
else
value.map! do |val|
if val.class.name == 'Hash'
id_existing = false
obj1[key].each do |val1|
if val1['_id'] == val['_id']
id_existing = true
break
end
if id_existing == false
if !val['_op'].nil? and val['_op'] != 'a'
# warnings
puts yellow("_op = #{val['_op']} is invalid for non-existing id: #{val}")
end
val['_op'] = 'a'
elsif val['_op'].nil?
val['_op'] = 'o'
end
if id_existing == false
if !val['_op'].nil? and val['_op'] != 'a'
# warnings
puts yellow("_op = #{val['_op']} is invalid for non-existing id: #{val}")
end
val['_op'] = 'a'
elsif val['_op'].nil?
val['_op'] = 'o'
end

if val['_op'] == 'a'
if val['_idx'].nil?
obj1_value.push(val)
else
obj1_value.insert(val['_idx'], val)
end
elsif val['_op'] == 'o'
obj1_value.map! do |val2|
if val2['_id'] == val['_id']
val2 = overrides(val2, val)
end
val2
if val['_op'] == 'a'
if val['_idx'].nil?
obj1_value.push(overrides({}, val))
else
obj1_value.insert(val['_idx'], overrides({}, val))
end
elsif val['_op'] == 'o'
obj1_value.map! do |val2|
if val2['_id'] == val['_id']
val2 = overrides(val2, val)
end
elsif val['_op'] == 'r'
obj1_value.map! do |val3|
if val3['_id'] == val['_id']
val3 = val
end
val3
val2
end
elsif val['_op'] == 'r'
obj1_value.map! do |val3|
if val3['_id'] == val['_id']
val3 = overrides({}, val)
end
elsif val['_op'] == 'd'
obj1_value.delete_if {|val4| val4['_id'] == val['_id'] }
val3
end
else
obj1_value = value
elsif val['_op'] == 'd'
obj1_value.delete_if {|val4| val4['_id'] == val['_id'] }
end
val
else
obj1_value = value
end
val
end
obj1[key] = obj1_value
else
obj1[key] = value
end
obj1[key] = obj1_value

else
# merge key here
obj1[key] = value
Expand Down
17 changes: 17 additions & 0 deletions spec/fixture/config_overide.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"vm":{
"synced_folders":[{ //see: http://docs.vagrantup.com/v2/synced-folders/index.html
"_id": "0",
"_op": "d"
}, {
"_id": "1",
"_op": "d"
}
]
},
"config_paths": [
"workspace/dev-setup/vagrant_config.default.json",
"workspace/angular-hello-world/vagrant_config.default.json",
"workspace/nextjs-hello-world/vagrant_config.default.json"
]
}
46 changes: 46 additions & 0 deletions spec/fixture/org_project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"vm": {
"hostname": "acme.dev",
"networks": [{
"_id": "0",
"bridge": [
// If it asks for your network interface, add it the right network interface here
// to choose it by default, you don't have to choose again when $ vagrant reload
// note that if you choose the inactive network interface, problems could happen
// then uncomment the line below and $ vagrant reload to select the right one
//"en0: Wi-Fi (AirPort)"
]
}]
},
"vb": {
"memory": 2048, // need to adjust for the right optimal MEM
"cpus": 2
},
"provisioners": [{
"_id": "0",
"_ua_cookbooks_path": [
"vendor-cookbooks",
"main-cookbooks",
"workspace/dev-setup/chef/main-cookbooks"
],
"_ua_run_list": [
"vim",
"teracy-dev",
"acme"
],
"json": {
"teracy-dev": {
"aliases": [ {
"name": "http", // `$ http` to make http requests, how to use: https://github.com/teracyhq/httpie-jwt-auth
"command": "docker container run -it --rm --net=host teracy/httpie-jwt-auth:latest-alpine",
"action": "add"
}],
"proxy": {
"container": {
"enabled": true
}
}
}
}
}]
}
64 changes: 64 additions & 0 deletions spec/fixture/project1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"vm": {
"hostname": "acme.dev",
"synced_folders":[{
"_id": "100",
"type": "rsync",
"host": "./workspace/angular-hello-world",
"guest": "/home/vagrant/workspace/angular-hello-world",
"rsync__exclude": [".git", ".idea/", "node_modules/", "bower_components/", ".npm/"]
}, {
"_id": "100",
"type": "virtual_box",
"host": "workspace/angular-hello-world/node_modules",
"guest": "/home/vagrant/workspace/angular-hello-world/node_modules",
"mount_options": [
"dmode=775",
"fmode=755"
]
}, {
// enable this to sync /dist back and forth to the host automatically
"_id": "101",
"type": "virtual_box",
"host": "workspace/angular-hello-world/dist",
"guest": "/home/vagrant/workspace/angular-hello-world/dist",
"mount_options": [
"dmode=775",
"fmode=755"
]
}]
},

"provisioners": [{
"_id": "0",
"_ua_cookbooks_path": [
"workspace/angular-hello-world/chef/main-cookbooks"
],
"_ua_run_list": [
"angular-hello-world"
],
"json": {
"teracy-dev": {
"aliases": [ {
"_id": "100",
"name": "ahw", // `$ ahw` to cd right into the angular-hello-world project
"command": "cd ~/workspace/angular-hello-world",
"action": "add"
}]
},
"acme": {
"angular-hello-world": {
"project_guest_path": "/home/vagrant/workspace/angular-hello-world"
}
}
}
}],
"plugins": [{
"_id": "2",
"options": {
"_ua_aliases": [
"dev.ahw.acme.dev", "review.ahw.acme.dev", "ahw.acme.dev"
]
}
}]
}
Loading

0 comments on commit 8576641

Please sign in to comment.