magicloader 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +5 -0
- data/LICENSE +58 -0
- data/README.markdown +151 -0
- data/Rakefile +12 -0
- data/lib/magic_loader.rb +115 -0
- data/lib/magic_loader/tasks.rb +85 -0
- data/magicloader.gemspec +24 -0
- data/spec/fixtures/resolvable/a.rb +1 -0
- data/spec/fixtures/resolvable/b.rb +1 -0
- data/spec/fixtures/resolvable/c.rb +1 -0
- data/spec/fixtures/resolvable/d.rb +1 -0
- data/spec/fixtures/unresolvable/a.rb +1 -0
- data/spec/fixtures/unresolvable/b.rb +1 -0
- data/spec/fixtures/unresolvable/c.rb +1 -0
- data/spec/fixtures/unresolvable/d.rb +1 -0
- data/spec/magic_loader_spec.rb +49 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/task_spec.rb +75 -0
- data/spec/tmp/example.rb +11 -0
- metadata +91 -0
data/CHANGES
ADDED
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.markdown
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
MagicLoader
|
2
|
+
===========
|
3
|
+
|
4
|
+
What if you could just point something at a big directory full of code and have
|
5
|
+
everything just automagically load regardless of the dependency structure?
|
6
|
+
|
7
|
+
Wouldn't that be nice? Well, now you can!
|
8
|
+
|
9
|
+
<code>require 'magic_loader'</code>
|
10
|
+
|
11
|
+
MagicLoader uses a special algorithm, sort of like Bundler, to calculate the
|
12
|
+
order in which various files in your project must be required in order for
|
13
|
+
your project to load successfully. If you've been manually maintaining a
|
14
|
+
dependencies list, MagicLoader provides for your code the same automation that
|
15
|
+
Bundler provides for your gem dependencies.
|
16
|
+
|
17
|
+
The "magicload" Rake task
|
18
|
+
-------------------------
|
19
|
+
|
20
|
+
The main way MagicLoader should be used is as a Rake task. Inside of your
|
21
|
+
project's Rakefile, do:
|
22
|
+
|
23
|
+
<pre><code>
|
24
|
+
require 'magicloader/tasks'
|
25
|
+
|
26
|
+
MagicLoader::Task.new 'lib/my_project',
|
27
|
+
:target => 'lib/my_project.rb',
|
28
|
+
:strip => 'lib/',
|
29
|
+
:name => 'magicload'
|
30
|
+
</code></pre>
|
31
|
+
|
32
|
+
What does this do exactly? Let's dig in.
|
33
|
+
|
34
|
+
The MagicLoader::Task.new method takes a list of strings as its arguments,
|
35
|
+
with an option options hash on the end (of course options are optional!)
|
36
|
+
|
37
|
+
In this example, we have only one string, which is the path to our project.
|
38
|
+
However, you can have multiple strings, and they don't need to just be paths,
|
39
|
+
they can be globs, too! For more information on the string arguments, see
|
40
|
+
"The wonderful require_all" method below.
|
41
|
+
|
42
|
+
Pay special attention to the :target option. If you leave this out,
|
43
|
+
MagicLoader will print what it would've generated to standard output. However,
|
44
|
+
if you set the target, you can annotate a particular file with a MagicLoader
|
45
|
+
Magic Block. What's that you ask? Well it looks a bit like this:
|
46
|
+
|
47
|
+
<pre><code>
|
48
|
+
#-----BEGIN MAGICLOADER MAGIC BLOCK-----
|
49
|
+
# Automagically generated by MagicLoader. Editing may
|
50
|
+
# result in bad juju. Edit at your own risk!
|
51
|
+
require "my_project/foo.rb"
|
52
|
+
require "my_project/bar.rb"
|
53
|
+
require "my_project/baz.rb"
|
54
|
+
require "my_project/qux.rb"
|
55
|
+
#------END MAGICLOADER MAGIC BLOCK------
|
56
|
+
</code></pre>
|
57
|
+
|
58
|
+
Here MagicLoader is automagically writing the dependency order of your library
|
59
|
+
into the master file for your project. The dependency order is appended to the
|
60
|
+
end of the file if it doesn't exist or updated if it does. The rest of your
|
61
|
+
file remains unchanged.
|
62
|
+
|
63
|
+
MagicLoader loads up your whole project within the Rake task, which is a nice,
|
64
|
+
clean-room, thread-free environment where your code can be safely loaded
|
65
|
+
without crazy wonky stuff going on. Here MagicLoader uses its magic algorithm
|
66
|
+
to calculate the dependencies, then writes them all out for you in the
|
67
|
+
MagicLoader Magic Block.
|
68
|
+
|
69
|
+
Now, let's dig into the rest of the options hash. You might be able to guess
|
70
|
+
what the options do already, but if you can't, here's some help:
|
71
|
+
|
72
|
+
* __target__: output file to annotate. See above.
|
73
|
+
|
74
|
+
* __strip__: remove the given leading string from all of the output paths written
|
75
|
+
to the target file. Optionally, you can give an arbitrary regular
|
76
|
+
expression, and whatever it matches will be removed from the string.
|
77
|
+
This is good if you have a leading directory prefix you want to remove
|
78
|
+
from the generated output files.
|
79
|
+
|
80
|
+
* __name__: the name of the Rake task to define. It defaults to "magicload" if you
|
81
|
+
don't specify it yourself, so specifying it explicitly as "magicload" is a
|
82
|
+
bit redundant. Otherwise, you can set it to whatever you want.
|
83
|
+
|
84
|
+
The wonderful require_all method
|
85
|
+
--------------------------------
|
86
|
+
|
87
|
+
You can probably guess what MagicLoader.require_all does: it requires a whole
|
88
|
+
bunch of files. It's highly configurable and can pull in globs or whole
|
89
|
+
directories of code.
|
90
|
+
|
91
|
+
However, there are some caveats about the require_all method: it's slow and it
|
92
|
+
isn't thread safe. That said, if you would like runtime code dependency
|
93
|
+
management, then proceed, young sorcerer.
|
94
|
+
|
95
|
+
The easiest way to use require_all is to just point it at a directory
|
96
|
+
containing a bunch of .rb files:
|
97
|
+
|
98
|
+
<code>MagicLoader.require_all 'lib'</code>
|
99
|
+
|
100
|
+
This will find all the .rb files under the lib directory (including all
|
101
|
+
subdirectories as well) and load them.
|
102
|
+
|
103
|
+
The proper order to in which to load them is determined automatically. If the
|
104
|
+
dependencies between the matched files are unresolvable, it will throw the
|
105
|
+
first unresolvable NameError.
|
106
|
+
|
107
|
+
You can also give it a glob, which will enumerate all the matching files:
|
108
|
+
|
109
|
+
<code>MagicLoader.require_all 'lib/**/*.rb'</code>
|
110
|
+
|
111
|
+
It will also accept an array of files:
|
112
|
+
|
113
|
+
<code>MagicLoader.require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file? f }</code>
|
114
|
+
|
115
|
+
Or if you want, just list the files directly as arguments:
|
116
|
+
|
117
|
+
<code>MagicLoader.require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'</code>
|
118
|
+
|
119
|
+
So what's the magic?
|
120
|
+
--------------------
|
121
|
+
|
122
|
+
MagicLoader is just a Ruby library, after all. There's no magic but what you
|
123
|
+
don't understand. I didn't invent the approach this gem uses. It was
|
124
|
+
shamelessly stolen from Merb (which apparently stole it from elsewhere).
|
125
|
+
|
126
|
+
Here's how it works:
|
127
|
+
|
128
|
+
* Enumerate the files to be loaded
|
129
|
+
* Try to load all of the files. If we encounter a NameError loading a
|
130
|
+
particular file, store that file in a "try to load it later" list.
|
131
|
+
* If all the files loaded, great, we're done! If not, go through the
|
132
|
+
"try to load it later" list again rescuing NameErrors the same way.
|
133
|
+
* If we walk the whole "try to load it later" list and it doesn't shrink
|
134
|
+
at all, we've encountered an unresolvable dependency. In this case,
|
135
|
+
require_all will rethrow the first NameError it encountered.
|
136
|
+
|
137
|
+
Questions? Comments? Concerns?
|
138
|
+
------------------------------
|
139
|
+
|
140
|
+
You can reach the author on github or freenode: "tarcieri"
|
141
|
+
|
142
|
+
or on Twitter: @bascule or email: [bascule@gmail.com](mailto:bascule@gmail.com)
|
143
|
+
|
144
|
+
Got issues with require_all to report? Post 'em here:
|
145
|
+
|
146
|
+
[Github Tracker](http://github.com/tarcieri/require_all/issues)
|
147
|
+
|
148
|
+
License
|
149
|
+
-------
|
150
|
+
|
151
|
+
MIT (see the LICENSE file for details)
|
data/Rakefile
ADDED
data/lib/magic_loader.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C)2009-10 Tony Arcieri
|
3
|
+
# You can redistribute this under the terms of the MIT license
|
4
|
+
# See file LICENSE for details
|
5
|
+
#++
|
6
|
+
|
7
|
+
# MagicLoader: painless code dependency management
|
8
|
+
# For more information, see http://github.com/tarcieri/MagicLoader
|
9
|
+
module MagicLoader
|
10
|
+
# A wonderfully simple way to load your code.
|
11
|
+
#
|
12
|
+
# The easiest way to use require_all is to just point it at a directory
|
13
|
+
# containing a bunch of .rb files. These files can be nested under
|
14
|
+
# subdirectories as well:
|
15
|
+
#
|
16
|
+
# MagicLoader.require_all 'lib'
|
17
|
+
#
|
18
|
+
# This will find all the .rb files under the lib directory and load them.
|
19
|
+
# The proper order to load them in will be determined automatically.
|
20
|
+
#
|
21
|
+
# If the dependencies between the matched files are unresolvable, it will
|
22
|
+
# throw the first unresolvable NameError.
|
23
|
+
#
|
24
|
+
# You can also give it a glob, which will enumerate all the matching files:
|
25
|
+
#
|
26
|
+
# MagicLoader.require_all 'lib/**/*.rb'
|
27
|
+
#
|
28
|
+
# It will also accept an array of files:
|
29
|
+
#
|
30
|
+
# MagicLoader.require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file(f) }
|
31
|
+
#
|
32
|
+
# Or if you want, just list the files directly as arguments:
|
33
|
+
#
|
34
|
+
# MagicLoader.require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'
|
35
|
+
#
|
36
|
+
def self.require_all(*args)
|
37
|
+
# Handle passing an array as an argument
|
38
|
+
args.flatten!
|
39
|
+
|
40
|
+
if args.size > 1
|
41
|
+
# Expand files below directories
|
42
|
+
files = args.map do |path|
|
43
|
+
if File.directory? path
|
44
|
+
Dir[File.join(path, '**', '*.rb')]
|
45
|
+
else
|
46
|
+
path
|
47
|
+
end
|
48
|
+
end.flatten
|
49
|
+
else
|
50
|
+
arg = args.first
|
51
|
+
begin
|
52
|
+
# Try assuming we're doing plain ol' require compat
|
53
|
+
stat = File.stat(arg)
|
54
|
+
|
55
|
+
if stat.file?
|
56
|
+
files = [arg]
|
57
|
+
elsif stat.directory?
|
58
|
+
files = Dir.glob File.join(arg, '**', '*.rb')
|
59
|
+
else
|
60
|
+
raise ArgumentError, "#{arg} isn't a file or directory"
|
61
|
+
end
|
62
|
+
rescue Errno::ENOENT
|
63
|
+
# If the stat failed, maybe we have a glob!
|
64
|
+
files = Dir.glob arg
|
65
|
+
|
66
|
+
# Maybe it's an .rb file and the .rb was omitted
|
67
|
+
if File.file?(arg + '.rb')
|
68
|
+
require(arg + '.rb')
|
69
|
+
return true
|
70
|
+
end
|
71
|
+
|
72
|
+
# If we ain't got no files, the glob failed
|
73
|
+
raise LoadError, "no such file to load -- #{arg}" if files.empty?
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# If there's nothing to load, you're doing it wrong!
|
78
|
+
raise LoadError, "no files to load" if files.empty?
|
79
|
+
|
80
|
+
# Sort input files to give semi-deterministic results
|
81
|
+
files.sort!
|
82
|
+
|
83
|
+
# Store load order as it's calculated
|
84
|
+
load_order = []
|
85
|
+
|
86
|
+
begin
|
87
|
+
failed = []
|
88
|
+
first_name_error = nil
|
89
|
+
|
90
|
+
# Attempt to load each file, rescuing which ones raise NameError for
|
91
|
+
# undefined constants. Keep trying to successively reload files that
|
92
|
+
# previously caused NameErrors until they've all been loaded or no new
|
93
|
+
# files can be loaded, indicating unresolvable dependencies.
|
94
|
+
files.each do |file|
|
95
|
+
begin
|
96
|
+
require file
|
97
|
+
load_order << file
|
98
|
+
rescue NameError => ex
|
99
|
+
failed << file
|
100
|
+
first_name_error ||= ex
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# If this pass didn't resolve any NameErrors, we've hit an unresolvable
|
105
|
+
# dependency, so raise one of the exceptions we encountered.
|
106
|
+
if failed.size == files.size
|
107
|
+
raise first_name_error
|
108
|
+
else
|
109
|
+
files = failed
|
110
|
+
end
|
111
|
+
end until failed.empty?
|
112
|
+
|
113
|
+
load_order
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C)2010 Tony Arcieri
|
3
|
+
# You can redistribute this under the terms of the MIT license
|
4
|
+
# See file LICENSE for details
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'magic_loader'
|
8
|
+
require 'rake/tasklib'
|
9
|
+
|
10
|
+
# Generates the MagicLoader rake task
|
11
|
+
module MagicLoader
|
12
|
+
BEGIN_MAGIC = "#-----BEGIN MAGICLOADER MAGIC BLOCK-----"
|
13
|
+
END_MAGIC = "#------END MAGICLOADER MAGIC BLOCK------"
|
14
|
+
MAGIC_WARNING = [
|
15
|
+
"# Automagically generated by MagicLoader. Editing may",
|
16
|
+
"# result in bad juju. Edit at your own risk!"
|
17
|
+
]
|
18
|
+
MAGIC_REGEXP = /#{BEGIN_MAGIC}.*#{END_MAGIC}/m
|
19
|
+
|
20
|
+
# Generates the MagicLoader rake task
|
21
|
+
class Task < Rake::TaskLib
|
22
|
+
def initialize(*paths)
|
23
|
+
options = paths.last.is_a?(Hash) ? paths.pop : {}
|
24
|
+
task_name = options[:name] || 'magicload'
|
25
|
+
|
26
|
+
task task_name do
|
27
|
+
load_order = MagicLoader.require_all(*paths)
|
28
|
+
strip_paths!(load_order, options[:strip]) if options[:strip]
|
29
|
+
|
30
|
+
magic_block = [
|
31
|
+
BEGIN_MAGIC,
|
32
|
+
MAGIC_WARNING,
|
33
|
+
"# Run \"rake #{task_name}\" to regenerate",
|
34
|
+
load_order.map { |t| "require #{t.dump}" },
|
35
|
+
END_MAGIC
|
36
|
+
].flatten.join("\n")
|
37
|
+
|
38
|
+
if options[:target]
|
39
|
+
if File.exists? options[:target]
|
40
|
+
annotate_file options[:target], magic_block
|
41
|
+
else
|
42
|
+
File.open(options[:target], "w") { |f| f << magic_block }
|
43
|
+
end
|
44
|
+
else
|
45
|
+
puts magic_block
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#######
|
51
|
+
private
|
52
|
+
#######
|
53
|
+
|
54
|
+
# Implement the path stripping logic described in the README
|
55
|
+
def strip_paths!(paths, to_strip)
|
56
|
+
paths.map! do |path|
|
57
|
+
case to_strip
|
58
|
+
when String
|
59
|
+
if path.index(to_strip) == 0
|
60
|
+
path.sub to_strip, ''
|
61
|
+
else
|
62
|
+
path
|
63
|
+
end
|
64
|
+
when Regexp
|
65
|
+
path.sub to_strip, ''
|
66
|
+
else raise ArgumentError, ":strip given a #{to_strip.class}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Annotate a MagicLoader Magic Block onto the end of an existing file
|
72
|
+
def annotate_file(path, magic_block)
|
73
|
+
data = File.read path
|
74
|
+
magic_matches = data.match(MAGIC_REGEXP)
|
75
|
+
case magic_matches
|
76
|
+
when MatchData
|
77
|
+
data.sub!(MAGIC_REGEXP, magic_block)
|
78
|
+
else
|
79
|
+
data << "\n\n" << magic_block
|
80
|
+
end
|
81
|
+
|
82
|
+
File.open(path, 'w') { |f| f << data }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/magicloader.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
GEMSPEC = Gem::Specification.new do |s|
|
4
|
+
s.name = "magicloader"
|
5
|
+
s.description = "Painless code dependency management"
|
6
|
+
s.summary = <<EOD
|
7
|
+
Painless code dependency management. Think Bundler, but for managing file load
|
8
|
+
ordering dependencies.
|
9
|
+
EOD
|
10
|
+
s.version = "0.9.0"
|
11
|
+
s.authors = "Tony Arcieri"
|
12
|
+
s.email = "bascule@gmail.com"
|
13
|
+
s.homepage = "http://github.com/tarcieri/MagicLoader"
|
14
|
+
s.date = Time.now
|
15
|
+
s.platform = Gem::Platform::RUBY
|
16
|
+
|
17
|
+
# Gem contents
|
18
|
+
s.files = Dir.glob("{lib,spec}/**/*") + ['Rakefile', 'magicloader.gemspec']
|
19
|
+
|
20
|
+
# RDoc settings
|
21
|
+
s.has_rdoc = true
|
22
|
+
s.rdoc_options = %w(--title MagicLoader --main README.textile --line-numbers)
|
23
|
+
s.extra_rdoc_files = ["LICENSE", "README.markdown", "CHANGES"]
|
24
|
+
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,49 @@
|
|
1
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
describe MagicLoader do
|
4
|
+
describe :require_all do
|
5
|
+
describe "dependency resolution" do
|
6
|
+
it "handles load ordering when dependencies are resolvable" do
|
7
|
+
MagicLoader.require_all File.expand_path('../fixtures/resolvable/*.rb', __FILE__)
|
8
|
+
|
9
|
+
defined?(A).should == "constant"
|
10
|
+
defined?(B).should == "constant"
|
11
|
+
defined?(C).should == "constant"
|
12
|
+
defined?(D).should == "constant"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "raises NameError if dependencies can't be resolved" do
|
16
|
+
proc do
|
17
|
+
MagicLoader.require_all File.expand_path('../fixtures/unresolvable/*.rb', __FILE__)
|
18
|
+
end.should raise_error(NameError)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "syntactic sugar" do
|
23
|
+
before :each do
|
24
|
+
@base_dir = File.expand_path('../fixtures/resolvable', __FILE__)
|
25
|
+
@file_list = ['b.rb', 'c.rb', 'a.rb', 'd.rb'].map { |f| "#{@base_dir}/#{f}" }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "works like a drop-in require replacement" do
|
29
|
+
MagicLoader.require_all(@base_dir + '/c').should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "accepts lists of files" do
|
33
|
+
MagicLoader.require_all(@file_list).should be_true
|
34
|
+
end
|
35
|
+
|
36
|
+
it "is totally cool with a splatted list of arguments" do
|
37
|
+
MagicLoader.require_all(*@file_list).should be_true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "will load all .rb files under a directory without a trailing slash" do
|
41
|
+
MagicLoader.require_all(@base_dir).should be_true
|
42
|
+
end
|
43
|
+
|
44
|
+
it "will load all .rb files under a directory with a trailing slash" do
|
45
|
+
MagicLoader.require_all("#{@base_dir}/").should be_true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/task_spec.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rake'
|
5
|
+
require 'magic_loader/tasks'
|
6
|
+
|
7
|
+
describe MagicLoader::Task do
|
8
|
+
before :all do
|
9
|
+
@prefix = File.dirname(__FILE__) + '/fixtures/'
|
10
|
+
@sources = @prefix + 'resolvable'
|
11
|
+
@output = File.expand_path('../tmp/example.rb', __FILE__)
|
12
|
+
end
|
13
|
+
|
14
|
+
before :each do
|
15
|
+
rm @output if File.exists? @output
|
16
|
+
File.exists?(@output).should be_false
|
17
|
+
end
|
18
|
+
|
19
|
+
it "prints to standard output unless a :target is specified" do
|
20
|
+
# It's left as an exercise to the end user to visually confirm this
|
21
|
+
MagicLoader::Task.new @sources, :strip => @prefix
|
22
|
+
Rake::Task['magicload'].invoke
|
23
|
+
end
|
24
|
+
|
25
|
+
it "creates new files if they don't exist" do
|
26
|
+
MagicLoader::Task.new @sources,
|
27
|
+
:target => @output,
|
28
|
+
:strip => @prefix,
|
29
|
+
:name => 'magicload2'
|
30
|
+
|
31
|
+
Rake::Task['magicload2'].invoke
|
32
|
+
|
33
|
+
File.exists?(@output).should be_true
|
34
|
+
end
|
35
|
+
|
36
|
+
it "annotates files that do exist" do
|
37
|
+
important_crap = "# OMFG IMPORTANT CRAP DON'T DELETE THIS"
|
38
|
+
File.open(@output, 'w') { |f| f << important_crap }
|
39
|
+
|
40
|
+
MagicLoader::Task.new @sources,
|
41
|
+
:target => @output,
|
42
|
+
:strip => @prefix,
|
43
|
+
:name => 'magicload3'
|
44
|
+
|
45
|
+
Rake::Task['magicload3'].invoke
|
46
|
+
|
47
|
+
File.exists?(@output).should be_true
|
48
|
+
data = File.read @output
|
49
|
+
data[important_crap].should be_an_instance_of(String)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "annotates files that do exist and already have magic blocks" do
|
53
|
+
important_crap = "# OMFG IMPORTANT CRAP DON'T DELETE THIS"
|
54
|
+
fake_magic_block = [
|
55
|
+
MagicLoader::BEGIN_MAGIC,
|
56
|
+
"# omgfake!",
|
57
|
+
MagicLoader::END_MAGIC
|
58
|
+
].join("\n")
|
59
|
+
|
60
|
+
important_crap << "\n\n" << fake_magic_block
|
61
|
+
File.open(@output, 'w') { |f| f << important_crap }
|
62
|
+
|
63
|
+
MagicLoader::Task.new @sources,
|
64
|
+
:target => @output,
|
65
|
+
:strip => @prefix,
|
66
|
+
:name => 'magicload4'
|
67
|
+
|
68
|
+
Rake::Task['magicload4'].invoke
|
69
|
+
|
70
|
+
File.exists?(@output).should be_true
|
71
|
+
data = File.read @output
|
72
|
+
data["omgfake"].should be_nil
|
73
|
+
data[MagicLoader::MAGIC_REGEXP].should be_an_instance_of(String)
|
74
|
+
end
|
75
|
+
end
|
data/spec/tmp/example.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# OMFG IMPORTANT CRAP DON'T DELETE THIS
|
2
|
+
|
3
|
+
#-----BEGIN MAGICLOADER MAGIC BLOCK-----
|
4
|
+
# Automagically generated by MagicLoader. Editing may
|
5
|
+
# result in bad juju. Edit at your own risk!
|
6
|
+
# Run "rake magicload4" to regenerate
|
7
|
+
require "resolvable/a.rb"
|
8
|
+
require "resolvable/b.rb"
|
9
|
+
require "resolvable/c.rb"
|
10
|
+
require "resolvable/d.rb"
|
11
|
+
#------END MAGICLOADER MAGIC BLOCK------
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: magicloader
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 59
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 9
|
9
|
+
- 0
|
10
|
+
version: 0.9.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Tony Arcieri
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-30 00:00:00 -06:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Painless code dependency management
|
23
|
+
email: bascule@gmail.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- LICENSE
|
30
|
+
- README.markdown
|
31
|
+
- CHANGES
|
32
|
+
files:
|
33
|
+
- lib/magic_loader/tasks.rb
|
34
|
+
- lib/magic_loader.rb
|
35
|
+
- spec/fixtures/resolvable/a.rb
|
36
|
+
- spec/fixtures/resolvable/b.rb
|
37
|
+
- spec/fixtures/resolvable/c.rb
|
38
|
+
- spec/fixtures/resolvable/d.rb
|
39
|
+
- spec/fixtures/unresolvable/a.rb
|
40
|
+
- spec/fixtures/unresolvable/b.rb
|
41
|
+
- spec/fixtures/unresolvable/c.rb
|
42
|
+
- spec/fixtures/unresolvable/d.rb
|
43
|
+
- spec/magic_loader_spec.rb
|
44
|
+
- spec/spec_helper.rb
|
45
|
+
- spec/task_spec.rb
|
46
|
+
- spec/tmp/example.rb
|
47
|
+
- Rakefile
|
48
|
+
- magicloader.gemspec
|
49
|
+
- LICENSE
|
50
|
+
- README.markdown
|
51
|
+
- CHANGES
|
52
|
+
has_rdoc: true
|
53
|
+
homepage: http://github.com/tarcieri/MagicLoader
|
54
|
+
licenses: []
|
55
|
+
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options:
|
58
|
+
- --title
|
59
|
+
- MagicLoader
|
60
|
+
- --main
|
61
|
+
- README.textile
|
62
|
+
- --line-numbers
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 3
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.3.7
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Painless code dependency management. Think Bundler, but for managing file load ordering dependencies.
|
90
|
+
test_files: []
|
91
|
+
|