rake 0.4.11 → 0.8.7

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.
Files changed (101) hide show
  1. data/CHANGES +288 -1
  2. data/README +101 -114
  3. data/Rakefile +269 -54
  4. data/TODO +1 -0
  5. data/bin/rake +26 -3
  6. data/doc/command_line_usage.rdoc +102 -0
  7. data/doc/jamis.rb +133 -106
  8. data/doc/rake.1.gz +0 -0
  9. data/doc/rakefile.rdoc +304 -4
  10. data/doc/release_notes/rake-0.4.14.rdoc +23 -0
  11. data/doc/release_notes/rake-0.4.15.rdoc +35 -0
  12. data/doc/release_notes/rake-0.5.0.rdoc +53 -0
  13. data/doc/release_notes/rake-0.5.3.rdoc +78 -0
  14. data/doc/release_notes/rake-0.5.4.rdoc +46 -0
  15. data/doc/release_notes/rake-0.6.0.rdoc +141 -0
  16. data/doc/release_notes/rake-0.7.0.rdoc +119 -0
  17. data/doc/release_notes/rake-0.7.1.rdoc +59 -0
  18. data/doc/release_notes/rake-0.7.2.rdoc +121 -0
  19. data/doc/release_notes/rake-0.7.3.rdoc +47 -0
  20. data/doc/release_notes/rake-0.8.0.rdoc +114 -0
  21. data/doc/release_notes/rake-0.8.2.rdoc +165 -0
  22. data/doc/release_notes/rake-0.8.3.rdoc +112 -0
  23. data/doc/release_notes/rake-0.8.4.rdoc +147 -0
  24. data/doc/release_notes/rake-0.8.5.rdoc +53 -0
  25. data/doc/release_notes/rake-0.8.6.rdoc +55 -0
  26. data/doc/release_notes/rake-0.8.7.rdoc +55 -0
  27. data/lib/rake/alt_system.rb +108 -0
  28. data/lib/rake/classic_namespace.rb +8 -0
  29. data/lib/rake/clean.rb +3 -1
  30. data/lib/rake/contrib/ftptools.rb +40 -26
  31. data/lib/rake/contrib/publisher.rb +1 -1
  32. data/lib/rake/contrib/rubyforgepublisher.rb +3 -3
  33. data/lib/rake/contrib/sshpublisher.rb +1 -1
  34. data/lib/rake/contrib/sys.rb +25 -23
  35. data/lib/rake/gempackagetask.rb +14 -15
  36. data/lib/rake/loaders/makefile.rb +42 -0
  37. data/lib/rake/packagetask.rb +65 -33
  38. data/lib/rake/rake_test_loader.rb +5 -0
  39. data/lib/rake/rdoctask.rb +112 -31
  40. data/lib/rake/ruby182_test_unit_fix.rb +23 -0
  41. data/lib/rake/runtest.rb +4 -4
  42. data/lib/rake/tasklib.rb +11 -12
  43. data/lib/rake/testtask.rb +67 -24
  44. data/lib/rake/win32.rb +55 -0
  45. data/lib/rake.rb +2087 -578
  46. data/test/capture_stdout.rb +26 -0
  47. data/test/check_expansion.rb +5 -0
  48. data/test/check_no_expansion.rb +5 -0
  49. data/test/data/chains/Rakefile +15 -0
  50. data/test/data/default/Rakefile +19 -0
  51. data/test/data/dryrun/Rakefile +22 -0
  52. data/test/data/file_creation_task/Rakefile +33 -0
  53. data/test/data/imports/Rakefile +19 -0
  54. data/test/data/imports/deps.mf +1 -0
  55. data/test/data/multidesc/Rakefile +17 -0
  56. data/test/data/namespace/Rakefile +57 -0
  57. data/test/data/rakelib/test1.rb +3 -0
  58. data/test/data/sample.mf +14 -0
  59. data/test/data/statusreturn/Rakefile +8 -0
  60. data/test/data/unittest/Rakefile +1 -0
  61. data/test/filecreation.rb +18 -12
  62. data/test/functional.rb +6 -73
  63. data/test/in_environment.rb +30 -0
  64. data/test/rake_test_setup.rb +24 -0
  65. data/test/reqfile.rb +3 -0
  66. data/test/reqfile2.rb +3 -0
  67. data/test/session_functional.rb +339 -0
  68. data/test/shellcommand.rb +0 -0
  69. data/test/test_application.rb +675 -0
  70. data/test/{testclean.rb → test_clean.rb} +1 -0
  71. data/test/test_definitions.rb +85 -0
  72. data/test/test_earlytime.rb +35 -0
  73. data/test/test_extension.rb +63 -0
  74. data/test/test_file_creation_task.rb +62 -0
  75. data/test/test_file_task.rb +143 -0
  76. data/test/test_filelist.rb +623 -0
  77. data/test/test_fileutils.rb +251 -0
  78. data/test/{testftp.rb → test_ftp.rb} +5 -1
  79. data/test/test_invocation_chain.rb +81 -0
  80. data/test/test_makefile_loader.rb +26 -0
  81. data/test/test_multitask.rb +45 -0
  82. data/test/test_namespace.rb +55 -0
  83. data/test/{testpackagetask.rb → test_package_task.rb} +49 -12
  84. data/test/test_pathmap.rb +210 -0
  85. data/test/test_pseudo_status.rb +26 -0
  86. data/test/test_rake.rb +41 -0
  87. data/test/test_rdoc_task.rb +88 -0
  88. data/test/test_require.rb +35 -0
  89. data/test/test_rules.rb +349 -0
  90. data/test/test_task_arguments.rb +89 -0
  91. data/test/test_task_manager.rb +173 -0
  92. data/test/test_tasklib.rb +12 -0
  93. data/test/test_tasks.rb +374 -0
  94. data/test/{testtesttask.rb → test_test_task.rb} +8 -2
  95. data/test/test_top_level_functions.rb +86 -0
  96. data/test/test_win32.rb +72 -0
  97. metadata +184 -84
  98. data/test/testfilelist.rb +0 -255
  99. data/test/testfileutils.rb +0 -83
  100. data/test/testtasks.rb +0 -371
  101. /data/test/contrib/{testsys.rb → test_sys.rb} +0 -0
data/doc/jamis.rb CHANGED
@@ -182,30 +182,39 @@ h3, h4, h5, h6 {
182
182
 
183
183
  CSS
184
184
 
185
- BODY = <<HTML
185
+ XHTML_PREAMBLE = %{<?xml version="1.0" encoding="%charset%"?>
186
+ <!DOCTYPE html
187
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
188
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
189
+ }
190
+
191
+ HEADER = XHTML_PREAMBLE + <<ENDHEADER
186
192
  <html>
187
193
  <head>
188
194
  <title>%title%</title>
189
195
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
190
196
  <link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
191
197
 
192
- <script type="text/javascript" language="JavaScript">
193
- <!--
198
+ <script language="JavaScript" type="text/javascript">
199
+ // <![CDATA[
200
+
194
201
  function toggleSource( id )
195
202
  {
196
203
  var elem
197
204
  var link
198
205
 
199
- if( document.all )
206
+ if( document.getElementById )
207
+ {
208
+ elem = document.getElementById( id )
209
+ link = document.getElementById( "l_" + id )
210
+ }
211
+ else if ( document.all )
200
212
  {
201
213
  elem = eval( "document.all." + id )
202
214
  link = eval( "document.all.l_" + id )
203
215
  }
204
216
  else
205
- {
206
- elem = document.getElementById( id )
207
- link = document.getElementById( "l_" + id )
208
- }
217
+ return false;
209
218
 
210
219
  if( elem.style.display == "block" )
211
220
  {
@@ -223,89 +232,12 @@ BODY = <<HTML
223
232
  {
224
233
  window.open( url, "SOURCE_CODE", "width=400,height=400,scrollbars=yes" )
225
234
  }
226
- //-->
235
+ // ]]>
227
236
  </script>
228
237
  </head>
229
238
 
230
239
  <body>
231
- !INCLUDE! <!-- banner header -->
232
-
233
- <div id="content">
234
- IF:diagram
235
- <table cellpadding='0' cellspacing='0' border='0' width="100%"><tr><td align="center">
236
- %diagram%
237
- </td></tr></table>
238
- ENDIF:diagram
239
-
240
- IF:description
241
- <div class="description">%description%</div>
242
- ENDIF:description
243
-
244
- IF:requires
245
- <div class="sectiontitle">Required Files</div>
246
- <ul>
247
- START:requires
248
- <li>HREF:aref:name:</li>
249
- END:requires
250
- </ul>
251
- ENDIF:requires
252
-
253
- IF:methods
254
- <div class="sectiontitle">Methods</div>
255
- <ul>
256
- START:methods
257
- <li>HREF:aref:name:</li>
258
- END:methods
259
- </ul>
260
- ENDIF:methods
261
-
262
- IF:constants
263
- <div class="sectiontitle">Constants</div>
264
- <table border='0' cellpadding='5'>
265
- START:constants
266
- <tr valign='top'>
267
- <td class="attr-name">%name%</td>
268
- <td>=</td>
269
- <td class="attr-value">%value%</td>
270
- </tr>
271
- IF:desc
272
- <tr valign='top'>
273
- <td>&nbsp;</td>
274
- <td colspan="2" class="attr-desc">%desc%</td>
275
- </tr>
276
- ENDIF:desc
277
- END:constants
278
- </table>
279
- ENDIF:constants
280
-
281
- IF:attributes
282
- <div class="sectiontitle">Attributes</div>
283
- <table border='0' cellpadding='5'>
284
- START:attributes
285
- <tr valign='top'>
286
- <td class='attr-rw'>
287
- IF:rw
288
- [%rw%]
289
- ENDIF:rw
290
- </td>
291
- <td class='attr-name'>%name%</td>
292
- <td class='attr-desc'>%a_desc%</td>
293
- </tr>
294
- END:attributes
295
- </table>
296
- ENDIF:attributes
297
-
298
- IF:classlist
299
- <div class="sectiontitle">Classes and Modules</div>
300
- %classlist%
301
- ENDIF:classlist
302
-
303
- !INCLUDE! <!-- method descriptions -->
304
-
305
- </div>
306
- </body>
307
- </html>
308
- HTML
240
+ ENDHEADER
309
241
 
310
242
  FILE_PAGE = <<HTML
311
243
  <table border='0' cellpadding='0' cellspacing='0' width="100%" class='banner'>
@@ -318,7 +250,7 @@ FILE_PAGE = <<HTML
318
250
  <td>Path:</td>
319
251
  <td>%full_path%
320
252
  IF:cvsurl
321
- &nbsp;(<a href="%cvsurl%">CVS</a>)
253
+ &nbsp;(<a href="%cvsurl%">CVS</a>)
322
254
  ENDIF:cvsurl
323
255
  </td>
324
256
  </tr>
@@ -374,6 +306,44 @@ HTML
374
306
  ###################################################################
375
307
 
376
308
  METHOD_LIST = <<HTML
309
+ <div id="content">
310
+ IF:diagram
311
+ <table cellpadding='0' cellspacing='0' border='0' width="100%"><tr><td align="center">
312
+ %diagram%
313
+ </td></tr></table>
314
+ ENDIF:diagram
315
+
316
+ IF:description
317
+ <div class="description">%description%</div>
318
+ ENDIF:description
319
+
320
+ IF:requires
321
+ <div class="sectiontitle">Required Files</div>
322
+ <ul>
323
+ START:requires
324
+ <li>HREF:aref:name:</li>
325
+ END:requires
326
+ </ul>
327
+ ENDIF:requires
328
+
329
+ IF:toc
330
+ <div class="sectiontitle">Contents</div>
331
+ <ul>
332
+ START:toc
333
+ <li><a href="#%href%">%secname%</a></li>
334
+ END:toc
335
+ </ul>
336
+ ENDIF:toc
337
+
338
+ IF:methods
339
+ <div class="sectiontitle">Methods</div>
340
+ <ul>
341
+ START:methods
342
+ <li>HREF:aref:name:</li>
343
+ END:methods
344
+ </ul>
345
+ ENDIF:methods
346
+
377
347
  IF:includes
378
348
  <div class="sectiontitle">Included Modules</div>
379
349
  <ul>
@@ -383,6 +353,57 @@ END:includes
383
353
  </ul>
384
354
  ENDIF:includes
385
355
 
356
+ START:sections
357
+ IF:sectitle
358
+ <div class="sectiontitle"><a nem="%secsequence%">%sectitle%</a></div>
359
+ IF:seccomment
360
+ <div class="description">
361
+ %seccomment%
362
+ </div>
363
+ ENDIF:seccomment
364
+ ENDIF:sectitle
365
+
366
+ IF:classlist
367
+ <div class="sectiontitle">Classes and Modules</div>
368
+ %classlist%
369
+ ENDIF:classlist
370
+
371
+ IF:constants
372
+ <div class="sectiontitle">Constants</div>
373
+ <table border='0' cellpadding='5'>
374
+ START:constants
375
+ <tr valign='top'>
376
+ <td class="attr-name">%name%</td>
377
+ <td>=</td>
378
+ <td class="attr-value">%value%</td>
379
+ </tr>
380
+ IF:desc
381
+ <tr valign='top'>
382
+ <td>&nbsp;</td>
383
+ <td colspan="2" class="attr-desc">%desc%</td>
384
+ </tr>
385
+ ENDIF:desc
386
+ END:constants
387
+ </table>
388
+ ENDIF:constants
389
+
390
+ IF:attributes
391
+ <div class="sectiontitle">Attributes</div>
392
+ <table border='0' cellpadding='5'>
393
+ START:attributes
394
+ <tr valign='top'>
395
+ <td class='attr-rw'>
396
+ IF:rw
397
+ [%rw%]
398
+ ENDIF:rw
399
+ </td>
400
+ <td class='attr-name'>%name%</td>
401
+ <td class='attr-desc'>%a_desc%</td>
402
+ </tr>
403
+ END:attributes
404
+ </table>
405
+ ENDIF:attributes
406
+
386
407
  IF:method_list
387
408
  START:method_list
388
409
  IF:methods
@@ -415,8 +436,8 @@ END:aka
415
436
  ENDIF:aka
416
437
  IF:sourcecode
417
438
  <div class="sourcecode">
418
- <p class="source-link">[ <a href="javascript:toggleSource('%aref%-source')" id="l_%aref%-source">show source</a> ]</p>
419
- <div id="%aref%-source" class="dyn-source">
439
+ <p class="source-link">[ <a href="javascript:toggleSource('%aref%_source')" id="l_%aref%_source">show source</a> ]</p>
440
+ <div id="%aref%_source" class="dyn-source">
420
441
  <pre>
421
442
  %sourcecode%
422
443
  </pre>
@@ -428,14 +449,28 @@ END:methods
428
449
  ENDIF:methods
429
450
  END:method_list
430
451
  ENDIF:method_list
452
+ END:sections
453
+ </div>
431
454
  HTML
432
455
 
433
- =begin
434
- =end
456
+ FOOTER = <<ENDFOOTER
457
+ </body>
458
+ </html>
459
+ ENDFOOTER
460
+
461
+ BODY = HEADER + <<ENDBODY
462
+ !INCLUDE! <!-- banner header -->
463
+
464
+ <div id="bodyContent">
465
+ #{METHOD_LIST}
466
+ </div>
467
+
468
+ #{FOOTER}
469
+ ENDBODY
435
470
 
436
471
  ########################## Source code ##########################
437
472
 
438
- SRC_PAGE = <<HTML
473
+ SRC_PAGE = XHTML_PREAMBLE + <<HTML
439
474
  <html>
440
475
  <head><title>%title%</title>
441
476
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
@@ -467,7 +502,7 @@ FR_INDEX_BODY = <<HTML
467
502
  !INCLUDE!
468
503
  HTML
469
504
 
470
- FILE_INDEX = <<HTML
505
+ FILE_INDEX = XHTML_PREAMBLE + <<HTML
471
506
  <html>
472
507
  <head>
473
508
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
@@ -494,6 +529,7 @@ FILE_INDEX = <<HTML
494
529
  a {
495
530
  color: #00F;
496
531
  text-decoration: none;
532
+ white-space: nowrap;
497
533
  }
498
534
  a:hover {
499
535
  color: #77F;
@@ -516,8 +552,8 @@ HTML
516
552
  CLASS_INDEX = FILE_INDEX
517
553
  METHOD_INDEX = FILE_INDEX
518
554
 
519
- INDEX = <<HTML
520
- <html>
555
+ INDEX = XHTML_PREAMBLE + <<HTML
556
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
521
557
  <head>
522
558
  <title>%title%</title>
523
559
  <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
@@ -549,16 +585,7 @@ ENDIF:inline_source
549
585
  </html>
550
586
  HTML
551
587
 
552
- # and a blank page to use as a target
553
- BLANK = %{
554
- <html><body bgcolor="white"></body></html>
555
- }
556
-
557
- def write_extra_pages
558
- template = TemplatePage.new(BLANK)
559
- File.open("blank.html", "w") { |f| template.write_html_on(f, {}) }
560
- end
561
-
562
588
  end
563
589
  end
564
590
 
591
+
data/doc/rake.1.gz ADDED
Binary file
data/doc/rakefile.rdoc CHANGED
@@ -1,4 +1,4 @@
1
- = Rakefile Format
1
+ = Rakefile Format (as of version 0.8.3)
2
2
 
3
3
  First of all, there is no special format for a Rakefile. A Rakefile
4
4
  contains executable Ruby code. Anything legal in a ruby script is
@@ -110,6 +110,171 @@ both prerequisites and actions can be added later. For example ...
110
110
  cp Dir["standard_data/*.data"], "testdata"
111
111
  end
112
112
 
113
+ == Tasks with Parallel Prerequisites
114
+
115
+ Rake allows parallel execution of prerequisites using the following syntax:
116
+
117
+ multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do
118
+ puts "All Copies Complete"
119
+ end
120
+
121
+ In this example, +copy_files+ is a normal rake task. Its actions are
122
+ executed whereever all of its prerequisites are done. The big
123
+ difference is that the prerequisites (+copy_src+, +copy_bin+ and
124
+ +copy_doc+) are executed in parallel. Each of the prerequisites are
125
+ run in their own Ruby thread, possibly allowing faster overall runtime.
126
+
127
+ === Secondary Prerequisites
128
+
129
+ If any of the primary prerequites of a multitask have common secondary
130
+ prerequisites, all of the primary/parallel prerequisites will wait
131
+ until the common prerequisites have been run.
132
+
133
+ For example, if the <tt>copy_<em>xxx</em></tt> tasks have the
134
+ following prerequisites:
135
+
136
+ task :copy_src => [:prep_for_copy]
137
+ task :copy_bin => [:prep_for_copy]
138
+ task :copy_doc => [:prep_for_copy]
139
+
140
+ Then the +prep_for_copy+ task is run before starting all the copies in
141
+ parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+,
142
+ and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is
143
+ run only once, even though it is referenced in multiple threads.
144
+
145
+ === Thread Safety
146
+
147
+ The Rake internal data structures are thread-safe with respect
148
+ to the multitask parallel execution, so there is no need for the user
149
+ to do extra synchronization for Rake's benefit. However, if there are
150
+ user data structures shared between the parallel prerequisites, the
151
+ user must do whatever is necessary to prevent race conditions.
152
+
153
+ == Tasks with Arguments
154
+
155
+ Prior to version 0.8.0, rake was only able to handle command line
156
+ arguments of the form NAME=VALUE that were passed into Rake via the
157
+ ENV hash. Many folks had asked for some kind of simple command line
158
+ arguments, perhaps using "--" to separate regular task names from
159
+ argument values on the command line. The problem is that there was no
160
+ easy way to associate positional arguments on the command line with
161
+ different tasks. Suppose both tasks :a and :b expect a command line
162
+ argument: does the first value go with :a? What if :b is run first?
163
+ Should it then get the first command line argument.
164
+
165
+ Rake 0.8.0 solves this problem by explicitly passing values directly
166
+ to the tasks that need them. For example, if I had a release task
167
+ that required a version number, I could say:
168
+
169
+ rake release[0.8.2]
170
+
171
+ And the string "0.8.2" will be passed to the :release task. Multiple
172
+ arguments can be passed by separating them with a comma, for example:
173
+
174
+ rake name[john,doe]
175
+
176
+ Just a few words of caution. The rake task name and its arguments
177
+ need to be a single command line argument to rake. This generally
178
+ means no spaces. If spaces are needed, then the entire rake +
179
+ argument string should be quoted. Something like this:
180
+
181
+ rake "name[billy bob, smith]"
182
+
183
+ (Quoting rules vary between operating systems and shells, so make sure
184
+ you consult the proper docs for your OS/shell).
185
+
186
+ === Tasks that Expect Parameters
187
+
188
+ Parameters are only given to tasks that are setup to expect them. In
189
+ order to handle named parameters, the task declaration syntax for
190
+ tasks has been extended slightly.
191
+
192
+ For example, a task that needs a first name and last name might be
193
+ declared as:
194
+
195
+ task :name, [:first_name, :last_name]
196
+
197
+ The first argument is still the name of the task (:name in this case).
198
+ The next to argumements are the names of the parameters expected by
199
+ :name in an array (:first_name and :last_name in the example).
200
+
201
+ To access the values of the paramters, the block defining the task
202
+ behaviour can now accept a second parameter:
203
+
204
+ task :name, [:first_name, :last_name] do |t, args|
205
+ puts "First name is #{args.first_name}"
206
+ puts "Last name is #{args.last_name}"
207
+ end
208
+
209
+ The first argument of the block "t" is always bound to the current
210
+ task object. The second argument "args" is an open-struct like object
211
+ that allows access to the task arguments. Extra command line
212
+ arguments to a task are ignored. Missing command line arguments are
213
+ given the nil value.
214
+
215
+ If you wish to specify default values for the arguments, you can use
216
+ the with_defaults method in the task body. Here is the above example
217
+ where we specify default values for the first and last names:
218
+
219
+ task :name, [:first_name, :last_name] do |t, args|
220
+ args.with_defaults(:first_name => "John", :last_name => "Dough")
221
+ puts "First name is #{args.first_name}"
222
+ puts "Last name is #{args.last_name}"
223
+ end
224
+
225
+ === Tasks that Expect Parameters and Have Prerequisites
226
+
227
+ Tasks that use parameters have a slightly different format for
228
+ prerequisites. Use the arrow notation to indicate the prerequisites
229
+ for tasks with arguments. For example:
230
+
231
+ task :name, [:first_name, :last_name] => [:pre_name] do |t, args|
232
+ args.with_defaults(:first_name => "John", :last_name => "Dough")
233
+ puts "First name is #{args.first_name}"
234
+ puts "Last name is #{args.last_name}"
235
+ end
236
+
237
+ === Deprecated Task Parameters Format
238
+
239
+ There is an older format for declaring task parameters that omitted
240
+ the task argument array and used the :needs keyword to introduce the
241
+ dependencies. That format is still supported for compatibility, but
242
+ is not recommended for use.
243
+
244
+ == Accessing Task Programatically
245
+
246
+ Sometimes it is useful to manipulate tasks programatically in a
247
+ Rakefile. To find a task object, use the <tt>:[]</tt> operator on the
248
+ <tt>Rake::Task</tt>.
249
+
250
+ === Programmatic Task Example
251
+
252
+ For example, the following Rakefile defines two tasks. The :doit task
253
+ simply prints a simple "DONE" message. The :dont class will lookup
254
+ the doit class and remove (clear) all of its prerequisites and
255
+ actions.
256
+
257
+ task :doit do
258
+ puts "DONE"
259
+ end
260
+
261
+ task :dont do
262
+ Rake::Task[:doit].clear
263
+ end
264
+
265
+ Running this example:
266
+
267
+ $ rake doit
268
+ (in /Users/jim/working/git/rake/x)
269
+ DONE
270
+ $ rake dont doit
271
+ (in /Users/jim/working/git/rake/x)
272
+ $
273
+
274
+ The ability to programmatically manipulate tasks gives rake very
275
+ powerful meta-programming capabilities w.r.t. task execution, but
276
+ should be used with cation.
277
+
113
278
  == Rules
114
279
 
115
280
  When a file is named as a prerequisite, but does not have a file task
@@ -128,8 +293,8 @@ prerequisite a source file with an extension of ".c" must exist. If
128
293
  Rake is able to find a file named "mycode.c", it will automatically
129
294
  create a task that builds "mycode.o" from "mycode.c".
130
295
 
131
- Notice that the source file "mycode.c" must exist. Rake does not
132
- (currently) try to do multi-level task synthesis.
296
+ If the file "mycode.c" does not exist, rake will attempt
297
+ to recursively synthesize a rule for it.
133
298
 
134
299
  When a task is synthesized from a rule, the +source+ attribute of the
135
300
  task is set to the matching source file. This allows us to write
@@ -163,6 +328,39 @@ The following rule might be used for Java files ...
163
328
  <b>NOTE:</b> +java_compile+ is a hypothetical method that invokes the
164
329
  java compiler.
165
330
 
331
+ == Importing Dependencies
332
+
333
+ Any ruby file (including other rakefiles) can be included with a
334
+ standard Ruby +require+ command. The rules and declarations in the
335
+ required file are just added to the definitions already accumulated.
336
+
337
+ Because the files are loaded _before_ the rake targets are evaluated,
338
+ the loaded files must be "ready to go" when the rake command is
339
+ invoked. This make generated dependency files difficult to use. By
340
+ the time rake gets around to updating the dependencies file, it is too
341
+ late to load it.
342
+
343
+ The +import+ command addresses this by specifying a file to be loaded
344
+ _after_ the main rakefile is loaded, but _before_ any targets on the
345
+ command line are specified. In addition, if the file name matches an
346
+ explicit task, that task is invoked before loading the file. This
347
+ allows dependency files to be generated and used in a single rake
348
+ command invocation.
349
+
350
+ === Example:
351
+
352
+ require 'rake/loaders/makefile'
353
+
354
+ file ".depends.mf" => [SRC_LIST] do |t|
355
+ sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}"
356
+ end
357
+
358
+ import ".depends.mf"
359
+
360
+ If ".depends" does not exist, or is out of date w.r.t. the source
361
+ files, a new ".depends" file is generated using +makedepend+ before
362
+ loading.
363
+
166
364
  == Comments
167
365
 
168
366
  Standard Ruby comments (beginning with "#") can be used anywhere it is
@@ -170,7 +368,7 @@ legal in Ruby source code, including comments for tasks and rules.
170
368
  However, if you wish a task to be described using the "-T" switch,
171
369
  then you need to use the +desc+ command to describe the task.
172
370
 
173
- Example:
371
+ === Example:
174
372
 
175
373
  desc "Create a distribution package"
176
374
  task :package => [ ... ] do ... end
@@ -198,6 +396,107 @@ Only tasks with descriptions will be displayed with the "-T" switch.
198
396
  Use "-P" (or "--prereqs") to get a list of all tasks and their
199
397
  prerequisites.
200
398
 
399
+ == Namespaces
400
+
401
+ As projects grow (and along with it, the number of tasks), it is
402
+ common for task names to begin to clash. For example, if you might
403
+ have a main program and a set of sample programs built by a single
404
+ Rakefile. By placing the tasks related to the main program in one
405
+ namespace, and the tasks for building the sample programs in a
406
+ different namespace, the task names will not will not interfer with
407
+ each other.
408
+
409
+ For example:
410
+
411
+ namespace "main"
412
+ task :build do
413
+ # Build the main program
414
+ end
415
+ end
416
+
417
+ namespace "samples" do
418
+ task :build do
419
+ # Build the sample programs
420
+ end
421
+ end
422
+
423
+ task :build => ["main:build", "samples:build"]
424
+
425
+ Referencing a task in a separate namespace can be achieved by
426
+ prefixing the task name with the namespace and a colon
427
+ (e.g. "main:build" refers to the :build task in the +main+ namespace).
428
+ Nested namespaces are supported, so
429
+
430
+ Note that the name given in the +task+ command is always the unadorned
431
+ task name without any namespace prefixes. The +task+ command always
432
+ defines a task in the current namespace.
433
+
434
+ === FileTasks
435
+
436
+ File task names are not scoped by the namespace command. Since the
437
+ name of a file task is the name of an actual file in the file system,
438
+ it makes little sense to include file task names in name space.
439
+ Directory tasks (created by the +directory+ command) are a type of
440
+ file task and are also not affected by namespaces.
441
+
442
+ === Name Resolution
443
+
444
+ When looking up a task name, rake will start with the current
445
+ namespace and attempt to find the name there. If it fails to find a
446
+ name in the current namespace, it will search the parent namespaces
447
+ until a match is found (or an error occurs if there is no match).
448
+
449
+ The "rake" namespace is a special implicit namespace that refers to
450
+ the toplevel names.
451
+
452
+ If a task name begins with a "^" character, the name resolution will
453
+ start in the parent namespace. Multiple "^" characters are allowed.
454
+
455
+ Here is an example file with multiple :run tasks and how various names
456
+ resolve in different locations.
457
+
458
+ task :run
459
+
460
+ namespace "one" do
461
+ task :run
462
+
463
+ namespace "two" do
464
+ task :run
465
+
466
+ # :run => "one:two:run"
467
+ # "two:run" => "one:two:run"
468
+ # "one:two:run" => "one:two:run"
469
+ # "one:run" => "one:run"
470
+ # "^run" => "one:run"
471
+ # "^^run" => "rake:run" (the top level task)
472
+ # "rake:run" => "rake:run" (the top level task)
473
+ end
474
+
475
+ # :run => "one:run"
476
+ # "two:run" => "one:two:run"
477
+ # "^run" => "rake:run"
478
+ end
479
+
480
+ # :run => "rake:run"
481
+ # "one:run" => "one:run"
482
+ # "one:two:run" => "one:two:run"
483
+
484
+ == FileLists
485
+
486
+ FileLists are the way Rake manages lists of files. You can treat a
487
+ FileList as an array of strings for the most part, but FileLists
488
+ support some additional operations.
489
+
490
+ === Creating a FileList
491
+
492
+ Creating a file list is easy. Just give it the list of file names:
493
+
494
+ fl = FileList['file1.rb', file2.rb']
495
+
496
+ Or give it a glob pattern:
497
+
498
+ fl = FileList['*.rb']
499
+
201
500
  == Odds and Ends
202
501
 
203
502
  === do/end verses { }
@@ -229,6 +528,7 @@ This is the proper way to specify the task ...
229
528
  end
230
529
 
231
530
  ----
531
+
232
532
  == See
233
533
 
234
534
  * README -- Main documentation for Rake.