rake 0.4.11 → 13.4.2
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.
- checksums.yaml +7 -0
- data/History.rdoc +2454 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +155 -0
- data/doc/command_line_usage.rdoc +171 -0
- data/doc/glossary.rdoc +40 -49
- data/doc/jamis.rb +135 -107
- data/doc/proto_rake.rdoc +22 -22
- data/doc/rake.1 +156 -0
- data/doc/rakefile.rdoc +428 -27
- data/doc/rational.rdoc +6 -6
- data/exe/rake +27 -0
- data/lib/rake/application.rb +847 -0
- data/lib/rake/backtrace.rb +25 -0
- data/lib/rake/clean.rb +57 -10
- data/lib/rake/cloneable.rb +17 -0
- data/lib/rake/cpu_counter.rb +122 -0
- data/lib/rake/default_loader.rb +15 -0
- data/lib/rake/dsl_definition.rb +196 -0
- data/lib/rake/early_time.rb +22 -0
- data/lib/rake/ext/core.rb +26 -0
- data/lib/rake/ext/string.rb +176 -0
- data/lib/rake/file_creation_task.rb +25 -0
- data/lib/rake/file_list.rb +435 -0
- data/lib/rake/file_task.rb +58 -0
- data/lib/rake/file_utils.rb +137 -0
- data/lib/rake/file_utils_ext.rb +135 -0
- data/lib/rake/invocation_chain.rb +57 -0
- data/lib/rake/invocation_exception_mixin.rb +17 -0
- data/lib/rake/late_time.rb +18 -0
- data/lib/rake/linked_list.rb +112 -0
- data/lib/rake/loaders/makefile.rb +54 -0
- data/lib/rake/multi_task.rb +14 -0
- data/lib/rake/name_space.rb +38 -0
- data/lib/rake/options.rb +31 -0
- data/lib/rake/packagetask.rb +124 -54
- data/lib/rake/phony.rb +16 -0
- data/lib/rake/private_reader.rb +21 -0
- data/lib/rake/promise.rb +100 -0
- data/lib/rake/pseudo_status.rb +30 -0
- data/lib/rake/rake_module.rb +67 -0
- data/lib/rake/rake_test_loader.rb +27 -0
- data/lib/rake/rule_recursion_overflow_error.rb +20 -0
- data/lib/rake/scope.rb +43 -0
- data/lib/rake/task.rb +434 -0
- data/lib/rake/task_argument_error.rb +8 -0
- data/lib/rake/task_arguments.rb +113 -0
- data/lib/rake/task_manager.rb +333 -0
- data/lib/rake/tasklib.rb +4 -16
- data/lib/rake/testtask.rb +110 -36
- data/lib/rake/thread_history_display.rb +49 -0
- data/lib/rake/thread_pool.rb +157 -0
- data/lib/rake/trace_output.rb +23 -0
- data/lib/rake/version.rb +10 -0
- data/lib/rake/win32.rb +17 -0
- data/lib/rake.rb +64 -992
- data/rake.gemspec +102 -0
- metadata +117 -89
- data/CHANGES +0 -153
- data/README +0 -209
- data/Rakefile +0 -215
- data/TODO +0 -19
- data/bin/rake +0 -8
- data/install.rb +0 -88
- data/lib/rake/contrib/compositepublisher.rb +0 -24
- data/lib/rake/contrib/ftptools.rb +0 -139
- data/lib/rake/contrib/publisher.rb +0 -75
- data/lib/rake/contrib/rubyforgepublisher.rb +0 -18
- data/lib/rake/contrib/sshpublisher.rb +0 -47
- data/lib/rake/contrib/sys.rb +0 -207
- data/lib/rake/gempackagetask.rb +0 -98
- data/lib/rake/rdoctask.rb +0 -128
- data/lib/rake/runtest.rb +0 -23
- data/test/contrib/testsys.rb +0 -47
- data/test/data/rbext/rakefile.rb +0 -3
- data/test/filecreation.rb +0 -26
- data/test/functional.rb +0 -82
- data/test/shellcommand.rb +0 -3
- data/test/testclean.rb +0 -13
- data/test/testfilelist.rb +0 -255
- data/test/testfileutils.rb +0 -83
- data/test/testftp.rb +0 -55
- data/test/testpackagetask.rb +0 -81
- data/test/testtasks.rb +0 -371
- data/test/testtesttask.rb +0 -71
data/doc/rakefile.rdoc
CHANGED
|
@@ -27,12 +27,12 @@ parameter that is the name of the task.
|
|
|
27
27
|
|
|
28
28
|
=== Tasks with Prerequisites
|
|
29
29
|
|
|
30
|
-
Any prerequisites are given as a list (
|
|
30
|
+
Any prerequisites are given as a list (enclosed in square brackets)
|
|
31
31
|
following the name and an arrow (=>).
|
|
32
32
|
|
|
33
33
|
task :name => [:prereq1, :prereq2]
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
*NOTE:* Although this syntax looks a little funky, it is legal
|
|
36
36
|
Ruby. We are constructing a hash where the key is :name and the value
|
|
37
37
|
for that key is the list of prerequisites. It is equivalent to the
|
|
38
38
|
following ...
|
|
@@ -41,13 +41,27 @@ following ...
|
|
|
41
41
|
hash[:name] = [:prereq1, :prereq2]
|
|
42
42
|
task(hash)
|
|
43
43
|
|
|
44
|
+
You can also use strings for task names and prerequisites, rake doesn't care.
|
|
45
|
+
This is the same task definition:
|
|
46
|
+
|
|
47
|
+
task 'name' => %w[prereq1 prereq2]
|
|
48
|
+
|
|
49
|
+
As is this:
|
|
50
|
+
|
|
51
|
+
task name: %w[prereq1 prereq2]
|
|
52
|
+
|
|
53
|
+
We'll prefer this style for regular tasks with prerequisites throughout the
|
|
54
|
+
rest of the document. Using an array of strings for the prerequisites means
|
|
55
|
+
you will need to make fewer changes if you need to move tasks into namespaces
|
|
56
|
+
or perform other refactorings.
|
|
57
|
+
|
|
44
58
|
=== Tasks with Actions
|
|
45
59
|
|
|
46
60
|
Actions are defined by passing a block to the +task+ method. Any Ruby
|
|
47
61
|
code can be placed in the block. The block may reference the task
|
|
48
|
-
object via the block
|
|
62
|
+
object via the block parameter.
|
|
49
63
|
|
|
50
|
-
task :
|
|
64
|
+
task name: [:prereq1, :prereq2] do |t|
|
|
51
65
|
# actions (may reference t)
|
|
52
66
|
end
|
|
53
67
|
|
|
@@ -62,8 +76,8 @@ For example, the following is equivalent to the single task
|
|
|
62
76
|
specification given above.
|
|
63
77
|
|
|
64
78
|
task :name
|
|
65
|
-
task :
|
|
66
|
-
task :
|
|
79
|
+
task name: :prereq1
|
|
80
|
+
task name: %w[prereq2]
|
|
67
81
|
task :name do |t|
|
|
68
82
|
# actions
|
|
69
83
|
end
|
|
@@ -79,8 +93,8 @@ method). In addition, file tasks are usually named with a string
|
|
|
79
93
|
rather than a symbol.
|
|
80
94
|
|
|
81
95
|
The following file task creates a executable program (named +prog+)
|
|
82
|
-
given two object files
|
|
83
|
-
for creating
|
|
96
|
+
given two object files named +a.o+ and +b.o+. The tasks
|
|
97
|
+
for creating +a.o+ and +b.o+ are not shown.
|
|
84
98
|
|
|
85
99
|
file "prog" => ["a.o", "b.o"] do |t|
|
|
86
100
|
sh "cc -o #{t.name} #{t.prerequisites.join(' ')}"
|
|
@@ -97,9 +111,9 @@ that creates the directory. For example, the following declaration
|
|
|
97
111
|
|
|
98
112
|
is equivalent to ...
|
|
99
113
|
|
|
100
|
-
file "testdata"
|
|
101
|
-
file "testdata/examples"
|
|
102
|
-
file "testdata/examples/doc" do |t| mkdir t.name end
|
|
114
|
+
file "testdata" do |t| mkdir t.name end
|
|
115
|
+
file "testdata/examples" => ["testdata"] do |t| mkdir t.name end
|
|
116
|
+
file "testdata/examples/doc" => ["testdata/examples"] do |t| mkdir t.name end
|
|
103
117
|
|
|
104
118
|
The +directory+ method does not accept prerequisites or actions, but
|
|
105
119
|
both prerequisites and actions can be added later. For example ...
|
|
@@ -110,6 +124,189 @@ both prerequisites and actions can be added later. For example ...
|
|
|
110
124
|
cp Dir["standard_data/*.data"], "testdata"
|
|
111
125
|
end
|
|
112
126
|
|
|
127
|
+
== Tasks with Parallel Prerequisites
|
|
128
|
+
|
|
129
|
+
Rake allows parallel execution of prerequisites using the following syntax:
|
|
130
|
+
|
|
131
|
+
multitask copy_files: %w[copy_src copy_doc copy_bin] do
|
|
132
|
+
puts "All Copies Complete"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
In this example, +copy_files+ is a normal rake task. Its actions are
|
|
136
|
+
executed whenever all of its prerequisites are done. The big
|
|
137
|
+
difference is that the prerequisites (+copy_src+, +copy_bin+ and
|
|
138
|
+
+copy_doc+) are executed in parallel. Each of the prerequisites are
|
|
139
|
+
run in their own Ruby thread, possibly allowing faster overall runtime.
|
|
140
|
+
|
|
141
|
+
=== Secondary Prerequisites
|
|
142
|
+
|
|
143
|
+
If any of the primary prerequisites of a multitask have common secondary
|
|
144
|
+
prerequisites, all of the primary/parallel prerequisites will wait
|
|
145
|
+
until the common prerequisites have been run.
|
|
146
|
+
|
|
147
|
+
For example, if the <tt>copy_<em>xxx</em></tt> tasks have the
|
|
148
|
+
following prerequisites:
|
|
149
|
+
|
|
150
|
+
task copy_src: :prep_for_copy
|
|
151
|
+
task copy_bin: :prep_for_copy
|
|
152
|
+
task copy_doc: :prep_for_copy
|
|
153
|
+
|
|
154
|
+
Then the +prep_for_copy+ task is run before starting all the copies in
|
|
155
|
+
parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+,
|
|
156
|
+
and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is
|
|
157
|
+
run only once, even though it is referenced in multiple threads.
|
|
158
|
+
|
|
159
|
+
=== Thread Safety
|
|
160
|
+
|
|
161
|
+
The Rake internal data structures are thread-safe with respect
|
|
162
|
+
to the multitask parallel execution, so there is no need for the user
|
|
163
|
+
to do extra synchronization for Rake's benefit. However, if there are
|
|
164
|
+
user data structures shared between the parallel prerequisites, the
|
|
165
|
+
user must do whatever is necessary to prevent race conditions.
|
|
166
|
+
|
|
167
|
+
== Tasks with Arguments
|
|
168
|
+
|
|
169
|
+
Prior to version 0.8.0, rake was only able to handle command line
|
|
170
|
+
arguments of the form NAME=VALUE that were passed into Rake via the
|
|
171
|
+
ENV hash. Many folks had asked for some kind of simple command line
|
|
172
|
+
arguments, perhaps using "--" to separate regular task names from
|
|
173
|
+
argument values on the command line. The problem is that there was no
|
|
174
|
+
easy way to associate positional arguments on the command line with
|
|
175
|
+
different tasks. Suppose both tasks :a and :b expect a command line
|
|
176
|
+
argument: does the first value go with :a? What if :b is run first?
|
|
177
|
+
Should it then get the first command line argument.
|
|
178
|
+
|
|
179
|
+
Rake 0.8.0 solves this problem by explicitly passing values directly
|
|
180
|
+
to the tasks that need them. For example, if I had a release task
|
|
181
|
+
that required a version number, I could say:
|
|
182
|
+
|
|
183
|
+
rake release[0.8.2]
|
|
184
|
+
|
|
185
|
+
And the string "0.8.2" will be passed to the :release task. Multiple
|
|
186
|
+
arguments can be passed by separating them with a comma, for example:
|
|
187
|
+
|
|
188
|
+
rake name[john,doe]
|
|
189
|
+
|
|
190
|
+
Just a few words of caution. The rake task name and its arguments
|
|
191
|
+
need to be a single command line argument to rake. This generally
|
|
192
|
+
means no spaces. If spaces are needed, then the entire name +
|
|
193
|
+
argument string should be quoted. Something like this:
|
|
194
|
+
|
|
195
|
+
rake "name[billy bob, smith]"
|
|
196
|
+
|
|
197
|
+
(Quoting rules vary between operating systems and shells, so make sure
|
|
198
|
+
you consult the proper docs for your OS/shell).
|
|
199
|
+
|
|
200
|
+
=== Tasks that Expect Parameters
|
|
201
|
+
|
|
202
|
+
Parameters are only given to tasks that are setup to expect them. In
|
|
203
|
+
order to handle named parameters, the task declaration syntax for
|
|
204
|
+
tasks has been extended slightly.
|
|
205
|
+
|
|
206
|
+
For example, a task that needs a first name and last name might be
|
|
207
|
+
declared as:
|
|
208
|
+
|
|
209
|
+
task :name, [:first_name, :last_name]
|
|
210
|
+
|
|
211
|
+
The first argument is still the name of the task (:name in this case).
|
|
212
|
+
The next two arguments are the names of the parameters expected by
|
|
213
|
+
:name in an array (:first_name and :last_name in the example).
|
|
214
|
+
|
|
215
|
+
To access the values of the parameters, the block defining the task
|
|
216
|
+
behaviour can now accept a second parameter:
|
|
217
|
+
|
|
218
|
+
task :name, [:first_name, :last_name] do |t, args|
|
|
219
|
+
puts "First name is #{args.first_name}"
|
|
220
|
+
puts "Last name is #{args.last_name}"
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
The first argument of the block "t" is always bound to the current
|
|
224
|
+
task object. The second argument "args" is an open-struct like object
|
|
225
|
+
that allows access to the task arguments. Extra command line
|
|
226
|
+
arguments to a task are ignored.
|
|
227
|
+
|
|
228
|
+
If you wish to specify default values for the arguments, you can use
|
|
229
|
+
the with_defaults method in the task body. Here is the above example
|
|
230
|
+
where we specify default values for the first and last names:
|
|
231
|
+
|
|
232
|
+
task :name, [:first_name, :last_name] do |t, args|
|
|
233
|
+
args.with_defaults(:first_name => "John", :last_name => "Dough")
|
|
234
|
+
puts "First name is #{args.first_name}"
|
|
235
|
+
puts "Last name is #{args.last_name}"
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
=== Tasks that Expect Parameters and Have Prerequisites
|
|
239
|
+
|
|
240
|
+
Tasks that use parameters have a slightly different format for
|
|
241
|
+
prerequisites. Use the arrow notation to indicate the prerequisites
|
|
242
|
+
for tasks with arguments. For example:
|
|
243
|
+
|
|
244
|
+
task :name, [:first_name, :last_name] => [:pre_name] do |t, args|
|
|
245
|
+
args.with_defaults(:first_name => "John", :last_name => "Dough")
|
|
246
|
+
puts "First name is #{args.first_name}"
|
|
247
|
+
puts "Last name is #{args.last_name}"
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
=== Tasks that take Variable-length Parameters
|
|
251
|
+
|
|
252
|
+
Tasks that need to handle a list of values as a parameter can use the
|
|
253
|
+
extras method of the args variable. This allows for tasks that can
|
|
254
|
+
loop over a variable number of values, and its compatible with named
|
|
255
|
+
parameters as well:
|
|
256
|
+
|
|
257
|
+
task :email, [:message] do |t, args|
|
|
258
|
+
mail = Mail.new(args.message)
|
|
259
|
+
recipients = args.extras
|
|
260
|
+
recipients.each do |target|
|
|
261
|
+
mail.send_to(target)
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
There is also the convenience method to_a that returns all parameters
|
|
266
|
+
in the sequential order they were given, including those associated
|
|
267
|
+
with named parameters.
|
|
268
|
+
|
|
269
|
+
=== Deprecated Task Parameters Format
|
|
270
|
+
|
|
271
|
+
There is an older format for declaring task parameters that omitted
|
|
272
|
+
the task argument array and used the :needs keyword to introduce the
|
|
273
|
+
dependencies. That format is still supported for compatibility, but
|
|
274
|
+
is not recommended for use. The older format may be dropped in future
|
|
275
|
+
versions of rake.
|
|
276
|
+
|
|
277
|
+
== Accessing Task Programmatically
|
|
278
|
+
|
|
279
|
+
Sometimes it is useful to manipulate tasks programmatically in a
|
|
280
|
+
Rakefile. To find a task object use Rake::Task.[].
|
|
281
|
+
|
|
282
|
+
=== Programmatic Task Example
|
|
283
|
+
|
|
284
|
+
For example, the following Rakefile defines two tasks. The :doit task
|
|
285
|
+
simply prints a simple "DONE" message. The :dont class will lookup
|
|
286
|
+
the doit class and remove (clear) all of its prerequisites and
|
|
287
|
+
actions.
|
|
288
|
+
|
|
289
|
+
task :doit do
|
|
290
|
+
puts "DONE"
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
task :dont do
|
|
294
|
+
Rake::Task[:doit].clear
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
Running this example:
|
|
298
|
+
|
|
299
|
+
$ rake doit
|
|
300
|
+
(in /Users/jim/working/git/rake/x)
|
|
301
|
+
DONE
|
|
302
|
+
$ rake dont doit
|
|
303
|
+
(in /Users/jim/working/git/rake/x)
|
|
304
|
+
$
|
|
305
|
+
|
|
306
|
+
The ability to programmatically manipulate tasks gives rake very
|
|
307
|
+
powerful meta-programming capabilities w.r.t. task execution, but
|
|
308
|
+
should be used with caution.
|
|
309
|
+
|
|
113
310
|
== Rules
|
|
114
311
|
|
|
115
312
|
When a file is named as a prerequisite, but does not have a file task
|
|
@@ -128,8 +325,8 @@ prerequisite a source file with an extension of ".c" must exist. If
|
|
|
128
325
|
Rake is able to find a file named "mycode.c", it will automatically
|
|
129
326
|
create a task that builds "mycode.o" from "mycode.c".
|
|
130
327
|
|
|
131
|
-
|
|
132
|
-
|
|
328
|
+
If the file "mycode.c" does not exist, rake will attempt
|
|
329
|
+
to recursively synthesize a rule for it.
|
|
133
330
|
|
|
134
331
|
When a task is synthesized from a rule, the +source+ attribute of the
|
|
135
332
|
task is set to the matching source file. This allows us to write
|
|
@@ -147,22 +344,68 @@ The following rule is equivalent to the example above.
|
|
|
147
344
|
proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') }
|
|
148
345
|
]) do |t|
|
|
149
346
|
sh "cc #{t.source} -c -o #{t.name}"
|
|
150
|
-
end
|
|
347
|
+
end
|
|
151
348
|
|
|
152
|
-
|
|
349
|
+
*NOTE:* Because of a _quirk_ in Ruby syntax, parenthesis are
|
|
153
350
|
required on *rule* when the first argument is a regular expression.
|
|
154
351
|
|
|
155
352
|
The following rule might be used for Java files ...
|
|
156
353
|
|
|
157
|
-
rule '.
|
|
354
|
+
rule '.class' => [
|
|
158
355
|
proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') }
|
|
159
356
|
] do |t|
|
|
160
|
-
java_compile(t.source, t.name)
|
|
357
|
+
java_compile(t.source, t.name)
|
|
161
358
|
end
|
|
162
359
|
|
|
163
|
-
|
|
360
|
+
*NOTE:* +java_compile+ is a hypothetical method that invokes the
|
|
164
361
|
java compiler.
|
|
165
362
|
|
|
363
|
+
=== Implicit File Tasks
|
|
364
|
+
|
|
365
|
+
When a task is not defined but a file with that name exists, Rake
|
|
366
|
+
automatically creates an implicit file task for it. For example:
|
|
367
|
+
|
|
368
|
+
$ rake hello_world # Error: task not found
|
|
369
|
+
$ touch hello_world # Create a file with the same name
|
|
370
|
+
$ rake hello_world # Now succeeds automatically
|
|
371
|
+
|
|
372
|
+
Use the <tt>--rules</tt> command line option to trace how rules are
|
|
373
|
+
resolved when searching for tasks; note that creation of implicit file
|
|
374
|
+
tasks is not traced.
|
|
375
|
+
|
|
376
|
+
== Importing Dependencies
|
|
377
|
+
|
|
378
|
+
Any ruby file (including other rakefiles) can be included with a
|
|
379
|
+
standard Ruby +require+ command. The rules and declarations in the
|
|
380
|
+
required file are just added to the definitions already accumulated.
|
|
381
|
+
|
|
382
|
+
Because the files are loaded _before_ the rake targets are evaluated,
|
|
383
|
+
the loaded files must be "ready to go" when the rake command is
|
|
384
|
+
invoked. This makes generated dependency files difficult to use. By
|
|
385
|
+
the time rake gets around to updating the dependencies file, it is too
|
|
386
|
+
late to load it.
|
|
387
|
+
|
|
388
|
+
The +import+ command addresses this by specifying a file to be loaded
|
|
389
|
+
_after_ the main rakefile is loaded, but _before_ any targets on the
|
|
390
|
+
command line are invoked. In addition, if the file name matches an
|
|
391
|
+
explicit task, that task is invoked before loading the file. This
|
|
392
|
+
allows dependency files to be generated and used in a single rake
|
|
393
|
+
command invocation.
|
|
394
|
+
|
|
395
|
+
Example:
|
|
396
|
+
|
|
397
|
+
require 'rake/loaders/makefile'
|
|
398
|
+
|
|
399
|
+
file ".depends.mf" => [SRC_LIST] do |t|
|
|
400
|
+
sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}"
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
import ".depends.mf"
|
|
404
|
+
|
|
405
|
+
If ".depends" does not exist, or is out of date w.r.t. the source
|
|
406
|
+
files, a new ".depends" file is generated using +makedepend+ before
|
|
407
|
+
loading.
|
|
408
|
+
|
|
166
409
|
== Comments
|
|
167
410
|
|
|
168
411
|
Standard Ruby comments (beginning with "#") can be used anywhere it is
|
|
@@ -173,14 +416,14 @@ then you need to use the +desc+ command to describe the task.
|
|
|
173
416
|
Example:
|
|
174
417
|
|
|
175
418
|
desc "Create a distribution package"
|
|
176
|
-
task :
|
|
419
|
+
task package: %w[ ... ] do ... end
|
|
177
420
|
|
|
178
421
|
The "-T" switch (or "--tasks" if you like to spell things out) will
|
|
179
|
-
display a list of tasks that have a
|
|
180
|
-
|
|
181
|
-
|
|
422
|
+
display a list of tasks that have a description. If you use +desc+ to
|
|
423
|
+
describe your major tasks, you have a semi-automatic way of generating
|
|
424
|
+
a summary of your Rake file.
|
|
182
425
|
|
|
183
|
-
|
|
426
|
+
$ rake -T
|
|
184
427
|
(in /home/.../rake)
|
|
185
428
|
rake clean # Remove any temporary products.
|
|
186
429
|
rake clobber # Remove any generated file.
|
|
@@ -198,19 +441,119 @@ Only tasks with descriptions will be displayed with the "-T" switch.
|
|
|
198
441
|
Use "-P" (or "--prereqs") to get a list of all tasks and their
|
|
199
442
|
prerequisites.
|
|
200
443
|
|
|
444
|
+
== Namespaces
|
|
445
|
+
|
|
446
|
+
As projects grow (and along with it, the number of tasks), it is
|
|
447
|
+
common for task names to begin to clash. For example, if you might
|
|
448
|
+
have a main program and a set of sample programs built by a single
|
|
449
|
+
Rakefile. By placing the tasks related to the main program in one
|
|
450
|
+
namespace, and the tasks for building the sample programs in a
|
|
451
|
+
different namespace, the task names will not interfere with each other.
|
|
452
|
+
|
|
453
|
+
For example:
|
|
454
|
+
|
|
455
|
+
namespace "main" do
|
|
456
|
+
task :build do
|
|
457
|
+
# Build the main program
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
namespace "samples" do
|
|
462
|
+
task :build do
|
|
463
|
+
# Build the sample programs
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
task build: %w[main:build samples:build]
|
|
468
|
+
|
|
469
|
+
Referencing a task in a separate namespace can be achieved by
|
|
470
|
+
prefixing the task name with the namespace and a colon
|
|
471
|
+
(e.g. "main:build" refers to the :build task in the +main+ namespace).
|
|
472
|
+
Nested namespaces are supported.
|
|
473
|
+
|
|
474
|
+
Note that the name given in the +task+ command is always the unadorned
|
|
475
|
+
task name without any namespace prefixes. The +task+ command always
|
|
476
|
+
defines a task in the current namespace.
|
|
477
|
+
|
|
478
|
+
=== FileTasks
|
|
479
|
+
|
|
480
|
+
File task names are not scoped by the namespace command. Since the
|
|
481
|
+
name of a file task is the name of an actual file in the file system,
|
|
482
|
+
it makes little sense to include file task names in name space.
|
|
483
|
+
Directory tasks (created by the +directory+ command) are a type of
|
|
484
|
+
file task and are also not affected by namespaces.
|
|
485
|
+
|
|
486
|
+
=== Name Resolution
|
|
487
|
+
|
|
488
|
+
When looking up a task name, rake will start with the current
|
|
489
|
+
namespace and attempt to find the name there. If it fails to find a
|
|
490
|
+
name in the current namespace, it will search the parent namespaces
|
|
491
|
+
until a match is found (or an error occurs if there is no match).
|
|
492
|
+
|
|
493
|
+
The "rake" namespace is a special implicit namespace that refers to
|
|
494
|
+
the toplevel names.
|
|
495
|
+
|
|
496
|
+
If a task name begins with a "^" character, the name resolution will
|
|
497
|
+
start in the parent namespace. Multiple "^" characters are allowed.
|
|
498
|
+
|
|
499
|
+
Here is an example file with multiple :run tasks and how various names
|
|
500
|
+
resolve in different locations.
|
|
501
|
+
|
|
502
|
+
task :run
|
|
503
|
+
|
|
504
|
+
namespace "one" do
|
|
505
|
+
task :run
|
|
506
|
+
|
|
507
|
+
namespace "two" do
|
|
508
|
+
task :run
|
|
509
|
+
|
|
510
|
+
# :run => "one:two:run"
|
|
511
|
+
# "two:run" => "one:two:run"
|
|
512
|
+
# "one:two:run" => "one:two:run"
|
|
513
|
+
# "one:run" => "one:run"
|
|
514
|
+
# "^run" => "one:run"
|
|
515
|
+
# "^^run" => "rake:run" (the top level task)
|
|
516
|
+
# "rake:run" => "rake:run" (the top level task)
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
# :run => "one:run"
|
|
520
|
+
# "two:run" => "one:two:run"
|
|
521
|
+
# "^run" => "rake:run"
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
# :run => "rake:run"
|
|
525
|
+
# "one:run" => "one:run"
|
|
526
|
+
# "one:two:run" => "one:two:run"
|
|
527
|
+
|
|
528
|
+
== FileLists
|
|
529
|
+
|
|
530
|
+
FileLists are the way Rake manages lists of files. You can treat a
|
|
531
|
+
FileList as an array of strings for the most part, but FileLists
|
|
532
|
+
support some additional operations.
|
|
533
|
+
|
|
534
|
+
=== Creating a FileList
|
|
535
|
+
|
|
536
|
+
Creating a file list is easy. Just give it the list of file names:
|
|
537
|
+
|
|
538
|
+
fl = FileList['file1.rb', file2.rb']
|
|
539
|
+
|
|
540
|
+
Or give it a glob pattern:
|
|
541
|
+
|
|
542
|
+
fl = FileList['*.rb']
|
|
543
|
+
|
|
201
544
|
== Odds and Ends
|
|
202
545
|
|
|
203
|
-
=== do/end
|
|
546
|
+
=== do/end versus { }
|
|
204
547
|
|
|
205
548
|
Blocks may be specified with either a +do+/+end+ pair, or with curly
|
|
206
549
|
braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the
|
|
207
550
|
actions for tasks and rules. Because the rakefile idiom tends to
|
|
208
|
-
leave off
|
|
551
|
+
leave off parentheses on the task/file/rule methods, unusual
|
|
209
552
|
ambiguities can arise when using curly braces.
|
|
210
553
|
|
|
211
554
|
For example, suppose that the method +object_files+ returns a list of
|
|
212
555
|
object files in a project. Now we use +object_files+ as the
|
|
213
|
-
|
|
556
|
+
prerequisites in a rule specified with actions in curly braces.
|
|
214
557
|
|
|
215
558
|
# DON'T DO THIS!
|
|
216
559
|
file "prog" => object_files {
|
|
@@ -228,7 +571,65 @@ This is the proper way to specify the task ...
|
|
|
228
571
|
# Actions go here
|
|
229
572
|
end
|
|
230
573
|
|
|
574
|
+
== Rakefile Path
|
|
575
|
+
|
|
576
|
+
When issuing the +rake+ command in a terminal, Rake will look
|
|
577
|
+
for a Rakefile in the current directory. If a Rakefile is not found,
|
|
578
|
+
it will search parent directories until one is found.
|
|
579
|
+
|
|
580
|
+
For example, if a Rakefile resides in the +project/+ directory,
|
|
581
|
+
moving deeper into the project's directory tree will not have an adverse
|
|
582
|
+
effect on rake tasks:
|
|
583
|
+
|
|
584
|
+
$ pwd
|
|
585
|
+
/home/user/project
|
|
586
|
+
|
|
587
|
+
$ cd lib/foo/bar
|
|
588
|
+
$ pwd
|
|
589
|
+
/home/user/project/lib/foo/bar
|
|
590
|
+
|
|
591
|
+
$ rake run_pwd
|
|
592
|
+
/home/user/project
|
|
593
|
+
|
|
594
|
+
As far as rake is concerned, all tasks are run from the directory in
|
|
595
|
+
which the Rakefile resides.
|
|
596
|
+
|
|
597
|
+
=== Multiple Rake Files
|
|
598
|
+
|
|
599
|
+
Not all tasks need to be included in a single Rakefile. Additional
|
|
600
|
+
rake files (with the file extension "+.rake+") may be placed in
|
|
601
|
+
+rakelib+ directory located at the top level of a project (i.e.
|
|
602
|
+
the same directory that contains the main +Rakefile+).
|
|
603
|
+
|
|
604
|
+
Also, rails projects may include additional rake files in the
|
|
605
|
+
+lib/tasks+ directory.
|
|
606
|
+
|
|
607
|
+
=== Clean and Clobber Tasks
|
|
608
|
+
|
|
609
|
+
Through <tt>require 'rake/clean'</tt> Rake provides +clean+ and +clobber+
|
|
610
|
+
tasks:
|
|
611
|
+
|
|
612
|
+
+clean+ ::
|
|
613
|
+
Clean up the project by deleting scratch files and backup files. Add files
|
|
614
|
+
to the +CLEAN+ FileList to have the +clean+ target handle them.
|
|
615
|
+
|
|
616
|
+
+clobber+ ::
|
|
617
|
+
Clobber all generated and non-source files in a project. The task depends
|
|
618
|
+
on +clean+, so all the +CLEAN+ files will be deleted as well as files in the
|
|
619
|
+
+CLOBBER+ FileList. The intent of this task is to return a project to its
|
|
620
|
+
pristine, just unpacked state.
|
|
621
|
+
|
|
622
|
+
You can add file names or glob patterns to both the +CLEAN+ and +CLOBBER+
|
|
623
|
+
lists.
|
|
624
|
+
|
|
625
|
+
=== Phony Task
|
|
626
|
+
|
|
627
|
+
The phony task can be used as a dependency to allow file-based tasks to use
|
|
628
|
+
non-file-based-tasks as prerequisites without forcing them to rebuild. You
|
|
629
|
+
can <tt>require 'rake/phony'</tt> to add the +phony+ task.
|
|
630
|
+
|
|
231
631
|
----
|
|
632
|
+
|
|
232
633
|
== See
|
|
233
634
|
|
|
234
|
-
* README -- Main documentation for Rake.
|
|
635
|
+
* README.rdoc -- Main documentation for Rake.
|
data/doc/rational.rdoc
CHANGED
|
@@ -38,13 +38,13 @@ too much work. And that was the end of that!
|
|
|
38
38
|
... Except I couldn't get the thought out of my head. What exactly
|
|
39
39
|
would be needed to make the about syntax work as a make file? Hmmm, you
|
|
40
40
|
would need to register the tasks, you need some way of specifying
|
|
41
|
-
dependencies between tasks, and some way of kicking off the process.
|
|
41
|
+
dependencies between tasks, and some way of kicking off the process.
|
|
42
42
|
Hey! What if we did ... and fifteen minutes later I had a working
|
|
43
43
|
prototype of Ruby make, complete with dependencies and actions.
|
|
44
44
|
|
|
45
45
|
I showed the code to my coworker and we had a good laugh. It was just
|
|
46
46
|
about a page worth of code that reproduced an amazing amount of the
|
|
47
|
-
functionality of make. We were both
|
|
47
|
+
functionality of make. We were both truly stunned with the power of
|
|
48
48
|
Ruby.
|
|
49
49
|
|
|
50
50
|
But it didn't do everything make did. In particular, it didn't have
|
|
@@ -53,7 +53,7 @@ prerequisite files have a later timestamp). Obviously THAT would be a
|
|
|
53
53
|
pain to add and so Ruby Make would remain an interesting experiment.
|
|
54
54
|
|
|
55
55
|
... Except as I walked back to my desk, I started thinking about what
|
|
56
|
-
file based
|
|
56
|
+
file based dependencies would really need. Rats! I was hooked again,
|
|
57
57
|
and by adding a new class and two new methods, file/timestamp
|
|
58
58
|
dependencies were implemented.
|
|
59
59
|
|
|
@@ -97,7 +97,7 @@ Here's another task with dependencies ...
|
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
Task :clobber depends upon task :clean, so :clean will be run before
|
|
100
|
-
:clobber is executed.
|
|
100
|
+
:clobber is executed.
|
|
101
101
|
|
|
102
102
|
Files are specified by using the "file" command. It is similar to the
|
|
103
103
|
task command, except that the task name represents a file, and the task
|
|
@@ -115,7 +115,7 @@ Here is a file based dependency that will compile "hello.cc" to
|
|
|
115
115
|
|
|
116
116
|
I normally specify file tasks with string (rather than symbols). Some
|
|
117
117
|
file names can't be represented by symbols. Plus it makes the
|
|
118
|
-
distinction between them more clear to the casual reader.
|
|
118
|
+
distinction between them more clear to the casual reader.
|
|
119
119
|
|
|
120
120
|
Currently writing a task for each and every file in the project would be
|
|
121
121
|
tedious at best. I envision a set of libraries to make this job
|
|
@@ -133,7 +133,7 @@ created for rake.
|
|
|
133
133
|
That's it. There's no documentation (other than whats in this
|
|
134
134
|
message). Does this sound interesting to anyone? If so, I'll continue
|
|
135
135
|
to clean it up and write it up and publish it on RAA. Otherwise, I'll
|
|
136
|
-
leave it as an interesting
|
|
136
|
+
leave it as an interesting exercise and a tribute to the power of Ruby.
|
|
137
137
|
|
|
138
138
|
Why /might/ rake be interesting to Ruby programmers. I don't know,
|
|
139
139
|
perhaps ...
|
data/exe/rake
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright (c) 2003, 2004, 2005, 2006, 2007 Jim Weirich
|
|
5
|
+
#
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
# of this software and associated documentation files (the "Software"), to
|
|
8
|
+
# deal in the Software without restriction, including without limitation the
|
|
9
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
10
|
+
# sell copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
# furnished to do so, subject to the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
|
14
|
+
# all copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
21
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
22
|
+
# IN THE SOFTWARE.
|
|
23
|
+
#++
|
|
24
|
+
|
|
25
|
+
require "rake"
|
|
26
|
+
|
|
27
|
+
Rake.application.run
|