module Kitchen::Plugin
def self.load(type, plugin, config)
-
(UserError)- if the plugin's dependencies could not be met -
(ClientError)- if a plugin instance could not be created
Returns:
-
(Kitchen::- a plugin instance::Base)
Parameters:
-
config(Hash) -- a configuration hash to initialize the plugin -
plugin(String) -- a plugin name, which will be constantized -
type(Module) -- a Kitchen::of one of the plugin types
def self.load(type, plugin, config) type_name = Kitchen::Util.snake_case(type.name.split("::").last) first_load = require("kitchen/#{type_name}/#{plugin}") str_const = Kitchen::Util.camel_case(plugin) klass = type.const_get(str_const) object = klass.new(config) object.verify_dependencies if first_load object rescue UserError raise rescue NameError => e raise ClientError, "Could not load the '#{plugin}' #{type_name}. Error: #{e.message}" rescue LoadError => e available_plugins = plugins_available(type_name) error_message = if available_plugins.include?(plugin) e.message else " Did you mean: #{available_plugins.join(", ")} ?" \ " Please ensure that your #{type_name} is installed as a gem or included" \ " in your Gemfile if using Bundler." end raise ClientError, "Could not load the '#{plugin}' #{type_name} from the load path." + error_message end
def self.plugins_available(plugin_type)
-
(Array- a collection of Ruby filenames that are probably)
Parameters:
-
plugin_type(String) -- the name of a plugin type (e.g. driver,
def self.plugins_available(plugin_type) $LOAD_PATH.map { |load_path| Dir[File.expand_path("kitchen/#{plugin_type}/*.rb", load_path)] } .reject(&:empty?) .flatten .uniq .select { |plugin_path| File.readlines(plugin_path).grep(/^\s*class \w* </).any? } .map { |plugin_path| File.basename(plugin_path).gsub(/\.rb$/, "") } .reject { |plugin_name| plugin_name == "base" } .sort end