Load the root path on demand.

This commit is contained in:
Mitchell Hashimoto 2010-09-03 14:58:27 -07:00
parent f85579a4de
commit 3470d98fca
3 changed files with 63 additions and 85 deletions

View File

@ -1,5 +1,6 @@
## 0.6.0 (unreleased)
- Fixed issue with not detecting Vagrantfile at root directory ("/").
- Vagrant now gives a nice error message if there is a syntax error
in any Vagrantfile. [GH-154]
- The format of the ".vagrant" file which stores persisted VMs has

View File

@ -14,7 +14,6 @@ module Vagrant
attr_reader :vm_name # The name of the VM (internal name) which this environment represents
attr_reader :cwd
attr_reader :root_path
attr_reader :config
attr_reader :box
attr_accessor :vm
@ -173,6 +172,21 @@ module Vagrant
@logger ||= Util::ResourceLogger.new(resource, self)
end
# The root path is the path where the top-most (loaded last)
# Vagrantfile resides. It can be considered the project root for
# this environment.
def root_path
return @root_path if defined?(@root_path)
root_finder = lambda do |path|
return path.to_s if File.exist?(File.join(path.to_s, ROOTFILE_NAME))
return nil if path.root?
root_finder.call(path.parent)
end
@root_path = root_finder.call(Pathname.new(cwd))
end
#---------------------------------------------------------------
# Load Methods
#---------------------------------------------------------------
@ -181,7 +195,6 @@ module Vagrant
# such as `vm`, `config`, etc. on this environment. The order this
# method calls its other methods is very particular.
def load!
load_root_path!
load_config!
load_home_directory!
load_box!
@ -191,25 +204,6 @@ module Vagrant
self
end
# Loads the root path of this environment, given the starting
# directory (the "cwd" of this environment for lack of better words).
# This method allows an environment in `/foo` to be detected from
# `/foo/bar` (similar to how git works in subdirectories)
def load_root_path!(path=nil)
path = Pathname.new(File.expand_path(path || cwd))
# Stop if we're at the root.
return false if path.root?
file = "#{path}/#{ROOTFILE_NAME}"
if File.exist?(file)
@root_path = path.to_s
return true
end
load_root_path!(path.parent)
end
# Loads this environment's configuration and stores it in the {config}
# variable. The configuration loaded by this method is specified to
# this environment, meaning that it will use the given root directory

View File

@ -304,6 +304,53 @@ class EnvironmentTest < Test::Unit::TestCase
end
end
context "loading the root path" do
setup do
@env = mock_environment
@env.stubs(:cwd).returns("/foo")
end
should "should walk the parent directories looking for rootfile" do
paths = [Pathname.new("/foo/bar/baz"),
Pathname.new("/foo/bar"),
Pathname.new("/foo"),
Pathname.new("/")
]
search_seq = sequence("search_seq")
paths.each do |path|
File.expects(:exist?).with(File.join(path.to_s, @klass::ROOTFILE_NAME)).returns(false).in_sequence(search_seq)
end
@env.stubs(:cwd).returns(paths.first.to_s)
assert !@env.root_path
end
should "should set the path for the rootfile" do
path = File.expand_path("/foo")
@env.stubs(:cwd).returns(path)
File.expects(:exist?).with(File.join(path, @klass::ROOTFILE_NAME)).returns(true)
assert_equal path, @env.root_path
end
should "only load the root path once" do
File.expects(:exist?).with(File.join(@env.cwd, @klass::ROOTFILE_NAME)).returns(true).once
assert_equal @env.cwd, @env.root_path
assert_equal @env.cwd, @env.root_path
assert_equal @env.cwd, @env.root_path
end
should "only load the root path once even if nil" do
File.expects(:exist?).twice.returns(false)
assert @env.root_path.nil?
assert @env.root_path.nil?
assert @env.root_path.nil?
end
end
context "loading" do
setup do
@env = mock_environment
@ -312,7 +359,6 @@ class EnvironmentTest < Test::Unit::TestCase
context "overall load method" do
should "load! should call proper sequence and return itself" do
call_seq = sequence("call_sequence")
@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_box!).once.in_sequence(call_seq)
@ -323,69 +369,6 @@ class EnvironmentTest < Test::Unit::TestCase
end
end
context "loading the root path" do
setup do
@env.stubs(:cwd).returns("/foo")
end
should "default the path to the cwd instance var if nil" do
@path = mock("path")
@path.stubs(:root?).returns(true)
File.expects(:expand_path).with(@env.cwd).returns(@env.cwd)
Pathname.expects(:new).with(@env.cwd).returns(@path)
@env.load_root_path!(nil)
end
should "not default the path to pwd if its not nil" do
@path = mock("path")
@path.stubs(:to_s).returns("/")
File.expects(:expand_path).with(@path).returns("/")
Pathname.expects(:new).with("/").returns(@path)
@path.stubs(:root?).returns(true)
@env.load_root_path!(@path)
end
should "should walk the parent directories looking for rootfile" do
paths = [
Pathname.new("/foo/bar/baz"),
Pathname.new("/foo/bar"),
Pathname.new("/foo")
]
search_seq = sequence("search_seq")
paths.each do |path|
# NOTE File.expect(:expand_path) causes tests to hang in windows below is the interim solution
File.expects(:exist?).with("#{File.expand_path(path)}/#{@klass::ROOTFILE_NAME}").returns(false).in_sequence(search_seq)
end
assert !@env.load_root_path!(paths.first)
end
should "return false if not found" do
path = Pathname.new("/")
assert !@env.load_root_path!(path)
end
should "return false if not found on windows-style root" do
# TODO: Is there _any_ way to test this on unix machines? The
# expand path doesn't work [properly for the test] on unix machines.
if RUBY_PLATFORM.downcase.include?("mswin")
# Note the escaped back slash
path = Pathname.new("C:\\")
assert !@env.load_root_path!(path)
end
end
should "should set the path for the rootfile" do
# NOTE File.expect(:expand_path) causes tests to hang in windows below is the interim solution
path = File.expand_path("/foo")
File.expects(:exist?).with("#{path}/#{@klass::ROOTFILE_NAME}").returns(true)
assert @env.load_root_path!(Pathname.new(path))
assert_equal path, @env.root_path
end
end
context "loading config" do
setup do
@root_path = "/foo"