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) ## 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 - Vagrant now gives a nice error message if there is a syntax error
in any Vagrantfile. [GH-154] in any Vagrantfile. [GH-154]
- The format of the ".vagrant" file which stores persisted VMs has - 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 :vm_name # The name of the VM (internal name) which this environment represents
attr_reader :cwd attr_reader :cwd
attr_reader :root_path
attr_reader :config attr_reader :config
attr_reader :box attr_reader :box
attr_accessor :vm attr_accessor :vm
@ -173,6 +172,21 @@ module Vagrant
@logger ||= Util::ResourceLogger.new(resource, self) @logger ||= Util::ResourceLogger.new(resource, self)
end 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 # Load Methods
#--------------------------------------------------------------- #---------------------------------------------------------------
@ -181,7 +195,6 @@ module Vagrant
# such as `vm`, `config`, etc. on this environment. The order this # such as `vm`, `config`, etc. on this environment. The order this
# method calls its other methods is very particular. # method calls its other methods is very particular.
def load! def load!
load_root_path!
load_config! load_config!
load_home_directory! load_home_directory!
load_box! load_box!
@ -191,25 +204,6 @@ module Vagrant
self self
end 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} # Loads this environment's configuration and stores it in the {config}
# variable. The configuration loaded by this method is specified to # variable. The configuration loaded by this method is specified to
# this environment, meaning that it will use the given root directory # this environment, meaning that it will use the given root directory

View File

@ -304,6 +304,53 @@ class EnvironmentTest < Test::Unit::TestCase
end end
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 context "loading" do
setup do setup do
@env = mock_environment @env = mock_environment
@ -312,7 +359,6 @@ class EnvironmentTest < Test::Unit::TestCase
context "overall load method" do context "overall load method" do
should "load! should call proper sequence and return itself" do should "load! should call proper sequence and return itself" do
call_seq = sequence("call_sequence") 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_config!).once.in_sequence(call_seq)
@env.expects(:load_home_directory!).once.in_sequence(call_seq) @env.expects(:load_home_directory!).once.in_sequence(call_seq)
@env.expects(:load_box!).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
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 context "loading config" do
setup do setup do
@root_path = "/foo" @root_path = "/foo"