From 59e1e43c74f56789662262a6a65e6e795148a535 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 3 Sep 2010 09:33:15 -0700 Subject: [PATCH] Autoload the util classes. HashWithIndifferentAccess for data store --- lib/vagrant.rb | 4 +- lib/vagrant/util.rb | 12 ++++ lib/vagrant/util/glob_loader.rb | 36 ++++++----- .../util/hash_with_indifferent_access.rb | 63 +++++++++++++++++++ .../util/hash_with_indifferent_access_test.rb | 30 +++++++++ 5 files changed, 126 insertions(+), 19 deletions(-) create mode 100644 lib/vagrant/util.rb create mode 100644 lib/vagrant/util/hash_with_indifferent_access.rb create mode 100644 test/vagrant/util/hash_with_indifferent_access_test.rb diff --git a/lib/vagrant.rb b/lib/vagrant.rb index e14446b13..588b34454 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -2,7 +2,6 @@ require 'json' require 'i18n' require 'virtualbox' require 'radar' -require 'vagrant/util/glob_loader' module Vagrant # TODO: Move more classes over to the autoload model. We'll @@ -12,6 +11,7 @@ module Vagrant autoload :Config, 'vagrant/config' autoload :DataStore, 'vagrant/data_store' autoload :Errors, 'vagrant/errors' + autoload :Util, 'vagrant/util' module Command autoload :Base, 'vagrant/command/base' @@ -41,7 +41,7 @@ I18n.load_path << File.expand_path("templates/locales/en.yml", Vagrant.source_ro # Load them up. One day we'll convert this to autoloads. Today # is not that day. Low hanging fruit for anyone wishing to do it. libdir = File.expand_path("lib/vagrant", Vagrant.source_root) -Vagrant::GlobLoader.glob_require(libdir, %w{util/stacked_proc_runner +Vagrant::Util::GlobLoader.glob_require(libdir, %w{ downloaders/base provisioners/base provisioners/chef systems/base hosts/base}) diff --git a/lib/vagrant/util.rb b/lib/vagrant/util.rb new file mode 100644 index 000000000..83bb78662 --- /dev/null +++ b/lib/vagrant/util.rb @@ -0,0 +1,12 @@ +module Vagrant + module Util + autoload :Busy, 'vagrant/util/busy' + autoload :GlobLoader, 'vagrant/util/glob_loader' + autoload :HashWithIndifferentAccess, 'vagrant/util/hash_with_indifferent_access' + autoload :PlainLogger, 'vagrant/util/plain_logger' + autoload :Platform, 'vagrant/util/platform' + autoload :ResourceLogger, 'vagrant/util/resource_logger' + autoload :StackedProcRunner, 'vagrant/util/stacked_proc_runner' + autoload :TemplateRenderer, 'vagrant/util/template_renderer' + end +end diff --git a/lib/vagrant/util/glob_loader.rb b/lib/vagrant/util/glob_loader.rb index 149b7654d..48cc34e19 100644 --- a/lib/vagrant/util/glob_loader.rb +++ b/lib/vagrant/util/glob_loader.rb @@ -1,22 +1,24 @@ module Vagrant - # Eases the processes of loading specific files then globbing - # the rest from a specified directory. - module GlobLoader - # Glob requires all ruby files in a directory, optionally loading select - # files initially (since others may depend on them). - # - # @param [String] dir The directory to glob - # @param [Array] initial_files Initial files (relative to `dir`) - # to load - def self.glob_require(dir, initial_files=[]) - initial_files.each do |file| - require File.expand_path(file, dir) - end + module Util + # Eases the processes of loading specific files then globbing + # the rest from a specified directory. + module GlobLoader + # Glob requires all ruby files in a directory, optionally loading select + # files initially (since others may depend on them). + # + # @param [String] dir The directory to glob + # @param [Array] initial_files Initial files (relative to `dir`) + # to load + def self.glob_require(dir, initial_files=[]) + initial_files.each do |file| + require File.expand_path(file, dir) + end - # Glob require the rest - Dir[File.join(dir, "**", "*.rb")].each do |f| - require File.expand_path(f) + # Glob require the rest + Dir[File.join(dir, "**", "*.rb")].each do |f| + require File.expand_path(f) + end end end end -end \ No newline at end of file +end diff --git a/lib/vagrant/util/hash_with_indifferent_access.rb b/lib/vagrant/util/hash_with_indifferent_access.rb new file mode 100644 index 000000000..176cfb9d6 --- /dev/null +++ b/lib/vagrant/util/hash_with_indifferent_access.rb @@ -0,0 +1,63 @@ +module Vagrant + module Util + # A hash with indifferent access. Mostly taken from Thor/Rails (thanks). + # Normally I'm not a fan of using an indifferent access hash sine Symbols + # are basically memory leaks in Ruby, but since Vagrant is typically a quick + # one-off binary run and it doesn't use too many hash keys where this is + # used, the effect should be minimal. + # + # hash[:foo] #=> 'bar' + # hash['foo'] #=> 'bar' + # + class HashWithIndifferentAccess < ::Hash + def initialize(hash={}) + super() + + hash.each do |key, value| + self[convert_key(key)] = value + end + end + + def [](key) + super(convert_key(key)) + end + + def []=(key, value) + super(convert_key(key), value) + end + + def delete(key) + super(convert_key(key)) + end + + def values_at(*indices) + indices.collect { |key| self[convert_key(key)] } + end + + def merge(other) + dup.merge!(other) + end + + def merge!(other) + other.each do |key, value| + self[convert_key(key)] = value + end + self + end + + def key?(key) + super(convert_key(key)) + end + + alias_method :include?, :key? + alias_method :has_key?, :key? + alias_method :member?, :key? + + protected + + def convert_key(key) + key.is_a?(Symbol) ? key.to_s : key + end + end + end +end diff --git a/test/vagrant/util/hash_with_indifferent_access_test.rb b/test/vagrant/util/hash_with_indifferent_access_test.rb new file mode 100644 index 000000000..acf94dfd6 --- /dev/null +++ b/test/vagrant/util/hash_with_indifferent_access_test.rb @@ -0,0 +1,30 @@ +require "test_helper" + +class HashWithIndifferentAccessUtilTest < Test::Unit::TestCase + setup do + @klass = Vagrant::Util::HashWithIndifferentAccess + @instance = @klass.new + end + + should "be a hash" do + assert @instance.is_a?(Hash) + end + + should "allow indifferent access when setting with a string" do + @instance["foo"] = "bar" + assert_equal "bar", @instance[:foo] + end + + should "allow indifferent access when setting with a symbol" do + @instance[:foo] = "bar" + assert_equal "bar", @instance["foo"] + end + + should "allow indifferent key lookup" do + @instance["foo"] = "bar" + assert @instance.key?(:foo) + assert @instance.has_key?(:foo) + assert @instance.include?(:foo) + assert @instance.member?(:foo) + end +end