Pluginator
Gem plugin system management, detects plugins using Gem.find_file
,
$LOAD_PATH
and $LOADED_FEATURES
.
Pluginator works with ruby 1.9.3+ and rubygems 2.0.0+.
Pluginator tries to stay out of your way, you do not have to include or inherit anything. Pluginator only finds and groups plugins, rest is up to you, you decide what methods to define and how to find them.
Defining plugins
create a gem with a path:
lib/plugins/<group>/<type>/<name>.rb
with a class inside:
<group>::<type>::<name>
where <type>
can be nested
Loading plugins
rvm2plugins = Pluginator.find("<group>")
type_plugins = rvm2plugins["<type>"]
types = rvm2plugins.types
Usage
Pluginator.find("<group>") => Pluginator object
plugins = Pluginator.find("<group>", type: "<type>", prefix: "/(lib|local_lib)", extends: %i[<extensions>])
plugins["<type>"] => Array of plugins
plugins.type => Array of plugins for type defined with `type: "<type>"`
plugins.types => Array of types
-
"<group>"
- Load plugins for given group. -
type: "<type>"
- Load plugins only of given type, optional, makestype
method accessible. -
prefix: "/prefix"
- Load plugins only from this paths, optional, default/lib
. -
extends: %i[<extensions>]
- Extend pluginator with given extensions.
Extensions
Pluginator comes with few handful extensions.
Class exist
Check if plugin with given class name exists.
plugins = Pluginator.find("<group>", extends: %i[class_exist]})
plugins.class_exist?("<type>", "<name>") => true or false
First ask
Call a method on plugin and return first one that returns true
.
plugins = Pluginator.find("<group>", extends: %i[first_ask])
plugins.first_ask( "<type>", "method_to_call", *params) => plugin or nil
plugins.first_ask!("<type>", "method_to_call", *params) => plugin or exception PluginatorError
First class
Find first plugin that class matches the given name.
plugins = Pluginator.find("<group>", extends: %i[first_class])
plugins.first_class( "<type>", "<name>") => plugin or nil
plugins.first_class!("<type>", "<name>") => plugin or exception PluginatorError
Matching
Map array of names to available plugins.
plugins = Pluginator.find("<group>", extends: %i[matching])
plugins.matching( "<type>", [<array_of_names>]) => [plugins] # nil for missing ones
plugins.matching!("<type>", [<array_of_names>]) => [plugins] or exception PluginatorError
Your own ones
You can define your own extensions for pluginator
, for example:
plugins/pluginator/extensions/first_one.rb
with:
module Pluginator::Extensions
class FirstOne
def first_one(type)
@plugins[type].first
end
end
end
And now you can use it:
plugins = Pluginator.find("<group>", extends: %i[first_one])
plugins.first_one("<type>") => first_plugin # nil when none
Exceptions
-
PluginatorError
- base error for all Pluginator errors -
MissingPlugin
- raised when plugin can not be found, generated by*!
methods -
MissingType
- raised when type can not be found, generated by*!
methods
Versioning plugins
In case plugin gets moved to other gem you can specify which gem to use for loading the plugin by specifying plugin version in gems gemspec metadata:
s.metadata = {
"plugins/v2test/stats/max.rb" => "1"
}
Examples
Example 1 - task plugins
plugins/rvm2/cli/echo.rb
:
class Rvm2::Cli::Echo
def self.question? command
command == "echo"
end
def answer param
puts param
end
end
where question?
and answer
are user defined methods
Now the plugin can be used:
require "pluginator"
rvm2plugins = Pluginator.find("rvm2")
plugin = rvm2plugins["cli"].first{ |plugin|
plugin.question?("echo")
}
plugin.new.answer("Hello world")
Or using extensions:
require "pluginator"
plugin = Pluginator.find("rvm2", extends: %i[first_ask]).first_ask("cli", &:question?, "echo")
plugin.new.answer("Hello world")
Example 2 - hook plugins
plugins/rvm2/hooks/after_install/show.rb
:
class Rvm2::Hooks::AfterInstall::Show
def self.execute name, path
puts "Ruby #{name.inspect} was installed in #{path.inspect}."
end
end
and using hooks:
require "pluginator"
Pluginator.find("rvm2", type: "hooks/after_install").type.each{ |plugin|
plugin.execute(name, path)
}
Testing
NOEXEC_DISABLE=1 rake test
License
Copyright 2013-2017 Michal Papis mpapis@gmail.com
pluginator is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
pluginator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with pluginator. If not, see http://www.gnu.org/licenses/.
For details on adding copyright visit: https://www.gnu.org/licenses/gpl-howto.html