Project

General

Profile

Patch #26439 » redmine_plugin_load.patch

Tiago Gonçalves, 2017-07-14 15:36

View differences:

lib/redmine/plugin.rb
19 19

  
20 20
  class PluginNotFound < StandardError; end
21 21
  class PluginRequirementError < StandardError; end
22
  class PluginDeferLoadError < StandardError; end
22 23

  
23 24
  # Base class for Redmine plugins.
24 25
  # Plugins are registered using the <tt>register</tt> class method that acts as the public constructor.
......
142 143
      registered_plugins[id.to_sym].present?
143 144
    end
144 145

  
146
    def self.requires_plugin(plugin_name)
147
      raise PluginDeferLoadError unless installed? plugin_name
148
    end
149

  
150
    def self.load_directory(directory)
151
      begin
152
        restore_a = $:.dup
153
        restore_b = ActiveSupport::Dependencies.autoload_paths.dup
154

  
155
        lib = File.join(directory, "lib")
156
        if File.directory?(lib)
157
          $:.unshift lib
158
          ActiveSupport::Dependencies.autoload_paths += [lib]
159
        end
160

  
161
        initializer = File.join(directory, "init.rb")
162
        if File.file?(initializer)
163
          Kernel.load initializer
164
        end
165

  
166
        true
167

  
168
      rescue PluginDeferLoadError => e
169
        $:[0..-1] = restore_a
170
        ActiveSupport::Dependencies.autoload_paths = restore_b
171

  
172
        false
173
      end
174
    end
175

  
145 176
    def self.load
177
      load_queue = []
178

  
146 179
      Dir.glob(File.join(self.directory, '*')).sort.each do |directory|
147
        if File.directory?(directory)
148
          lib = File.join(directory, "lib")
149
          if File.directory?(lib)
150
            $:.unshift lib
151
            ActiveSupport::Dependencies.autoload_paths += [lib]
152
          end
153
          initializer = File.join(directory, "init.rb")
154
          if File.file?(initializer)
155
            require initializer
156
          end
180
        load_queue << directory if File.directory?(directory)
181
      end
182

  
183
      while load_queue.count > 0
184
        amount_before = load_queue.count
185

  
186
        load_queue.delete_if {|directory| self.load_directory directory }
187

  
188
        if load_queue.count == amount_before
189
          raise "Could not load plugins directories #{load_queue.map{|d| File.basename d}.inspect}. Possible dependency cycle?"
157 190
        end
158 191
      end
159 192
    end
    (1-1/1)