Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 6277

Show
Ignore:
Timestamp:
03/02/07 00:20:32 (1 year ago)
Author:
marcel
Message:

Split plugin location and loading out of the initializer and into a new Plugin namespace, which includes Plugin::Locater and Plugin::Loader. The loader class that is used can be customized using the config.plugin_loader option. Those monkey patching the plugin loading subsystem take note, the internals changing here will likely break your modifications. The good news is that it should be substantially easier to hook into the plugin locating and loading process now. [Marcel Molina Jr.]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/railties/CHANGELOG

    r6244 r6277  
    11*SVN* 
     2 
     3* Split plugin location and loading out of the initializer and into a new Plugin namespace, which includes Plugin::Locater and Plugin::Loader. The loader class that is used can be customized using the config.plugin_loader option.  Those monkey patching the plugin loading subsystem take note, the internals changing here will likely break your modifications. The good news is that it should be substantially easier to hook into the plugin locating and loading process now.  [Marcel Molina Jr.] 
    24 
    35* Added assumption that all plugin creators desire to be sharing individuals and release their work under the MIT license [DHH] 
  • trunk/railties/lib/initializer.rb

    r6212 r6277  
    33require File.join(File.dirname(__FILE__), 'railties_path') 
    44require File.join(File.dirname(__FILE__), 'rails/version') 
     5require File.join(File.dirname(__FILE__), 'plugin/locater') 
     6require File.join(File.dirname(__FILE__), 'plugin/loader') 
     7 
    58 
    69RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV) 
     
    185188    # order. 
    186189    def load_plugins 
    187       if configuration.plugins.nil? 
    188         # a nil value implies we don't care about plugins; load 'em all in a reliable order 
    189         find_plugins(configuration.plugin_paths).sort.each { |path| load_plugin path } 
    190       elsif !configuration.plugins.empty? 
    191         # we've specified a config.plugins array, so respect that order 
    192         plugin_paths = find_plugins(configuration.plugin_paths) 
    193         configuration.plugins.each do |name| 
    194           path = plugin_paths.find { |p| File.basename(p) == name } 
    195           raise(LoadError, "Cannot find the plugin '#{name}'!") if path.nil? 
    196           load_plugin path 
    197         end 
    198       end  
    199       $LOAD_PATH.uniq! 
     190      Plugin::Locater.new(self).each do |plugin| 
     191        plugin.load 
     192      end 
     193      $LOAD_PATH.uniq!       
    200194    end 
    201195 
     
    344338      end 
    345339    end 
    346  
    347     protected 
    348       # Return a list of plugin paths within base_path.  A plugin path is 
    349       # a directory that contains either a lib directory or an init.rb file. 
    350       # This recurses into directories which are not plugin paths, so you 
    351       # may organize your plugins within the plugin path. 
    352       def find_plugins(*base_paths) 
    353         base_paths.flatten.inject([]) do |plugins, base_path| 
    354           Dir.glob(File.join(base_path, '*')).each do |path| 
    355             if plugin_path?(path) 
    356               plugins << path if plugin_enabled?(path) 
    357             elsif File.directory?(path) 
    358               plugins += find_plugins(path) 
    359             end 
    360           end 
    361           plugins 
    362         end 
    363       end 
    364  
    365       def plugin_path?(path) 
    366         File.directory?(path) and (File.directory?(File.join(path, 'lib')) or File.file?(File.join(path, 'init.rb'))) 
    367       end 
    368  
    369       def plugin_enabled?(path) 
    370         configuration.plugins.nil? || configuration.plugins.include?(File.basename(path)) 
    371       end 
    372  
    373       # Load the plugin at <tt>path</tt> unless already loaded. 
    374       # 
    375       # Each plugin is initialized: 
    376       # * add its +lib+ directory, if present, to the beginning of the load path 
    377       # * evaluate <tt>init.rb</tt> if present 
    378       # 
    379       # Returns <tt>true</tt> if the plugin is successfully loaded or 
    380       # <tt>false</tt> if it is already loaded (similar to Kernel#require). 
    381       # Raises <tt>LoadError</tt> if the plugin is not found. 
    382       def load_plugin(directory) 
    383         name = File.basename(directory) 
    384         return false if loaded_plugins.include?(name) 
    385  
    386         # Catch nonexistent and empty plugins. 
    387         raise LoadError, "No such plugin: #{directory}" unless plugin_path?(directory) 
    388  
    389         lib_path  = File.join(directory, 'lib') 
    390         init_path = File.join(directory, 'init.rb') 
    391         has_lib   = File.directory?(lib_path) 
    392         has_init  = File.file?(init_path) 
    393  
    394         # Add lib to load path *after* the application lib, to allow 
    395         # application libraries to override plugin libraries. 
    396         if has_lib 
    397           application_lib_index = $LOAD_PATH.index(File.join(RAILS_ROOT, "lib")) || 0 
    398           $LOAD_PATH.insert(application_lib_index + 1, lib_path) 
    399           Dependencies.load_paths << lib_path 
    400           Dependencies.load_once_paths << lib_path 
    401         end 
    402  
    403         # Allow plugins to reference the current configuration object 
    404         config = configuration 
    405          
    406         # Add to set of loaded plugins before 'name' collapsed in eval. 
    407         loaded_plugins << name 
    408  
    409         # Evaluate init.rb. 
    410         silence_warnings { eval(IO.read(init_path), binding, init_path) } if has_init 
    411  
    412         true 
    413       end 
    414340  end 
    415341 
     
    503429    # <tt>vendor/plugins</tt>. 
    504430    attr_accessor :plugin_paths 
     431     
     432    # The class that handles loading each plugin. Defaults to Rails::Plugin::Loader, but  
     433    # a sub class would have access to fine grained modification of the loading behavior. See 
     434    # the implementation of Rails::Plugin::Loader for more details. 
     435    attr_accessor :plugin_loader 
    505436 
    506437    # Create a new Configuration instance, initialized with the default 
     
    519450      self.plugins                      = default_plugins 
    520451      self.plugin_paths                 = default_plugin_paths 
     452      self.plugin_loader                = default_plugin_loader 
    521453      self.database_configuration_file  = default_database_configuration_file 
    522454 
     
    673605        ["#{root_path}/vendor/plugins"] 
    674606      end 
     607       
     608      def default_plugin_loader 
     609        Plugin::Loader 
     610      end 
    675611  end 
    676612end