New BoxCollection class to keep track of all boxes.

This commit is contained in:
Mitchell Hashimoto 2010-09-11 10:17:26 -07:00
parent 4b17ac0f89
commit 0ee21998f6
6 changed files with 140 additions and 32 deletions

View File

@ -8,6 +8,8 @@ module Vagrant
# TODO: Move more classes over to the autoload model. We'll
# start small, but slowly move everything over.
autoload :Box, 'vagrant/box'
autoload :BoxCollection, 'vagrant/box_collection'
autoload :CLI, 'vagrant/cli'
autoload :Config, 'vagrant/config'
autoload :DataStore, 'vagrant/data_store'

View File

@ -0,0 +1,38 @@
module Vagrant
# Represents a collection of boxes, providing helpful methods for
# finding boxes.
class BoxCollection < Array
attr_reader :env
def initialize(env)
super()
@env = env
reload!
end
# Find a box in the collection by the given name. The name must
# be a string, for now.
def find(name)
each do |box|
return box if box.name == name
end
nil
end
# Loads the list of all boxes from the source. This modifies the
# current array.
def reload!
clear
Dir.open(env.boxes_path) do |dir|
dir.each do |d|
next if d == "." || d == ".." || !File.directory?(env.boxes_path.join(d))
self << Box.new(env, d)
end
end
end
end
end

View File

@ -13,7 +13,6 @@ module Vagrant
attr_reader :parent # Parent environment (in the case of multi-VMs)
attr_reader :cwd
attr_reader :box
attr_accessor :vm
attr_writer :ui
@ -81,6 +80,17 @@ module Vagrant
vm.name rescue "vagrant"
end
# Returns the collection of boxes for the environment.
def boxes
return parent.boxes if parent
@_boxes ||= BoxCollection.new(self)
end
# Returns the box that this environment represents.
def box
boxes.find(config.vm.box)
end
# Returns the VMs associated with this environment.
def vms
return parent.vms if parent
@ -252,7 +262,6 @@ module Vagrant
# After the first run we want to load the configuration again since
# it can change due to box Vagrantfiles and home directory Vagrantfiles
load_home_directory!
load_box!
load_config!
end
end
@ -273,11 +282,6 @@ module Vagrant
end
end
# Loads the specified box for this environment.
def load_box!
@box = Box.find(self, config.vm.box) if config.vm.box
end
# Loads the persisted VM (if it exists) for this environment.
def load_vm!
# This environment represents a single sub VM. The VM is then

View File

@ -26,7 +26,11 @@ module VagrantTestHelpers
# Cleans all the test temp paths
def clean_paths
FileUtils.rm_rf(tmp_path)
FileUtils.mkdir_p(tmp_path)
# Call these methods only to rebuild the directories
tmp_path
home_path
boxes_path
end
end
end

View File

@ -0,0 +1,44 @@
require "test_helper"
class BoxCollectionTest < Test::Unit::TestCase
setup do
clean_paths
@klass = Vagrant::BoxCollection
end
should "load all the boxes from the box path" do
vagrant_box("foo")
vagrant_box("bar")
result = @klass.new(vagrant_env)
names = result.collect { |b| b.name }.sort
assert_equal 2, result.length
assert_equal ["bar", "foo"], names
end
should "reload the box list" do
instance = @klass.new(vagrant_env)
assert instance.empty?
vagrant_box("foo")
instance.reload!
assert !instance.empty?
end
should "find a specific box" do
vagrant_box("foo")
vagrant_box("bar")
instance = @klass.new(vagrant_env)
result = instance.find("foo")
assert result
assert_equal "foo", result.name
end
should "return nil if it couldn't find a specific box" do
instance = @klass.new(vagrant_env)
assert_nil instance.find("thisshouldnotexist")
end
end

View File

@ -285,6 +285,41 @@ class EnvironmentTest < Test::Unit::TestCase
end
end
context "accessing the box collection" do
should "create a box collection representing the environment" do
env = vagrant_env
assert env.boxes.is_a?(Vagrant::BoxCollection)
assert_equal env, env.boxes.env
end
should "not load the environment if its already loaded" do
env = vagrant_env
env.expects(:load!).never
env.boxes
end
should "return the parent's box collection if it has one" do
env = vagrant_env(vagrantfile(<<-vf))
config.vm.define :web
config.vm.define :db
vf
assert env.vms[:web].env.boxes.equal?(env.boxes)
end
end
context "accessing the current box" do
should "return the box that is specified in the config" do
vagrant_box("foo")
env = vagrant_env(vagrantfile(<<-vf))
config.vm.box = "foo"
vf
assert env.box
assert_equal "foo", env.box.name
end
end
context "accessing the VMs hash" do
should "load the environment if its not already loaded" do
env = @klass.new(:cwd => vagrantfile)
@ -405,25 +440,6 @@ class EnvironmentTest < Test::Unit::TestCase
end
end
context "loading box" do
should "not load the box if its not set" do
env = vagrant_env
assert env.config.vm.box.nil?
Vagrant::Box.expects(:find).never
env.load_box!
end
should "set the box to what is found by the Box class" do
env = vagrant_env(vagrantfile("config.vm.box = 'foo'"))
@box = mock("box")
@box.stubs(:env=)
Vagrant::Box.expects(:find).with(env, env.config.vm.box).once.returns(@box)
env.load_box!
assert @box.equal?(env.box)
end
end
context "loading the UUID out from the persisted dotfile" do
setup do
@env = vagrant_env