Module | CodeRay::PluginHost |
In: |
lib/coderay/helpers/plugin.rb
|
A simple subclass/subfolder plugin system.
Example:
class Generators extend PluginHost plugin_path 'app/generators' end class Generator extend Plugin PLUGIN_HOST = Generators end class FancyGenerator < Generator register_for :fancy end Generators[:fancy] #-> FancyGenerator # or CodeRay.require_plugin 'Generators/fancy' # or Generators::Fancy
Tries to load the missing plugin by translating const to the underscore form (eg. LinesOfCode becomes lines_of_code).
# File lib/coderay/helpers/plugin.rb, line 61 61: def const_missing const 62: id = const.to_s. 63: gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). 64: gsub(/([a-z\d])([A-Z])/,'\1_\2'). 65: downcase 66: load id 67: end
Define the default plugin to use when no plugin is found for a given id, or return the default plugin.
See also map.
class MyColorHost < PluginHost map :navy => :dark_blue default :gray end MyColorHost.default # loads and returns the Gray plugin
# File lib/coderay/helpers/plugin.rb, line 114 114: def default id = nil 115: if id 116: id = validate_id id 117: raise "The default plugin can't be named \"default\"." if id == :default 118: plugin_hash[:default] = id 119: else 120: load :default 121: end 122: end
Returns an array of all .rb files in the plugin path.
The extension .rb is not included.
# File lib/coderay/helpers/plugin.rb, line 140 140: def list 141: Dir[path_to('*')].select do |file| 142: File.basename(file)[/^(?!_)\w+\.rb$/] 143: end.map do |file| 144: File.basename(file, '.rb').to_sym 145: end 146: end
This is done automatically when plugin_path is called.
# File lib/coderay/helpers/plugin.rb, line 159 159: def load_plugin_map 160: mapfile = path_to '_map' 161: @plugin_map_loaded = true 162: if File.exist? mapfile 163: require mapfile 164: true 165: else 166: false 167: end 168: end
Map a plugin_id to another.
Usage: Put this in a file plugin_path/_map.rb.
class MyColorHost < PluginHost map :navy => :dark_blue, :maroon => :brown, :luna => :moon end
# File lib/coderay/helpers/plugin.rb, line 95 95: def map hash 96: for from, to in hash 97: from = validate_id from 98: to = validate_id to 99: plugin_hash[from] = to unless plugin_hash.has_key? from 100: end 101: end
The path where the plugins can be found.
# File lib/coderay/helpers/plugin.rb, line 79 79: def plugin_path *args 80: unless args.empty? 81: @plugin_path = File.expand_path File.join(*args) 82: end 83: @plugin_path ||= '' 84: end
Every plugin must register itself for id by calling register_for, which calls this method.
See Plugin#register_for.
# File lib/coderay/helpers/plugin.rb, line 128 128: def register plugin, id 129: plugin_hash[validate_id(id)] = plugin 130: end
Return a plugin hash that automatically loads plugins.
# File lib/coderay/helpers/plugin.rb, line 173 173: def make_plugin_hash 174: @plugin_map_loaded ||= false 175: Hash.new do |h, plugin_id| 176: id = validate_id(plugin_id) 177: path = path_to id 178: begin 179: require path 180: rescue LoadError => boom 181: if @plugin_map_loaded 182: if h.has_key?(:default) 183: warn '%p could not load plugin %p; falling back to %p' % [self, id, h[:default]] 184: h[:default] 185: else 186: raise PluginNotFound, '%p could not load plugin %p: %s' % [self, id, boom] 187: end 188: else 189: load_plugin_map 190: h[plugin_id] 191: end 192: else 193: # Plugin should have registered by now 194: if h.has_key? id 195: h[id] 196: else 197: raise PluginNotFound, "No #{self.name} plugin for #{id.inspect} found in #{path}." 198: end 199: end 200: end 201: end
Returns the expected path to the plugin file for the given id.
# File lib/coderay/helpers/plugin.rb, line 204 204: def path_to plugin_id 205: File.join plugin_path, "#{plugin_id}.rb" 206: end
Converts id to a Symbol if it is a String, or returns id if it already is a Symbol.
Raises ArgumentError for all other objects, or if the given String includes non-alphanumeric characters (\W).
# File lib/coderay/helpers/plugin.rb, line 213 213: def validate_id id 214: if id.is_a? Symbol or id.nil? 215: id 216: elsif id.is_a? String 217: if id[/\w+/] == id 218: id.downcase.to_sym 219: else 220: raise ArgumentError, "Invalid id given: #{id}" 221: end 222: else 223: raise ArgumentError, "String or Symbol expected, but #{id.class} given." 224: end 225: end