diff --git a/lib/redmine/plugin.rb b/lib/redmine/plugin.rb index 503c3db..0c0affa 100644 --- a/lib/redmine/plugin.rb +++ b/lib/redmine/plugin.rb @@ -19,6 +19,7 @@ module Redmine #:nodoc: class PluginNotFound < StandardError; end class PluginRequirementError < StandardError; end + class PluginDeferLoadError < StandardError; end # Base class for Redmine plugins. # Plugins are registered using the register class method that acts as the public constructor. @@ -142,18 +143,50 @@ module Redmine #:nodoc: registered_plugins[id.to_sym].present? end + def self.requires_plugin(plugin_name) + raise PluginDeferLoadError unless installed? plugin_name + end + + def self.load_directory(directory) + begin + restore_a = $:.dup + restore_b = ActiveSupport::Dependencies.autoload_paths.dup + + lib = File.join(directory, "lib") + if File.directory?(lib) + $:.unshift lib + ActiveSupport::Dependencies.autoload_paths += [lib] + end + + initializer = File.join(directory, "init.rb") + if File.file?(initializer) + Kernel.load initializer + end + + true + + rescue PluginDeferLoadError => e + $:[0..-1] = restore_a + ActiveSupport::Dependencies.autoload_paths = restore_b + + false + end + end + def self.load + load_queue = [] + Dir.glob(File.join(self.directory, '*')).sort.each do |directory| - if File.directory?(directory) - lib = File.join(directory, "lib") - if File.directory?(lib) - $:.unshift lib - ActiveSupport::Dependencies.autoload_paths += [lib] - end - initializer = File.join(directory, "init.rb") - if File.file?(initializer) - require initializer - end + load_queue << directory if File.directory?(directory) + end + + while load_queue.count > 0 + amount_before = load_queue.count + + load_queue.delete_if {|directory| self.load_directory directory } + + if load_queue.count == amount_before + raise "Could not load plugins directories #{load_queue.map{|d| File.basename d}.inspect}. Possible dependency cycle?" end end end