diff --git a/config/default.rb b/config/default.rb index 99608ea22..e8c34c204 100644 --- a/config/default.rb +++ b/config/default.rb @@ -3,6 +3,7 @@ Vagrant::Config.run do |config| config.vagrant.log_output = STDOUT config.vagrant.dotfile_name = ".vagrant" config.vagrant.home = "~/.vagrant" + config.vagrant.host = :detect config.ssh.username = "vagrant" config.ssh.host = "localhost" diff --git a/lib/vagrant.rb b/lib/vagrant.rb index 790c2b94d..17e0a0ee2 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -13,7 +13,7 @@ require File.expand_path("util/glob_loader", libdir) # Load them up Vagrant::GlobLoader.glob_require(libdir, %w{util/stacked_proc_runner downloaders/base config provisioners/base provisioners/chef systems/base - commands/base commands/box action/exception_catcher}) + commands/base commands/box action/exception_catcher hosts/base}) # Initialize the built-in actions Vagrant::Action.builtin! diff --git a/lib/vagrant/config.rb b/lib/vagrant/config.rb index b1593ff61..0bfbc89e0 100644 --- a/lib/vagrant/config.rb +++ b/lib/vagrant/config.rb @@ -193,6 +193,7 @@ module Vagrant attr_accessor :dotfile_name attr_accessor :log_output attr_accessor :home + attr_accessor :host def home @home ? File.expand_path(@home) : nil diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index 0ec2ff2c8..e691a9da7 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -15,6 +15,7 @@ module Vagrant attr_accessor :cwd attr_reader :root_path attr_reader :config + attr_reader :host attr_reader :box attr_accessor :vm attr_reader :vms @@ -137,6 +138,7 @@ module Vagrant load_root_path! load_config! load_home_directory! + load_host! load_box! load_config! self.class.check_virtualbox! @@ -237,6 +239,11 @@ module Vagrant end end + # Loads the host class for this environment. + def load_host! + @host = Hosts::Base.load(self, config.vagrant.host) + end + # Loads the specified box for this environment. def load_box! return unless root_path diff --git a/lib/vagrant/hosts/base.rb b/lib/vagrant/hosts/base.rb new file mode 100644 index 000000000..554de307a --- /dev/null +++ b/lib/vagrant/hosts/base.rb @@ -0,0 +1,55 @@ +module Vagrant + module Hosts + # Base class representing a host machine. These classes + # define methods which may have host-specific (Mac OS X, Windows, + # Linux, etc) behavior. The class is automatically determined by + # default but may be explicitly set via `config.vagrant.host`. + class Base + # The {Environment} which this host belongs to. + attr_reader :env + + class << self + # Loads the proper host for the given value. If the value is nil + # or is the symbol `:detect`, then the host class will be detected + # using the `RUBY_PLATFORM` constant. + # + # @param [Environment] env + # @param [String] klass + # @return [Base] + def load(env, klass) + klass = detect if klass.nil? || klass == :detect + return nil if !klass + return klass.new(env) + end + + # Detects the proper host class for current platform and returns + # the class. + # + # @return [Class] + def detect + # More coming soon + classes = { + :darwin => BSD, + :bsd => BSD + } + + classes.each do |type, klass| + return klass if Util::Platform.send("#{type}?") + end + + nil + rescue Exception + nil + end + end + + # Initialzes a new host. This method shouldn't be called directly, + # typically, since it will be called by {Environment#load_host!} + # + # @param [Environment] env + def initialize(env) + @env = env + end + end + end +end diff --git a/lib/vagrant/hosts/bsd.rb b/lib/vagrant/hosts/bsd.rb new file mode 100644 index 000000000..9aa02dd62 --- /dev/null +++ b/lib/vagrant/hosts/bsd.rb @@ -0,0 +1,7 @@ +module Vagrant + module Hosts + # Represents a BSD host, such as FreeBSD and Darwin (Mac OS X). + class BSD < Base + end + end +end diff --git a/lib/vagrant/util/platform.rb b/lib/vagrant/util/platform.rb index 303a7559c..74f37134d 100644 --- a/lib/vagrant/util/platform.rb +++ b/lib/vagrant/util/platform.rb @@ -7,10 +7,28 @@ module Vagrant RUBY_PLATFORM.downcase.include?("darwin9") end + [:darwin, :bsd, :linux].each do |type| + define_method("#{type}?") do + platform.include?(type.to_s) + end + end + + def windows? + %W[mingw mswin].each do |text| + return true if platform.include?(text) + end + + false + end + def tar_file_options # create, write only, fail if the file exists, binary if windows File::WRONLY|File::EXCL|File::CREAT|(Mario::Platform.windows? ? File::BINARY : 0) end + + def platform + RUBY_PLATFORM.to_s.downcase + end end end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 751b53394..142293ca1 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -26,6 +26,7 @@ class Test::Unit::TestCase config.vagrant.home = '~/.home' config.vagrant.dotfile_name = ".vagrant" config.vagrant.log_output = nil + config.vagrant.host = :detect config.ssh.username = "foo" config.ssh.host = "baz" diff --git a/test/vagrant/environment_test.rb b/test/vagrant/environment_test.rb index 68c6f458d..53ab5ad96 100644 --- a/test/vagrant/environment_test.rb +++ b/test/vagrant/environment_test.rb @@ -220,6 +220,7 @@ class EnvironmentTest < Test::Unit::TestCase @env.expects(:load_root_path!).once.in_sequence(call_seq) @env.expects(:load_config!).once.in_sequence(call_seq) @env.expects(:load_home_directory!).once.in_sequence(call_seq) + @env.expects(:load_host!).once.in_sequence(call_seq) @env.expects(:load_box!).once.in_sequence(call_seq) @env.expects(:load_config!).once.in_sequence(call_seq) Vagrant::Environment.expects(:check_virtualbox!).once.in_sequence(call_seq) @@ -447,6 +448,19 @@ class EnvironmentTest < Test::Unit::TestCase end end + context "loading host" do + setup do + @env = mock_environment + end + + should "load the host by calling the load method on Host::Base" do + result = mock("result") + Vagrant::Hosts::Base.expects(:load).with(@env, @env.config.vagrant.host).once.returns(result) + @env.load_host! + assert_equal result, @env.host + end + end + context "loading box" do setup do @box = mock("box") diff --git a/test/vagrant/hosts/base_test.rb b/test/vagrant/hosts/base_test.rb new file mode 100644 index 000000000..dbba39701 --- /dev/null +++ b/test/vagrant/hosts/base_test.rb @@ -0,0 +1,46 @@ +require File.join(File.dirname(__FILE__), '..', '..', 'test_helper') + +class BaseHostTest < Test::Unit::TestCase + setup do + @klass = Vagrant::Hosts::Base + end + + context "class methods" do + context "loading" do + setup do + @env = mock_environment + end + + should "return detected class if klass is nil" do + Vagrant::Util::Platform.stubs(:platform).returns("darwin") + result = @klass.load(@env, nil) + assert result.is_a?(Vagrant::Hosts::BSD) + end + + should "instantiate the given class" do + result = @klass.load(@env, Vagrant::Hosts::BSD) + assert result.is_a?(Vagrant::Hosts::BSD) + assert_equal @env, result.env + end + end + + context "detecting class" do + should "return the proper class" do + Vagrant::Util::Platform.stubs(:platform).returns("darwin10") + assert_equal Vagrant::Hosts::BSD, @klass.detect + end + + should "return nil if no class is detected" do + Vagrant::Util::Platform.stubs(:platform).returns("boo") + assert_nil @klass.detect + end + + should "return nil if an exception is raised" do + Vagrant::Util::Platform.expects(:darwin?).raises(Exception) + assert_nothing_raised { + assert_nil @klass.detect + } + end + end + end +end