/
loader.rb
166 lines (151 loc) · 4.49 KB
/
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
module Padrino
class << self
##
# Hooks to be called before a load/reload
#
# ==== Examples
#
# before_load do
# pre_initialize_something
# end
#
#
def before_load(&block)
@_before_load ||= []
@_before_load << Proc.new(&block) if block_given?
@_before_load
end
##
# Hooks to be called after a load/reload
#
# ==== Examples
#
# after_load do
# DataMapper.finalize
# end
#
#
def after_load(&block)
@_after_load ||= []
@_after_load << Proc.new(&block) if block_given?
@_after_load
end
##
# Requires necessary dependencies as well as application files from root lib and models
#
def load!
return false if loaded?
@_called_from = first_caller
set_encoding
set_load_paths(*load_paths) # We set the padrino load paths
Padrino.logger # Initialize our logger
before_load.each { |bl| bl.call } # Run before hooks
dependency_paths.each { |path| require_dependency(path) }
Reloader::Stat.run! # We need to fill our Stat::CACHE
after_load.each { |al| al.call } # Run after hooks
Thread.current[:padrino_loaded] = true
end
##
# Method for reloading required applications and their files
#
def reload!
before_load.each { |bl| bl.call } # Run before hooks
Reloader::Stat.reload! # detects the modified files
after_load.each { |al| al.call } # Run after hooks
end
##
# This adds the ablity to instantiate Padrino.load! after Padrino::Application definition.
#
def called_from
@_called_from || first_caller
end
##
# Return true if Padrino was loaded with Padrino.load!
#
def loaded?
Thread.current[:padrino_loaded]
end
##
# Attempts to require all dependency libs that we need.
# If you use this method we can perform correctly a Padrino.reload!
# Another good thing that this method are dependency check, for example:
#
# models
# \-- a.rb => require something of b.rb
# \-- b.rb
#
# In the example above if we do:
#
# Dir["/models/*.rb"].each { |r| require r }
#
# we get an error, because we try to require first a.rb that need +something+ of b.rb.
#
# With +require_dependencies+ we don't have this problem.
#
# ==== Examples
# # For require all our app libs we need to do:
# require_dependencies("#{Padrino.root}/lib/**/*.rb")
#
def require_dependencies(*paths)
# Extract all files to load
files = paths.map { |path| Dir[path] }.flatten
while files.present?
# We need a size to make sure things are loading
size_at_start = files.size
# List of errors and failed files
errors, failed = [], []
# Now we try to require our dependencies
files.each do |file|
begin
Reloader::Stat.safe_load(file)
files.delete(file)
rescue Exception => e
errors << e
failed << files
end
end
# Stop processing if nothing loads or if everything has loaded
raise errors.last if files.size == size_at_start && files.present?
break if files.empty?
end
end
alias :require_dependency :require_dependencies
##
# Returns default list of path globs to load as dependencies
#
def dependency_paths
# Load db adapter, libs, root models, app configuration
@dependency_paths ||= [
"#{root}/config/database.rb", "#{root}/lib/**/*.rb", "#{root}/shared/lib/**/*.rb",
"#{root}/models/**/*.rb", "#{root}/shared/models/**/*.rb", @custom_dependencies,
"#{root}/config/apps.rb"
].flatten.compact
end
##
# Appends custom dependency patterns to the be loaded for Padrino
# ==== Examples
# Padrino.custom_dependencies("#{Padrino.root}/foo/bar/*.rb")
#
def custom_dependencies(*globs)
@custom_dependencies ||= []
@custom_dependencies.concat(globs)
end
##
# Attempts to load all dependency libs that we need.
# If you use this method we can perform correctly a Padrino.reload!
#
def load_dependencies(*paths)
paths.each do |path|
FileSet.glob(path) { |file| load(file) }
end
end
alias :load_dependency :load_dependencies
##
# Concat to $LOAD_PATH the given paths
#
def set_load_paths(*paths)
$:.concat(paths)
$:.uniq!
end
end # self
end # Padrino