From 82b9b151ffde44305d67744c0bfd9bb5505f6fbe Mon Sep 17 00:00:00 2001
From: Yehuda Katz + Carl Lerche <ykatz+clerche@engineyard.com>
Date: Fri, 6 Nov 2009 17:21:39 -0800
Subject: Refactor plugins

---
 railties/lib/rails.rb                |  12 ++
 railties/lib/rails/application.rb    |  50 +++------
 railties/lib/rails/configuration.rb  |  33 +-----
 railties/lib/rails/initializable.rb  |   3 +-
 railties/lib/rails/initializer.rb    |  14 +--
 railties/lib/rails/paths.rb          |   6 +-
 railties/lib/rails/plugin.rb         | 209 ++++++++---------------------------
 railties/lib/rails/plugin/loader.rb  | 200 ---------------------------------
 railties/lib/rails/plugin/locator.rb | 100 -----------------
 9 files changed, 82 insertions(+), 545 deletions(-)
 delete mode 100644 railties/lib/rails/plugin/loader.rb
 delete mode 100644 railties/lib/rails/plugin/locator.rb

(limited to 'railties/lib')

diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb
index 43ece14a49..c23b67e321 100644
--- a/railties/lib/rails.rb
+++ b/railties/lib/rails.rb
@@ -1 +1,13 @@
+require "pathname"
+
+require 'rails/initializable'
+require 'rails/application'
+require 'rails/railties_path'
+require 'rails/version'
+require 'rails/rack'
+require 'rails/paths'
+require 'rails/core'
+require 'rails/configuration'
+require 'rails/deprecation'
 require 'rails/initializer'
+require 'rails/plugin'
\ No newline at end of file
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index b43dcb0041..10cba8ab6c 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -23,10 +23,6 @@ module Rails
         @config = config
       end
 
-      def plugin_loader
-        @plugin_loader ||= config.plugin_loader.new(self)
-      end
-
       def root
         config.root
       end
@@ -37,7 +33,7 @@ module Rails
     end
 
     def initialize
-      run_initializers
+      run_initializers(self)
     end
 
     def config
@@ -46,10 +42,6 @@ module Rails
 
     alias configuration config
 
-    def plugin_loader
-      self.class.plugin_loader
-    end
-
     def middleware
       config.middleware
     end
@@ -58,6 +50,18 @@ module Rails
       ActionController::Routing::Routes
     end
 
+    def initializers
+      initializers = super
+      plugins.each { |p| initializers += p.initializers }
+      initializers
+    end
+
+    def plugins
+      @plugins ||= begin
+        Plugin::Vendored.all(config.plugins || [:all], config.paths.vendor.plugins)
+      end
+    end
+
     def call(env)
       @app ||= middleware.build(routes)
       @app.call(env)
@@ -111,13 +115,6 @@ module Rails
       config.load_once_paths.freeze
     end
 
-    # Adds all load paths from plugins to the global set of load paths, so that
-    # code from plugins can be required (explicitly or automatically via ActiveSupport::Dependencies).
-    initializer :add_plugin_load_paths do
-      require 'active_support/dependencies'
-      plugin_loader.add_plugin_load_paths
-    end
-
     # Create tmp directories
     initializer :ensure_tmp_directories_exist do
       %w(cache pids sessions sockets).each do |dir_to_make|
@@ -321,7 +318,6 @@ module Rails
       # TODO: Make Rails and metal work without ActionController
       if config.frameworks.include?(:action_controller)
         Rails::Rack::Metal.requested_metals = config.metals
-        Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
 
         config.middleware.insert_before(
           :"ActionDispatch::ParamsParser",
@@ -329,26 +325,6 @@ module Rails
       end
     end
 
-    # Loads all plugins in <tt>config.plugin_paths</tt>.  <tt>plugin_paths</tt>
-    # defaults to <tt>vendor/plugins</tt> but may also be set to a list of
-    # paths, such as
-    #   config.plugin_paths = ["#{config.root}/lib/plugins", "#{config.root}/vendor/plugins"]
-    #
-    # In the default implementation, as each plugin discovered in <tt>plugin_paths</tt> is initialized:
-    # * its +lib+ directory, if present, is added to the load path (immediately after the applications lib directory)
-    # * <tt>init.rb</tt> is evaluated, if present
-    #
-    # After all plugins are loaded, duplicates are removed from the load path.
-    # If an array of plugin names is specified in config.plugins, only those plugins will be loaded
-    # and they plugins will be loaded in that order. Otherwise, plugins are loaded in alphabetical
-    # order.
-    #
-    # if config.plugins ends contains :all then the named plugins will be loaded in the given order and all other
-    # plugins will be loaded in alphabetical order
-    initializer :load_plugins do
-      plugin_loader.load_plugins
-    end
-
     # # bail out if gems are missing - note that check_gem_dependencies will have
     # # already called abort() unless $gems_rake_task is set
     # return unless gems_dependencies_loaded
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index 2b847ba711..102a0836dc 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -1,17 +1,13 @@
-require 'rails/plugin/loader'
-require 'rails/plugin/locator'
 require 'active_support/ordered_options'
 
 module Rails
   class Configuration
-    attr_accessor :cache_classes, :load_paths,
-                  :load_once_paths, :after_initialize_blocks,
-                  :frameworks, :framework_root_path, :root, :plugin_paths, :plugins,
-                  :plugin_loader, :plugin_locators, :gems, :loaded_plugins, :reload_plugins,
+    attr_accessor :cache_classes, :load_paths, :load_once_paths, :after_initialize_blocks,
+                  :frameworks, :framework_root_path, :root, :gems, :plugins,
                   :i18n, :gems, :whiny_nils, :consider_all_requests_local,
                   :action_controller, :active_record, :action_view, :active_support,
                   :action_mailer, :active_resource,
-                  :log_path, :log_level, :logger, :preload_frameworks,
+                  :reload_plugins, :log_path, :log_level, :logger, :preload_frameworks,
                   :database_configuration_file, :cache_store, :time_zone,
                   :view_path, :metals, :controller_paths, :routes_configuration_file,
                   :eager_load_paths, :dependency_loading, :paths, :serve_static_assets
@@ -19,7 +15,6 @@ module Rails
     def initialize
       @load_once_paths              = []
       @after_initialize_blocks      = []
-      @loaded_plugins               = []
       @dependency_loading           = true
       @serve_static_assets          = true
 
@@ -199,24 +194,6 @@ module Rails
       @frameworks ||= [ :active_record, :action_controller, :action_view, :action_mailer, :active_resource ]
     end
 
-    def plugin_paths
-      @plugin_paths ||= ["#{root}/vendor/plugins"]
-    end
-
-    def plugin_loader
-      @plugin_loader ||= begin
-        Plugin::Loader
-      end
-    end
-
-    def plugin_locators
-      @plugin_locators ||= begin
-        locators = []
-        locators << Plugin::GemLocator if defined? Gem
-        locators << Plugin::FileSystemLocator
-      end
-    end
-
     def i18n
       @i18n ||= begin
         i18n = ActiveSupport::OrderedOptions.new
@@ -235,10 +212,6 @@ module Rails
       "#{root}/config/environments/#{RAILS_ENV}.rb"
     end
 
-    def reload_plugins?
-      @reload_plugins
-    end
-
     # Holds generators configuration:
     #
     #   config.generators do |g|
diff --git a/railties/lib/rails/initializable.rb b/railties/lib/rails/initializable.rb
index d78eab9a75..3866b856b2 100644
--- a/railties/lib/rails/initializable.rb
+++ b/railties/lib/rails/initializable.rb
@@ -42,7 +42,8 @@ module Rails
           if initializer.before
             index = index_for(initializer.before)
           elsif initializer.after
-            index = index_for(initializer.after) + 1
+            index = index_for(initializer.after)
+            index += 1 if index
           else
             index = length
           end
diff --git a/railties/lib/rails/initializer.rb b/railties/lib/rails/initializer.rb
index 2ad1e52746..44d04688c8 100644
--- a/railties/lib/rails/initializer.rb
+++ b/railties/lib/rails/initializer.rb
@@ -1,14 +1,4 @@
-require "pathname"
-
-require 'rails/initializable'
-require 'rails/application'
-require 'rails/railties_path'
-require 'rails/version'
-require 'rails/rack'
-require 'rails/paths'
-require 'rails/core'
-require 'rails/configuration'
-require 'rails/deprecation'
+require "rails" # In case people require this file directly
 
 RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV)
 
@@ -24,4 +14,4 @@ module Rails
       end
     end
   end
-end
+end
\ No newline at end of file
diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb
index 0f24106353..b3d105d8c7 100644
--- a/railties/lib/rails/paths.rb
+++ b/railties/lib/rails/paths.rb
@@ -64,7 +64,7 @@ module Rails
     end
 
     class Path
-      include PathParent
+      include PathParent, Enumerable
 
       attr_reader :path
       attr_accessor :glob
@@ -83,6 +83,10 @@ module Rails
         @root.all_paths << self
       end
 
+      def each
+        to_a.each { |p| yield p }
+      end
+
       def push(path)
         @paths.push path
       end
diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb
index 090ec6e4cb..86bf032641 100644
--- a/railties/lib/rails/plugin.rb
+++ b/railties/lib/rails/plugin.rb
@@ -1,183 +1,64 @@
 module Rails
-  # The Plugin class should be an object which provides the following methods:
-  #
-  # * +name+       - Used during initialisation to order the plugin (based on name and
-  #                  the contents of <tt>config.plugins</tt>).
-  # * +valid?+     - Returns true if this plugin can be loaded.
-  # * +load_paths+ - Each path within the returned array will be added to the <tt>$LOAD_PATH</tt>.
-  # * +load+       - Finally 'load' the plugin.
-  #
-  # These methods are expected by the Rails::Plugin::Locator and Rails::Plugin::Loader classes.
-  # The default implementation returns the <tt>lib</tt> directory as its <tt>load_paths</tt>, 
-  # and evaluates <tt>init.rb</tt> when <tt>load</tt> is called.
-  #
-  # You can also inspect the about.yml data programmatically:
-  #
-  #   plugin = Rails::Plugin.new(path_to_my_plugin)
-  #   plugin.about["author"] # => "James Adam"
-  #   plugin.about["url"] # => "http://interblah.net"
   class Plugin
-    include Comparable
     include Initializable
-    
-    attr_reader :directory, :name
-    
-    def initialize(directory)
-      @directory = directory
-      @name      = File.basename(@directory) rescue nil
-      @loaded    = false
-    end
-    
-    def valid?
-      File.directory?(directory) && (has_app_directory? || has_lib_directory? || has_init_file?)
-    end
-  
-    # Returns a list of paths this plugin wishes to make available in <tt>$LOAD_PATH</tt>.
-    def load_paths
-      report_nonexistant_or_empty_plugin! unless valid?
-      
-      load_paths = []
-      load_paths << lib_path  if has_lib_directory?
-      load_paths << app_paths if has_app_directory?
-      load_paths.flatten
-    end
-    
-    # Evaluates a plugin's init.rb file.
-    def load(initializer)
-      return if loaded?
-      report_nonexistant_or_empty_plugin! unless valid?
-      evaluate_init_rb(initializer)
-      @loaded = true
-    end
-    
-    def loaded?
-      @loaded
-    end
-    
-    def <=>(other_plugin)
-      name <=> other_plugin.name
-    end
-
-    def about
-      @about ||= load_about_information
-    end
-
-    # Engines are plugins with an app/ directory.
-    def engine?
-      has_app_directory?
-    end
-    
-    # Returns true if the engine ships with a routing file
-    def routed?
-      File.exist?(routing_file)
-    end
-
-    # Returns true if there is any localization file in locale_path
-    def localized?
-      locale_files.any?
-    end
-
-    def view_path
-      File.join(directory, 'app', 'views')
-    end
-
-    def controller_path
-      File.join(directory, 'app', 'controllers')
-    end
-
-    def metal_path
-      File.join(directory, 'app', 'metal')
-    end
-
-    def routing_file
-      File.join(directory, 'config', 'routes.rb')
-    end
-
-    def locale_path
-      File.join(directory, 'config', 'locales')
-    end
-
-    def locale_files
-      Dir[ File.join(locale_path, '*.{rb,yml}') ]
-    end
-
-  private
-    def load_about_information
-      about_yml_path = File.join(@directory, "about.yml")
-      parsed_yml = File.exist?(about_yml_path) ? YAML.load(File.read(about_yml_path)) : {}
-      parsed_yml || {}
-    rescue Exception
-      {}
-    end
 
-    def report_nonexistant_or_empty_plugin!
-      raise LoadError, "Can not find the plugin named: #{name}"
-    end
-
-    def app_paths
-      [ File.join(directory, 'app', 'models'), File.join(directory, 'app', 'helpers'), controller_path, metal_path ]
-    end
-
-    def lib_path
-      File.join(directory, 'lib')
-    end
-
-    def classic_init_path
-      File.join(directory, 'init.rb')
-    end
+    class Vendored < Plugin
+      def self.all(list, paths)
+        plugins = []
+        paths.each do |path|
+          Dir["#{path}/*"].each do |plugin_path|
+            plugin = new(plugin_path)
+            next unless list.include?(plugin.name) || list.include?(:all)
+            plugins << plugin
+          end
+        end
 
-    def gem_init_path
-      File.join(directory, 'rails', 'init.rb')
-    end
+        plugins.sort_by do |p|
+          [list.index(p.name) || list.index(:all), p.name.to_s]
+        end
+      end
 
-    def init_path
-      File.file?(gem_init_path) ? gem_init_path : classic_init_path
-    end
+      attr_reader :name, :path
 
-    def has_app_directory?
-      File.directory?(File.join(directory, 'app'))
-    end
+      def initialize(path)
+        @name = File.basename(path).to_sym
+        @path = path
+      end
 
-    def has_lib_directory?
-      File.directory?(lib_path)
-    end
+      def load_paths
+        Dir["#{path}/{lib}", "#{path}/app/{models,controllers,helpers}"]
+      end
 
-    def has_init_file?
-      File.file?(init_path)
-    end
+      initializer :add_to_load_path, :after => :set_autoload_paths do |app|
+        load_paths.each do |path|
+          $LOAD_PATH << path
+          require "active_support/dependencies"
 
-    def evaluate_init_rb(initializer)
-      if has_init_file?
-        require 'active_support/core_ext/kernel/reporting'
-        silence_warnings do
-          # Allow plugins to reference the current configuration object
-          config = initializer.configuration
+          ActiveSupport::Dependencies.load_paths << path
 
-          eval(IO.read(init_path), binding, init_path)
+          unless app.config.reload_plugins
+            ActiveSupport::Dependencies.load_once_paths << path
+          end
         end
       end
-    end
 
-    class Vendored < Plugin
-      initializer :init_rb do |application|
-        evaluate_init_rb(application)
+      initializer :load_init_rb, :before => :load_application_initializers do |app|
+        file   = "#{@path}/init.rb"
+        config = app.config
+        eval File.read(file), binding, file if File.file?(file)
       end
-    end
-  end
 
-  # This Plugin subclass represents a Gem plugin. Although RubyGems has already
-  # taken care of $LOAD_PATHs, it exposes its load_paths to add them
-  # to Dependencies.load_paths.
-  class GemPlugin < Plugin
-    # Initialize this plugin from a Gem::Specification.
-    def initialize(spec, gem)
-      directory = spec.full_gem_path
-      super(directory)
-      @name = spec.name
-    end
+      initializer :add_view_paths, :after => :initialize_framework_views do
+        ActionController::Base.view_paths.concat ["#{path}/app/views"] if File.directory?("#{path}/app/views")
+      end
 
-    def init_path
-      File.join(directory, 'rails', 'init.rb')
+      initializer :add_routing_file, :after => :initialize_routing do |app|
+        routing_file = "#{path}/config/routes.rb"
+        if File.exist?(routing_file)
+          app.routes.add_configuration_file(routing_file)
+          app.routes.reload!
+        end
+      end
     end
   end
-end
+end
\ No newline at end of file
diff --git a/railties/lib/rails/plugin/loader.rb b/railties/lib/rails/plugin/loader.rb
deleted file mode 100644
index 4808c6ad57..0000000000
--- a/railties/lib/rails/plugin/loader.rb
+++ /dev/null
@@ -1,200 +0,0 @@
-require "rails/plugin"
-
-module Rails
-  class Plugin
-    class Loader
-      attr_reader :initializer
-
-      # Creates a new Plugin::Loader instance, associated with the given
-      # Rails::Initializer. This default implementation automatically locates
-      # all plugins, and adds all plugin load paths, when it is created. The plugins
-      # are then fully loaded (init.rb is evaluated) when load_plugins is called.
-      #
-      # It is the loader's responsibility to ensure that only the plugins specified
-      # in the configuration are actually loaded, and that the order defined
-      # is respected.
-      def initialize(initializer)
-        @initializer = initializer
-      end
-
-      # Returns the plugins to be loaded, in the order they should be loaded.
-      def plugins
-        @plugins ||= all_plugins.select { |plugin| should_load?(plugin) }.sort { |p1, p2| order_plugins(p1, p2) }
-      end
-
-      # Returns the plugins that are in engine-form (have an app/ directory)
-      def engines
-        @engines ||= plugins.select {|plugin| plugin.engine? }
-      end
-
-      # Returns all the plugins that could be found by the current locators.
-      def all_plugins
-        @all_plugins ||= locate_plugins
-        @all_plugins
-      end
-
-      def load_plugins
-        plugins.each do |plugin|
-          plugin.load(initializer)
-          register_plugin_as_loaded(plugin)
-        end
-
-        configure_engines
-
-        ensure_all_registered_plugins_are_loaded!
-      end
-
-      # Adds the load paths for every plugin into the $LOAD_PATH. Plugin load paths are
-      # added *after* the application's <tt>lib</tt> directory, to ensure that an application
-      # can always override code within a plugin.
-      #
-      # Plugin load paths are also added to Dependencies.load_paths, and Dependencies.load_once_paths.
-      def add_plugin_load_paths
-        plugins.each do |plugin|
-          plugin.load_paths.each do |path|
-            $LOAD_PATH.insert(application_lib_index + 1, path)
-
-            ActiveSupport::Dependencies.load_paths << path
-
-            unless configuration.reload_plugins?
-              ActiveSupport::Dependencies.load_once_paths << path
-            end
-          end
-        end
-
-        $LOAD_PATH.uniq!
-      end
-
-      def engine_metal_paths
-        engines.collect {|engine| engine.metal_path }
-      end
-
-      protected
-        def configure_engines
-          if engines.any?
-            add_engine_routing_configurations
-            add_engine_locales
-            add_engine_controller_paths
-            add_engine_view_paths
-          end
-        end
-
-        def add_engine_routing_configurations
-          engines.select {|engine| engine.routed? }.map {|engine| engine.routing_file }.each do |routing_file|
-            ActionController::Routing::Routes.add_configuration_file(routing_file)
-          end
-        end
-
-        def add_engine_locales
-          localized_engines = engines.select { |engine| engine.localized? }
-
-          # reverse it such that the last engine can overwrite translations from the first, like with routes
-          locale_files = localized_engines.collect { |engine| engine.locale_files }.reverse.flatten
-          I18n.load_path += locale_files - I18n.load_path
-        end
-
-        def add_engine_controller_paths
-          ActionController::Routing.controller_paths += engines.collect {|engine| engine.controller_path }
-        end
-
-        def add_engine_view_paths
-          # reverse it such that the last engine can overwrite view paths from the first, like with routes
-          paths = ActionView::PathSet.new(engines.collect {|engine| engine.view_path }.reverse)
-          ActionController::Base.view_paths.concat(paths)
-          ActionMailer::Base.view_paths.concat(paths) if configuration.frameworks.include?(:action_mailer)
-        end
-
-        # The locate_plugins method uses each class in config.plugin_locators to
-        # find the set of all plugins available to this Rails application.
-        def locate_plugins
-          configuration.plugin_locators.map do |locator|
-            locator.new(initializer).plugins
-          end.flatten
-          # TODO: sorting based on config.plugins
-        end
-
-        def register_plugin_as_loaded(plugin)
-          initializer.config.loaded_plugins << plugin
-        end
-
-        def configuration
-          initializer.configuration
-        end
-
-        def should_load?(plugin)
-          # uses Plugin#name and Plugin#valid?
-          enabled?(plugin) && plugin.valid?
-        end
-
-        def order_plugins(plugin_a, plugin_b)
-          if !explicit_plugin_loading_order?
-            plugin_a <=> plugin_b
-          else
-            if !explicitly_enabled?(plugin_a) && !explicitly_enabled?(plugin_b)
-              plugin_a <=> plugin_b
-            else
-              effective_order_of(plugin_a) <=> effective_order_of(plugin_b)
-            end
-          end
-        end
-
-        def effective_order_of(plugin)
-          if explicitly_enabled?(plugin)
-            registered_plugin_names.index(plugin.name)
-          else
-            registered_plugin_names.index('all')
-          end
-        end
-
-        def application_lib_index
-          $LOAD_PATH.index(File.join(Rails.root, 'lib')) || 0
-        end
-
-        def enabled?(plugin)
-          !explicit_plugin_loading_order? || registered?(plugin)
-        end
-
-        def explicit_plugin_loading_order?
-          !registered_plugin_names.nil?
-        end
-
-        def registered?(plugin)
-          explicit_plugin_loading_order? && registered_plugins_names_plugin?(plugin)
-        end
-
-        def explicitly_enabled?(plugin)
-          !explicit_plugin_loading_order? || explicitly_registered?(plugin)
-        end
-
-        def explicitly_registered?(plugin)
-          explicit_plugin_loading_order? && registered_plugin_names.include?(plugin.name)
-        end
-
-        def registered_plugins_names_plugin?(plugin)
-          registered_plugin_names.include?(plugin.name) || registered_plugin_names.include?('all')
-        end
-
-        # The plugins that have been explicitly listed with config.plugins. If this list is nil
-        # then it means the client does not care which plugins or in what order they are loaded,
-        # so we load all in alphabetical order. If it is an empty array, we load no plugins, if it is
-        # non empty, we load the named plugins in the order specified.
-        def registered_plugin_names
-          configuration.plugins ? configuration.plugins.map {|plugin| plugin.to_s } : nil
-        end
-
-        def loaded?(plugin_name)
-          initializer.config.loaded_plugins.detect { |plugin| plugin.name == plugin_name.to_s }
-        end
-
-        def ensure_all_registered_plugins_are_loaded!
-          if explicit_plugin_loading_order?
-            if configuration.plugins.detect {|plugin| plugin != :all && !loaded?(plugin) }
-              missing_plugins = configuration.plugins - (plugins.map{|p| p.name.to_sym} + [:all])
-              raise LoadError, "Could not locate the following plugins: #{missing_plugins.to_sentence(:locale => :en)}"
-            end
-          end
-        end
-
-    end
-  end
-end
diff --git a/railties/lib/rails/plugin/locator.rb b/railties/lib/rails/plugin/locator.rb
deleted file mode 100644
index 56cbaf37c6..0000000000
--- a/railties/lib/rails/plugin/locator.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-module Rails
-  class Plugin
-    
-    # The Plugin::Locator class should be subclasses to provide custom plugin-finding
-    # abilities to Rails (i.e. loading plugins from Gems, etc). Each subclass should implement
-    # the <tt>located_plugins</tt> method, which return an array of Plugin objects that have been found.
-    class Locator
-      include Enumerable
-      
-      attr_reader :initializer
-      
-      def initialize(initializer)
-        @initializer = initializer
-      end
-      
-      # This method should return all the plugins which this Plugin::Locator can find
-      # These will then be used by the current Plugin::Loader, which is responsible for actually
-      # loading the plugins themselves
-      def plugins
-        raise "The `plugins' method must be defined by concrete subclasses of #{self.class}"
-      end
-      
-      def each(&block)
-        plugins.each(&block)
-      end
-      
-      def plugin_names
-        plugins.map {|plugin| plugin.name }
-      end
-    end
-    
-    # The Rails::Plugin::FileSystemLocator will try to locate plugins by examining the directories
-    # in the paths given in configuration.plugin_paths. Any plugins that can be found are returned
-    # in a list. 
-    #
-    # The criteria for a valid plugin in this case is found in Rails::Plugin#valid?, although
-    # other subclasses of Rails::Plugin::Locator can of course use different conditions.
-    class FileSystemLocator < Locator
-      
-      # Returns all the plugins which can be loaded in the filesystem, under the paths given
-      # by configuration.plugin_paths.
-      def plugins
-        initializer.configuration.plugin_paths.flatten.inject([]) do |plugins, path|
-          plugins.concat locate_plugins_under(path)
-          plugins
-        end.flatten
-      end
-          
-      private
-      
-        # Attempts to create a plugin from the given path. If the created plugin is valid?
-        # (see Rails::Plugin#valid?) then the plugin instance is returned; otherwise nil.
-        def create_plugin(path)
-          plugin = Rails::Plugin.new(path)
-          plugin.valid? ? plugin : nil
-        end
-
-        # This starts at the base path looking for valid plugins (see Rails::Plugin#valid?).
-        # Since plugins can be nested arbitrarily deep within an unspecified number of intermediary 
-        # directories, this method runs recursively until it finds a plugin directory, e.g.
-        #
-        #     locate_plugins_under('vendor/plugins/acts/acts_as_chunky_bacon')
-        #     => <Rails::Plugin name: 'acts_as_chunky_bacon' ... >
-        #
-        def locate_plugins_under(base_path)
-           Dir.glob(File.join(base_path, '*')).sort.inject([]) do |plugins, path|
-            if plugin = create_plugin(path)
-              plugins << plugin
-            elsif File.directory?(path)
-              plugins.concat locate_plugins_under(path)
-            end
-            plugins
-          end
-        end
-    end
-
-    # The GemLocator scans all the loaded RubyGems, looking for gems with
-    # a <tt>rails/init.rb</tt> file.
-    class GemLocator < Locator
-      def plugins
-        gem_index = {}
-        specs     = gem_index.keys
-        specs    += Gem.loaded_specs.values.select do |spec|
-          spec.loaded_from && # prune stubs
-            File.exist?(File.join(spec.full_gem_path, "rails", "init.rb"))
-        end
-        specs.compact!
-
-        require "rubygems/dependency_list"
-
-        deps = Gem::DependencyList.new
-        deps.add(*specs) unless specs.empty?
-
-        deps.dependency_order.collect do |spec|
-          Rails::GemPlugin.new(spec, gem_index[spec])
-        end
-      end
-    end
-  end
-end
\ No newline at end of file
-- 
cgit v1.2.3


From 2675ba9ef4ae1839f721aff77c255ee1cb8ac7ac Mon Sep 17 00:00:00 2001
From: Yehuda Katz <wycats@Yehuda-Katz.local>
Date: Mon, 16 Nov 2009 12:37:43 -0800
Subject: Require action_dispatch, not action_controller

---
 railties/lib/rails/commands/server.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'railties/lib')

diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 29359e49a4..37dfa3b9bb 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -1,4 +1,4 @@
-require 'action_controller'
+require 'action_dispatch'
 
 require 'fileutils'
 require 'optparse'
-- 
cgit v1.2.3


From c2997017f79321a8d90af84b1de35f87e3dd2445 Mon Sep 17 00:00:00 2001
From: Yehuda Katz <wycats@Yehuda-Katz.local>
Date: Mon, 16 Nov 2009 13:58:08 -0800
Subject: Make script/server work with correct application.rb

---
 railties/lib/rails/application.rb     | 5 +++++
 railties/lib/rails/commands/server.rb | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

(limited to 'railties/lib')

diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 10cba8ab6c..7c2d8eab67 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -3,6 +3,11 @@ module Rails
     include Initializable
 
     class << self
+      def inherited(klass)
+        Rails.application ||= klass unless klass.name =~ /Rails/
+        super
+      end
+
       # Stub out App initialize
       def initialize!
         new
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 37dfa3b9bb..2c90851fb2 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -42,7 +42,7 @@ unless server
 end
 
 puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
-puts "=> Rails #{Rails.version} application starting on http://#{options[:Host]}:#{options[:Port]}}"
+puts "=> Rails #{Rails.version} application starting on http://#{options[:Host]}:#{options[:Port]}"
 
 if options[:detach]
   Process.daemon
-- 
cgit v1.2.3


From 520b8b59110dd130c89b317b6bd65d8644c7836f Mon Sep 17 00:00:00 2001
From: Yehuda Katz + Carl Lerche <ykatz+clerche@engineyard.com>
Date: Wed, 18 Nov 2009 16:28:12 -0800
Subject: Final steps toward clean rails "foo"; cd foo; gem bundle;
 script/server working

---
 railties/lib/rails/application.rb                                   | 6 +-----
 railties/lib/rails/commands/server.rb                               | 4 +++-
 railties/lib/rails/generators/rails/app/app_generator.rb            | 2 +-
 railties/lib/rails/generators/rails/app/templates/config.ru         | 2 +-
 .../lib/rails/generators/rails/app/templates/config/application.rb  | 2 +-
 .../lib/rails/generators/rails/app/templates/config/environment.rb  | 2 +-
 railties/lib/rails/generators/rails/app/templates/script/server     | 3 +++
 railties/lib/rails/rack/log_tailer.rb                               | 5 ++---
 8 files changed, 13 insertions(+), 13 deletions(-)

(limited to 'railties/lib')

diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 7c2d8eab67..c8e4d8943b 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -3,11 +3,6 @@ module Rails
     include Initializable
 
     class << self
-      def inherited(klass)
-        Rails.application ||= klass unless klass.name =~ /Rails/
-        super
-      end
-
       # Stub out App initialize
       def initialize!
         new
@@ -38,6 +33,7 @@ module Rails
     end
 
     def initialize
+      Rails.application ||= self
       run_initializers(self)
     end
 
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 2c90851fb2..450970e4f5 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -3,11 +3,13 @@ require 'action_dispatch'
 require 'fileutils'
 require 'optparse'
 
+# Waiting for Rack::Server patch
+
 options = {
   :Port        => 3000,
   :Host        => "0.0.0.0",
   :environment => (ENV['RAILS_ENV'] || "development").dup,
-  :config      => "#{Rails.root}/config.ru",
+  :config      => $config_ru,
   :detach      => false,
   :debugger    => false
 }
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 2bcea4bc8f..d970bd8db8 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -50,7 +50,7 @@ module Rails::Generators
     def create_root_files
       copy_file "Rakefile"
       copy_file "README"
-      copy_file "config.ru"
+      template "config.ru"
       template "Gemfile"
     end
 
diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru b/railties/lib/rails/generators/rails/app/templates/config.ru
index 509a0da5b7..fea9ba7fe5 100644
--- a/railties/lib/rails/generators/rails/app/templates/config.ru
+++ b/railties/lib/rails/generators/rails/app/templates/config.ru
@@ -2,4 +2,4 @@
 require ::File.expand_path('../config/environment',  __FILE__)
 
 # Dispatch the request
-run Rails.application
+run <%= app_name.classify %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index 8008c6ba07..43067b2530 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -1,6 +1,6 @@
 require File.expand_path('../boot', __FILE__)
 
-Rails::Initializer.run do |config|
+class <%= app_name.classify %> < Rails::Application
   # Settings in config/environments/* take precedence over those specified here.
   # Application configuration should go into files in config/initializers
   # -- all .rb files in that directory are automatically loaded.
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environment.rb b/railties/lib/rails/generators/rails/app/templates/config/environment.rb
index 0bb191f205..1c35ae44d2 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environment.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/environment.rb
@@ -2,4 +2,4 @@
 require File.expand_path('../application', __FILE__)
 
 # Initialize the rails application
-Rails.initialize!
+<%= app_name.classify %>.initialize!
diff --git a/railties/lib/rails/generators/rails/app/templates/script/server b/railties/lib/rails/generators/rails/app/templates/script/server
index a7aaee2953..b4864eb745 100755
--- a/railties/lib/rails/generators/rails/app/templates/script/server
+++ b/railties/lib/rails/generators/rails/app/templates/script/server
@@ -1,2 +1,5 @@
 require File.expand_path('../../config/application',  __FILE__)
+# Temporary patch until Rack::Server
+# Will be Rails::Server.start(File.expand_path("../../config.ru", __FILE__))
+$config_ru = File.expand_path("../../config.ru", __FILE__)
 require 'rails/commands/server'
diff --git a/railties/lib/rails/rack/log_tailer.rb b/railties/lib/rails/rack/log_tailer.rb
index a237cee6bc..f3ebebf67d 100644
--- a/railties/lib/rails/rack/log_tailer.rb
+++ b/railties/lib/rails/rack/log_tailer.rb
@@ -1,12 +1,11 @@
 module Rails
   module Rack
     class LogTailer
-      EnvironmentLog = "#{File.expand_path(Rails.root)}/log/#{Rails.env}.log"
-
       def initialize(app, log = nil)
+        @default_log = "#{File.expand_path(Rails.root)}/log/#{Rails.env}.log"
         @app = app
 
-        path = Pathname.new(log || EnvironmentLog).cleanpath
+        path = Pathname.new(log || @default_log).cleanpath
         @cursor = ::File.size(path)
         @last_checked = Time.now.to_f
 
-- 
cgit v1.2.3


From c7c39f52dcce4ea6de2051ee7816c0cb9d583f8f Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Thu, 19 Nov 2009 15:24:00 -0800
Subject: Revert "Final steps toward clean rails "foo"; cd foo; gem bundle;
 script/server working"

Broke stuff.

This reverts commit 520b8b59110dd130c89b317b6bd65d8644c7836f.
---
 railties/lib/rails/application.rb                                   | 6 +++++-
 railties/lib/rails/commands/server.rb                               | 4 +---
 railties/lib/rails/generators/rails/app/app_generator.rb            | 2 +-
 railties/lib/rails/generators/rails/app/templates/config.ru         | 2 +-
 .../lib/rails/generators/rails/app/templates/config/application.rb  | 2 +-
 .../lib/rails/generators/rails/app/templates/config/environment.rb  | 2 +-
 railties/lib/rails/generators/rails/app/templates/script/server     | 3 ---
 railties/lib/rails/rack/log_tailer.rb                               | 5 +++--
 8 files changed, 13 insertions(+), 13 deletions(-)

(limited to 'railties/lib')

diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index c8e4d8943b..7c2d8eab67 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -3,6 +3,11 @@ module Rails
     include Initializable
 
     class << self
+      def inherited(klass)
+        Rails.application ||= klass unless klass.name =~ /Rails/
+        super
+      end
+
       # Stub out App initialize
       def initialize!
         new
@@ -33,7 +38,6 @@ module Rails
     end
 
     def initialize
-      Rails.application ||= self
       run_initializers(self)
     end
 
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 450970e4f5..2c90851fb2 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -3,13 +3,11 @@ require 'action_dispatch'
 require 'fileutils'
 require 'optparse'
 
-# Waiting for Rack::Server patch
-
 options = {
   :Port        => 3000,
   :Host        => "0.0.0.0",
   :environment => (ENV['RAILS_ENV'] || "development").dup,
-  :config      => $config_ru,
+  :config      => "#{Rails.root}/config.ru",
   :detach      => false,
   :debugger    => false
 }
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index d970bd8db8..2bcea4bc8f 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -50,7 +50,7 @@ module Rails::Generators
     def create_root_files
       copy_file "Rakefile"
       copy_file "README"
-      template "config.ru"
+      copy_file "config.ru"
       template "Gemfile"
     end
 
diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru b/railties/lib/rails/generators/rails/app/templates/config.ru
index fea9ba7fe5..509a0da5b7 100644
--- a/railties/lib/rails/generators/rails/app/templates/config.ru
+++ b/railties/lib/rails/generators/rails/app/templates/config.ru
@@ -2,4 +2,4 @@
 require ::File.expand_path('../config/environment',  __FILE__)
 
 # Dispatch the request
-run <%= app_name.classify %>
+run Rails.application
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index 43067b2530..8008c6ba07 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -1,6 +1,6 @@
 require File.expand_path('../boot', __FILE__)
 
-class <%= app_name.classify %> < Rails::Application
+Rails::Initializer.run do |config|
   # Settings in config/environments/* take precedence over those specified here.
   # Application configuration should go into files in config/initializers
   # -- all .rb files in that directory are automatically loaded.
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environment.rb b/railties/lib/rails/generators/rails/app/templates/config/environment.rb
index 1c35ae44d2..0bb191f205 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environment.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/environment.rb
@@ -2,4 +2,4 @@
 require File.expand_path('../application', __FILE__)
 
 # Initialize the rails application
-<%= app_name.classify %>.initialize!
+Rails.initialize!
diff --git a/railties/lib/rails/generators/rails/app/templates/script/server b/railties/lib/rails/generators/rails/app/templates/script/server
index b4864eb745..a7aaee2953 100755
--- a/railties/lib/rails/generators/rails/app/templates/script/server
+++ b/railties/lib/rails/generators/rails/app/templates/script/server
@@ -1,5 +1,2 @@
 require File.expand_path('../../config/application',  __FILE__)
-# Temporary patch until Rack::Server
-# Will be Rails::Server.start(File.expand_path("../../config.ru", __FILE__))
-$config_ru = File.expand_path("../../config.ru", __FILE__)
 require 'rails/commands/server'
diff --git a/railties/lib/rails/rack/log_tailer.rb b/railties/lib/rails/rack/log_tailer.rb
index f3ebebf67d..a237cee6bc 100644
--- a/railties/lib/rails/rack/log_tailer.rb
+++ b/railties/lib/rails/rack/log_tailer.rb
@@ -1,11 +1,12 @@
 module Rails
   module Rack
     class LogTailer
+      EnvironmentLog = "#{File.expand_path(Rails.root)}/log/#{Rails.env}.log"
+
       def initialize(app, log = nil)
-        @default_log = "#{File.expand_path(Rails.root)}/log/#{Rails.env}.log"
         @app = app
 
-        path = Pathname.new(log || @default_log).cleanpath
+        path = Pathname.new(log || EnvironmentLog).cleanpath
         @cursor = ::File.size(path)
         @last_checked = Time.now.to_f
 
-- 
cgit v1.2.3


From e1935e3c0c35f8f1196239e2b1213c4436049fa5 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sat, 21 Nov 2009 10:45:42 -0800
Subject: Fix Rails::Rack::Static deprecated constant proxy

---
 railties/lib/rails/rack/static.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'railties/lib')

diff --git a/railties/lib/rails/rack/static.rb b/railties/lib/rails/rack/static.rb
index d6b8face27..ebe8b9e103 100644
--- a/railties/lib/rails/rack/static.rb
+++ b/railties/lib/rails/rack/static.rb
@@ -1,5 +1,5 @@
 require 'action_dispatch'
 
 module Rails::Rack
-  Static = Deprecation::DeprecatedConstantProxy.new('Rails::Rack::Static', ActionDispatch::Static)
+  Static = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Rails::Rack::Static', ActionDispatch::Static)
 end
-- 
cgit v1.2.3


From d6f10126eb12e08ad670f803d237b942ebae5018 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?= <jose.valim@gmail.com>
Date: Fri, 20 Nov 2009 09:29:35 -0200
Subject: Also load generators at lib/rails_generators.

Signed-off-by: Yehuda Katz <wycats@Yehuda-Katz.local>
---
 railties/lib/rails/generators.rb | 32 ++++++++++----------------------
 1 file changed, 10 insertions(+), 22 deletions(-)

(limited to 'railties/lib')

diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 19412c259e..9f274b9edc 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -86,28 +86,16 @@ module Rails
       @options ||= DEFAULT_OPTIONS.dup
     end
 
-    # We have two scenarios here: when rubygems is loaded and when bundler is
-    # being used. If rubygems is loaded, we get all generators paths from loaded
-    # specs. Otherwise we just have to look into vendor/gems/gems.
-    #
-    def self.gems_generators_paths
-      paths = []
-
-      if defined?(Gem) && Gem.respond_to?(:loaded_specs)
-        Gem.loaded_specs.each do |name, spec|
-          generator_path = File.join(spec.full_gem_path, "lib/generators")
-          paths << generator_path if File.exist?(generator_path)
-        end
+    def self.gems_generators_paths #:nodoc:
+      return [] unless defined?(Gem) && Gem.respond_to?(:loaded_specs)
+      Gem.loaded_specs.inject([]) do |paths, (name, spec)|
+        paths += Dir[File.join(spec.full_gem_path, "lib/{generators,rails_generators}")]
       end
-
-      paths
     end
 
-    # Load paths from plugin.
-    #
-    def self.plugins_generators_paths
+    def self.plugins_generators_paths #:nodoc:
       return [] unless Rails.root
-      Dir[File.join(Rails.root, "vendor", "plugins", "*", "lib", "generators")]
+      Dir[File.join(Rails.root, "vendor", "plugins", "*", "lib", "{generators,rails_generators}")]
     end
 
     # Hold configured generators fallbacks. If a plugin developer wants a
@@ -147,8 +135,8 @@ module Rails
     def self.load_paths
       @load_paths ||= begin
         paths = []
-        paths << File.join(Rails.root, "lib", "generators") if Rails.root
-        paths << File.join(Thor::Util.user_home, ".rails", "generators")
+        paths += Dir[File.join(Rails.root, "lib", "{generators,rails_generators}")] if Rails.root
+        paths += Dir[File.join(Thor::Util.user_home, ".rails", "{generators,rails_generators}")]
         paths += self.plugins_generators_paths
         paths += self.gems_generators_paths
         paths << File.expand_path(File.join(File.dirname(__FILE__), "generators"))
@@ -278,13 +266,13 @@ module Rails
 
       # By default, Rails strips the generator namespace to make invocations
       # easier. This method generaters the both possibilities names.
-      def self.generator_names(first, second)
+      def self.generator_names(first, second) #:nodoc:
         [ "#{first}:generators:#{second}", "#{first}:#{second}" ]
       end
 
       # Try callbacks for the given base.
       #
-      def self.invoke_fallbacks_for(name, base)
+      def self.invoke_fallbacks_for(name, base) #:nodoc:
         return nil unless base && fallbacks[base.to_sym]
         invoked_fallbacks = []
 
-- 
cgit v1.2.3


From d0aa0cfbd76a919e536e76d65419930fb7fe31da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?= <jose.valim@gmail.com>
Date: Fri, 20 Nov 2009 12:16:01 -0200
Subject: Ensure generator fallbacks work even when a context is given.

Signed-off-by: Yehuda Katz <wycats@Yehuda-Katz.local>
---
 railties/lib/rails/generators.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'railties/lib')

diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 9f274b9edc..85c2fd52a4 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -198,7 +198,7 @@ module Rails
         return klass if klass
       end
 
-      invoke_fallbacks_for(name, base)
+      invoke_fallbacks_for(name, base) || invoke_fallbacks_for(context, name)
     end
 
     # Receives a namespace, arguments and the behavior to invoke the generator.
-- 
cgit v1.2.3


From 35eda7d6d2ea13b4e42eeea9f11245e22c245fc2 Mon Sep 17 00:00:00 2001
From: David Heinemeier Hansson <david@loudthinking.com>
Date: Mon, 23 Nov 2009 15:36:48 -0600
Subject: Fixed that the debugger wouldn't go into IRB mode because of
 left-over ARGVs [DHH]

---
 railties/lib/rails/rack/debugger.rb | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'railties/lib')

diff --git a/railties/lib/rails/rack/debugger.rb b/railties/lib/rails/rack/debugger.rb
index aa2711c616..0a7b405553 100644
--- a/railties/lib/rails/rack/debugger.rb
+++ b/railties/lib/rails/rack/debugger.rb
@@ -4,6 +4,8 @@ module Rails
       def initialize(app)
         @app = app
 
+        ARGV.clear # clear ARGV so that script/server options aren't passed to IRB
+
         require_library_or_gem 'ruby-debug'
         ::Debugger.start
         ::Debugger.settings[:autoeval] = true if ::Debugger.respond_to?(:settings)
-- 
cgit v1.2.3