From 2a772f10e8f0262487de9bbacd92988bd512bc64 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 7 Sep 2010 19:59:21 +0200 Subject: [PATCH] implement redmine plugin loader --- config/environment.rb | 4 +++ lib/redmine/plugin.rb | 52 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/config/environment.rb b/config/environment.rb index 97fc54a..fdae0a1 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -50,6 +50,10 @@ Rails::Initializer.run do |config| # It will automatically turn deliveries on config.action_mailer.perform_deliveries = false + # Use redmine's custom plugin locater + require File.join(RAILS_ROOT, "lib/redmine_plugin_locator") + config.plugin_locators = [RedminePluginLocator] + config.gem 'rubytree', :lib => 'tree' # Load any local configuration that is kept out of source control diff --git a/lib/redmine/plugin.rb b/lib/redmine/plugin.rb index 2be8ac8..4344259 100644 --- a/lib/redmine/plugin.rb +++ b/lib/redmine/plugin.rb @@ -17,7 +17,13 @@ module Redmine #:nodoc: - class PluginNotFound < StandardError; end + class PluginNotFound < StandardError + attr_reader :plugin_id + def initialize(plug_id=nil) + super + @plugin_id = plug_id + end + end class PluginRequirementError < StandardError; end # Base class for Redmine plugins. @@ -44,8 +50,10 @@ module Redmine #:nodoc: # When rendered, the plugin settings value is available as the local variable +settings+ class Plugin @registered_plugins = {} + @deferred_plugins = {} + class << self - attr_reader :registered_plugins + attr_reader :registered_plugins, :deferred_plugins private :new def def_field(*names) @@ -63,14 +71,36 @@ module Redmine #:nodoc: # Plugin constructor def self.register(id, &block) - p = new(id) - p.instance_eval(&block) - # Set a default name if it was not provided during registration - p.name(id.to_s.humanize) if p.name.nil? - # Adds plugin locales if any - # YAML translation files should be found under /config/locales/ - ::I18n.load_path += Dir.glob(File.join(RAILS_ROOT, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml')) - registered_plugins[id] = p + begin + id = id.to_sym + p = new(id) + p.instance_eval(&block) + # Set a default name if it was not provided during registration + p.name(id.to_s.humanize) if p.name.nil? + # Adds plugin locales if any + # YAML translation files should be found under /config/locales/ + ::I18n.load_path += Dir.glob(File.join(RAILS_ROOT, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml')) + registered_plugins[id] = p + + # If there are plugins waiting for us to be loaded, we try loading those, again + if deferred_plugins[id] + deferred_plugins[id].each do |ary| + plugin_id, block = ary + register(plugin_id, &block) + end + deferred_plugins.delete(id) + end + + return p + rescue PluginNotFound => e + if RedminePluginLocator.instance.plugin_names.include? e.plugin_id.to_s + # The required plugin is going to be loaded later, defer loading this plugin + (deferred_plugins[e.plugin_id] ||= []) << [id, block] + return p + else + raise e + end + end end # Returns an array off all registered plugins @@ -81,7 +111,7 @@ module Redmine #:nodoc: # Finds a plugin by its id # Returns a PluginNotFound exception if the plugin doesn't exist def self.find(id) - registered_plugins[id.to_sym] || raise(PluginNotFound) + registered_plugins[id.to_sym] || raise(PluginNotFound.new(id.to_sym)) end # Clears the registered plugins hash -- 1.7.2.3