Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#321 #314 #302 should implement project specific config support feature #326

Merged
merged 1 commit into from
Jul 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 56 additions & 9 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,75 @@ 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')

begin
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)
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]: ")
if ans.downcase != 'y'
exit!
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['vagrant'] && data_hash['vagrant']['config_paths']
data_hash['vagrant']['config_paths'].map do |default_config_file_path|
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


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

vm_hash = data_hash["vm"]
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
12 changes: 12 additions & 0 deletions spec/fixture/config_overide.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"vm":{
"synced_folders":[{ //see: http://docs.vagrantup.com/v2/synced-folders/index.html
"_id": "0",
"_op": "d"
}, {
"_id": "1",
"_op": "d"
}
]
}
}
49 changes: 49 additions & 0 deletions spec/fixture/org_project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should add "config_paths" for org_project here

"vm": {
"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)"
]
}]
},
"vagrant": {
"config_paths": [
"workspace/angular-hello-world/vagrant_config.default.json",
"workspace/nextjs-hello-world/vagrant_config.default.json"
]
},
"vb": {
"memory": 2048, // need to adjust for the right optimal MEM
"cpus": 2
},
"provisioners": [{
"_id": "0",
"_a_cookbooks_path": [
"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
}
}
}
}
}]
}
63 changes: 63 additions & 0 deletions spec/fixture/project1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"vm": {
"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",
"_a_cookbooks_path": [
"workspace/angular-hello-world/dev-setup/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