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,11 +8,13 @@ module Vagrant
# TODO: Move more classes over to the autoload model. We'll # TODO: Move more classes over to the autoload model. We'll
# start small, but slowly move everything over. # start small, but slowly move everything over.
autoload :CLI, 'vagrant/cli' autoload :Box, 'vagrant/box'
autoload :Config, 'vagrant/config' autoload :BoxCollection, 'vagrant/box_collection'
autoload :DataStore, 'vagrant/data_store' autoload :CLI, 'vagrant/cli'
autoload :Errors, 'vagrant/errors' autoload :Config, 'vagrant/config'
autoload :Util, 'vagrant/util' autoload :DataStore, 'vagrant/data_store'
autoload :Errors, 'vagrant/errors'
autoload :Util, 'vagrant/util'
module Command module Command
autoload :Base, 'vagrant/command/base' autoload :Base, 'vagrant/command/base'

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 :parent # Parent environment (in the case of multi-VMs)
attr_reader :cwd attr_reader :cwd
attr_reader :box
attr_accessor :vm attr_accessor :vm
attr_writer :ui attr_writer :ui
@ -81,6 +80,17 @@ module Vagrant
vm.name rescue "vagrant" vm.name rescue "vagrant"
end 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. # Returns the VMs associated with this environment.
def vms def vms
return parent.vms if parent return parent.vms if parent
@ -252,7 +262,6 @@ module Vagrant
# After the first run we want to load the configuration again since # After the first run we want to load the configuration again since
# it can change due to box Vagrantfiles and home directory Vagrantfiles # it can change due to box Vagrantfiles and home directory Vagrantfiles
load_home_directory! load_home_directory!
load_box!
load_config! load_config!
end end
end end
@ -273,11 +282,6 @@ module Vagrant
end end
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. # Loads the persisted VM (if it exists) for this environment.
def load_vm! def load_vm!
# This environment represents a single sub VM. The VM is then # 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 # Cleans all the test temp paths
def clean_paths def clean_paths
FileUtils.rm_rf(tmp_path) 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 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
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 context "accessing the VMs hash" do
should "load the environment if its not already loaded" do should "load the environment if its not already loaded" do
env = @klass.new(:cwd => vagrantfile) env = @klass.new(:cwd => vagrantfile)
@ -405,25 +440,6 @@ class EnvironmentTest < Test::Unit::TestCase
end end
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 context "loading the UUID out from the persisted dotfile" do
setup do setup do
@env = vagrant_env @env = vagrant_env