Basic Plugin class

This commit is contained in:
Mitchell Hashimoto 2012-04-15 15:34:44 -05:00
parent 4034a2db21
commit 2eebc2cb68
5 changed files with 144 additions and 0 deletions

View File

@ -91,6 +91,22 @@ module Vagrant
@source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
end
# Returns a superclass to use when creating a plugin for Vagrant.
# Given a specific version, this returns a proper superclass to use
# to register plugins for that version.
#
# Plugins should subclass the class returned by this method, and will
# be registered as soon as they have a name associated with them.
#
# @return [Class]
def self.plugin(version)
# We only support version 1 right now.
return Plugin::V1 if version == "1"
# Raise an error that the plugin version is invalid
raise ArgumentError, "Invalid plugin version API: #{version}"
end
# Global registry of commands that are available via the CLI.
#
# This registry is used to look up the sub-commands that are available

View File

@ -9,6 +9,9 @@ module Vagrant
# (for debugging), the list of loaded plugins is stored in the {plugins}
# array.
class Plugin
# XXX: Make Plugin a module at some point
autoload :V1, 'vagrant/plugin/v1'
# The array of gem specifications that were loaded as plugins.
@@plugins = []

68
lib/vagrant/plugin/v1.rb Normal file
View File

@ -0,0 +1,68 @@
module Vagrant
class Plugin
# The superclass for version 1 plugins.
class V1
# Returns a list of registered plugins for this version.
#
# @return [Array]
def self.registered
@registry || []
end
# Set the name of the plugin. The moment that this is called, the
# plugin will be registered and available. Before this is called, a
# plugin does not exist. The name must be unique among all installed
# plugins.
#
# @param [String] name Name of the plugin.
# @return [String] The name of the plugin.
def self.name(name=UNSET_VALUE)
# The plugin should be registered if we're setting a real name on it
register!(self) if name != UNSET_VALUE
# Get or set the value
get_or_set(:name, name)
end
# Sets a human-friendly descrition of the plugin.
#
# @param [String] value Description of the plugin.
# @return [String] Description of the plugin.
def self.description(value=UNSET_VALUE)
get_or_set(:description, value)
end
protected
# Sentinel value denoting that a value has not been set.
UNSET_VALUE = Object.new
# Helper method that will set a value if a value is given, or otherwise
# return the already set value.
#
# @param [Symbol] key Key for the data
# @param [Object] value Value to store.
# @return [Object] Stored value.
def self.get_or_set(key, value=UNSET_VALUE)
@data ||= {}
# If no value is to be set, then return the value we have already set
return @data[key] if value.eql?(UNSET_VALUE)
# Otherwise set the value
@data[key] = value
end
# Registers the plugin. This makes the plugin actually work with
# Vagrant. Prior to registering, the plugin is merely a skeleton.
def self.register!(plugin)
# Register only on the root class
return V1.register!(plugin) if self != V1
# Register it into the list
@registry ||= []
@registry << plugin if !@registry.include?(plugin)
end
end
end
end

View File

@ -0,0 +1,46 @@
require File.expand_path("../../../base", __FILE__)
describe Vagrant::Plugin::V1 do
after(:each) do
# We want to make sure that the registered plugins remains empty
# after each test.
described_class.registered.clear
end
it "should be able to set and get the name" do
plugin = Class.new(described_class) do
name "foo"
end
plugin.name.should == "foo"
end
it "should be able to set and get the description" do
plugin = Class.new(described_class) do
description "bar"
end
plugin.description.should == "bar"
end
it "should have no registered plugins" do
described_class.registered.should be_empty
end
it "should register a plugin when a name is set" do
plugin = Class.new(described_class) do
name "foo"
end
described_class.registered.should == [plugin]
end
it "should register a plugin only once" do
plugin = Class.new(described_class) do
name "foo"
name "bar"
end
described_class.registered.should == [plugin]
end
end

View File

@ -24,4 +24,15 @@ describe Vagrant do
it "has a registry for provisioners" do
described_class.provisioners.should be_a(Vagrant::Registry)
end
describe "plugin superclass" do
it "returns the proper class for version 1" do
described_class.plugin("1").should == Vagrant::Plugin::V1
end
it "raises an exception if an unsupported version is given" do
expect { described_class.plugin("88") }.
to raise_error(ArgumentError)
end
end
end