require_all 1.3.2 → 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,9 @@
1
1
  rvm:
2
- - 1.9.3
2
+ - 2.2.1
3
+ - 2.1.5
3
4
  - 2.0.0
4
- - jruby-19mode
5
- - rbx-19mode
5
+ - jruby
6
+ - rbx
6
7
  - ruby-head
7
8
  notifications:
8
9
  recipients:
data/CHANGES CHANGED
@@ -1,3 +1,7 @@
1
+ 1.3.3:
2
+
3
+ * Support empty directories without crashing. Issue #11. Thanks to Eric Kessler.
4
+
1
5
  1.3.2:
2
6
 
3
7
  * Add license to gemspec.
data/Rakefile CHANGED
@@ -1,7 +1,6 @@
1
- require "bundler/gem_tasks"
2
-
3
- require "rspec/core/rake_task"
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
7
- task :release => :spec
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rspec/core/rake_task"
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
6
+ task :release => :spec
@@ -1,277 +1,276 @@
1
- #--
2
- # Copyright (C)2009 Tony Arcieri
3
- # You can redistribute this under the terms of the MIT license
4
- # See file LICENSE for details
5
- #++
6
-
7
- module RequireAll
8
- # A wonderfully simple way to load your code.
9
- #
10
- # The easiest way to use require_all is to just point it at a directory
11
- # containing a bunch of .rb files. These files can be nested under
12
- # subdirectories as well:
13
- #
14
- # require_all 'lib'
15
- #
16
- # This will find all the .rb files under the lib directory and load them.
17
- # The proper order to load them in will be determined automatically.
18
- #
19
- # If the dependencies between the matched files are unresolvable, it will
20
- # throw the first unresolvable NameError.
21
- #
22
- # You can also give it a glob, which will enumerate all the matching files:
23
- #
24
- # require_all 'lib/**/*.rb'
25
- #
26
- # It will also accept an array of files:
27
- #
28
- # require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file(f) }
29
- #
30
- # Or if you want, just list the files directly as arguments:
31
- #
32
- # require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'
33
- #
34
- def require_all(*args)
35
- # Handle passing an array as an argument
36
- args.flatten!
37
-
38
- options = {:method => :require}
39
- options.merge!(args.pop) if args.last.is_a?(Hash)
40
-
41
- if args.empty?
42
- puts "no files were loaded due to an empty Array" if $DEBUG
43
- return false
44
- end
45
-
46
- if args.size > 1
47
- # Expand files below directories
48
- files = args.map do |path|
49
- if File.directory? path
50
- Dir[File.join(path, '**', '*.rb')]
51
- else
52
- path
53
- end
54
- end.flatten
55
- else
56
- arg = args.first
57
- begin
58
- # Try assuming we're doing plain ol' require compat
59
- stat = File.stat(arg)
60
-
61
- if stat.file?
62
- files = [arg]
63
- elsif stat.directory?
64
- files = Dir.glob File.join(arg, '**', '*.rb')
65
- else
66
- raise ArgumentError, "#{arg} isn't a file or directory"
67
- end
68
- rescue SystemCallError
69
- # If the stat failed, maybe we have a glob!
70
- files = Dir.glob arg
71
-
72
- # Maybe it's an .rb file and the .rb was omitted
73
- if File.file?(arg + '.rb')
74
- file = arg + '.rb'
75
- options[:method] != :autoload ? Kernel.send(options[:method], file) : __autoload(file, file, options)
76
- return true
77
- end
78
-
79
- # If we ain't got no files, the glob failed
80
- raise LoadError, "no such file to load -- #{arg}" if files.empty?
81
- end
82
- end
83
-
84
- # If there's nothing to load, you're doing it wrong!
85
- raise LoadError, "no files to load" if files.empty?
86
-
87
- if options[:method] == :autoload
88
- files.map! { |file| [file, File.expand_path(file)] }
89
- files.each do |file, full_path|
90
- __autoload(file, full_path, options)
91
- end
92
-
93
- return true
94
- end
95
-
96
- files.map! { |file| File.expand_path file }
97
- files.sort!
98
-
99
- begin
100
- failed = []
101
- first_name_error = nil
102
-
103
- # Attempt to load each file, rescuing which ones raise NameError for
104
- # undefined constants. Keep trying to successively reload files that
105
- # previously caused NameErrors until they've all been loaded or no new
106
- # files can be loaded, indicating unresolvable dependencies.
107
- files.each do |file|
108
- begin
109
- Kernel.send(options[:method], file)
110
- rescue NameError => ex
111
- failed << file
112
- first_name_error ||= ex
113
- rescue ArgumentError => ex
114
- # Work around ActiveSuport freaking out... *sigh*
115
- #
116
- # ActiveSupport sometimes throws these exceptions and I really
117
- # have no idea why. Code loading will work successfully if these
118
- # exceptions are swallowed, although I've run into strange
119
- # nondeterministic behaviors with constants mysteriously vanishing.
120
- # I've gone spelunking through dependencies.rb looking for what
121
- # exactly is going on, but all I ended up doing was making my eyes
122
- # bleed.
123
- #
124
- # FIXME: If you can understand ActiveSupport's dependencies.rb
125
- # better than I do I would *love* to find a better solution
126
- raise unless ex.message["is not missing constant"]
127
-
128
- STDERR.puts "Warning: require_all swallowed ActiveSupport 'is not missing constant' error"
129
- STDERR.puts ex.backtrace[0..9]
130
- end
131
- end
132
-
133
- # If this pass didn't resolve any NameErrors, we've hit an unresolvable
134
- # dependency, so raise one of the exceptions we encountered.
135
- if failed.size == files.size
136
- raise first_name_error
137
- else
138
- files = failed
139
- end
140
- end until failed.empty?
141
-
142
- true
143
- end
144
-
145
- # Works like require_all, but paths are relative to the caller rather than
146
- # the current working directory
147
- def require_rel(*paths)
148
- # Handle passing an array as an argument
149
- paths.flatten!
150
- return false if paths.empty?
151
-
152
- source_directory = File.dirname caller.first.sub(/:\d+$/, '')
153
- paths.each do |path|
154
- require_all File.join(source_directory, path)
155
- end
156
- end
157
-
158
- # Loads all files like require_all instead of requiring
159
- def load_all(*paths)
160
- require_all paths, :method => :load
161
- end
162
-
163
- # Loads all files by using relative paths of the caller rather than
164
- # the current working directory
165
- def load_rel(*paths)
166
- paths.flatten!
167
- return false if paths.empty?
168
-
169
- source_directory = File.dirname caller.first.sub(/:\d+$/, '')
170
- paths.each do |path|
171
- require_all File.join(source_directory, path), :method => :load
172
- end
173
- end
174
-
175
- # Performs Kernel#autoload on all of the files rather than requiring immediately.
176
- #
177
- # Note that all Ruby files inside of the specified directories should have same module name as
178
- # the directory itself and file names should reflect the class/module names.
179
- # For example if there is a my_file.rb in directories dir1/dir2/ then
180
- # there should be a declaration like this in my_file.rb:
181
- # module Dir1
182
- # module Dir2
183
- # class MyFile
184
- # ...
185
- # end
186
- # end
187
- # end
188
- #
189
- # If the filename and namespaces won't match then my_file.rb will be loaded into wrong module!
190
- # Better to fix these files.
191
- #
192
- # Set $DEBUG=true to see how files will be autoloaded if experiencing any problems.
193
- #
194
- # If trying to perform autoload on some individual file or some inner module, then you'd have
195
- # to always specify *:base_dir* option to specify where top-level namespace resides.
196
- # Otherwise it's impossible to know the namespace of the loaded files.
197
- #
198
- # For example loading only my_file.rb from dir1/dir2 with autoload_all:
199
- #
200
- # autoload_all File.dirname(__FILE__) + '/dir1/dir2/my_file',
201
- # :base_dir => File.dirname(__FILE__) + '/dir1'
202
- #
203
- # WARNING: All modules will be created even if files themselves aren't loaded yet, meaning
204
- # that all the code which depends of the modules being loaded or not will not work, like usages
205
- # of define? and it's friends.
206
- #
207
- # Also, normal caveats of using Kernel#autoload apply - you have to remember that before
208
- # applying any monkey-patches to code using autoload, you'll have to reference the full constant
209
- # to load the code before applying your patch!
210
-
211
- def autoload_all(*paths)
212
- paths.flatten!
213
- return false if paths.empty?
214
- require "pathname"
215
-
216
- options = {:method => :autoload}
217
- options.merge!(paths.pop) if paths.last.is_a?(Hash)
218
-
219
- paths.each do |path|
220
- require_all path, {:base_dir => path}.merge(options)
221
- end
222
- end
223
-
224
- # Performs autoloading relatively from the caller instead of using current working directory
225
- def autoload_rel(*paths)
226
- paths.flatten!
227
- return false if paths.empty?
228
- require "pathname"
229
-
230
- options = {:method => :autoload}
231
- options.merge!(paths.pop) if paths.last.is_a?(Hash)
232
-
233
- source_directory = File.dirname caller.first.sub(/:\d+$/, '')
234
- paths.each do |path|
235
- file_path = Pathname.new(source_directory).join(path).to_s
236
- require_all file_path, {:method => :autoload,
237
- :base_dir => source_directory}.merge(options)
238
- end
239
- end
240
-
241
- private
242
-
243
- def __autoload(file, full_path, options)
244
- last_module = "Object" # default constant where namespaces are created into
245
- begin
246
- base_dir = Pathname.new(options[:base_dir]).realpath
247
- rescue Errno::ENOENT
248
- raise LoadError, ":base_dir doesn't exist at #{options[:base_dir]}"
249
- end
250
- Pathname.new(file).realpath.descend do |entry|
251
- # skip until *entry* is same as desired directory
252
- # or anything inside of it avoiding to create modules
253
- # from the top-level directories
254
- next if (entry <=> base_dir) < 0
255
-
256
- # get the module into which a new module is created or
257
- # autoload performed
258
- mod = Object.class_eval(last_module)
259
-
260
- without_ext = entry.basename(entry.extname).to_s
261
- const = without_ext.split("_").map {|word| word.capitalize}.join
262
-
263
- if entry.directory?
264
- mod.class_eval "module #{const} end"
265
- last_module += "::#{const}"
266
- else
267
- mod.class_eval do
268
- puts "autoloading #{mod}::#{const} from #{full_path}" if $DEBUG
269
- autoload const, full_path
270
- end
271
- end
272
- end
273
- end
274
-
275
- end
276
-
277
- include RequireAll
1
+ #--
2
+ # Copyright (C)2009 Tony Arcieri
3
+ # You can redistribute this under the terms of the MIT license
4
+ # See file LICENSE for details
5
+ #++
6
+
7
+ module RequireAll
8
+ # A wonderfully simple way to load your code.
9
+ #
10
+ # The easiest way to use require_all is to just point it at a directory
11
+ # containing a bunch of .rb files. These files can be nested under
12
+ # subdirectories as well:
13
+ #
14
+ # require_all 'lib'
15
+ #
16
+ # This will find all the .rb files under the lib directory and load them.
17
+ # The proper order to load them in will be determined automatically.
18
+ #
19
+ # If the dependencies between the matched files are unresolvable, it will
20
+ # throw the first unresolvable NameError.
21
+ #
22
+ # You can also give it a glob, which will enumerate all the matching files:
23
+ #
24
+ # require_all 'lib/**/*.rb'
25
+ #
26
+ # It will also accept an array of files:
27
+ #
28
+ # require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file(f) }
29
+ #
30
+ # Or if you want, just list the files directly as arguments:
31
+ #
32
+ # require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'
33
+ #
34
+ def require_all(*args)
35
+ # Handle passing an array as an argument
36
+ args.flatten!
37
+
38
+ options = {:method => :require}
39
+ options.merge!(args.pop) if args.last.is_a?(Hash)
40
+
41
+ if args.empty?
42
+ puts "no files were loaded due to an empty Array" if $DEBUG
43
+ return false
44
+ end
45
+
46
+ if args.size > 1
47
+ # Expand files below directories
48
+ files = args.map do |path|
49
+ if File.directory? path
50
+ Dir[File.join(path, '**', '*.rb')]
51
+ else
52
+ path
53
+ end
54
+ end.flatten
55
+ else
56
+ arg = args.first
57
+ begin
58
+ # Try assuming we're doing plain ol' require compat
59
+ stat = File.stat(arg)
60
+
61
+ if stat.file?
62
+ files = [arg]
63
+ elsif stat.directory?
64
+ files = Dir.glob File.join(arg, '**', '*.rb')
65
+ else
66
+ raise ArgumentError, "#{arg} isn't a file or directory"
67
+ end
68
+ rescue SystemCallError
69
+ # If the stat failed, maybe we have a glob!
70
+ files = Dir.glob arg
71
+
72
+ # Maybe it's an .rb file and the .rb was omitted
73
+ if File.file?(arg + '.rb')
74
+ file = arg + '.rb'
75
+ options[:method] != :autoload ? Kernel.send(options[:method], file) : __autoload(file, file, options)
76
+ return true
77
+ end
78
+
79
+ # If we ain't got no files, the glob failed
80
+ raise LoadError, "no such file to load -- #{arg}" if files.empty?
81
+ end
82
+ end
83
+
84
+ return if files.empty?
85
+
86
+ if options[:method] == :autoload
87
+ files.map! { |file_| [file_, File.expand_path(file_)] }
88
+ files.each do |file_, full_path|
89
+ __autoload(file_, full_path, options)
90
+ end
91
+
92
+ return true
93
+ end
94
+
95
+ files.map! { |file_| File.expand_path file_ }
96
+ files.sort!
97
+
98
+ begin
99
+ failed = []
100
+ first_name_error = nil
101
+
102
+ # Attempt to load each file, rescuing which ones raise NameError for
103
+ # undefined constants. Keep trying to successively reload files that
104
+ # previously caused NameErrors until they've all been loaded or no new
105
+ # files can be loaded, indicating unresolvable dependencies.
106
+ files.each do |file_|
107
+ begin
108
+ Kernel.send(options[:method], file_)
109
+ rescue NameError => ex
110
+ failed << file_
111
+ first_name_error ||= ex
112
+ rescue ArgumentError => ex
113
+ # Work around ActiveSuport freaking out... *sigh*
114
+ #
115
+ # ActiveSupport sometimes throws these exceptions and I really
116
+ # have no idea why. Code loading will work successfully if these
117
+ # exceptions are swallowed, although I've run into strange
118
+ # nondeterministic behaviors with constants mysteriously vanishing.
119
+ # I've gone spelunking through dependencies.rb looking for what
120
+ # exactly is going on, but all I ended up doing was making my eyes
121
+ # bleed.
122
+ #
123
+ # FIXME: If you can understand ActiveSupport's dependencies.rb
124
+ # better than I do I would *love* to find a better solution
125
+ raise unless ex.message["is not missing constant"]
126
+
127
+ STDERR.puts "Warning: require_all swallowed ActiveSupport 'is not missing constant' error"
128
+ STDERR.puts ex.backtrace[0..9]
129
+ end
130
+ end
131
+
132
+ # If this pass didn't resolve any NameErrors, we've hit an unresolvable
133
+ # dependency, so raise one of the exceptions we encountered.
134
+ if failed.size == files.size
135
+ raise first_name_error
136
+ else
137
+ files = failed
138
+ end
139
+ end until failed.empty?
140
+
141
+ true
142
+ end
143
+
144
+ # Works like require_all, but paths are relative to the caller rather than
145
+ # the current working directory
146
+ def require_rel(*paths)
147
+ # Handle passing an array as an argument
148
+ paths.flatten!
149
+ return false if paths.empty?
150
+
151
+ source_directory = File.dirname caller.first.sub(/:\d+$/, '')
152
+ paths.each do |path|
153
+ require_all File.join(source_directory, path)
154
+ end
155
+ end
156
+
157
+ # Loads all files like require_all instead of requiring
158
+ def load_all(*paths)
159
+ require_all paths, :method => :load
160
+ end
161
+
162
+ # Loads all files by using relative paths of the caller rather than
163
+ # the current working directory
164
+ def load_rel(*paths)
165
+ paths.flatten!
166
+ return false if paths.empty?
167
+
168
+ source_directory = File.dirname caller.first.sub(/:\d+$/, '')
169
+ paths.each do |path|
170
+ require_all File.join(source_directory, path), :method => :load
171
+ end
172
+ end
173
+
174
+ # Performs Kernel#autoload on all of the files rather than requiring immediately.
175
+ #
176
+ # Note that all Ruby files inside of the specified directories should have same module name as
177
+ # the directory itself and file names should reflect the class/module names.
178
+ # For example if there is a my_file.rb in directories dir1/dir2/ then
179
+ # there should be a declaration like this in my_file.rb:
180
+ # module Dir1
181
+ # module Dir2
182
+ # class MyFile
183
+ # ...
184
+ # end
185
+ # end
186
+ # end
187
+ #
188
+ # If the filename and namespaces won't match then my_file.rb will be loaded into wrong module!
189
+ # Better to fix these files.
190
+ #
191
+ # Set $DEBUG=true to see how files will be autoloaded if experiencing any problems.
192
+ #
193
+ # If trying to perform autoload on some individual file or some inner module, then you'd have
194
+ # to always specify *:base_dir* option to specify where top-level namespace resides.
195
+ # Otherwise it's impossible to know the namespace of the loaded files.
196
+ #
197
+ # For example loading only my_file.rb from dir1/dir2 with autoload_all:
198
+ #
199
+ # autoload_all File.dirname(__FILE__) + '/dir1/dir2/my_file',
200
+ # :base_dir => File.dirname(__FILE__) + '/dir1'
201
+ #
202
+ # WARNING: All modules will be created even if files themselves aren't loaded yet, meaning
203
+ # that all the code which depends of the modules being loaded or not will not work, like usages
204
+ # of define? and it's friends.
205
+ #
206
+ # Also, normal caveats of using Kernel#autoload apply - you have to remember that before
207
+ # applying any monkey-patches to code using autoload, you'll have to reference the full constant
208
+ # to load the code before applying your patch!
209
+
210
+ def autoload_all(*paths)
211
+ paths.flatten!
212
+ return false if paths.empty?
213
+ require "pathname"
214
+
215
+ options = {:method => :autoload}
216
+ options.merge!(paths.pop) if paths.last.is_a?(Hash)
217
+
218
+ paths.each do |path|
219
+ require_all path, {:base_dir => path}.merge(options)
220
+ end
221
+ end
222
+
223
+ # Performs autoloading relatively from the caller instead of using current working directory
224
+ def autoload_rel(*paths)
225
+ paths.flatten!
226
+ return false if paths.empty?
227
+ require "pathname"
228
+
229
+ options = {:method => :autoload}
230
+ options.merge!(paths.pop) if paths.last.is_a?(Hash)
231
+
232
+ source_directory = File.dirname caller.first.sub(/:\d+$/, '')
233
+ paths.each do |path|
234
+ file_path = Pathname.new(source_directory).join(path).to_s
235
+ require_all file_path, {:method => :autoload,
236
+ :base_dir => source_directory}.merge(options)
237
+ end
238
+ end
239
+
240
+ private
241
+
242
+ def __autoload(file, full_path, options)
243
+ last_module = "Object" # default constant where namespaces are created into
244
+ begin
245
+ base_dir = Pathname.new(options[:base_dir]).realpath
246
+ rescue Errno::ENOENT
247
+ raise LoadError, ":base_dir doesn't exist at #{options[:base_dir]}"
248
+ end
249
+ Pathname.new(file).realpath.descend do |entry|
250
+ # skip until *entry* is same as desired directory
251
+ # or anything inside of it avoiding to create modules
252
+ # from the top-level directories
253
+ next if (entry <=> base_dir) < 0
254
+
255
+ # get the module into which a new module is created or
256
+ # autoload performed
257
+ mod = Object.class_eval(last_module)
258
+
259
+ without_ext = entry.basename(entry.extname).to_s
260
+ const = without_ext.split("_").map {|word| word.capitalize}.join
261
+
262
+ if entry.directory?
263
+ mod.class_eval "module #{const} end"
264
+ last_module += "::#{const}"
265
+ else
266
+ mod.class_eval do
267
+ puts "autoloading #{mod}::#{const} from #{full_path}" if $DEBUG
268
+ autoload const, full_path
269
+ end
270
+ end
271
+ end
272
+ end
273
+
274
+ end
275
+
276
+ include RequireAll