require_all 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES ADDED
@@ -0,0 +1,4 @@
1
+ 1.0.0:
2
+
3
+ * Initial release (was originally load_glob, converted to require_all which is
4
+ a lot cooler, seriously trust me)
data/LICENSE ADDED
@@ -0,0 +1,58 @@
1
+ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.co.jp>.
2
+ You can redistribute it and/or modify it under either the terms of the GPL
3
+ (see COPYING.txt file), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) rename any non-standard executables so the names do not conflict
21
+ with standard executables, which must also be provided.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or executable
26
+ form, provided that you do at least ONE of the following:
27
+
28
+ a) distribute the executables and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard executables non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under this terms.
43
+
44
+ They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
45
+ files under the ./missing directory. See each file for the copying
46
+ condition.
47
+
48
+ 5. The scripts and library files supplied as input to or produced as
49
+ output from the software do not automatically fall under the
50
+ copyright of the software, but belong to whomever generated them,
51
+ and may be sold commercially, and may be aggregated with this
52
+ software.
53
+
54
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
55
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
56
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57
+ PURPOSE.
58
+
data/README.textile ADDED
@@ -0,0 +1,66 @@
1
+ h1. require_all
2
+
3
+ A wonderfully simple way to load your code.
4
+
5
+ Tired of futzing around with require statements everywhere, littering your code
6
+ with <code>require File.dirname(__FILE__)</code> crap? What if you could just
7
+ point something at a big directory full of code and have everything just
8
+ automagically load regardless of the dependency structure?
9
+
10
+ Wouldn't that be nice? Well, now you can!
11
+
12
+ <code>require 'require_all'</code>
13
+
14
+ You can now require_all in a multitude of different ways:
15
+
16
+ <code>require_all *args</code>
17
+
18
+ One of the easiest ways to require_all is to give it a glob, which will
19
+ enumerate all the matching files and load them in the proper order. For
20
+ example, to load all the Ruby files under the 'lib' directory, just do:
21
+
22
+ <code>require_all 'lib/**/*.rb'</code>
23
+
24
+ If the dependencies between the matched files are unresolvable, it will
25
+ throw the first unresolvable NameError.
26
+
27
+ Don't want to give it a glob? Just give it a list of files:
28
+
29
+ <code>require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file(f) }</code>
30
+
31
+ Or if you want, just list the files directly as arguments:
32
+
33
+ <code>require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'</code>
34
+
35
+ It's just that easy! Code loading shouldn't be hard.
36
+
37
+ h2. Methodology
38
+
39
+ I didn't invent the approach this gem uses. It was shamelessly stolen from
40
+ Merb. Once upon a time at MountainWest RubyConf we were discussing how
41
+ horrible ActiveSupport's dependencies.rb hijacking of const_missing and
42
+ someone described the approach Merb used to me. It was so simple and clean!
43
+ Here's how it works:
44
+
45
+ # Enumerate the files in the glob
46
+ # Try to load all of the files. If we encounter a NameError loading a
47
+ particular file, store that file in a "try to load it later" list.
48
+ # If all the files loaded, great, we're done! If not, go through the
49
+ "try to load it later" list again rescuing NameErrors the same way.
50
+ # If we walk the whole "try to load it later" list and it doesn't shrink
51
+ at all, we've encountered an unresolvable dependency. In this case,
52
+ require_all will rethrow the first NameError it encountered.
53
+
54
+ h2. Questions? Comments? Concerns?
55
+
56
+ You can reach the author on github or freenode: "tarcieri"
57
+
58
+ Or by email: "tony@medioh.com":mailto:tony@medioh.com
59
+
60
+ Got issues with require_all to report? Post 'em here:
61
+
62
+ "Github Tracker":http://github.com/tarcieri/require_all/issues
63
+
64
+ h2. License
65
+
66
+ MIT (see the LICENSE file for details)
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rake'
2
+ require 'rake/clean'
3
+
4
+ Dir['tasks/**/*.rake'].each { |task| load task }
5
+
6
+ task :default => :spec
7
+
8
+ task :clean do
9
+ %w[pkg coverage].each do |dir|
10
+ rm_rf dir
11
+ end
12
+ end
@@ -0,0 +1,100 @@
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
+ # Load all files matching the given glob, handling dependencies between
9
+ # the files gracefully
10
+ # One of the easiest ways to require_all is to give it a glob, which will
11
+ # enumerate all the matching files and load them in the proper order. For
12
+ # example, to load all the Ruby files under the 'lib' directory, just do:
13
+ #
14
+ # require_all 'lib/**/*.rb'
15
+ #
16
+ # If the dependencies between the matched files are unresolvable, it will
17
+ # throw the first unresolvable NameError.
18
+ #
19
+ # Don't want to give it a glob? Just give it a list of files:
20
+ #
21
+ # require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file(f) }
22
+ #
23
+ # Or if you want, just list the files directly as arguments:
24
+ #
25
+ # require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'
26
+ #
27
+ # It's just that easy! Code loading shouldn't be hard, especially in a language
28
+ # as versatile as ruby.
29
+ def require_all(*args)
30
+ # Handle passing an array as an argument
31
+ args = args.flatten
32
+
33
+ if args.size > 1
34
+ # If we got a list, those be are files!
35
+ files = args
36
+ else
37
+ arg = args.first
38
+ begin
39
+ # Try assuming we're doing plain ol' require compat
40
+ File.stat(arg)
41
+ files = [arg]
42
+ rescue Errno::ENOENT
43
+ # If the stat failed, maybe we have a glob!
44
+ files = Dir.glob arg
45
+
46
+ # If we ain't got no files, the glob failed
47
+ raise LoadError, 'no such file to load -- #{arg}' if files.empty?
48
+ end
49
+ end
50
+
51
+ files.map! { |file| File.expand_path file }
52
+
53
+ begin
54
+ failed = []
55
+ first_name_error = nil
56
+
57
+ # Attempt to load each file, rescuing which ones raise NameError for
58
+ # undefined constants. Keep trying to successively reload files that
59
+ # previously caused NameErrors until they've all been loaded or no new
60
+ # files can be loaded, indicating unresolvable dependencies.
61
+ files.each do |file|
62
+ begin
63
+ require file
64
+ rescue NameError => ex
65
+ failed << file
66
+ first_name_error ||= ex
67
+ rescue ArgumentError => ex
68
+ # Work around ActiveSuport freaking out... *sigh*
69
+ #
70
+ # ActiveSupport sometimes throws these exceptions and I really
71
+ # have no idea why. Code loading will work successfully if these
72
+ # exceptions are swallowed, although I've run into strange
73
+ # nondeterministic behaviors with constants mysteriously vanishing.
74
+ # I've gone spelunking through dependencies.rb looking for what
75
+ # exactly is going on, but all I ended up doing was making my eyes
76
+ # bleed.
77
+ #
78
+ # FIXME: If you can understand ActiveSupport's dependencies.rb
79
+ # better than I do I would *love* to find a better solution
80
+ raise unless ex.message["is not missing constant"]
81
+
82
+ STDERR.puts "Warning: require_all swallowed ActiveSupport 'is not missing constant' error"
83
+ STDERR.puts ex.backtrace[0..9]
84
+ end
85
+ end
86
+
87
+ # If this pass didn't resolve any NameErrors, we've hit an unresolvable
88
+ # dependency, so raise one of the exceptions we encountered.
89
+ if failed.size == files.size
90
+ raise first_name_error
91
+ else
92
+ files = failed
93
+ end
94
+ end until failed.empty?
95
+
96
+ true
97
+ end
98
+ end
99
+
100
+ include RequireAll
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+
3
+ GEMSPEC = Gem::Specification.new do |s|
4
+ s.name = "require_all"
5
+ s.version = "1.0.0"
6
+ s.authors = "Tony Arcieri"
7
+ s.email = "tony@medioh.com"
8
+ s.date = "2009-06-09"
9
+ s.summary = "A wonderfully simple way to load your code"
10
+ s.platform = Gem::Platform::RUBY
11
+
12
+ # Gem contents
13
+ s.files = Dir.glob("{lib,spec}/**/*") + ['Rakefile', 'require_all.gemspec']
14
+
15
+ # RubyForge info
16
+ s.homepage = "http://github.com/tarcieri/require_all"
17
+ s.rubyforge_project = "codeforpeople"
18
+
19
+ # RDoc settings
20
+ s.has_rdoc = true
21
+ s.rdoc_options = %w(--title require_all --main README.textile --line-numbers)
22
+ s.extra_rdoc_files = ["LICENSE", "README.textile", "CHANGES"]
23
+
24
+ # Extensions
25
+ s.extensions = FileList["ext/**/extconf.rb"].to_a
26
+ end
@@ -0,0 +1 @@
1
+ class A < C; end
@@ -0,0 +1 @@
1
+ class B < A; end
@@ -0,0 +1 @@
1
+ class C; end
@@ -0,0 +1 @@
1
+ class D < C; end
@@ -0,0 +1 @@
1
+ class A < C; end
@@ -0,0 +1 @@
1
+ class B < A; end
@@ -0,0 +1 @@
1
+ class C < Nonexistent; end
@@ -0,0 +1 @@
1
+ class D < C; end
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/../lib/require_all.rb'
2
+
3
+ describe "require_all" do
4
+ describe "dependency resolution" do
5
+ it "handles load ordering when dependencies are resolvable" do
6
+ require_all File.dirname(__FILE__) + '/fixtures/resolvable/*.rb'
7
+
8
+ defined?(A).should == "constant"
9
+ defined?(B).should == "constant"
10
+ defined?(C).should == "constant"
11
+ defined?(D).should == "constant"
12
+ end
13
+
14
+ it "raises NameError if dependencies can't be resolved" do
15
+ proc do
16
+ require_all File.dirname(__FILE__) + '/fixtures/unresolvable/*.rb'
17
+ end.should raise_error(NameError)
18
+ end
19
+ end
20
+
21
+ describe "syntactic sugar" do
22
+ before :all do
23
+ @base_dir = File.dirname(__FILE__) + '/fixtures/resolvable/'
24
+ @file_list = ['b.rb', 'c.rb', 'a.rb', 'd.rb'].map { |f| @base_dir + f }
25
+ end
26
+
27
+ it "works like a drop-in require replacement" do
28
+ require_all @base_dir + 'c.rb'
29
+ defined?(C).should == "constant"
30
+ end
31
+
32
+ it "accepts lists of files" do
33
+ require_all @file_list
34
+ end
35
+
36
+ it "is totally cool with a splatted list of arguments" do
37
+ require_all *@file_list
38
+ end
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: require_all
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Tony Arcieri
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-09 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: tony@medioh.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.textile
25
+ - CHANGES
26
+ files:
27
+ - lib/require_all.rb
28
+ - spec/fixtures/resolvable/a.rb
29
+ - spec/fixtures/resolvable/b.rb
30
+ - spec/fixtures/resolvable/c.rb
31
+ - spec/fixtures/resolvable/d.rb
32
+ - spec/fixtures/unresolvable/a.rb
33
+ - spec/fixtures/unresolvable/b.rb
34
+ - spec/fixtures/unresolvable/c.rb
35
+ - spec/fixtures/unresolvable/d.rb
36
+ - spec/require_all_spec.rb
37
+ - Rakefile
38
+ - require_all.gemspec
39
+ - LICENSE
40
+ - README.textile
41
+ - CHANGES
42
+ has_rdoc: true
43
+ homepage: http://github.com/tarcieri/require_all
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --title
49
+ - require_all
50
+ - --main
51
+ - README.textile
52
+ - --line-numbers
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project: codeforpeople
70
+ rubygems_version: 1.3.4
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: A wonderfully simple way to load your code
74
+ test_files: []
75
+