./lib/coderay/helpers/plugin.rb in coderay-0.4.5.73 vs ./lib/coderay/helpers/plugin.rb in coderay-0.5.0.100

- old
+ new

@@ -1,8 +1,8 @@ # = PluginHost # -# $Id: plugin.rb 59 2005-10-29 04:55:15Z murphy $ +# $Id: plugin.rb 100 2005-12-10 04:20:30Z murphy $ # # A simple subclass plugin system. # # Example: # class Generators < PluginHost @@ -30,16 +30,46 @@ HostNotFound = Class.new Exception PLUGIN_HOSTS = [] PLUGIN_HOSTS_BY_ID = {} # dummy hash + # Loads all plugins using all_plugin_names and load. + def load_all + for plugin in all_plugin_names + load plugin + end + end + + # Returns the Plugin for +id+. + # + # Example: + # yaml_plugin = MyPluginHost[:yaml] + def [] id, *args, &blk + plugin = validate_id(id) + begin + plugin = plugin_hash.[] plugin, *args, &blk + end while plugin.is_a? Symbol + plugin + end + + # Alias for +[]+. + alias load [] + + def require_helper plugin_id, helper_name + path = path_to File.join(plugin_id, helper_name) + #$stderr.puts 'Loading helper: ' + path + require path + end + class << self + # Adds the module/class to the PLUGIN_HOSTS list. def extended mod PLUGIN_HOSTS << mod end + # Warns you that you should not #include this module. def included mod warn "#{name} should not be included. Use extend." end # Find the PluginHost for host_id. @@ -56,21 +86,15 @@ PLUGIN_HOSTS_BY_ID[host_id] end end - def plugin_host_id host_id - if host_id.is_a? String - raise ArgumentError, - "String or Symbol expected, but #{lang.class} given." - end - end - # The path where the plugins can be found. def plugin_path *args unless args.empty? - @plugin_path = File.join(*args) + @plugin_path = File.expand_path File.join(*args) + load_map end @plugin_path end # The host's ID. @@ -82,10 +106,48 @@ else name end 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 + def map hash + for from, to in hash + from = validate_id from + to = validate_id to + plugin_hash[from] = to unless plugin_hash.has_key? from + end + end + + # Every plugin must register itself for one or more + # +ids+ by calling register_for, which calls this method. + # + # See Plugin#register_for. + def register plugin, *ids + for id in ids + unless id.is_a? Symbol + raise ArgumentError, + "id must be a Symbol, but it was a #{id.class}" + end + plugin_hash[validate_id(id)] = plugin + end + end + + # A Hash of plugion_id => Plugin pairs. + def plugin_hash + @plugin_hash ||= create_plugin_hash + end + +protected + # Created a new plugin list and stores it to @plugin_hash. def create_plugin_hash @plugin_hash = Hash.new do |h, plugin_id| id = validate_id(plugin_id) path = path_to id @@ -103,59 +165,42 @@ end h[id] end end - def plugin_hash - @plugin_hash ||= create_plugin_hash + # Makes a map of all loaded scanners. + def inspect + map = plugin_hash.dup + map.each do |id, plugin| + map[id] = plugin.name[/(?>[\w_]+)$/] + end + map.inspect end - - # Every plugin must register itself for one or more - # +ids+ by calling register_for, which calls this method. + # Loads the map file (see map). # - # See Plugin#register_for. - def register plugin, *ids - for id in ids - unless id.is_a? Symbol - raise ArgumentError, - "id must be a Symbol, but it was a #{id.class}" - end - plugin_hash[validate_id(id)] = plugin + # This is done automatically when plaugin_path is called. + def load_map + begin + require path_to('_map') + rescue LoadError + warn 'no _map.rb found for %s' % name if $DEBUG end end - # Returns an array of all .rb files in the plugin path. # # The extension .rb is not included. def all_plugin_names - Dir[path_to('*')].map do |file| + Dir[path_to('*')].select do |file| + File.basename(file)[/^(?!_)\w+\.rb$/] + end.map do |file| File.basename file, '.rb' end end - # Loads all plugins using all_plugin_names and load. - def load_all - for plugin in all_plugin_names - load_plugin plugin - end - end - - # Returns the Plugin for +id+. - # - # Example: - # yaml_plugin = MyPluginHost[:yaml] - def [] id, *args, &blk - plugin_hash.[] validate_id(id), *args, &blk - end - - # Alias for +[]+. - alias load [] - - # Returns the Plugin for +id+. # Use it like Hash#fetch. # # Example: # yaml_plugin = MyPluginHost[:yaml, :default] def fetch id, *args, &blk @@ -165,21 +210,21 @@ # Returns the path to the encoder for format. def path_to plugin_id File.join plugin_path, "#{plugin_id}.rb" end - # Converts +id+ to a downcase Symbol if it is a String, + # 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). def validate_id id if id.is_a? Symbol id elsif id.is_a? String if id[/\w+/] == id - id.downcase.to_sym + id.to_sym else raise ArgumentError, "Invalid id: '#{id}' given." end else raise ArgumentError, @@ -223,10 +268,20 @@ end self.const_set :PLUGIN_HOST, host if host self::PLUGIN_HOST end + def helper *helpers + for helper in helpers + self::PLUGIN_HOST.require_helper plugin_id, helper.to_s + end + end + + def plugin_id + name[/[\w_]+$/].downcase + end + end # Convenience method for plugin loading. # The syntax used is: @@ -238,49 +293,6 @@ host_id, plugin_id = path.split '/', 2 host = PluginHost.host_by_id(host_id) raise PluginHost::HostNotFound, "No host for #{host_id.inspect} found." unless host host.load plugin_id -end - - -if $0 == __FILE__ - $VERBOSE = $DEBUG = true - eval DATA.read, nil, $0, __LINE__+4 -end - -__END__ - -require 'test/unit' - -class TC_PLUGINS < Test::Unit::TestCase - - class Generators - extend PluginHost - plugin_path '.' - end - - class Generator - extend Plugin - plugin_host Generators - end - - class FancyGenerator < Generator - register_for :plugin_host - end - - def test_plugin - assert_nothing_raised do - Generators[:plugin_host] - end - assert_equal FancyGenerator, Generators[:plugin_host] - end - - def test_require - assert_nothing_raised do - require_plugin('TC_PLUGINS::Generators/plugin_host') - end - assert_equal FancyGenerator, - require_plugin('TC_PLUGINS::Generators/plugin_host') - end - end