Hobo::Config revamp

This commit is contained in:
Mitchell Hashimoto 2010-02-01 22:14:40 -08:00
parent 303cc90a12
commit c9d341ae2b
10 changed files with 175 additions and 151 deletions

13
config/default.rb Normal file
View File

@ -0,0 +1,13 @@
Hobo::Config.run do |config|
# default config goes here
config.ssh.uname = "hobo"
config.ssh.pass = "hobo"
config.ssh.host = "localhost"
config.ssh.port = 2222
config.ssh.max_tries = 10
config.dotfile_name = ".hobo"
config.vm.base = "~/.hobo/base/base.ovf"
config.vm.base_mac = "0800279C2E41"
end

View File

@ -1,12 +0,0 @@
:ssh:
:uname: hobo
:pass: hobo
:host: localhost
:port: 2222
:max_tries: 10
:dotfile_name: .hobo
:vm:
:base: ~/.hobo/base/base.ovf
:base_mac: 0800279C2E41

View File

@ -1,29 +1,64 @@
require 'forwardable'
module Hobo
module_function
def config
@@config
def self.config
Config.config
end
def config!(hash)
@@config = hash
class Config
@config = nil
@config_runners = []
class <<self
def config
@config ||= Config::Top.new
end
def config_runners
@config_runners ||= []
end
def run(&block)
config_runners << block
end
def execute!
config_runners.each do |block|
block.call(config)
end
end
end
end
def set_config_value(chain, val, cfg=@@config)
keys = chain.split('.')
return if keys.empty?
if keys.length == 1
# If we're out of keys and the value for this key is not a leaf blow up
raise InvalidSettingAlteration if cfg[keys.first.to_sym].is_a?(Hash)
# set the value and return if the value is a leaf
return cfg[keys.first.to_sym] = val
class Config
class Base
def [](key)
send(key)
end
end
set_config_value(keys[1..-1].join('.'), val, cfg[keys.first.to_sym])
end
class SSHConfig < Base
attr_accessor :uname
attr_accessor :pass
attr_accessor :host
attr_accessor :port
attr_accessor :max_tries
end
class InvalidSettingAlteration < StandardError; end
class VMConfig < Base
attr_accessor :base
attr_accessor :base_mac
end
class Top < Base
attr_accessor :dotfile_name
attr_reader :ssh
attr_reader :vm
def initialize
@ssh = SSHConfig.new
@vm = VMConfig.new
end
end
end
end

View File

@ -2,13 +2,7 @@ require 'yaml'
module Hobo
class Env
HOBOFILE_NAME = "hobofile"
HOME = File.expand_path('~/.hobo')
CONFIG = { File.join(HOME, 'config.yml') => '/config/default.yml' }
ENSURE = {
:files => CONFIG.merge({}), #additional files go mhia!
:dirs => [HOME] #additional dirs go mhia!
}
HOBOFILE_NAME = "Hobofile"
# Initialize class variables used
@@persisted_vm = nil
@ -17,7 +11,7 @@ module Hobo
class << self
def persisted_vm; @@persisted_vm; end
def root_path; @@root_path; end
def dotfile_path; File.join(root_path, Hobo.config[:dotfile_name]); end
def dotfile_path; File.join(root_path, Hobo.config.dotfile_name); end
def load!
load_root_path!
@ -25,25 +19,19 @@ module Hobo
load_vm!
end
def ensure_directories
ENSURE[:dirs].each do |name|
Dir.mkdir(name) unless File.exists?(name)
end
end
def ensure_files
ENSURE[:files].each do |target, default|
File.copy(File.join(PROJECT_ROOT, default), target) unless File.exists?(target)
end
end
def load_config!
ensure_directories
ensure_files
load_paths = [
File.join(PROJECT_ROOT, "config", "default.rb"),
File.join(root_path, HOBOFILE_NAME)
]
HOBO_LOGGER.info "Loading config from #{CONFIG.keys.first}"
parsed = YAML.load_file(CONFIG.keys.first)
Hobo.config!(parsed)
load_paths.each do |path|
HOBO_LOGGER.info "Loading config from #{path}..."
load path if File.exist?(path)
end
# Execute the configurations
Config.execute!
end
def load_vm!

View File

@ -6,7 +6,7 @@ module Hobo
def connect(opts={})
options = {}
[:port, :host, :pass, :uname].each do |param|
options[param] = opts[param] || Hobo.config[:ssh][param]
options[param] = opts[param] || Hobo.config.ssh.send(param)
end
Kernel.exec "#{SCRIPT} #{options[:uname]} #{options[:pass]} #{options[:host]} #{options[:port]}".strip

View File

@ -1,27 +1,46 @@
require File.join(File.dirname(__FILE__), '..', 'test_helper')
class ConfigTest < Test::Unit::TestCase
context "Hobo configuration" do
context "accessing configuration" do
setup do
@settings = {:a => { :b => 1}}
Hobo.config!(@settings)
Hobo::Config.run { |config| }
Hobo::Config.execute!
end
should "alter the config given a dot chain of keys" do
Hobo.set_config_value 'a.b', 2
assert_equal Hobo.config[:a][:b], 2
should "forward config to the class method" do
assert_equal Hobo.config, Hobo::Config.config
end
end
context "initializing" do
teardown do
Hobo::Config.instance_variable_set(:@config_runners, nil)
Hobo::Config.instance_variable_set(:@config, nil)
end
should "prevent the alteration of a non leaf setting value" do
assert_raise Hobo::InvalidSettingAlteration do
Hobo.set_config_value 'a', 2
end
should "not run the blocks right away" do
obj = mock("obj")
obj.expects(:foo).never
Hobo::Config.run { |config| obj.foo }
Hobo::Config.run { |config| obj.foo }
Hobo::Config.run { |config| obj.foo }
end
should "not alter settings through the chain method when provided and empty string" do
prev = Hobo.config
Hobo.set_config_value '', 2
assert_equal Hobo.config, prev
should "run the blocks when execute! is ran" do
obj = mock("obj")
obj.expects(:foo).times(2)
Hobo::Config.run { |config| obj.foo }
Hobo::Config.run { |config| obj.foo }
Hobo::Config.execute!
end
should "run the blocks with the same config object" do
config = mock("config")
config.expects(:foo).twice
Hobo::Config.stubs(:config).returns(config)
Hobo::Config.run { |config| config.foo }
Hobo::Config.run { |config| config.foo }
Hobo::Config.execute!
end
end
end

View File

@ -6,10 +6,6 @@ class EnvTest < Test::Unit::TestCase
File.expects(:open).with(dotfile, 'r').returns(['foo'])
end
def config_file_expectation
YAML.expects(:load_file).with(Hobo::Env::CONFIG.keys.first).returns(hobo_mock_config)
end
def dotfile(dir=Dir.pwd)
"#{dir}/#{hobo_mock_config[:dotfile_name]}"
end
@ -24,6 +20,7 @@ class EnvTest < Test::Unit::TestCase
setup do
Hobo::Env.stubs(:error_and_exit)
hobo_mock_config
end
context "requiring a VM" do
@ -40,6 +37,43 @@ class EnvTest < Test::Unit::TestCase
end
end
context "loading config" do
setup do
@root_path = "/foo"
Hobo::Env.stubs(:root_path).returns(@root_path)
File.stubs(:exist?).returns(false)
Hobo::Config.stubs(:execute!)
end
should "load from the project root" do
File.expects(:exist?).with(File.join(PROJECT_ROOT, "config", "default.rb")).once
Hobo::Env.load_config!
end
should "load from the root path" do
File.expects(:exist?).with(File.join(@root_path, Hobo::Env::HOBOFILE_NAME)).once
Hobo::Env.load_config!
end
should "load the files only if exist? returns true" do
File.expects(:exist?).once.returns(true)
Hobo::Env.expects(:load).once
Hobo::Env.load_config!
end
should "not load the files if exist? returns false" do
Hobo::Env.expects(:load).never
Hobo::Env.load_config!
end
should "execute after loading" do
File.expects(:exist?).once.returns(true)
Hobo::Env.expects(:load).once
Hobo::Config.expects(:execute!).once
Hobo::Env.load_config!
end
end
context "initial load" do
test "load! should load the config and set the persisted_uid" do
Hobo::Env.expects(:load_config!).once
@ -49,61 +83,9 @@ class EnvTest < Test::Unit::TestCase
end
end
context "loading config" do
setup do
@handler = Hobo::Env
@ensure = Hobo::Env::ENSURE
Hobo.config! nil
end
test "should not create any directories if they exist" do
File.expects(:exists?).times(@ensure[:dirs].length).returns(true)
Dir.expects(:mkdir).never
@handler.ensure_directories
end
test "should not copy any files if they exist" do
File.expects(:exists?).times(@ensure[:files].length).returns(true)
File.expects(:copy).never
@handler.ensure_files
end
test "should create the ensured directories if they don't exist" do
file_seq = sequence("file_seq")
@ensure[:dirs].each do |dir|
File.expects(:exists?).returns(false).in_sequence(file_seq)
Dir.expects(:mkdir).with(dir).in_sequence(file_seq)
end
@handler.ensure_directories
end
test "should create the ensured files if they don't exist" do
file_seq = sequence("file_seq")
@ensure[:files].each do |target, default|
File.expects(:exists?).with(target).returns(false).in_sequence(file_seq)
File.expects(:copy).with(File.join(PROJECT_ROOT, default), target).in_sequence(file_seq)
end
@handler.ensure_files
end
test "should load of the default" do
config_file_expectation
@handler.load_config!
assert_equal Hobo.config[:ssh], hobo_mock_config[:ssh]
end
test "Hobo.config should be nil unless loaded" do
assert_equal Hobo.config, nil
end
end
context "persisting the VM into a file" do
setup do
Hobo.config! hobo_mock_config
hobo_mock_config
end
test "should save it to the dotfile path" do
@ -118,10 +100,6 @@ class EnvTest < Test::Unit::TestCase
end
context "loading the UUID out from the persisted file" do
setup do
Hobo.config! hobo_mock_config
end
test "loading of the uuid from the dotfile" do
mock_persisted_vm
assert_equal 'foovm', Hobo::Env.persisted_vm
@ -134,7 +112,7 @@ class EnvTest < Test::Unit::TestCase
end
test "should build up the dotfile out of the root path and the dotfile name" do
assert_equal File.join(Hobo::Env.root_path, hobo_mock_config[:dotfile_name]), Hobo::Env.dotfile_path
assert_equal File.join(Hobo::Env.root_path, Hobo.config.dotfile_name), Hobo::Env.dotfile_path
end
end

View File

@ -3,13 +3,12 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper')
class SshTest < Test::Unit::TestCase
context "hobo ssh" do
setup do
@handler = Hobo::SSH
@script = Hobo::SSH::SCRIPT
Hobo.config!(hobo_mock_config)
hobo_mock_config
end
test "should call exec with defaults when no options are supplied" do
ssh = hobo_mock_config[:ssh]
ssh = Hobo.config.ssh
Kernel.expects(:exec).with("#{@script} #{ssh[:uname]} #{ssh[:pass]} #{ssh[:host]} #{ssh[:port]}")
Hobo::SSH.connect
end

View File

@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper')
class VMTest < Test::Unit::TestCase
setup do
@mock_vm = mock("vm")
Hobo.config!(hobo_mock_config)
hobo_mock_config
@persisted_vm = mock("persisted_vm")
Hobo::Env.stubs(:persisted_vm).returns(@persisted_vm)

View File

@ -28,18 +28,22 @@ require 'mocha'
class Test::Unit::TestCase
def hobo_mock_config
{ :ssh => {
:uname => 'foo',
:pass => 'bar',
:host => 'baz',
:port => 'bak',
:max_tries => 10
},
:vm => {
:base => "foo",
:base_mac => "42"
},
:dotfile_name => '.hobo'
}
Hobo::Config.instance_variable_set(:@config_runners, nil)
Hobo::Config.instance_variable_set(:@config, nil)
Hobo::Config.run do |config|
config.dotfile_name = ".hobo"
config.ssh.uname = "foo"
config.ssh.pass = "bar"
config.ssh.host = "baz"
config.ssh.port = "bak"
config.ssh.max_tries = 10
config.vm.base = "foo"
config.vm.base_mac = "42"
end
Hobo::Config.execute!
end
end