Basic Plugin class
This commit is contained in:
parent
4034a2db21
commit
2eebc2cb68
|
@ -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
|
||||
|
|
|
@ -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 = []
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue