1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
require "rails/plugin"
module Rails
class Plugin
class Loader
attr_reader :initializer
# Creates a new Plugin::Loader instance, associated with the given
# Rails::Initializer. This default implementation automatically locates
# all plugins, and adds all plugin load paths, when it is created. The plugins
# are then fully loaded (init.rb is evaluated) when load_plugins is called.
#
# It is the loader's responsibility to ensure that only the plugins specified
# in the configuration are actually loaded, and that the order defined
# is respected.
def initialize(initializer)
@initializer = initializer
end
# Returns the plugins to be loaded, in the order they should be loaded.
def plugins
@plugins ||= all_plugins.select { |plugin| should_load?(plugin) }.sort { |p1, p2| order_plugins(p1, p2) }
end
# Returns all the plugins that could be found by the current locators.
def all_plugins
@all_plugins ||= locate_plugins
@all_plugins
end
def load_plugins
plugins.each do |plugin|
plugin.load(initializer)
register_plugin_as_loaded(plugin)
end
ensure_all_registered_plugins_are_loaded!
end
# Adds the load paths for every plugin into the $LOAD_PATH. Plugin load paths are
# added *after* the application's <tt>lib</tt> directory, to ensure that an application
# can always override code within a plugin.
#
# Plugin load paths are also added to Dependencies.load_paths, and Dependencies.load_once_paths.
def add_plugin_load_paths
plugins.each do |plugin|
plugin.load_paths.each do |path|
$LOAD_PATH.insert(application_lib_index + 1, path)
ActiveSupport::Dependencies.load_paths << path
unless Rails.configuration.reload_plugins?
ActiveSupport::Dependencies.load_once_paths << path
end
end
end
$LOAD_PATH.uniq!
end
protected
# The locate_plugins method uses each class in config.plugin_locators to
# find the set of all plugins available to this Rails application.
def locate_plugins
configuration.plugin_locators.map { |locator|
locator.new(initializer).plugins
}.flatten
# TODO: sorting based on config.plugins
end
def register_plugin_as_loaded(plugin)
initializer.loaded_plugins << plugin
end
def configuration
initializer.configuration
end
def should_load?(plugin)
# uses Plugin#name and Plugin#valid?
enabled?(plugin) && plugin.valid?
end
def order_plugins(plugin_a, plugin_b)
if !explicit_plugin_loading_order?
plugin_a <=> plugin_b
else
if !explicitly_enabled?(plugin_a) && !explicitly_enabled?(plugin_b)
plugin_a <=> plugin_b
else
effective_order_of(plugin_a) <=> effective_order_of(plugin_b)
end
end
end
def effective_order_of(plugin)
if explicitly_enabled?(plugin)
registered_plugin_names.index(plugin.name)
else
registered_plugin_names.index('all')
end
end
def application_lib_index
$LOAD_PATH.index(File.join(RAILS_ROOT, 'lib')) || 0
end
def enabled?(plugin)
!explicit_plugin_loading_order? || registered?(plugin)
end
def explicit_plugin_loading_order?
!registered_plugin_names.nil?
end
def registered?(plugin)
explicit_plugin_loading_order? && registered_plugins_names_plugin?(plugin)
end
def explicitly_enabled?(plugin)
!explicit_plugin_loading_order? || explicitly_registered?(plugin)
end
def explicitly_registered?(plugin)
explicit_plugin_loading_order? && registered_plugin_names.include?(plugin.name)
end
def registered_plugins_names_plugin?(plugin)
registered_plugin_names.include?(plugin.name) || registered_plugin_names.include?('all')
end
# The plugins that have been explicitly listed with config.plugins. If this list is nil
# then it means the client does not care which plugins or in what order they are loaded,
# so we load all in alphabetical order. If it is an empty array, we load no plugins, if it is
# non empty, we load the named plugins in the order specified.
def registered_plugin_names
configuration.plugins ? configuration.plugins.map(&:to_s) : nil
end
def loaded?(plugin_name)
initializer.loaded_plugins.detect { |plugin| plugin.name == plugin_name.to_s }
end
def ensure_all_registered_plugins_are_loaded!
if explicit_plugin_loading_order?
if configuration.plugins.detect {|plugin| plugin != :all && !loaded?(plugin) }
missing_plugins = configuration.plugins - (plugins + [:all])
raise LoadError, "Could not locate the following plugins: #{missing_plugins.to_sentence}"
end
end
end
end
end
end
|