/
extension_loader.rb
174 lines (145 loc) · 5.1 KB
/
extension_loader.rb
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
require 'radiant/extension'
require 'method_observer'
module Radiant
class ExtensionLoader
class DependenciesObserver < MethodObserver
attr_accessor :config
def initialize(rails_config)
@config = rails_config
end
def before_clear(*args)
ExtensionLoader.deactivate_extensions
end
def after_clear(*args)
ExtensionLoader.load_extensions
ExtensionLoader.activate_extensions
end
end
include Simpleton
attr_accessor :initializer, :extensions
def initialize
self.extensions = []
end
def configuration
initializer.configuration
end
def extension_load_paths
load_extension_roots.map { |extension| load_paths_for(extension) }.flatten.select { |d| File.directory?(d) }
end
def plugin_paths
load_extension_roots.map {|extension| "#{extension}/vendor/plugins" }.select {|d| File.directory?(d) }
end
def add_extension_paths
extension_load_paths.reverse_each do |path|
configuration.load_paths.unshift path
$LOAD_PATH.unshift path
end
end
def add_plugin_paths
configuration.plugin_paths.concat plugin_paths
end
def locale_paths
load_extension_roots.map { |extension| "#{extension}/config/locales" }.select { |d| File.directory?(d) }.reverse
end
def add_locale_paths
configuration.i18n.load_path.concat(locale_paths.map{ |path| Dir[File.join("#{path}","*.{rb,yml}")] })
end
def controller_paths
extensions.map { |extension| "#{extension.root}/app/controllers" }.select { |d| File.directory?(d) }
end
def add_controller_paths
configuration.controller_paths.concat(controller_paths)
end
def view_paths
extensions.map { |extension| "#{extension.root}/app/views" }.select { |d| File.directory?(d) }.reverse
end
def metal_paths
load_extension_roots.map { |extension| "#{extension}/app/metal" }.select { |d| File.directory?(d) }.reverse
end
# Load the extensions
def load_extensions
@observer ||= DependenciesObserver.new(configuration).observe(::ActiveSupport::Dependencies)
self.extensions = load_extension_roots.map do |root|
begin
extension_file = "#{File.basename(root).gsub(/^radiant-|-extension-([\d\.a-z]+|[a-z\d]+)$/,'')}_extension"
extension = extension_file.camelize.constantize
extension.unloadable
extension.root = root
extension
rescue LoadError, NameError => e
$stderr.puts "Could not load extension from file: #{extension_file}.\n#{e.inspect}"
nil
end
end.compact
end
def load_extension_initalizers
extensions.each &:load_initializers
end
def deactivate_extensions
extensions.each &:deactivate
end
def activate_extensions
initializer.initialize_default_admin_tabs
# Reset the view paths after
initializer.initialize_framework_views
# Reset the admin UI regions
initializer.admin.load_default_regions
extensions.each &:activate
# Make sure we have our subclasses loaded!
Page.load_subclasses
end
alias :reactivate :activate_extensions
private
def load_paths_for(dir)
if File.directory?(dir)
%w(lib app/models app/controllers app/metal app/helpers test/helpers).collect do |p|
path = "#{dir}/#{p}"
path if File.directory?(path)
end.compact << dir
else
[]
end
end
def load_extension_roots
@load_extension_roots ||= unless configuration.extensions.empty?
select_extension_roots
else
[]
end
end
def select_extension_roots
all_roots = all_extension_roots.dup
roots = configuration.extensions.uniq.map do |ext_name|
if :all === ext_name
:all
else
ext_path = all_roots.detect do |maybe_path|
File.basename(maybe_path).gsub(/^radiant-|-extension-([\d\.a-z]+|[a-z\d]+)$/, '') == ext_name.to_s
end
raise LoadError, "Cannot find the extension '#{ext_name}'!" if ext_path.nil?
all_roots.delete(ext_path)
end
end
if placeholder = roots.index(:all)
# replace the :all symbol with any remaining paths
roots[placeholder, 1] = all_roots
end
configuration.ignored_extensions.each do |removed|
roots.delete_if{|root| root.split('/').last.to_s == removed.to_s }
end
roots
end
def all_extension_roots
@all_extension_roots ||= begin
roots = configuration.extension_paths.map do |path|
Dir["#{path}/*"].map {|f| File.expand_path(f) if File.directory?(f) }.compact.sort
end
configuration.gems.inject(roots) do |paths,gem|
paths.tap { |p| p << gem.specification.full_gem_path if gem.specification and
gem.specification.full_gem_path[/radiant-.*-extension-([\d\.a-z]+|[a-z\d]+)$/] }
end
roots.flatten
end
end
end
end