From d22eb7d0b08a197c0315b6224f50ab23983ebed5 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 7 Sep 2010 19:59:21 +0200 Subject: [PATCH] Add a Redmine plugin locator to be able to query the rails plugin search path for dependencies when loading redmine plugins --- config/environment.rb | 4 +++ lib/redmine/plugin.rb | 52 ++++++++++++++++++++++++++++++++-------- lib/redmine_plugin_locator.rb | 22 +++++++++++++++++ 3 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 lib/redmine_plugin_locator.rb diff --git a/config/environment.rb b/config/environment.rb index 97fc54a..891f407 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..2f3aadc 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.has_plugin? e.plugin_id + # 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 diff --git a/lib/redmine_plugin_locator.rb b/lib/redmine_plugin_locator.rb new file mode 100644 index 0000000..28ffcd8 --- /dev/null +++ b/lib/redmine_plugin_locator.rb @@ -0,0 +1,22 @@ +class RedminePluginLocator < Rails::Plugin::FileSystemLocator + def initialize(initializer) + super + @@instance = self + end + + def self.instance + @@instance + end + + # This locator is not meant for loading plugins + # The plugin loading is done by the default rails locator, this one is + # only for querying available plugins easily + def plugins(for_loading = true) + return [] if for_loading + super() + end + + def has_plugin?(name) + plugins(false).collect(&:name).include? name.to_s + end +end -- 1.7.2.3