Class: GemPlugin::Manager
- Inherits:
-
Object
- Object
- GemPlugin::Manager
- Includes:
- Singleton
- Defined in:
- lib/gem_plugin.rb
Overview
This class is used by people who use gem plugins (but don’t necessarily make them) to add plugins to their own systems. It provides a way to load plugins, list them, and create them as needed.
It is a singleton so you use like this: GemPlugins::Manager.instance.load
Instance Method Summary collapse
-
#available ⇒ Object
Returns a map of URIs->=> Plugin that you can use to investigate available handlers.
-
#create(name, options = {}) ⇒ Object
Resolves the given name (should include /category/name) to find the plugin class and create an instance.
-
#initialize ⇒ Manager
constructor
A new instance of Manager.
-
#load(needs = {}) ⇒ Object
Responsible for going through the list of available gems and loading any plugins requested.
-
#register(category, name, klass) ⇒ Object
Not necessary for you to call directly, but this is how GemPlugin::Base.inherited actually adds a plugin to a category.
Constructor Details
#initialize ⇒ Manager
Returns a new instance of Manager.
63 64 65 66 |
# File 'lib/gem_plugin.rb', line 63 def initialize @plugins = {} @loaded_gems = [] end |
Instance Method Details
#available ⇒ Object
Returns a map of URIs->=> Plugin that you can use to investigate available handlers.
151 152 153 |
# File 'lib/gem_plugin.rb', line 151 def available return @plugins end |
#create(name, options = {}) ⇒ Object
Resolves the given name (should include /category/name) to find the plugin class and create an instance. You can pass a second hash option that is then given to the Plugin to configure it.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/gem_plugin.rb', line 133 def create(name, = {}) last_slash = name.rindex("/") category = name[0 ... last_slash] plugin = name[last_slash .. -1] map = @plugins[category] if not map raise "Plugin category #{category} does not exist" elsif not map.has_key? plugin raise "Plugin #{plugin} does not exist in category #{category}" else map[plugin].new() end end |
#load(needs = {}) ⇒ Object
Responsible for going through the list of available gems and loading any plugins requested. It keeps track of what it’s loaded already and won’t load them again.
It accepts one parameter which is a hash of gem depends that should include or exclude a gem from being loaded. A gem must depend on gem_plugin to be considered, but then each system has to add it’s own INCLUDE to make sure that only plugins related to it are loaded.
An example again comes from Mongrel. In order to load all Mongrel plugins:
GemPlugin::Manager.instance.load "mongrel" => GemPlugin::INCLUDE
Which will load all plugins that depend on mongrel AND gem_plugin. Now, one extra thing we do is we delay loading Rails Mongrel plugins until after rails is configured. Do do this the mongrel_rails script has:
GemPlugin::Manager.instance.load "mongrel" => GemPlugin::INCLUDE, "rails" => GemPlugin::EXCLUDE
The only thing to remember is that this is saying “include a plugin if it depends on gem_plugin, mongrel, but NOT rails”. If a plugin also depends on other stuff then it’s loaded just fine. Only gem_plugin, mongrel, and rails are ever used to determine if it should be included.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/gem_plugin.rb', line 91 def load(needs = {}) sdir = File.join(Gem.dir, "specifications") gems = Gem::SourceIndex.from_installed_gems(sdir) needs = needs.merge({"gem_plugin" => INCLUDE}) gems.each do |path, gem| # don't load gems more than once next if @loaded_gems.include? gem.name check = needs.dup # rolls through the depends and inverts anything it finds gem.dependencies.each do |dep| # this will fail if a gem is depended more than once if check.has_key? dep.name check[dep.name] = !check[dep.name] end end # now since excluded gems start as true, inverting them # makes them false so we'll skip this gem if any excludes are found if (check.select {|name,test| !test}).length == 0 # looks like no needs were set to false, so it's good require_gem gem.name @loaded_gems << gem.name end end end |
#register(category, name, klass) ⇒ Object
Not necessary for you to call directly, but this is how GemPlugin::Base.inherited actually adds a plugin to a category.
124 125 126 127 |
# File 'lib/gem_plugin.rb', line 124 def register(category, name, klass) @plugins[category] ||= {} @plugins[category][name.downcase] = klass end |