about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--bin/mongrel_rails20
-rw-r--r--lib/mongrel/plugins.rb57
2 files changed, 61 insertions, 16 deletions
diff --git a/bin/mongrel_rails b/bin/mongrel_rails
index 2b363bd..059c782 100644
--- a/bin/mongrel_rails
+++ b/bin/mongrel_rails
@@ -1,5 +1,6 @@
 require 'rubygems'
 require 'mongrel/rails'
+require 'yaml'
 
 
 class Start < Mongrel::Plugin "/commands"
@@ -18,7 +19,6 @@ class Start < Mongrel::Plugin "/commands"
       ['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil],
       ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
       ['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
-      ['-L', '--load PATH', "Loads plugins from the given directory", :@load_from, nil],
     ]
   end
   
@@ -34,8 +34,6 @@ class Start < Mongrel::Plugin "/commands"
     valid_dir? @docroot, "Path to docroot not valid: #@docroot"
     valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
 
-    valid_dir? @load_from, "Plugin directory path does not exist" if @load_from
-
     return @valid
   end
 
@@ -87,6 +85,8 @@ class Start < Mongrel::Plugin "/commands"
 
     server = Mongrel::HttpServer.new(@address, @port, @num_procs.to_i, @timeout.to_i)
     server.register("/", rails)
+
+    # start mongrel processing thread
     server.run
 
     # signal trapping just applies to posix systems
@@ -109,7 +109,10 @@ class Start < Mongrel::Plugin "/commands"
         @restart = true
       }
     end
-    
+
+    # hook up any rails specific plugins
+    Mongrel::PluginManager.instance.load(MONGREL_PLUGINS_DIR)
+
     begin
       STDERR.puts "Server ready."
       server.acceptor.join
@@ -123,7 +126,6 @@ class Start < Mongrel::Plugin "/commands"
   end
 
   def run
-    Mongrel::PluginManager.instance.load(@load_from) if @load_from
     daemonize
     rails = configure_rails
     start_mongrel(rails)
@@ -212,5 +214,13 @@ class Restart < Mongrel::Plugin "/commands"
   end
 end
 
+if ARGV[0] == "-L" || ARGV[0] == "--load"
+  ARGV.shift # drop the -L
+  MONGREL_PLUGINS_DIR=ARGV.shift
+else
+  MONGREL_PLUGINS_DIR=nil
+end
+
 
+Mongrel::PluginManager.instance.load(MONGREL_PLUGINS_DIR, ["rails"])
 Mongrel::Command::Registry.instance.run ARGV
diff --git a/lib/mongrel/plugins.rb b/lib/mongrel/plugins.rb
index 0f3b8ec..e82977c 100644
--- a/lib/mongrel/plugins.rb
+++ b/lib/mongrel/plugins.rb
@@ -1,4 +1,5 @@
 require 'singleton'
+require 'rubygems'
 
 module Mongrel
 
@@ -47,20 +48,54 @@ module Mongrel
     
     def initialize
       @plugins = URIClassifier.new
+      @loaded_gems = []
     end
-    
-    # Tell the PluginManager to scan the given path (recursively)
-    # and load the *.rb files found there.  This is how you'd
-    # setup your own plugin directory.
-    def load(path)
-      Dir.chdir(path) do
-        Dir["**/*.rb"].each do |rbfile|
-          STDERR.puts "Loading plugins from #{rbfile}"
-          require rbfile
+
+    # Loads all the rubygems that depend on Mongrel so that they
+    # can be configured into the plugins system.  This works by
+    # checking if the gem depends on Mongrel, and then doing require_gem.
+    # Since only plugins will configure themselves as plugins then
+    # everything is safe.
+    #
+    # You can also specify an alternative load path from the official
+    # system gems location.  For example you can do the following:
+    #
+    #  mkdir mygems
+    #  gem install -i mygems fancy_plugin
+    #  mongrel_rails -L mygems start
+    #
+    # Which installs the fancy_plugin to your mygems directory and then
+    # tells mongrel_rails to load from mygems instead.
+    #
+    # The excludes list is used to prevent mongrel from loading gem plugins
+    # that aren't ready yet.  In the mongrel_rails script this is used to
+    # load gems that might need rails configured after rails is ready.
+    def load(load_path = nil, excludes=[])
+      sdir = File.join(load_path || Gem.dir, "specifications")
+      gems = Gem::SourceIndex.from_installed_gems(sdir)
+      
+      gems.each do |path, gem|
+        found_one = false
+        gem.dependencies.each do |dep|
+          # don't load excluded or already loaded gems
+          if excludes.include? dep.name or @loaded_gems.include? gem.name
+            found_one = false
+            break
+          elsif dep.name == "mongrel"
+            found_one = true
+          end
+        end
+
+        if found_one
+          STDERR.puts "loading #{gem.name}"
+          require_gem gem.name
+          @loaded_gems << gem.name
         end
+
       end
     end
-    
+
+
     # Not necessary for you to call directly, but this is
     # how Mongrel::PluginBase.inherited actually adds a
     # plugin to a category.
@@ -84,7 +119,7 @@ module Mongrel
     def create(name, options = {})
       category, plugin, map = @plugins.resolve(name)
 
-      if category and plugin and plugin.length > 0
+      if category and plugin and plugin.length > 0 and map[plugin]
         map[plugin].new(options)
       else
         raise "Plugin #{name} does not exist"