drake 0.8.7.0.2.4 → 0.9.0.0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. data/.gemtest +0 -0
  2. data/CHANGES +77 -9
  3. data/{CHANGES.drake → CHANGES-drake} +6 -2
  4. data/MIT-LICENSE +2 -0
  5. data/{README → README.rdoc} +30 -18
  6. data/Rakefile +144 -130
  7. data/Rakefile-drake +67 -0
  8. data/TODO +1 -1
  9. data/bin/drake +2 -0
  10. data/doc/command_line_usage.rdoc +25 -11
  11. data/doc/glossary.rdoc +2 -2
  12. data/doc/jamis.rb +2 -2
  13. data/doc/parallel.rdoc +37 -29
  14. data/doc/proto_rake.rdoc +22 -22
  15. data/doc/rake.1.gz +0 -0
  16. data/doc/rakefile.rdoc +56 -33
  17. data/doc/rational.rdoc +6 -6
  18. data/doc/release_notes/rake-0.4.15.rdoc +1 -1
  19. data/doc/release_notes/rake-0.5.0.rdoc +1 -1
  20. data/doc/release_notes/rake-0.7.0.rdoc +1 -1
  21. data/doc/release_notes/rake-0.7.2.rdoc +3 -3
  22. data/doc/release_notes/rake-0.7.3.rdoc +2 -2
  23. data/doc/release_notes/rake-0.8.0.rdoc +1 -1
  24. data/doc/release_notes/rake-0.8.2.rdoc +3 -3
  25. data/doc/release_notes/rake-0.8.3.rdoc +2 -2
  26. data/doc/release_notes/rake-0.8.4.rdoc +1 -1
  27. data/doc/release_notes/rake-0.8.5.rdoc +1 -1
  28. data/doc/release_notes/rake-0.8.6.rdoc +1 -1
  29. data/doc/release_notes/rake-0.8.7.rdoc +1 -1
  30. data/doc/release_notes/rake-0.9.0.rdoc +112 -0
  31. data/install.rb +14 -12
  32. data/lib/rake.rb +31 -2527
  33. data/lib/rake/alt_system.rb +7 -6
  34. data/lib/rake/application.rb +626 -0
  35. data/lib/rake/classic_namespace.rb +1 -0
  36. data/lib/rake/clean.rb +2 -4
  37. data/lib/rake/cloneable.rb +25 -0
  38. data/lib/rake/contrib/compositepublisher.rb +2 -5
  39. data/lib/rake/contrib/ftptools.rb +5 -8
  40. data/lib/rake/contrib/publisher.rb +2 -8
  41. data/lib/rake/contrib/rubyforgepublisher.rb +2 -4
  42. data/lib/rake/contrib/sshpublisher.rb +4 -6
  43. data/lib/rake/contrib/sys.rb +7 -25
  44. data/lib/rake/default_loader.rb +10 -0
  45. data/lib/rake/dsl.rb +2 -0
  46. data/lib/rake/dsl_definition.rb +143 -0
  47. data/lib/rake/early_time.rb +18 -0
  48. data/lib/rake/ext/core.rb +27 -0
  49. data/lib/rake/ext/module.rb +39 -0
  50. data/lib/rake/ext/string.rb +167 -0
  51. data/lib/rake/ext/time.rb +14 -0
  52. data/lib/rake/file_creation_task.rb +24 -0
  53. data/lib/rake/file_list.rb +403 -0
  54. data/lib/rake/file_task.rb +47 -0
  55. data/lib/rake/file_utils.rb +112 -0
  56. data/lib/rake/file_utils_ext.rb +142 -0
  57. data/lib/rake/gempackagetask.rb +6 -90
  58. data/lib/rake/invocation_chain.rb +51 -0
  59. data/lib/rake/invocation_exception_mixin.rb +16 -0
  60. data/lib/rake/loaders/makefile.rb +13 -15
  61. data/lib/rake/multi_task.rb +16 -0
  62. data/lib/rake/name_space.rb +25 -0
  63. data/lib/rake/packagetask.rb +13 -12
  64. data/lib/rake/parallel.rb +17 -28
  65. data/lib/rake/pathmap.rb +1 -0
  66. data/lib/rake/pseudo_status.rb +24 -0
  67. data/lib/rake/rake_module.rb +29 -0
  68. data/lib/rake/rake_test_loader.rb +10 -2
  69. data/lib/rake/rdoctask.rb +211 -190
  70. data/lib/rake/ruby182_test_unit_fix.rb +9 -7
  71. data/lib/rake/rule_recursion_overflow_error.rb +20 -0
  72. data/lib/rake/runtest.rb +4 -6
  73. data/lib/rake/task.rb +351 -0
  74. data/lib/rake/task_argument_error.rb +7 -0
  75. data/lib/rake/task_arguments.rb +74 -0
  76. data/lib/rake/task_manager.rb +307 -0
  77. data/lib/rake/tasklib.rb +1 -2
  78. data/lib/rake/testtask.rb +57 -27
  79. data/lib/rake/version.rb +13 -0
  80. data/lib/rake/win32.rb +4 -4
  81. data/test/contrib/test_sys.rb +8 -31
  82. data/test/data/access/Rakefile +33 -0
  83. data/test/data/comments/Rakefile +18 -0
  84. data/test/data/default/Rakefile +1 -1
  85. data/test/data/deprecated_import/Rakefile +1 -0
  86. data/test/data/dryrun/Rakefile +1 -1
  87. data/test/data/file_creation_task/Rakefile +1 -1
  88. data/test/data/namespace/Rakefile +9 -0
  89. data/test/data/rakelib/test1.rb +1 -0
  90. data/test/data/verbose/Rakefile +34 -0
  91. data/test/{filecreation.rb → file_creation.rb} +11 -7
  92. data/test/functional/functional_test.rb +25 -0
  93. data/test/{session_functional.rb → functional/session_based_tests.rb} +141 -23
  94. data/test/in_environment.rb +7 -5
  95. data/test/{test_application.rb → lib/application_test.rb} +331 -143
  96. data/test/{test_clean.rb → lib/clean_test.rb} +1 -0
  97. data/test/{test_definitions.rb → lib/definitions_test.rb} +4 -4
  98. data/test/lib/dsl_test.rb +52 -0
  99. data/test/{test_earlytime.rb → lib/earlytime_test.rb} +1 -2
  100. data/test/{test_extension.rb → lib/extension_test.rb} +2 -2
  101. data/test/{test_file_creation_task.rb → lib/file_creation_task_test.rb} +1 -1
  102. data/test/{test_file_task.rb → lib/file_task_test.rb} +9 -5
  103. data/test/{test_filelist.rb → lib/filelist_test.rb} +38 -24
  104. data/test/{test_fileutils.rb → lib/fileutils_test.rb} +27 -22
  105. data/test/{test_ftp.rb → lib/ftp_test.rb} +0 -0
  106. data/test/{test_invocation_chain.rb → lib/invocation_chain_test.rb} +0 -0
  107. data/test/{test_makefile_loader.rb → lib/makefile_loader_test.rb} +0 -0
  108. data/test/{test_multitask.rb → lib/multitask_test.rb} +3 -2
  109. data/test/{test_namespace.rb → lib/namespace_test.rb} +0 -0
  110. data/test/lib/package_task_test.rb +82 -0
  111. data/test/{test_parallel.rb → lib/parallel_test.rb} +5 -5
  112. data/test/{test_pathmap.rb → lib/pathmap_test.rb} +3 -2
  113. data/test/{test_pseudo_status.rb → lib/pseudo_status_test.rb} +0 -0
  114. data/test/{test_rake.rb → lib/rake_test.rb} +1 -1
  115. data/test/{test_rdoc_task.rb → lib/rdoc_task_test.rb} +19 -23
  116. data/test/{test_require.rb → lib/require_test.rb} +8 -2
  117. data/test/{test_rules.rb → lib/rules_test.rb} +4 -5
  118. data/test/{test_task_arguments.rb → lib/task_arguments_test.rb} +5 -5
  119. data/test/{test_task_manager.rb → lib/task_manager_test.rb} +15 -5
  120. data/test/{test_tasks.rb → lib/task_test.rb} +91 -28
  121. data/test/{test_tasklib.rb → lib/tasklib_test.rb} +0 -0
  122. data/test/{test_test_task.rb → lib/test_task_test.rb} +3 -3
  123. data/test/lib/testtask_test.rb +49 -0
  124. data/test/{test_top_level_functions.rb → lib/top_level_functions_test.rb} +5 -3
  125. data/test/{test_win32.rb → lib/win32_test.rb} +19 -0
  126. data/test/rake_test_setup.rb +6 -10
  127. data/test/ruby_version_test.rb +3 -0
  128. data/test/test_helper.rb +19 -0
  129. metadata +108 -66
  130. data/Rakefile.drake +0 -73
  131. data/test/functional.rb +0 -15
  132. data/test/test_package_task.rb +0 -118
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 truely stunned with the power of
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 dependecies would really need. Rats! I was hooked again,
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 excerise and a tribute to the power of Ruby.
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 ...
@@ -9,7 +9,7 @@ changes. This release includes:
9
9
  revised for 1.8.2 test task.
10
10
 
11
11
  * Updated the docs on --trace to indicate that it also enables a full
12
- backtrace on errors.
12
+ backtrace on errors.
13
13
 
14
14
  * Several fixes for new warnings generated.
15
15
 
@@ -1,7 +1,7 @@
1
1
  = Rake 0.5.0 Released
2
2
 
3
3
  It has been a long time in coming, but we finally have a new version
4
- of Rake available.
4
+ of Rake available.
5
5
 
6
6
  == Changes
7
7
 
@@ -64,7 +64,7 @@ commands:
64
64
 
65
65
  Or invoke both via the :build_all command:
66
66
 
67
- rake build_all
67
+ rake build_all
68
68
 
69
69
  Namespaces may be nested arbitrarily. Since the name of file tasks
70
70
  correspond to the name of a file in the external file system,
@@ -24,7 +24,7 @@ Rake:
24
24
  appliation instead of using its own data.
25
25
 
26
26
  * Fixed the method name leak from FileUtils (bug found by Glenn
27
- Vanderburg).
27
+ Vanderburg).
28
28
 
29
29
  * Added test for noop, bad_option and verbose flags to sh command.
30
30
 
@@ -40,13 +40,13 @@ Rake:
40
40
  The following new features are available in Rake version 0.7.2:
41
41
 
42
42
  * Added square and curly bracket patterns to FileList#include (Tilman
43
- Sauerbeck).
43
+ Sauerbeck).
44
44
 
45
45
  * FileLists can now pass a block to FileList#exclude to exclude files
46
46
  based on calculated values.
47
47
 
48
48
  * Added plain filename support to rule dependents (suggested by Nobu
49
- Nakada).
49
+ Nakada).
50
50
 
51
51
  * Added pathmap support to rule dependents. In other words, if a
52
52
  pathmap format (beginning with a '%') is given as a Rake rule
@@ -13,11 +13,11 @@ support custom Rake applications.
13
13
  require 'rake'
14
14
 
15
15
  Rake.application.init('myrake')
16
-
16
+
17
17
  task :default do
18
18
  something_interesting
19
19
  end
20
-
20
+
21
21
  Rake.application.top_level
22
22
 
23
23
  == What is Rake
@@ -1,7 +1,7 @@
1
1
  = Rake 0.8.0/0.8.1 Released
2
2
 
3
3
  Rake version 0.8.0 is a new release of rake that includes serveral new
4
- features.
4
+ features.
5
5
 
6
6
  == Changes
7
7
 
@@ -46,14 +46,14 @@ new features and numerous bug fixes.
46
46
 
47
47
  * Fixed bug with rules involving multiple source, where only the first
48
48
  dependency of a rule has any effect (Patch supplied by Emanuel
49
- Inderm�hle)
49
+ Indermühle)
50
50
 
51
51
  * FileList#clone and FileList#dup have better sematics w.r.t. taint
52
52
  and freeze.
53
53
 
54
54
  * Changed from using Mutex to Monitor. Evidently Mutex causes thread
55
55
  join errors when Ruby is compiled with -disable-pthreads. (Patch
56
- supplied by Ittay Dror)
56
+ supplied by Ittay Dror)
57
57
 
58
58
  * Fixed bug in makefile parser that had problems with extra spaces in
59
59
  file task names. (Patch supplied by Ittay Dror)
@@ -157,7 +157,7 @@ otherwise helpful comments. Thanks to ...
157
157
  * Gavin Stark
158
158
  * Adam Q. Salter
159
159
  * Adam Majer
160
- * Emanuel Inderm�hle
160
+ * Emanuel Indermühle
161
161
  * Ittay Dror
162
162
  * Bheeshmar Redheendran (for spending an afternoon with me debugging
163
163
  windows issues)
@@ -12,7 +12,7 @@ Rake version 0.8.3 is a bug-fix release of rake.
12
12
  directory.
13
13
 
14
14
  * Added fix to handle ruby installations in directories with spaces in
15
- their name.
15
+ their name.
16
16
 
17
17
  == What is Rake
18
18
 
@@ -104,7 +104,7 @@ otherwise helpful comments. Thanks to ...
104
104
  * Gavin Stark
105
105
  * Adam Q. Salter
106
106
  * Adam Majer
107
- * Emanuel Inderm�hle
107
+ * Emanuel Indermühle
108
108
  * Ittay Dror
109
109
  * Bheeshmar Redheendran (for spending an afternoon with me debugging
110
110
  windows issues)
@@ -69,7 +69,7 @@ Otherwise, you can get it from the more traditional places:
69
69
 
70
70
  Home Page:: http://rake.rubyforge.org/
71
71
  Download:: http://rubyforge.org/project/showfiles.php?group_id=50
72
- GitHub:: git://github.com/jimweirich/rake.git
72
+ GitHub:: git://github.com/jimweirich/rake.git
73
73
 
74
74
  == Task Argument Examples
75
75
 
@@ -39,7 +39,7 @@ Otherwise, you can get it from the more traditional places:
39
39
 
40
40
  Home Page:: http://rake.rubyforge.org/
41
41
  Download:: http://rubyforge.org/project/showfiles.php?group_id=50
42
- GitHub:: git://github.com/jimweirich/rake.git
42
+ GitHub:: git://github.com/jimweirich/rake.git
43
43
 
44
44
  == Thanks
45
45
 
@@ -41,7 +41,7 @@ Otherwise, you can get it from the more traditional places:
41
41
 
42
42
  Home Page:: http://rake.rubyforge.org/
43
43
  Download:: http://rubyforge.org/project/showfiles.php?group_id=50
44
- GitHub:: git://github.com/jimweirich/rake.git
44
+ GitHub:: git://github.com/jimweirich/rake.git
45
45
 
46
46
  == Thanks
47
47
 
@@ -42,7 +42,7 @@ Otherwise, you can get it from the more traditional places:
42
42
 
43
43
  Home Page:: http://rake.rubyforge.org/
44
44
  Download:: http://rubyforge.org/project/showfiles.php?group_id=50
45
- GitHub:: git://github.com/jimweirich/rake.git
45
+ GitHub:: git://github.com/jimweirich/rake.git
46
46
 
47
47
  == Thanks
48
48
 
@@ -0,0 +1,112 @@
1
+ = Rake 0.9.0 Released
2
+
3
+ Rake version 0.9.0 has a number of bug fixes and enhancments (see
4
+ below for more details). Additionally, the internals have be slightly
5
+ restructured and improved.
6
+
7
+ == Changes
8
+
9
+ === New Features / Enhancements / Bug Fixes in Version 0.9.0
10
+
11
+ * Rake now warns when the deprecated :needs syntax used (and suggests
12
+ the proper syntax in the warning).
13
+
14
+ * Moved Rake DSL commands to top level ruby object 'main'. Rake DSL
15
+ commands are no longer private methods in Object. (Suggested by
16
+ James M. Lawrence/quix)
17
+
18
+ * Rake now uses case-insensitive comparisons to find the Rakefile on Windows.
19
+ Based on patch by Roger Pack.
20
+
21
+ * Rake now requires (instead of loads) files in the test task. Patch by Cezary
22
+ Baginski.
23
+
24
+ * Fixed typos. Patches by Sean Scot August Moon and R.T. Lechow.
25
+
26
+ * Rake now prints the Rakefile directory only when it's different from the
27
+ current directory. Patch by Alex Chaffee.
28
+
29
+ * Improved rakefile_location discovery on Windows. Patch by James Tucker.
30
+
31
+ * Rake now recognizes "Windows Server" as a windows system. Patch by Matthias
32
+ Lüdtke
33
+
34
+ * Rake::RDocTask is deprecated. Use RDoc::Task from RDoc 2.4.2+ (require
35
+ 'rdoc/task')
36
+
37
+ * Rake::GemPackageTask is deprecated. Use Gem::PackageTask (require
38
+ 'rubygems/package_task')
39
+
40
+ * Rake now outputs various messages to $stderr instead of $stdout.
41
+
42
+ * Rake no longer emits warnings for Config. Patch by Santiago Pastorino.
43
+
44
+ * Removed Rake's DSL methods from the top level scope. If you need to
45
+ call 'task :xzy' in your code, include Rake::DSL into your class, or
46
+ put the code in a Rake::DSL.environment do ... end block.
47
+
48
+ * Split rake.rb into individual files.
49
+
50
+ * Support for the --where (-W) flag for showing where a task is defined.
51
+
52
+ * Fixed quoting in test task.
53
+ (http://onestepback.org/redmine/issues/show/44,
54
+ http://www.pivotaltracker.com/story/show/1223138)
55
+
56
+ * Fixed the silent option parsing problem.
57
+ (http://onestepback.org/redmine/issues/show/47)
58
+
59
+ * Fixed :verbose=>false flag on sh and ruby commands.
60
+
61
+ * Rake command line options may be given by default in a RAKEOPT
62
+ environment variable.
63
+
64
+ * Errors in Rake will now display the task invocation chain in effect
65
+ at the time of the error.
66
+
67
+ * Accepted change by warnickr to not expand test patterns in shell
68
+ (allowing more files in the test suite).
69
+
70
+ * Fixed that file tasks did not perform prereq lookups in scope
71
+ (Redmine #57).
72
+
73
+ == What is Rake
74
+
75
+ Rake is a build tool similar to the make program in many ways. But
76
+ instead of cryptic make recipes, Rake uses standard Ruby code to
77
+ declare tasks and dependencies. You have the full power of a modern
78
+ scripting language built right into your build tool.
79
+
80
+ == Availability
81
+
82
+ The easiest way to get and install rake is via RubyGems ...
83
+
84
+ gem install rake (you may need root/admin privileges)
85
+
86
+ Otherwise, you can get it from the more traditional places:
87
+
88
+ Home Page:: http://rake.rubyforge.org/
89
+ Download:: http://rubyforge.org/project/showfiles.php?group_id=50
90
+ GitHub:: git://github.com/jimweirich/rake.git
91
+
92
+ == Thanks
93
+
94
+ As usual, it was input from users that drove a alot of these changes. The
95
+ following people either contributed patches, made suggestions or made
96
+ otherwise helpful comments. Thanks to ...
97
+
98
+ * James M. Lawrence (quix)
99
+ * Roger Pack
100
+ * Cezary Baginski
101
+ * Sean Scot August Moon
102
+ * R.T. Lechow
103
+ * Alex Chaffee
104
+ * James Tucker
105
+ * Matthias Lüdtke
106
+ * Santiago Pastorino
107
+
108
+ Also, bit thanks to Eric Hodel for assisting with getting this release
109
+ out the door (where "assisting" includes, but is not by any means
110
+ limited to, "pushing" me to get it done).
111
+
112
+ -- Jim Weirich
data/install.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  require 'rbconfig'
2
2
  require 'find'
3
- require 'ftools'
3
+ require 'fileutils'
4
4
 
5
- include Config
5
+ include RbConfig
6
6
 
7
7
  $ruby = CONFIG['ruby_install_name']
8
8
 
@@ -27,7 +27,7 @@ def installBIN(from, opfile)
27
27
 
28
28
  fail "Cannot find a temporary directory" unless tmp_dir
29
29
  tmp_file = File.join(tmp_dir, "_tmp")
30
-
30
+
31
31
  File.open(from) do |ip|
32
32
  File.open(tmp_file, "w") do |op|
33
33
  ruby = File.join($realbindir, $ruby)
@@ -37,8 +37,9 @@ def installBIN(from, opfile)
37
37
  end
38
38
 
39
39
  opfile += ".rb" if CONFIG["target_os"] =~ /mswin/i
40
- File::install(tmp_file, File.join($bindir, opfile), 0755, true)
41
- File::unlink(tmp_file)
40
+ FileUtils.install(tmp_file, File.join($bindir, opfile),
41
+ {:mode => 0755, :verbose => true})
42
+ File.unlink(tmp_file)
42
43
  end
43
44
 
44
45
  $sitedir = CONFIG["sitelibdir"]
@@ -61,14 +62,14 @@ bindir = CONFIG["bindir"]
61
62
  if (destdir = ENV['DESTDIR'])
62
63
  $bindir = destdir + $bindir
63
64
  $sitedir = destdir + $sitedir
64
-
65
- File::makedirs($bindir)
66
- File::makedirs($sitedir)
65
+
66
+ FileUtils.mkdir_p($bindir)
67
+ FileUtils.mkdir_p($sitedir)
67
68
  end
68
69
 
69
70
  rake_dest = File.join($sitedir, "rake")
70
- File::makedirs(rake_dest, true)
71
- File::chmod(0755, rake_dest)
71
+ FileUtils.mkdir_p(rake_dest, {:verbose => true})
72
+ File.chmod(0755, rake_dest)
72
73
 
73
74
  # The library files
74
75
 
@@ -78,9 +79,10 @@ for fn in files
78
79
  fn_dir = File.dirname(fn)
79
80
  target_dir = File.join($sitedir, fn_dir)
80
81
  if ! File.exist?(target_dir)
81
- File.makedirs(target_dir)
82
+ FileUtils.mkdir_p(target_dir)
82
83
  end
83
- File::install(File.join('lib', fn), File.join($sitedir, fn), 0644, true)
84
+ FileUtils.install(File.join('lib', fn), File.join($sitedir, fn),
85
+ {:mode => 0644, :verbose => true})
84
86
  end
85
87
 
86
88
  # and the executable
data/lib/rake.rb CHANGED
@@ -1,8 +1,8 @@
1
- #!/usr/bin/env ruby
2
-
3
1
  #--
4
2
 
5
- # Copyright 2003, 2004, 2005, 2006, 2007, 2008 by Jim Weirich (jim@weirichhouse.org)
3
+ # Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com)
4
+ #
5
+ # Copyright 2008-2011 by James M. Lawrence (quixoticsycophant@gmail.com)
6
6
  #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  # of this software and associated documentation files (the "Software"), to
@@ -22,14 +22,10 @@
22
22
  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23
23
  # IN THE SOFTWARE.
24
24
  #++
25
- #
26
- # = Rake -- Ruby Make
27
- #
28
- # This is the main file for the Rake application. Normally it is referenced
29
- # as a library via a require statement, but it can be distributed
30
- # independently as an application.
31
25
 
32
- RAKEVERSION = '0.8.7.0.2.4'
26
+ require 'rake/version'
27
+
28
+ RAKEVERSION = Rake::VERSION
33
29
 
34
30
  require 'rbconfig'
35
31
  require 'fileutils'
@@ -38,2526 +34,34 @@ require 'monitor'
38
34
  require 'optparse'
39
35
  require 'ostruct'
40
36
 
41
- require 'rake/win32'
42
-
43
- $trace = false
44
-
45
- ######################################################################
46
- # Rake extensions to Module.
47
- #
48
- class Module
49
- # Check for an existing method in the current class before extending. IF
50
- # the method already exists, then a warning is printed and the extension is
51
- # not added. Otherwise the block is yielded and any definitions in the
52
- # block will take effect.
53
- #
54
- # Usage:
55
- #
56
- # class String
57
- # rake_extension("xyz") do
58
- # def xyz
59
- # ...
60
- # end
61
- # end
62
- # end
63
- #
64
- def rake_extension(method)
65
- if method_defined?(method)
66
- $stderr.puts "WARNING: Possible conflict with Rake extension: #{self}##{method} already exists"
67
- else
68
- yield
69
- end
70
- end
71
- end # module Module
72
-
73
-
74
- ######################################################################
75
- # User defined methods to be added to String.
76
- #
77
- class String
78
- rake_extension("ext") do
79
- # Replace the file extension with +newext+. If there is no extension on
80
- # the string, append the new extension to the end. If the new extension
81
- # is not given, or is the empty string, remove any existing extension.
82
- #
83
- # +ext+ is a user added method for the String class.
84
- def ext(newext='')
85
- return self.dup if ['.', '..'].include? self
86
- if newext != ''
87
- newext = (newext =~ /^\./) ? newext : ("." + newext)
88
- end
89
- self.chomp(File.extname(self)) << newext
90
- end
91
- end
92
-
93
- rake_extension("pathmap") do
94
- # Explode a path into individual components. Used by +pathmap+.
95
- def pathmap_explode
96
- head, tail = File.split(self)
97
- return [self] if head == self
98
- return [tail] if head == '.' || tail == '/'
99
- return [head, tail] if head == '/'
100
- return head.pathmap_explode + [tail]
101
- end
102
- protected :pathmap_explode
103
-
104
- # Extract a partial path from the path. Include +n+ directories from the
105
- # front end (left hand side) if +n+ is positive. Include |+n+|
106
- # directories from the back end (right hand side) if +n+ is negative.
107
- def pathmap_partial(n)
108
- dirs = File.dirname(self).pathmap_explode
109
- partial_dirs =
110
- if n > 0
111
- dirs[0...n]
112
- elsif n < 0
113
- dirs.reverse[0...-n].reverse
114
- else
115
- "."
116
- end
117
- File.join(partial_dirs)
118
- end
119
- protected :pathmap_partial
120
-
121
- # Preform the pathmap replacement operations on the given path. The
122
- # patterns take the form 'pat1,rep1;pat2,rep2...'.
123
- def pathmap_replace(patterns, &block)
124
- result = self
125
- patterns.split(';').each do |pair|
126
- pattern, replacement = pair.split(',')
127
- pattern = Regexp.new(pattern)
128
- if replacement == '*' && block_given?
129
- result = result.sub(pattern, &block)
130
- elsif replacement
131
- result = result.sub(pattern, replacement)
132
- else
133
- result = result.sub(pattern, '')
134
- end
135
- end
136
- result
137
- end
138
- protected :pathmap_replace
139
-
140
- # Map the path according to the given specification. The specification
141
- # controls the details of the mapping. The following special patterns are
142
- # recognized:
143
- #
144
- # * <b>%p</b> -- The complete path.
145
- # * <b>%f</b> -- The base file name of the path, with its file extension,
146
- # but without any directories.
147
- # * <b>%n</b> -- The file name of the path without its file extension.
148
- # * <b>%d</b> -- The directory list of the path.
149
- # * <b>%x</b> -- The file extension of the path. An empty string if there
150
- # is no extension.
151
- # * <b>%X</b> -- Everything *but* the file extension.
152
- # * <b>%s</b> -- The alternate file separater if defined, otherwise use
153
- # the standard file separator.
154
- # * <b>%%</b> -- A percent sign.
155
- #
156
- # The %d specifier can also have a numeric prefix (e.g. '%2d'). If the
157
- # number is positive, only return (up to) +n+ directories in the path,
158
- # starting from the left hand side. If +n+ is negative, return (up to)
159
- # |+n+| directories from the right hand side of the path.
160
- #
161
- # Examples:
162
- #
163
- # 'a/b/c/d/file.txt'.pathmap("%2d") => 'a/b'
164
- # 'a/b/c/d/file.txt'.pathmap("%-2d") => 'c/d'
165
- #
166
- # Also the %d, %p, %f, %n, %x, and %X operators can take a
167
- # pattern/replacement argument to perform simple string substititions on a
168
- # particular part of the path. The pattern and replacement are speparated
169
- # by a comma and are enclosed by curly braces. The replacement spec comes
170
- # after the % character but before the operator letter. (e.g.
171
- # "%{old,new}d"). Muliple replacement specs should be separated by
172
- # semi-colons (e.g. "%{old,new;src,bin}d").
173
- #
174
- # Regular expressions may be used for the pattern, and back refs may be
175
- # used in the replacement text. Curly braces, commas and semi-colons are
176
- # excluded from both the pattern and replacement text (let's keep parsing
177
- # reasonable).
178
- #
179
- # For example:
180
- #
181
- # "src/org/onestepback/proj/A.java".pathmap("%{^src,bin}X.class")
182
- #
183
- # returns:
184
- #
185
- # "bin/org/onestepback/proj/A.class"
186
- #
187
- # If the replacement text is '*', then a block may be provided to perform
188
- # some arbitrary calculation for the replacement.
189
- #
190
- # For example:
191
- #
192
- # "/path/to/file.TXT".pathmap("%X%{.*,*}x") { |ext|
193
- # ext.downcase
194
- # }
195
- #
196
- # Returns:
197
- #
198
- # "/path/to/file.txt"
199
- #
200
- def pathmap(spec=nil, &block)
201
- return self if spec.nil?
202
- result = ''
203
- spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag|
204
- case frag
205
- when '%f'
206
- result << File.basename(self)
207
- when '%n'
208
- result << File.basename(self).ext
209
- when '%d'
210
- result << File.dirname(self)
211
- when '%x'
212
- result << File.extname(self)
213
- when '%X'
214
- result << self.ext
215
- when '%p'
216
- result << self
217
- when '%s'
218
- result << (File::ALT_SEPARATOR || File::SEPARATOR)
219
- when '%-'
220
- # do nothing
221
- when '%%'
222
- result << "%"
223
- when /%(-?\d+)d/
224
- result << pathmap_partial($1.to_i)
225
- when /^%\{([^}]*)\}(\d*[dpfnxX])/
226
- patterns, operator = $1, $2
227
- result << pathmap('%' + operator).pathmap_replace(patterns, &block)
228
- when /^%/
229
- fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'"
230
- else
231
- result << frag
232
- end
233
- end
234
- result
235
- end
236
- end
237
- end # class String
238
-
239
- ##############################################################################
240
- module Rake
241
-
242
- # Errors -----------------------------------------------------------
243
-
244
- # Error indicating an ill-formed task declaration.
245
- class TaskArgumentError < ArgumentError
246
- end
247
-
248
- # Error indicating a recursion overflow error in task selection.
249
- class RuleRecursionOverflowError < StandardError
250
- def initialize(*args)
251
- super
252
- @targets = []
253
- end
254
-
255
- def add_target(target)
256
- @targets << target
257
- end
258
-
259
- def message
260
- super + ": [" + @targets.reverse.join(' => ') + "]"
261
- end
262
- end
263
-
264
- # --------------------------------------------------------------------------
265
- # Rake module singleton methods.
266
- #
267
- class << self
268
- # Current Rake Application
269
- def application
270
- @application ||= Rake::Application.new
271
- end
272
-
273
- # Set the current Rake application object.
274
- def application=(app)
275
- @application = app
276
- end
277
-
278
- # Return the original directory where the Rake application was started.
279
- def original_dir
280
- application.original_dir
281
- end
282
-
283
- end
284
-
285
- ####################################################################
286
- # Mixin for creating easily cloned objects.
287
- #
288
- module Cloneable
289
- # Clone an object by making a new object and setting all the instance
290
- # variables to the same values.
291
- def dup
292
- sibling = self.class.new
293
- instance_variables.each do |ivar|
294
- value = self.instance_variable_get(ivar)
295
- new_value = value.clone rescue value
296
- sibling.instance_variable_set(ivar, new_value)
297
- end
298
- sibling.taint if tainted?
299
- sibling
300
- end
301
-
302
- def clone
303
- sibling = dup
304
- sibling.freeze if frozen?
305
- sibling
306
- end
307
- end
308
-
309
- ####################################################################
310
- # Exit status class for times the system just gives us a nil.
311
- class PseudoStatus
312
- attr_reader :exitstatus
313
- def initialize(code=0)
314
- @exitstatus = code
315
- end
316
- def to_i
317
- @exitstatus << 8
318
- end
319
- def >>(n)
320
- to_i >> n
321
- end
322
- def stopped?
323
- false
324
- end
325
- def exited?
326
- true
327
- end
328
- end
329
-
330
- ####################################################################
331
- # TaskAguments manage the arguments passed to a task.
332
- #
333
- class TaskArguments
334
- include Enumerable
335
-
336
- attr_reader :names
337
-
338
- # Create a TaskArgument object with a list of named arguments
339
- # (given by :names) and a set of associated values (given by
340
- # :values). :parent is the parent argument object.
341
- def initialize(names, values, parent=nil)
342
- @names = names
343
- @parent = parent
344
- @hash = {}
345
- names.each_with_index { |name, i|
346
- @hash[name.to_sym] = values[i] unless values[i].nil?
347
- }
348
- end
349
-
350
- # Create a new argument scope using the prerequisite argument
351
- # names.
352
- def new_scope(names)
353
- values = names.collect { |n| self[n] }
354
- self.class.new(names, values, self)
355
- end
356
-
357
- # Find an argument value by name or index.
358
- def [](index)
359
- lookup(index.to_sym)
360
- end
361
-
362
- # Specify a hash of default values for task arguments. Use the
363
- # defaults only if there is no specific value for the given
364
- # argument.
365
- def with_defaults(defaults)
366
- @hash = defaults.merge(@hash)
367
- end
368
-
369
- def each(&block)
370
- @hash.each(&block)
371
- end
372
-
373
- def method_missing(sym, *args, &block)
374
- lookup(sym.to_sym)
375
- end
376
-
377
- def to_hash
378
- @hash
379
- end
380
-
381
- def to_s
382
- @hash.inspect
383
- end
384
-
385
- def inspect
386
- to_s
387
- end
388
-
389
- protected
390
-
391
- def lookup(name)
392
- if @hash.has_key?(name)
393
- @hash[name]
394
- elsif ENV.has_key?(name.to_s)
395
- ENV[name.to_s]
396
- elsif ENV.has_key?(name.to_s.upcase)
397
- ENV[name.to_s.upcase]
398
- elsif @parent
399
- @parent.lookup(name)
400
- end
401
- end
402
- end
403
-
404
- EMPTY_TASK_ARGS = TaskArguments.new([], [])
405
-
406
- ####################################################################
407
- # InvocationChain tracks the chain of task invocations to detect
408
- # circular dependencies.
409
- class InvocationChain
410
- attr_reader :value # :nodoc:
411
-
412
- def initialize(value, tail)
413
- @value = value
414
- @tail = tail
415
- end
416
-
417
- def member?(obj)
418
- @value == obj || @tail.member?(obj)
419
- end
420
-
421
- def append(value)
422
- if member?(value)
423
- fail RuntimeError, "Circular dependency detected: #{to_s} => #{value}"
424
- end
425
- self.class.new(value, self)
426
- end
427
-
428
- def to_s
429
- "#{prefix}#{@value}"
430
- end
431
-
432
- def self.append(value, chain)
433
- chain.append(value)
434
- end
435
-
436
- private
437
-
438
- def prefix
439
- "#{@tail.to_s} => "
440
- end
441
-
442
- class EmptyInvocationChain
443
- def member?(obj)
444
- false
445
- end
446
- def append(value)
447
- InvocationChain.new(value, self)
448
- end
449
- def to_s
450
- "TOP"
451
- end
452
- end
453
-
454
- EMPTY = EmptyInvocationChain.new
455
-
456
- end # class InvocationChain
457
-
458
- end # module Rake
459
-
460
- module Rake
461
-
462
- ###########################################################################
463
- # A Task is the basic unit of work in a Rakefile. Tasks have associated
464
- # actions (possibly more than one) and a list of prerequisites. When
465
- # invoked, a task will first ensure that all of its prerequisites have an
466
- # opportunity to run and then it will execute its own actions.
467
- #
468
- # Tasks are not usually created directly using the new method, but rather
469
- # use the +file+ and +task+ convenience methods.
470
- #
471
- class Task
472
- # List of prerequisites for a task.
473
- attr_reader :prerequisites
474
-
475
- # List of actions attached to a task.
476
- attr_reader :actions
477
-
478
- # Application owning this task.
479
- attr_accessor :application
480
-
481
- # Comment for this task. Restricted to a single line of no more than 50
482
- # characters.
483
- attr_reader :comment
484
-
485
- # Full text of the (possibly multi-line) comment.
486
- attr_reader :full_comment
487
-
488
- # Array of nested namespaces names used for task lookup by this task.
489
- attr_reader :scope
490
-
491
- # Return task name
492
- def to_s
493
- name
494
- end
495
-
496
- def inspect
497
- "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>"
498
- end
499
-
500
- # List of sources for task.
501
- attr_writer :sources
502
- def sources
503
- @sources ||= []
504
- end
505
-
506
- # First source from a rule (nil if no sources)
507
- def source
508
- @sources.first if defined?(@sources)
509
- end
510
-
511
- # Create a task named +task_name+ with no actions or prerequisites. Use
512
- # +enhance+ to add actions and prerequisites.
513
- def initialize(task_name, app)
514
- @name = task_name.to_s
515
- @prerequisites = []
516
- @actions = []
517
- @already_invoked = false
518
- @full_comment = nil
519
- @comment = nil
520
- @lock = Monitor.new
521
- @application = app
522
- @scope = app.current_scope
523
- @arg_names = nil
524
- end
525
-
526
- # Enhance a task with prerequisites or actions. Returns self.
527
- def enhance(deps=nil, &block)
528
- @prerequisites |= deps if deps
529
- @actions << block if block_given?
530
- self
531
- end
532
-
533
- # Name of the task, including any namespace qualifiers.
534
- def name
535
- @name.to_s
536
- end
537
-
538
- # Name of task with argument list description.
539
- def name_with_args # :nodoc:
540
- if arg_description
541
- "#{name}#{arg_description}"
542
- else
543
- name
544
- end
545
- end
546
-
547
- # Argument description (nil if none).
548
- def arg_description # :nodoc:
549
- @arg_names ? "[#{(arg_names || []).join(',')}]" : nil
550
- end
551
-
552
- # Name of arguments for this task.
553
- def arg_names
554
- @arg_names || []
555
- end
556
-
557
- # Reenable the task, allowing its tasks to be executed if the task
558
- # is invoked again.
559
- def reenable
560
- @already_invoked = false
561
- end
562
-
563
- # Clear the existing prerequisites and actions of a rake task.
564
- def clear
565
- clear_prerequisites
566
- clear_actions
567
- self
568
- end
569
-
570
- # Clear the existing prerequisites of a rake task.
571
- def clear_prerequisites
572
- prerequisites.clear
573
- self
574
- end
575
-
576
- # Clear the existing actions on a rake task.
577
- def clear_actions
578
- actions.clear
579
- self
580
- end
581
-
582
- def invoke_serial(*args) # :nodoc:
583
- task_args = TaskArguments.new(arg_names, args)
584
- invoke_with_call_chain(task_args, InvocationChain::EMPTY)
585
- end
586
-
587
- # Invoke the task if it is needed. Prerequites are invoked first.
588
- def invoke(*args)
589
- if application.options.threads == 1
590
- invoke_serial(*args)
591
- else
592
- invoke_parallel(*args)
593
- end
594
- end
595
-
596
- # Same as invoke, but explicitly pass a call chain to detect
597
- # circular dependencies.
598
- def invoke_with_call_chain(task_args, invocation_chain) # :nodoc:
599
- new_chain = InvocationChain.append(self, invocation_chain)
600
- if application.options.threads == 1
601
- @lock.synchronize do
602
- return unless prepare_invoke
603
- invoke_prerequisites(task_args, new_chain)
604
- execute(task_args) if needed?
605
- end
606
- else
607
- return unless prepare_invoke
608
- invoke_with_call_chain_collector(task_args, new_chain, invocation_chain)
609
- end
610
- end
611
- protected :invoke_with_call_chain
612
-
613
- def prepare_invoke # :nodoc:
614
- if application.options.randomize
615
- @prerequisites = @prerequisites.sort_by { rand }
616
- end
617
- if application.options.trace
618
- puts "** Invoke #{name} #{format_trace_flags}"
619
- end
620
- return if @already_invoked
621
- @already_invoked = true
622
- end
623
-
624
- # Invoke all the prerequisites of a task.
625
- def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
626
- @prerequisites.each { |n|
627
- invoke_prerequisite(n, task_args, invocation_chain)
628
- }
629
- end
630
-
631
- def invoke_prerequisite(prereq_name, task_args, invocation_chain) #:nodoc:
632
- prereq = application[prereq_name, @scope]
633
- prereq_args = task_args.new_scope(prereq.arg_names)
634
- prereq.invoke_with_call_chain(prereq_args, invocation_chain)
635
- prereq
636
- end
637
-
638
- # Format the trace flags for display.
639
- def format_trace_flags
640
- flags = []
641
- flags << "first_time" unless @already_invoked
642
- flags << "not_needed" unless needed?
643
- flags.empty? ? "" : "(" + flags.join(", ") + ")"
644
- end
645
- private :format_trace_flags
646
-
647
- # Execute the actions associated with this task.
648
- def execute(args=nil)
649
- args ||= EMPTY_TASK_ARGS
650
- if application.options.dryrun
651
- puts "** Execute (dry run) #{name}"
652
- return
653
- end
654
- if application.options.trace
655
- puts "** Execute #{name}"
656
- end
657
- application.enhance_with_matching_rule(name) if @actions.empty?
658
- @actions.each do |act|
659
- case act.arity
660
- when 1
661
- act.call(self)
662
- else
663
- act.call(self, args)
664
- end
665
- end
666
- end
667
-
668
- # Is this task needed?
669
- def needed?
670
- true
671
- end
672
-
673
- # Timestamp for this task. Basic tasks return the current time for their
674
- # time stamp. Other tasks can be more sophisticated.
675
- def timestamp
676
- @prerequisites.collect { |p| application[p].timestamp }.max || Time.now
677
- end
678
-
679
- # Add a description to the task. The description can consist of an option
680
- # argument list (enclosed brackets) and an optional comment.
681
- def add_description(description)
682
- return if ! description
683
- comment = description.strip
684
- add_comment(comment) if comment && ! comment.empty?
685
- end
686
-
687
- # Writing to the comment attribute is the same as adding a description.
688
- def comment=(description)
689
- add_description(description)
690
- end
691
-
692
- # Add a comment to the task. If a comment alread exists, separate
693
- # the new comment with " / ".
694
- def add_comment(comment)
695
- if @full_comment
696
- @full_comment << " / "
697
- else
698
- @full_comment = ''
699
- end
700
- @full_comment << comment
701
- if @full_comment =~ /\A([^.]+?\.)( |$)/
702
- @comment = $1
703
- else
704
- @comment = @full_comment
705
- end
706
- end
707
- private :add_comment
708
-
709
- # Set the names of the arguments for this task. +args+ should be
710
- # an array of symbols, one for each argument name.
711
- def set_arg_names(args)
712
- @arg_names = args.map { |a| a.to_sym }
713
- end
714
-
715
- # Return a string describing the internal state of a task. Useful for
716
- # debugging.
717
- def investigation
718
- result = "------------------------------\n"
719
- result << "Investigating #{name}\n"
720
- result << "class: #{self.class}\n"
721
- result << "task needed: #{needed?}\n"
722
- result << "timestamp: #{timestamp}\n"
723
- result << "pre-requisites: \n"
724
- prereqs = @prerequisites.collect {|name| application[name]}
725
- prereqs.sort! {|a,b| a.timestamp <=> b.timestamp}
726
- prereqs.each do |p|
727
- result << "--#{p.name} (#{p.timestamp})\n"
728
- end
729
- latest_prereq = @prerequisites.collect{|n| application[n].timestamp}.max
730
- result << "latest-prerequisite time: #{latest_prereq}\n"
731
- result << "................................\n\n"
732
- return result
733
- end
734
-
735
- # ----------------------------------------------------------------
736
- # Rake Module Methods
737
- #
738
- class << self
739
-
740
- # Clear the task list. This cause rake to immediately forget all the
741
- # tasks that have been assigned. (Normally used in the unit tests.)
742
- def clear
743
- Rake.application.clear
744
- end
745
-
746
- # List of all defined tasks.
747
- def tasks
748
- Rake.application.tasks
749
- end
750
-
751
- # Return a task with the given name. If the task is not currently
752
- # known, try to synthesize one from the defined rules. If no rules are
753
- # found, but an existing file matches the task name, assume it is a file
754
- # task with no dependencies or actions.
755
- def [](task_name)
756
- Rake.application[task_name]
757
- end
758
-
759
- # TRUE if the task name is already defined.
760
- def task_defined?(task_name)
761
- Rake.application.lookup(task_name) != nil
762
- end
763
-
764
- # Define a task given +args+ and an option block. If a rule with the
765
- # given name already exists, the prerequisites and actions are added to
766
- # the existing task. Returns the defined task.
767
- def define_task(*args, &block)
768
- Rake.application.define_task(self, *args, &block)
769
- end
770
-
771
- # Define a rule for synthesizing tasks.
772
- def create_rule(*args, &block)
773
- Rake.application.create_rule(*args, &block)
774
- end
775
-
776
- # Apply the scope to the task name according to the rules for
777
- # this kind of task. Generic tasks will accept the scope as
778
- # part of the name.
779
- def scope_name(scope, task_name)
780
- (scope + [task_name]).join(':')
781
- end
782
-
783
- end # class << Rake::Task
784
- end # class Rake::Task
785
-
786
-
787
- ###########################################################################
788
- # A FileTask is a task that includes time based dependencies. If any of a
789
- # FileTask's prerequisites have a timestamp that is later than the file
790
- # represented by this task, then the file must be rebuilt (using the
791
- # supplied actions).
792
- #
793
- class FileTask < Task
794
-
795
- # Is this file task needed? Yes if it doesn't exist, or if its time stamp
796
- # is out of date.
797
- def needed?
798
- ! File.exist?(name) || out_of_date?(timestamp)
799
- end
800
-
801
- # Time stamp for file task.
802
- def timestamp
803
- if File.exist?(name)
804
- File.mtime(name.to_s)
805
- else
806
- Rake::EARLY
807
- end
808
- end
809
-
810
- private
811
-
812
- # Are there any prerequisites with a later time than the given time stamp?
813
- def out_of_date?(stamp)
814
- @prerequisites.any? { |n| application[n].timestamp > stamp}
815
- end
816
-
817
- # ----------------------------------------------------------------
818
- # Task class methods.
819
- #
820
- class << self
821
- # Apply the scope to the task name according to the rules for this kind
822
- # of task. File based tasks ignore the scope when creating the name.
823
- def scope_name(scope, task_name)
824
- task_name
825
- end
826
- end
827
- end # class Rake::FileTask
828
-
829
- ###########################################################################
830
- # A FileCreationTask is a file task that when used as a dependency will be
831
- # needed if and only if the file has not been created. Once created, it is
832
- # not re-triggered if any of its dependencies are newer, nor does trigger
833
- # any rebuilds of tasks that depend on it whenever it is updated.
834
- #
835
- class FileCreationTask < FileTask
836
- # Is this file task needed? Yes if it doesn't exist.
837
- def needed?
838
- ! File.exist?(name)
839
- end
840
-
841
- # Time stamp for file creation task. This time stamp is earlier
842
- # than any other time stamp.
843
- def timestamp
844
- Rake::EARLY
845
- end
846
- end
847
-
848
- ###########################################################################
849
- # Same as a regular task, but the immediate prerequisites are done in
850
- # parallel using Ruby threads.
851
- #
852
- class MultiTask < Task
853
- private
854
- def invoke_prerequisites(args, invocation_chain)
855
- threads = @prerequisites.collect { |p|
856
- Thread.new(p) { |r| application[r].invoke_with_call_chain(args, invocation_chain) }
857
- }
858
- threads.each { |t| t.join }
859
- end
860
- end
861
- end # module Rake
862
-
863
- ## ###########################################################################
864
- # Task Definition Functions ...
865
-
866
- # Declare a basic task.
867
- #
868
- # Example:
869
- # task :clobber => [:clean] do
870
- # rm_rf "html"
871
- # end
872
- #
873
- def task(*args, &block)
874
- Rake::Task.define_task(*args, &block)
875
- end
876
-
877
-
878
- # Declare a file task.
879
- #
880
- # Example:
881
- # file "config.cfg" => ["config.template"] do
882
- # open("config.cfg", "w") do |outfile|
883
- # open("config.template") do |infile|
884
- # while line = infile.gets
885
- # outfile.puts line
886
- # end
887
- # end
888
- # end
889
- # end
890
- #
891
- def file(*args, &block)
892
- Rake::FileTask.define_task(*args, &block)
893
- end
894
-
895
- # Declare a file creation task.
896
- # (Mainly used for the directory command).
897
- def file_create(args, &block)
898
- Rake::FileCreationTask.define_task(args, &block)
899
- end
900
-
901
- # Declare a set of files tasks to create the given directories on demand.
902
- #
903
- # Example:
904
- # directory "testdata/doc"
905
- #
906
- def directory(dir)
907
- Rake.each_dir_parent(dir) do |d|
908
- file_create d do |t|
909
- mkdir_p t.name if ! File.exist?(t.name)
910
- end
911
- end
912
- end
913
-
914
- # Declare a task that performs its prerequisites in parallel. Multitasks does
915
- # *not* guarantee that its prerequisites will execute in any given order
916
- # (which is obvious when you think about it)
917
- #
918
- # Example:
919
- # multitask :deploy => [:deploy_gem, :deploy_rdoc]
920
- #
921
- def multitask(args, &block)
922
- Rake::MultiTask.define_task(args, &block)
923
- end
924
-
925
- # Create a new rake namespace and use it for evaluating the given block.
926
- # Returns a NameSpace object that can be used to lookup tasks defined in the
927
- # namespace.
928
- #
929
- # E.g.
930
- #
931
- # ns = namespace "nested" do
932
- # task :run
933
- # end
934
- # task_run = ns[:run] # find :run in the given namespace.
935
- #
936
- def namespace(name=nil, &block)
937
- Rake.application.in_namespace(name, &block)
938
- end
939
-
940
- # Declare a rule for auto-tasks.
941
- #
942
- # Example:
943
- # rule '.o' => '.c' do |t|
944
- # sh %{cc -o #{t.name} #{t.source}}
945
- # end
946
- #
947
- def rule(*args, &block)
948
- Rake::Task.create_rule(*args, &block)
949
- end
950
-
951
- # Describe the next rake task.
952
- #
953
- # Example:
954
- # desc "Run the Unit Tests"
955
- # task :test => [:build]
956
- # runtests
957
- # end
958
- #
959
- def desc(description)
960
- Rake.application.last_description = description
961
- end
962
-
963
- # Import the partial Rakefiles +fn+. Imported files are loaded _after_ the
964
- # current file is completely loaded. This allows the import statement to
965
- # appear anywhere in the importing file, and yet allowing the imported files
966
- # to depend on objects defined in the importing file.
967
- #
968
- # A common use of the import statement is to include files containing
969
- # dependency declarations.
970
- #
971
- # See also the --rakelibdir command line option.
972
- #
973
- # Example:
974
- # import ".depend", "my_rules"
975
- #
976
- def import(*fns)
977
- fns.each do |fn|
978
- Rake.application.add_import(fn)
979
- end
980
- end
981
-
982
- #############################################################################
983
- # This a FileUtils extension that defines several additional commands to be
984
- # added to the FileUtils utility functions.
985
- #
986
- module FileUtils
987
- RUBY_EXT = ((Config::CONFIG['ruby_install_name'] =~ /\.(com|cmd|exe|bat|rb|sh)$/) ?
988
- "" :
989
- Config::CONFIG['EXEEXT'])
990
-
991
- RUBY = File.join(
992
- Config::CONFIG['bindir'],
993
- Config::CONFIG['ruby_install_name'] + RUBY_EXT).
994
- sub(/.*\s.*/m, '"\&"')
995
-
996
- OPT_TABLE['sh'] = %w(noop verbose)
997
- OPT_TABLE['ruby'] = %w(noop verbose)
998
-
999
- # Run the system command +cmd+. If multiple arguments are given the command
1000
- # is not run with the shell (same semantics as Kernel::exec and
1001
- # Kernel::system).
1002
- #
1003
- # Example:
1004
- # sh %{ls -ltr}
1005
- #
1006
- # sh 'ls', 'file with spaces'
1007
- #
1008
- # # check exit status after command runs
1009
- # sh %{grep pattern file} do |ok, res|
1010
- # if ! ok
1011
- # puts "pattern not found (status = #{res.exitstatus})"
1012
- # end
1013
- # end
1014
- #
1015
- def sh(*cmd, &block)
1016
- options = (Hash === cmd.last) ? cmd.pop : {}
1017
- unless block_given?
1018
- show_command = cmd.join(" ")
1019
- show_command = show_command[0,42] + "..." unless $trace
1020
- # TODO code application logic heref show_command.length > 45
1021
- block = lambda { |ok, status|
1022
- ok or fail "Command failed with status (#{status.exitstatus}): [#{show_command}]"
1023
- }
1024
- end
1025
- if RakeFileUtils.verbose_flag == :default
1026
- options[:verbose] = true
1027
- else
1028
- options[:verbose] ||= RakeFileUtils.verbose_flag
1029
- end
1030
- options[:noop] ||= RakeFileUtils.nowrite_flag
1031
- rake_check_options options, :noop, :verbose
1032
- rake_output_message cmd.join(" ") if options[:verbose]
1033
- unless options[:noop]
1034
- res = rake_system(*cmd)
1035
- status = $?
1036
- status = PseudoStatus.new(1) if !res && status.nil?
1037
- block.call(res, status)
1038
- end
1039
- end
1040
-
1041
- def rake_system(*cmd)
1042
- Rake::AltSystem.system(*cmd)
1043
- end
1044
- private :rake_system
1045
-
1046
- # Run a Ruby interpreter with the given arguments.
1047
- #
1048
- # Example:
1049
- # ruby %{-pe '$_.upcase!' <README}
1050
- #
1051
- def ruby(*args,&block)
1052
- options = (Hash === args.last) ? args.pop : {}
1053
- if args.length > 1 then
1054
- sh(*([RUBY] + args + [options]), &block)
1055
- else
1056
- sh("#{RUBY} #{args.first}", options, &block)
1057
- end
1058
- end
1059
-
1060
- LN_SUPPORTED = [true]
1061
-
1062
- # Attempt to do a normal file link, but fall back to a copy if the link
1063
- # fails.
1064
- def safe_ln(*args)
1065
- unless LN_SUPPORTED[0]
1066
- cp(*args)
1067
- else
1068
- begin
1069
- ln(*args)
1070
- rescue StandardError, NotImplementedError => ex
1071
- LN_SUPPORTED[0] = false
1072
- cp(*args)
1073
- end
1074
- end
1075
- end
37
+ require 'rake/ext/module'
38
+ require 'rake/ext/string'
39
+ require 'rake/ext/time'
1076
40
 
1077
- # Split a file path into individual directory names.
1078
- #
1079
- # Example:
1080
- # split_all("a/b/c") => ['a', 'b', 'c']
1081
- #
1082
- def split_all(path)
1083
- head, tail = File.split(path)
1084
- return [tail] if head == '.' || tail == '/'
1085
- return [head, tail] if head == '/'
1086
- return split_all(head) + [tail]
1087
- end
1088
- end
1089
-
1090
- #############################################################################
1091
- # RakeFileUtils provides a custom version of the FileUtils methods that
1092
- # respond to the <tt>verbose</tt> and <tt>nowrite</tt> commands.
1093
- #
1094
- module RakeFileUtils
1095
- include FileUtils
1096
-
1097
- class << self
1098
- attr_accessor :verbose_flag, :nowrite_flag
1099
- end
1100
- RakeFileUtils.verbose_flag = :default
1101
- RakeFileUtils.nowrite_flag = false
1102
-
1103
- $fileutils_verbose = true
1104
- $fileutils_nowrite = false
1105
-
1106
- FileUtils::OPT_TABLE.each do |name, opts|
1107
- default_options = []
1108
- if opts.include?(:verbose) || opts.include?("verbose")
1109
- default_options << ':verbose => RakeFileUtils.verbose_flag'
1110
- end
1111
- if opts.include?(:noop) || opts.include?("noop")
1112
- default_options << ':noop => RakeFileUtils.nowrite_flag'
1113
- end
1114
-
1115
- next if default_options.empty?
1116
- module_eval(<<-EOS, __FILE__, __LINE__ + 1)
1117
- def #{name}( *args, &block )
1118
- super(
1119
- *rake_merge_option(args,
1120
- #{default_options.join(', ')}
1121
- ), &block)
1122
- end
1123
- EOS
1124
- end
1125
-
1126
- # Get/set the verbose flag controlling output from the FileUtils utilities.
1127
- # If verbose is true, then the utility method is echoed to standard output.
1128
- #
1129
- # Examples:
1130
- # verbose # return the current value of the verbose flag
1131
- # verbose(v) # set the verbose flag to _v_.
1132
- # verbose(v) { code } # Execute code with the verbose flag set temporarily to _v_.
1133
- # # Return to the original value when code is done.
1134
- def verbose(value=nil)
1135
- oldvalue = RakeFileUtils.verbose_flag
1136
- RakeFileUtils.verbose_flag = value unless value.nil?
1137
- if block_given?
1138
- begin
1139
- yield
1140
- ensure
1141
- RakeFileUtils.verbose_flag = oldvalue
1142
- end
1143
- end
1144
- RakeFileUtils.verbose_flag
1145
- end
1146
-
1147
- # Get/set the nowrite flag controlling output from the FileUtils utilities.
1148
- # If verbose is true, then the utility method is echoed to standard output.
1149
- #
1150
- # Examples:
1151
- # nowrite # return the current value of the nowrite flag
1152
- # nowrite(v) # set the nowrite flag to _v_.
1153
- # nowrite(v) { code } # Execute code with the nowrite flag set temporarily to _v_.
1154
- # # Return to the original value when code is done.
1155
- def nowrite(value=nil)
1156
- oldvalue = RakeFileUtils.nowrite_flag
1157
- RakeFileUtils.nowrite_flag = value unless value.nil?
1158
- if block_given?
1159
- begin
1160
- yield
1161
- ensure
1162
- RakeFileUtils.nowrite_flag = oldvalue
1163
- end
1164
- end
1165
- oldvalue
1166
- end
1167
-
1168
- # Use this function to prevent protentially destructive ruby code from
1169
- # running when the :nowrite flag is set.
1170
- #
1171
- # Example:
1172
- #
1173
- # when_writing("Building Project") do
1174
- # project.build
1175
- # end
1176
- #
1177
- # The following code will build the project under normal conditions. If the
1178
- # nowrite(true) flag is set, then the example will print:
1179
- # DRYRUN: Building Project
1180
- # instead of actually building the project.
1181
- #
1182
- def when_writing(msg=nil)
1183
- if RakeFileUtils.nowrite_flag
1184
- puts "DRYRUN: #{msg}" if msg
1185
- else
1186
- yield
1187
- end
1188
- end
1189
-
1190
- # Merge the given options with the default values.
1191
- def rake_merge_option(args, defaults)
1192
- if Hash === args.last
1193
- defaults.update(args.last)
1194
- args.pop
1195
- end
1196
- args.push defaults
1197
- args
1198
- end
1199
- private :rake_merge_option
1200
-
1201
- # Send the message to the default rake output (which is $stderr).
1202
- def rake_output_message(message)
1203
- $stderr.puts(message)
1204
- end
1205
- private :rake_output_message
1206
-
1207
- # Check that the options do not contain options not listed in +optdecl+. An
1208
- # ArgumentError exception is thrown if non-declared options are found.
1209
- def rake_check_options(options, *optdecl)
1210
- h = options.dup
1211
- optdecl.each do |name|
1212
- h.delete name
1213
- end
1214
- raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless h.empty?
1215
- end
1216
- private :rake_check_options
1217
-
1218
- extend self
1219
- end
1220
-
1221
- #############################################################################
1222
- # Include the FileUtils file manipulation functions in the top level module,
1223
- # but mark them private so that they don't unintentionally define methods on
1224
- # other objects.
1225
-
1226
- include RakeFileUtils
1227
- private(*FileUtils.instance_methods(false))
1228
- private(*RakeFileUtils.instance_methods(false))
1229
-
1230
- ######################################################################
1231
- module Rake
1232
-
1233
- ###########################################################################
1234
- # A FileList is essentially an array with a few helper methods defined to
1235
- # make file manipulation a bit easier.
1236
- #
1237
- # FileLists are lazy. When given a list of glob patterns for possible files
1238
- # to be included in the file list, instead of searching the file structures
1239
- # to find the files, a FileList holds the pattern for latter use.
1240
- #
1241
- # This allows us to define a number of FileList to match any number of
1242
- # files, but only search out the actual files when then FileList itself is
1243
- # actually used. The key is that the first time an element of the
1244
- # FileList/Array is requested, the pending patterns are resolved into a real
1245
- # list of file names.
1246
- #
1247
- class FileList
1248
-
1249
- include Cloneable
1250
-
1251
- # == Method Delegation
1252
- #
1253
- # The lazy evaluation magic of FileLists happens by implementing all the
1254
- # array specific methods to call +resolve+ before delegating the heavy
1255
- # lifting to an embedded array object (@items).
1256
- #
1257
- # In addition, there are two kinds of delegation calls. The regular kind
1258
- # delegates to the @items array and returns the result directly. Well,
1259
- # almost directly. It checks if the returned value is the @items object
1260
- # itself, and if so will return the FileList object instead.
1261
- #
1262
- # The second kind of delegation call is used in methods that normally
1263
- # return a new Array object. We want to capture the return value of these
1264
- # methods and wrap them in a new FileList object. We enumerate these
1265
- # methods in the +SPECIAL_RETURN+ list below.
1266
-
1267
- # List of array methods (that are not in +Object+) that need to be
1268
- # delegated.
1269
- ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).map { |n| n.to_s }
1270
-
1271
- # List of additional methods that must be delegated.
1272
- MUST_DEFINE = %w[to_a inspect]
1273
-
1274
- # List of methods that should not be delegated here (we define special
1275
- # versions of them explicitly below).
1276
- MUST_NOT_DEFINE = %w[to_a to_ary partition *]
1277
-
1278
- # List of delegated methods that return new array values which need
1279
- # wrapping.
1280
- SPECIAL_RETURN = %w[
1281
- map collect sort sort_by select find_all reject grep
1282
- compact flatten uniq values_at
1283
- + - & |
1284
- ]
1285
-
1286
- DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).collect{ |s| s.to_s }.sort.uniq
1287
-
1288
- # Now do the delegation.
1289
- DELEGATING_METHODS.each_with_index do |sym, i|
1290
- if SPECIAL_RETURN.include?(sym)
1291
- ln = __LINE__+1
1292
- class_eval %{
1293
- def #{sym}(*args, &block)
1294
- resolve
1295
- result = @items.send(:#{sym}, *args, &block)
1296
- FileList.new.import(result)
1297
- end
1298
- }, __FILE__, ln
1299
- else
1300
- ln = __LINE__+1
1301
- class_eval %{
1302
- def #{sym}(*args, &block)
1303
- resolve
1304
- result = @items.send(:#{sym}, *args, &block)
1305
- result.object_id == @items.object_id ? self : result
1306
- end
1307
- }, __FILE__, ln
1308
- end
1309
- end
1310
-
1311
- # Create a file list from the globbable patterns given. If you wish to
1312
- # perform multiple includes or excludes at object build time, use the
1313
- # "yield self" pattern.
1314
- #
1315
- # Example:
1316
- # file_list = FileList.new('lib/**/*.rb', 'test/test*.rb')
1317
- #
1318
- # pkg_files = FileList.new('lib/**/*') do |fl|
1319
- # fl.exclude(/\bCVS\b/)
1320
- # end
1321
- #
1322
- def initialize(*patterns)
1323
- @pending_add = []
1324
- @pending = false
1325
- @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup
1326
- @exclude_procs = DEFAULT_IGNORE_PROCS.dup
1327
- @exclude_re = nil
1328
- @items = []
1329
- patterns.each { |pattern| include(pattern) }
1330
- yield self if block_given?
1331
- end
1332
-
1333
- # Add file names defined by glob patterns to the file list. If an array
1334
- # is given, add each element of the array.
1335
- #
1336
- # Example:
1337
- # file_list.include("*.java", "*.cfg")
1338
- # file_list.include %w( math.c lib.h *.o )
1339
- #
1340
- def include(*filenames)
1341
- # TODO: check for pending
1342
- filenames.each do |fn|
1343
- if fn.respond_to? :to_ary
1344
- include(*fn.to_ary)
1345
- else
1346
- @pending_add << fn
1347
- end
1348
- end
1349
- @pending = true
1350
- self
1351
- end
1352
- alias :add :include
1353
-
1354
- # Register a list of file name patterns that should be excluded from the
1355
- # list. Patterns may be regular expressions, glob patterns or regular
1356
- # strings. In addition, a block given to exclude will remove entries that
1357
- # return true when given to the block.
1358
- #
1359
- # Note that glob patterns are expanded against the file system. If a file
1360
- # is explicitly added to a file list, but does not exist in the file
1361
- # system, then an glob pattern in the exclude list will not exclude the
1362
- # file.
1363
- #
1364
- # Examples:
1365
- # FileList['a.c', 'b.c'].exclude("a.c") => ['b.c']
1366
- # FileList['a.c', 'b.c'].exclude(/^a/) => ['b.c']
1367
- #
1368
- # If "a.c" is a file, then ...
1369
- # FileList['a.c', 'b.c'].exclude("a.*") => ['b.c']
1370
- #
1371
- # If "a.c" is not a file, then ...
1372
- # FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c']
1373
- #
1374
- def exclude(*patterns, &block)
1375
- patterns.each do |pat|
1376
- @exclude_patterns << pat
1377
- end
1378
- if block_given?
1379
- @exclude_procs << block
1380
- end
1381
- resolve_exclude if ! @pending
1382
- self
1383
- end
1384
-
1385
-
1386
- # Clear all the exclude patterns so that we exclude nothing.
1387
- def clear_exclude
1388
- @exclude_patterns = []
1389
- @exclude_procs = []
1390
- calculate_exclude_regexp if ! @pending
1391
- self
1392
- end
1393
-
1394
- # Define equality.
1395
- def ==(array)
1396
- to_ary == array
1397
- end
1398
-
1399
- # Return the internal array object.
1400
- def to_a
1401
- resolve
1402
- @items
1403
- end
1404
-
1405
- # Return the internal array object.
1406
- def to_ary
1407
- to_a
1408
- end
1409
-
1410
- # Lie about our class.
1411
- def is_a?(klass)
1412
- klass == Array || super(klass)
1413
- end
1414
- alias kind_of? is_a?
1415
-
1416
- # Redefine * to return either a string or a new file list.
1417
- def *(other)
1418
- result = @items * other
1419
- case result
1420
- when Array
1421
- FileList.new.import(result)
1422
- else
1423
- result
1424
- end
1425
- end
1426
-
1427
- # Resolve all the pending adds now.
1428
- def resolve
1429
- if @pending
1430
- @pending = false
1431
- @pending_add.each do |fn| resolve_add(fn) end
1432
- @pending_add = []
1433
- resolve_exclude
1434
- end
1435
- self
1436
- end
1437
-
1438
- def calculate_exclude_regexp
1439
- ignores = []
1440
- @exclude_patterns.each do |pat|
1441
- case pat
1442
- when Regexp
1443
- ignores << pat
1444
- when /[*?]/
1445
- Dir[pat].each do |p| ignores << p end
1446
- else
1447
- ignores << Regexp.quote(pat)
1448
- end
1449
- end
1450
- if ignores.empty?
1451
- @exclude_re = /^$/
1452
- else
1453
- re_str = ignores.collect { |p| "(" + p.to_s + ")" }.join("|")
1454
- @exclude_re = Regexp.new(re_str)
1455
- end
1456
- end
1457
-
1458
- def resolve_add(fn)
1459
- case fn
1460
- when %r{[*?\[\{]}
1461
- add_matching(fn)
1462
- else
1463
- self << fn
1464
- end
1465
- end
1466
- private :resolve_add
1467
-
1468
- def resolve_exclude
1469
- calculate_exclude_regexp
1470
- reject! { |fn| exclude?(fn) }
1471
- self
1472
- end
1473
- private :resolve_exclude
1474
-
1475
- # Return a new FileList with the results of running +sub+ against each
1476
- # element of the oringal list.
1477
- #
1478
- # Example:
1479
- # FileList['a.c', 'b.c'].sub(/\.c$/, '.o') => ['a.o', 'b.o']
1480
- #
1481
- def sub(pat, rep)
1482
- inject(FileList.new) { |res, fn| res << fn.sub(pat,rep) }
1483
- end
1484
-
1485
- # Return a new FileList with the results of running +gsub+ against each
1486
- # element of the original list.
1487
- #
1488
- # Example:
1489
- # FileList['lib/test/file', 'x/y'].gsub(/\//, "\\")
1490
- # => ['lib\\test\\file', 'x\\y']
1491
- #
1492
- def gsub(pat, rep)
1493
- inject(FileList.new) { |res, fn| res << fn.gsub(pat,rep) }
1494
- end
1495
-
1496
- # Same as +sub+ except that the oringal file list is modified.
1497
- def sub!(pat, rep)
1498
- each_with_index { |fn, i| self[i] = fn.sub(pat,rep) }
1499
- self
1500
- end
1501
-
1502
- # Same as +gsub+ except that the original file list is modified.
1503
- def gsub!(pat, rep)
1504
- each_with_index { |fn, i| self[i] = fn.gsub(pat,rep) }
1505
- self
1506
- end
1507
-
1508
- # Apply the pathmap spec to each of the included file names, returning a
1509
- # new file list with the modified paths. (See String#pathmap for
1510
- # details.)
1511
- def pathmap(spec=nil)
1512
- collect { |fn| fn.pathmap(spec) }
1513
- end
1514
-
1515
- # Return a new FileList with <tt>String#ext</tt> method applied
1516
- # to each member of the array.
1517
- #
1518
- # This method is a shortcut for:
1519
- #
1520
- # array.collect { |item| item.ext(newext) }
1521
- #
1522
- # +ext+ is a user added method for the Array class.
1523
- def ext(newext='')
1524
- collect { |fn| fn.ext(newext) }
1525
- end
1526
-
1527
-
1528
- # Grep each of the files in the filelist using the given pattern. If a
1529
- # block is given, call the block on each matching line, passing the file
1530
- # name, line number, and the matching line of text. If no block is given,
1531
- # a standard emac style file:linenumber:line message will be printed to
1532
- # standard out.
1533
- def egrep(pattern, *options)
1534
- each do |fn|
1535
- open(fn, "rb", *options) do |inf|
1536
- count = 0
1537
- inf.each do |line|
1538
- count += 1
1539
- if pattern.match(line)
1540
- if block_given?
1541
- yield fn, count, line
1542
- else
1543
- puts "#{fn}:#{count}:#{line}"
1544
- end
1545
- end
1546
- end
1547
- end
1548
- end
1549
- end
1550
-
1551
- # Return a new file list that only contains file names from the current
1552
- # file list that exist on the file system.
1553
- def existing
1554
- select { |fn| File.exist?(fn) }
1555
- end
1556
-
1557
- # Modify the current file list so that it contains only file name that
1558
- # exist on the file system.
1559
- def existing!
1560
- resolve
1561
- @items = @items.select { |fn| File.exist?(fn) }
1562
- self
1563
- end
1564
-
1565
- # FileList version of partition. Needed because the nested arrays should
1566
- # be FileLists in this version.
1567
- def partition(&block) # :nodoc:
1568
- resolve
1569
- result = @items.partition(&block)
1570
- [
1571
- FileList.new.import(result[0]),
1572
- FileList.new.import(result[1]),
1573
- ]
1574
- end
1575
-
1576
- # Convert a FileList to a string by joining all elements with a space.
1577
- def to_s
1578
- resolve
1579
- self.join(' ')
1580
- end
1581
-
1582
- # Add matching glob patterns.
1583
- def add_matching(pattern)
1584
- Dir[pattern].each do |fn|
1585
- self << fn unless exclude?(fn)
1586
- end
1587
- end
1588
- private :add_matching
1589
-
1590
- # Should the given file name be excluded?
1591
- def exclude?(fn)
1592
- calculate_exclude_regexp unless @exclude_re
1593
- fn =~ @exclude_re || @exclude_procs.any? { |p| p.call(fn) }
1594
- end
1595
-
1596
- DEFAULT_IGNORE_PATTERNS = [
1597
- /(^|[\/\\])CVS([\/\\]|$)/,
1598
- /(^|[\/\\])\.svn([\/\\]|$)/,
1599
- /\.bak$/,
1600
- /~$/
1601
- ]
1602
- DEFAULT_IGNORE_PROCS = [
1603
- proc { |fn| fn =~ /(^|[\/\\])core$/ && ! File.directory?(fn) }
1604
- ]
1605
- # @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup
1606
-
1607
- def import(array)
1608
- @items = array
1609
- self
1610
- end
41
+ require 'rake/win32'
1611
42
 
1612
- class << self
1613
- # Create a new file list including the files listed. Similar to:
1614
- #
1615
- # FileList.new(*args)
1616
- def [](*args)
1617
- new(*args)
1618
- end
1619
- end
1620
- end # FileList
1621
- end
43
+ require 'rake/task_argument_error'
44
+ require 'rake/rule_recursion_overflow_error'
45
+ require 'rake/rake_module'
46
+ require 'rake/pseudo_status'
47
+ require 'rake/task_arguments'
48
+ require 'rake/invocation_chain'
49
+ require 'rake/task'
50
+ require 'rake/file_task'
51
+ require 'rake/file_creation_task'
52
+ require 'rake/multi_task'
53
+ require 'rake/dsl_definition'
54
+ require 'rake/file_utils_ext'
55
+ require 'rake/file_list'
56
+ require 'rake/default_loader'
57
+ require 'rake/early_time'
58
+ require 'rake/name_space'
59
+ require 'rake/task_manager'
60
+ require 'rake/application'
1622
61
 
1623
- module Rake
1624
- class << self
62
+ $trace = false
1625
63
 
1626
- # Yield each file or directory component.
1627
- def each_dir_parent(dir) # :nodoc:
1628
- old_length = nil
1629
- while dir != '.' && dir.length != old_length
1630
- yield(dir)
1631
- old_length = dir.length
1632
- dir = File.dirname(dir)
1633
- end
1634
- end
1635
- end
1636
- end # module Rake
64
+ # Some top level Constants.
1637
65
 
1638
- # Alias FileList to be available at the top level.
1639
66
  FileList = Rake::FileList
1640
-
1641
- #############################################################################
1642
- module Rake
1643
-
1644
- # Default Rakefile loader used by +import+.
1645
- class DefaultLoader
1646
- def load(fn)
1647
- Kernel.load(File.expand_path(fn))
1648
- end
1649
- end
1650
-
1651
- # EarlyTime is a fake timestamp that occurs _before_ any other time value.
1652
- class EarlyTime
1653
- include Comparable
1654
- include Singleton
1655
-
1656
- def <=>(other)
1657
- -1
1658
- end
1659
-
1660
- def to_s
1661
- "<EARLY TIME>"
1662
- end
1663
- end
1664
-
1665
- EARLY = EarlyTime.instance
1666
- end # module Rake
1667
-
1668
- #############################################################################
1669
- # Extensions to time to allow comparisons with an early time class.
1670
- #
1671
- class Time
1672
- alias rake_original_time_compare :<=>
1673
- def <=>(other)
1674
- if Rake::EarlyTime === other
1675
- - other.<=>(self)
1676
- else
1677
- rake_original_time_compare(other)
1678
- end
1679
- end
1680
- end # class Time
1681
-
1682
- module Rake
1683
-
1684
- ####################################################################
1685
- # The NameSpace class will lookup task names in the the scope
1686
- # defined by a +namespace+ command.
1687
- #
1688
- class NameSpace
1689
-
1690
- # Create a namespace lookup object using the given task manager
1691
- # and the list of scopes.
1692
- def initialize(task_manager, scope_list)
1693
- @task_manager = task_manager
1694
- @scope = scope_list.dup
1695
- end
1696
-
1697
- # Lookup a task named +name+ in the namespace.
1698
- def [](name)
1699
- @task_manager.lookup(name, @scope)
1700
- end
1701
-
1702
- # Return the list of tasks defined in this and nested namespaces.
1703
- def tasks
1704
- @task_manager.tasks_in_scope(@scope)
1705
- end
1706
- end # NameSpace
1707
-
1708
-
1709
- ####################################################################
1710
- # The TaskManager module is a mixin for managing tasks.
1711
- module TaskManager
1712
- # Track the last comment made in the Rakefile.
1713
- attr_accessor :last_description
1714
- alias :last_comment :last_description # Backwards compatibility
1715
-
1716
- def initialize
1717
- super
1718
- @tasks = Hash.new
1719
- @rules = Array.new
1720
- @scope = Array.new
1721
- @last_description = nil
1722
- end
1723
-
1724
- def create_rule(*args, &block)
1725
- pattern, arg_names, deps = resolve_args(args)
1726
- pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
1727
- @rules << [pattern, deps, block]
1728
- end
1729
-
1730
- def define_task(task_class, *args, &block)
1731
- task_name, arg_names, deps = resolve_args(args)
1732
- task_name = task_class.scope_name(@scope, task_name)
1733
- deps = [deps] unless deps.respond_to?(:to_ary)
1734
- deps = deps.collect {|d| d.to_s }
1735
- task = intern(task_class, task_name)
1736
- task.set_arg_names(arg_names) unless arg_names.empty?
1737
- task.add_description(@last_description)
1738
- @last_description = nil
1739
- task.enhance(deps, &block)
1740
- task
1741
- end
1742
-
1743
- # Lookup a task. Return an existing task if found, otherwise
1744
- # create a task of the current type.
1745
- def intern(task_class, task_name)
1746
- @tasks[task_name.to_s] ||= task_class.new(task_name, self)
1747
- end
1748
-
1749
- # Find a matching task for +task_name+.
1750
- def [](task_name, scopes=nil)
1751
- task_name = task_name.to_s
1752
- self.lookup(task_name, scopes) or
1753
- enhance_with_matching_rule(task_name) or
1754
- synthesize_file_task(task_name) or
1755
- fail "Don't know how to build task '#{task_name}'"
1756
- end
1757
-
1758
- def synthesize_file_task(task_name)
1759
- return nil unless File.exist?(task_name)
1760
- define_task(Rake::FileTask, task_name)
1761
- end
1762
-
1763
- # Resolve the arguments for a task/rule. Returns a triplet of
1764
- # [task_name, arg_name_list, prerequisites].
1765
- def resolve_args(args)
1766
- if args.last.is_a?(Hash)
1767
- deps = args.pop
1768
- resolve_args_with_dependencies(args, deps)
1769
- else
1770
- resolve_args_without_dependencies(args)
1771
- end
1772
- end
1773
-
1774
- # Resolve task arguments for a task or rule when there are no
1775
- # dependencies declared.
1776
- #
1777
- # The patterns recognized by this argument resolving function are:
1778
- #
1779
- # task :t
1780
- # task :t, [:a]
1781
- # task :t, :a (deprecated)
1782
- #
1783
- def resolve_args_without_dependencies(args)
1784
- task_name = args.shift
1785
- if args.size == 1 && args.first.respond_to?(:to_ary)
1786
- arg_names = args.first.to_ary
1787
- else
1788
- arg_names = args
1789
- end
1790
- [task_name, arg_names, []]
1791
- end
1792
- private :resolve_args_without_dependencies
1793
-
1794
- # Resolve task arguments for a task or rule when there are
1795
- # dependencies declared.
1796
- #
1797
- # The patterns recognized by this argument resolving function are:
1798
- #
1799
- # task :t => [:d]
1800
- # task :t, [a] => [:d]
1801
- # task :t, :needs => [:d] (deprecated)
1802
- # task :t, :a, :needs => [:d] (deprecated)
1803
- #
1804
- def resolve_args_with_dependencies(args, hash) # :nodoc:
1805
- fail "Task Argument Error" if hash.size != 1
1806
- key, value = hash.map { |k, v| [k,v] }.first
1807
- if args.empty?
1808
- task_name = key
1809
- arg_names = []
1810
- deps = value
1811
- elsif key == :needs
1812
- task_name = args.shift
1813
- arg_names = args
1814
- deps = value
1815
- else
1816
- task_name = args.shift
1817
- arg_names = key
1818
- deps = value
1819
- end
1820
- deps = [deps] unless deps.respond_to?(:to_ary)
1821
- [task_name, arg_names, deps]
1822
- end
1823
- private :resolve_args_with_dependencies
1824
-
1825
- # If a rule can be found that matches the task name, enhance the
1826
- # task with the prerequisites and actions from the rule. Set the
1827
- # source attribute of the task appropriately for the rule. Return
1828
- # the enhanced task or nil of no rule was found.
1829
- def enhance_with_matching_rule(task_name, level=0)
1830
- fail Rake::RuleRecursionOverflowError,
1831
- "Rule Recursion Too Deep" if level >= 16
1832
- @rules.each do |pattern, extensions, block|
1833
- if md = pattern.match(task_name)
1834
- task = attempt_rule(task_name, extensions, block, level)
1835
- return task if task
1836
- end
1837
- end
1838
- nil
1839
- rescue Rake::RuleRecursionOverflowError => ex
1840
- ex.add_target(task_name)
1841
- fail ex
1842
- end
1843
-
1844
- # List of all defined tasks in this application.
1845
- def tasks
1846
- @tasks.values.sort_by { |t| t.name }
1847
- end
1848
-
1849
- # List of all the tasks defined in the given scope (and its
1850
- # sub-scopes).
1851
- def tasks_in_scope(scope)
1852
- prefix = scope.join(":")
1853
- tasks.select { |t|
1854
- /^#{prefix}:/ =~ t.name
1855
- }
1856
- end
1857
-
1858
- # Clear all tasks in this application.
1859
- def clear
1860
- @tasks.clear
1861
- @rules.clear
1862
- end
1863
-
1864
- # Lookup a task, using scope and the scope hints in the task name.
1865
- # This method performs straight lookups without trying to
1866
- # synthesize file tasks or rules. Special scope names (e.g. '^')
1867
- # are recognized. If no scope argument is supplied, use the
1868
- # current scope. Return nil if the task cannot be found.
1869
- def lookup(task_name, initial_scope=nil)
1870
- initial_scope ||= @scope
1871
- task_name = task_name.to_s
1872
- if task_name =~ /^rake:/
1873
- scopes = []
1874
- task_name = task_name.sub(/^rake:/, '')
1875
- elsif task_name =~ /^(\^+)/
1876
- scopes = initial_scope[0, initial_scope.size - $1.size]
1877
- task_name = task_name.sub(/^(\^+)/, '')
1878
- else
1879
- scopes = initial_scope
1880
- end
1881
- lookup_in_scope(task_name, scopes)
1882
- end
1883
-
1884
- # Lookup the task name
1885
- def lookup_in_scope(name, scope)
1886
- n = scope.size
1887
- while n >= 0
1888
- tn = (scope[0,n] + [name]).join(':')
1889
- task = @tasks[tn]
1890
- return task if task
1891
- n -= 1
1892
- end
1893
- nil
1894
- end
1895
- private :lookup_in_scope
1896
-
1897
- # Return the list of scope names currently active in the task
1898
- # manager.
1899
- def current_scope
1900
- @scope.dup
1901
- end
1902
-
1903
- # Evaluate the block in a nested namespace named +name+. Create
1904
- # an anonymous namespace if +name+ is nil.
1905
- def in_namespace(name)
1906
- name ||= generate_name
1907
- @scope.push(name)
1908
- ns = NameSpace.new(self, @scope)
1909
- yield(ns)
1910
- ns
1911
- ensure
1912
- @scope.pop
1913
- end
1914
-
1915
- private
1916
-
1917
- # Generate an anonymous namespace name.
1918
- def generate_name
1919
- @seed ||= 0
1920
- @seed += 1
1921
- "_anon_#{@seed}"
1922
- end
1923
-
1924
- def trace_rule(level, message)
1925
- puts "#{" "*level}#{message}" if Rake.application.options.trace_rules
1926
- end
1927
-
1928
- # Attempt to create a rule given the list of prerequisites.
1929
- def attempt_rule(task_name, extensions, block, level)
1930
- sources = make_sources(task_name, extensions)
1931
- prereqs = sources.collect { |source|
1932
- trace_rule level, "Attempting Rule #{task_name} => #{source}"
1933
- if File.exist?(source) || Rake::Task.task_defined?(source)
1934
- trace_rule level, "(#{task_name} => #{source} ... EXIST)"
1935
- source
1936
- elsif parent = enhance_with_matching_rule(source, level+1)
1937
- trace_rule level, "(#{task_name} => #{source} ... ENHANCE)"
1938
- parent.name
1939
- else
1940
- trace_rule level, "(#{task_name} => #{source} ... FAIL)"
1941
- return nil
1942
- end
1943
- }
1944
- task = FileTask.define_task({task_name => prereqs}, &block)
1945
- task.sources = prereqs
1946
- task
1947
- end
1948
-
1949
- # Make a list of sources from the list of file name extensions /
1950
- # translation procs.
1951
- def make_sources(task_name, extensions)
1952
- extensions.collect { |ext|
1953
- case ext
1954
- when /%/
1955
- task_name.pathmap(ext)
1956
- when %r{/}
1957
- ext
1958
- when /^\./
1959
- task_name.ext(ext)
1960
- when String
1961
- ext
1962
- when Proc
1963
- if ext.arity == 1
1964
- ext.call(task_name)
1965
- else
1966
- ext.call
1967
- end
1968
- else
1969
- fail "Don't know how to handle rule dependent: #{ext.inspect}"
1970
- end
1971
- }.flatten
1972
- end
1973
-
1974
- end # TaskManager
1975
-
1976
- #
1977
- # Lazily pull in the parallelizing code
1978
- #
1979
- class Options < OpenStruct # :nodoc:
1980
- attr_reader :threads
1981
-
1982
- def initialize
1983
- super
1984
- @threads = 1
1985
- end
1986
-
1987
- def threads=(n)
1988
- if n > 1 and require('rake/parallel')
1989
- Task.module_eval { include Parallel::TaskMixin }
1990
- Application.module_eval { include Parallel::ApplicationMixin }
1991
- end
1992
- @threads = n
1993
- end
1994
- end
1995
-
1996
- ######################################################################
1997
- # Rake main application object. When invoking +rake+ from the
1998
- # command line, a Rake::Application object is created and run.
1999
- #
2000
- class Application
2001
- include TaskManager
2002
-
2003
- # The name of the application (typically 'rake')
2004
- attr_reader :name
2005
-
2006
- # The original directory where rake was invoked.
2007
- attr_reader :original_dir
2008
-
2009
- # Name of the actual rakefile used.
2010
- attr_reader :rakefile
2011
-
2012
- # List of the top level task names (task names from the command line).
2013
- attr_reader :top_level_tasks
2014
-
2015
- DEFAULT_RAKEFILES = ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze
2016
-
2017
- # Initialize a Rake::Application object.
2018
- def initialize
2019
- super
2020
- @name = 'rake'
2021
- @rakefiles = DEFAULT_RAKEFILES.dup
2022
- @rakefile = nil
2023
- @pending_imports = []
2024
- @imported = []
2025
- @loaders = {}
2026
- @default_loader = Rake::DefaultLoader.new
2027
- @original_dir = Dir.pwd
2028
- @top_level_tasks = []
2029
- add_loader('rb', DefaultLoader.new)
2030
- add_loader('rf', DefaultLoader.new)
2031
- add_loader('rake', DefaultLoader.new)
2032
- @tty_output = STDOUT.tty?
2033
- end
2034
-
2035
- # Run the Rake application. The run method performs the following three steps:
2036
- #
2037
- # * Initialize the command line options (+init+).
2038
- # * Define the tasks (+load_rakefile+).
2039
- # * Run the top level tasks (+run_tasks+).
2040
- #
2041
- # If you wish to build a custom rake command, you should call +init+ on your
2042
- # application. The define any tasks. Finally, call +top_level+ to run your top
2043
- # level tasks.
2044
- def run
2045
- standard_exception_handling do
2046
- init
2047
- load_rakefile
2048
- top_level
2049
- end
2050
- end
2051
-
2052
- # Initialize the command line parameters and app name.
2053
- def init(app_name='rake')
2054
- standard_exception_handling do
2055
- @name = app_name
2056
- handle_options
2057
- collect_tasks
2058
- end
2059
- end
2060
-
2061
- # Find the rakefile and then load it and any pending imports.
2062
- def load_rakefile
2063
- standard_exception_handling do
2064
- raw_load_rakefile
2065
- end
2066
- end
2067
-
2068
- # Run the top level tasks of a Rake application.
2069
- def top_level
2070
- standard_exception_handling do
2071
- if options.show_tasks
2072
- display_tasks_and_comments
2073
- elsif options.show_prereqs
2074
- display_prerequisites
2075
- else
2076
- top_level_tasks.each { |task_name| invoke_task(task_name) }
2077
- end
2078
- end
2079
- end
2080
-
2081
- # Add a loader to handle imported files ending in the extension
2082
- # +ext+.
2083
- def add_loader(ext, loader)
2084
- ext = ".#{ext}" unless ext =~ /^\./
2085
- @loaders[ext] = loader
2086
- end
2087
-
2088
- # Application options from the command line
2089
- def options
2090
- @options ||= Options.new
2091
- end
2092
-
2093
- # private ----------------------------------------------------------------
2094
-
2095
- def invoke_task(task_string)
2096
- name, args = parse_task_string(task_string)
2097
- t = self[name]
2098
- t.invoke(*args)
2099
- end
2100
-
2101
- def parse_task_string(string)
2102
- if string =~ /^([^\[]+)(\[(.*)\])$/
2103
- name = $1
2104
- args = $3.split(/\s*,\s*/)
2105
- else
2106
- name = string
2107
- args = []
2108
- end
2109
- [name, args]
2110
- end
2111
-
2112
- # Provide standard execption handling for the given block.
2113
- def standard_exception_handling
2114
- begin
2115
- yield
2116
- rescue SystemExit => ex
2117
- # Exit silently with current status
2118
- raise
2119
- rescue OptionParser::InvalidOption => ex
2120
- # Exit silently
2121
- exit(false)
2122
- rescue Exception => ex
2123
- # Exit with error message
2124
- $stderr.puts "#{name} aborted!"
2125
- $stderr.puts ex.message
2126
- if options.trace
2127
- $stderr.puts ex.backtrace.join("\n")
2128
- else
2129
- $stderr.puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
2130
- $stderr.puts "(See full trace by running task with --trace)"
2131
- end
2132
- exit(false)
2133
- end
2134
- end
2135
-
2136
- # True if one of the files in RAKEFILES is in the current directory.
2137
- # If a match is found, it is copied into @rakefile.
2138
- def have_rakefile
2139
- @rakefiles.each do |fn|
2140
- if File.exist?(fn)
2141
- others = Dir.glob(fn, File::FNM_CASEFOLD)
2142
- return others.size == 1 ? others.first : fn
2143
- elsif fn == ''
2144
- return fn
2145
- end
2146
- end
2147
- return nil
2148
- end
2149
-
2150
- # True if we are outputting to TTY, false otherwise
2151
- def tty_output?
2152
- @tty_output
2153
- end
2154
-
2155
- # Override the detected TTY output state (mostly for testing)
2156
- def tty_output=( tty_output_state )
2157
- @tty_output = tty_output_state
2158
- end
2159
-
2160
- # We will truncate output if we are outputting to a TTY or if we've been
2161
- # given an explicit column width to honor
2162
- def truncate_output?
2163
- tty_output? || ENV['RAKE_COLUMNS']
2164
- end
2165
-
2166
- # Display the tasks and comments.
2167
- def display_tasks_and_comments
2168
- displayable_tasks = tasks.select { |t|
2169
- t.comment && t.name =~ options.show_task_pattern
2170
- }
2171
- if options.full_description
2172
- displayable_tasks.each do |t|
2173
- puts "#{name} #{t.name_with_args}"
2174
- t.full_comment.split("\n").each do |line|
2175
- puts " #{line}"
2176
- end
2177
- puts
2178
- end
2179
- else
2180
- width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10
2181
- max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil
2182
- displayable_tasks.each do |t|
2183
- printf "#{name} %-#{width}s # %s\n",
2184
- t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment
2185
- end
2186
- end
2187
- end
2188
-
2189
- def terminal_width
2190
- if ENV['RAKE_COLUMNS']
2191
- result = ENV['RAKE_COLUMNS'].to_i
2192
- else
2193
- result = unix? ? dynamic_width : 80
2194
- end
2195
- (result < 10) ? 80 : result
2196
- rescue
2197
- 80
2198
- end
2199
-
2200
- # Calculate the dynamic width of the
2201
- def dynamic_width
2202
- @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
2203
- end
2204
-
2205
- def dynamic_width_stty
2206
- %x{stty size 2>/dev/null}.split[1].to_i
2207
- end
2208
-
2209
- def dynamic_width_tput
2210
- %x{tput cols 2>/dev/null}.to_i
2211
- end
2212
-
2213
- def unix?
2214
- RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
2215
- end
2216
-
2217
- def windows?
2218
- Win32.windows?
2219
- end
2220
-
2221
- def truncate(string, width)
2222
- if string.length <= width
2223
- string
2224
- else
2225
- ( string[0, width-3] || "" ) + "..."
2226
- end
2227
- end
2228
-
2229
- # Display the tasks and prerequisites
2230
- def display_prerequisites
2231
- tasks.each do |t|
2232
- puts "#{name} #{t.name}"
2233
- t.prerequisites.each { |pre| puts " #{pre}" }
2234
- end
2235
- end
2236
-
2237
- # A list of all the standard options used in rake, suitable for
2238
- # passing to OptionParser.
2239
- def standard_rake_options
2240
- [
2241
- ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace",
2242
- lambda { |value|
2243
- require 'rake/classic_namespace'
2244
- options.classic_namespace = true
2245
- }
2246
- ],
2247
- ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
2248
- lambda { |value|
2249
- options.show_tasks = true
2250
- options.full_description = true
2251
- options.show_task_pattern = Regexp.new(value || '')
2252
- }
2253
- ],
2254
- ['--dry-run', '-n', "Do a dry run without executing actions.",
2255
- lambda { |value|
2256
- verbose(true)
2257
- nowrite(true)
2258
- options.dryrun = true
2259
- options.trace = true
2260
- }
2261
- ],
2262
- ['--execute', '-e CODE', "Execute some Ruby code and exit.",
2263
- lambda { |value|
2264
- eval(value)
2265
- exit
2266
- }
2267
- ],
2268
- ['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.",
2269
- lambda { |value|
2270
- puts eval(value)
2271
- exit
2272
- }
2273
- ],
2274
- ['--execute-continue', '-E CODE',
2275
- "Execute some Ruby code, then continue with normal task processing.",
2276
- lambda { |value| eval(value) }
2277
- ],
2278
- ['--threads', '-j N', "Run up to N independent tasks simultaneously in separate threads.",
2279
- lambda { |value| options.threads = value.to_i }
2280
- ],
2281
- ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
2282
- lambda { |value| $:.push(value) }
2283
- ],
2284
- ['--prereqs', '-P', "Display the tasks and dependencies, then exit.",
2285
- lambda { |value| options.show_prereqs = true }
2286
- ],
2287
- ['--quiet', '-q', "Do not log messages to standard output.",
2288
- lambda { |value| verbose(false) }
2289
- ],
2290
- ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.",
2291
- lambda { |value|
2292
- value ||= ''
2293
- @rakefiles.clear
2294
- @rakefiles << value
2295
- }
2296
- ],
2297
- ['--rakelibdir', '--rakelib', '-R RAKELIBDIR',
2298
- "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')",
2299
- lambda { |value| options.rakelib = value.split(':') }
2300
- ],
2301
- ['--randomize[=SEED]', "Randomize the order of sibling prerequisites.",
2302
- lambda { |value|
2303
- options.randomize = true
2304
- MultiTask.class_eval { remove_method(:invoke_prerequisites) }
2305
- srand(value.hash) if value
2306
- }
2307
- ],
2308
- ['--require', '-r MODULE', "Require MODULE before executing rakefile.",
2309
- lambda { |value|
2310
- begin
2311
- require value
2312
- rescue LoadError => ex
2313
- begin
2314
- rake_require value
2315
- rescue LoadError => ex2
2316
- raise ex
2317
- end
2318
- end
2319
- }
2320
- ],
2321
- ['--rules', "Trace the rules resolution.",
2322
- lambda { |value| options.trace_rules = true }
2323
- ],
2324
- ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.",
2325
- lambda { |value| options.nosearch = true }
2326
- ],
2327
- ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.",
2328
- lambda { |value|
2329
- verbose(false)
2330
- options.silent = true
2331
- }
2332
- ],
2333
- ['--system', '-g',
2334
- "Using system wide (global) rakefiles (usually '~/.rake/*.rake').",
2335
- lambda { |value| options.load_system = true }
2336
- ],
2337
- ['--no-system', '--nosystem', '-G',
2338
- "Use standard project Rakefile search paths, ignore system wide rakefiles.",
2339
- lambda { |value| options.ignore_system = true }
2340
- ],
2341
- ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.",
2342
- lambda { |value|
2343
- options.show_tasks = true
2344
- options.show_task_pattern = Regexp.new(value || '')
2345
- options.full_description = false
2346
- }
2347
- ],
2348
- ['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.",
2349
- lambda { |value|
2350
- options.trace = true
2351
- verbose(true)
2352
- }
2353
- ],
2354
- ['--verbose', '-v', "Log message to standard output.",
2355
- lambda { |value| verbose(true) }
2356
- ],
2357
- ['--version', '-V', "Display the program version.",
2358
- lambda { |value|
2359
- puts "rake, version #{RAKEVERSION}"
2360
- exit
2361
- }
2362
- ]
2363
- ]
2364
- end
2365
-
2366
- # Read and handle the command line options.
2367
- def handle_options
2368
- options.rakelib = ['rakelib']
2369
-
2370
- OptionParser.new do |opts|
2371
- opts.banner = "rake [-f rakefile] {options} targets..."
2372
- opts.separator ""
2373
- opts.separator "Options are ..."
2374
-
2375
- opts.on_tail("-h", "--help", "-H", "Display this help message.") do
2376
- puts opts
2377
- exit
2378
- end
2379
-
2380
- standard_rake_options.each { |args| opts.on(*args) }
2381
- end.parse!
2382
-
2383
- # If class namespaces are requested, set the global options
2384
- # according to the values in the options structure.
2385
- if options.classic_namespace
2386
- $show_tasks = options.show_tasks
2387
- $show_prereqs = options.show_prereqs
2388
- $trace = options.trace
2389
- $dryrun = options.dryrun
2390
- $silent = options.silent
2391
- end
2392
- end
2393
-
2394
- # Similar to the regular Ruby +require+ command, but will check
2395
- # for *.rake files in addition to *.rb files.
2396
- def rake_require(file_name, paths=$LOAD_PATH, loaded=$")
2397
- return false if loaded.include?(file_name)
2398
- paths.each do |path|
2399
- fn = file_name + ".rake"
2400
- full_path = File.join(path, fn)
2401
- if File.exist?(full_path)
2402
- load full_path
2403
- loaded << fn
2404
- return true
2405
- end
2406
- end
2407
- fail LoadError, "Can't find #{file_name}"
2408
- end
2409
-
2410
- def find_rakefile_location
2411
- here = Dir.pwd
2412
- while ! (fn = have_rakefile)
2413
- Dir.chdir("..")
2414
- if Dir.pwd == here || options.nosearch
2415
- return nil
2416
- end
2417
- here = Dir.pwd
2418
- end
2419
- [fn, here]
2420
- ensure
2421
- Dir.chdir(Rake.original_dir)
2422
- end
2423
-
2424
- def raw_load_rakefile # :nodoc:
2425
- rakefile, location = find_rakefile_location
2426
- if (! options.ignore_system) &&
2427
- (options.load_system || rakefile.nil?) &&
2428
- system_dir && File.directory?(system_dir)
2429
- puts "(in #{Dir.pwd})" unless options.silent
2430
- glob("#{system_dir}/*.rake") do |name|
2431
- add_import name
2432
- end
2433
- else
2434
- fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})" if
2435
- rakefile.nil?
2436
- @rakefile = rakefile
2437
- Dir.chdir(location)
2438
- puts "(in #{Dir.pwd})" unless options.silent
2439
- $rakefile = @rakefile if options.classic_namespace
2440
- load File.expand_path(@rakefile) if @rakefile && @rakefile != ''
2441
- options.rakelib.each do |rlib|
2442
- glob("#{rlib}/*.rake") do |name|
2443
- add_import name
2444
- end
2445
- end
2446
- end
2447
- load_imports
2448
- end
2449
-
2450
- def glob(path, &block)
2451
- Dir[path.gsub("\\", '/')].each(&block)
2452
- end
2453
- private :glob
2454
-
2455
- # The directory path containing the system wide rakefiles.
2456
- def system_dir
2457
- @system_dir ||=
2458
- begin
2459
- if ENV['RAKE_SYSTEM']
2460
- ENV['RAKE_SYSTEM']
2461
- else
2462
- standard_system_dir
2463
- end
2464
- end
2465
- end
2466
-
2467
- # The standard directory containing system wide rake files.
2468
- if Win32.windows?
2469
- def standard_system_dir #:nodoc:
2470
- Win32.win32_system_dir
2471
- end
2472
- else
2473
- def standard_system_dir #:nodoc:
2474
- File.join(File.expand_path('~'), '.rake')
2475
- end
2476
- end
2477
- private :standard_system_dir
2478
-
2479
- # Collect the list of tasks on the command line. If no tasks are
2480
- # given, return a list containing only the default task.
2481
- # Environmental assignments are processed at this time as well.
2482
- def collect_tasks
2483
- @top_level_tasks = []
2484
- ARGV.each do |arg|
2485
- if arg =~ /^(\w+)=(.*)$/
2486
- ENV[$1] = $2
2487
- else
2488
- @top_level_tasks << arg unless arg =~ /^-/
2489
- end
2490
- end
2491
- @top_level_tasks.push("default") if @top_level_tasks.size == 0
2492
- end
2493
-
2494
- # Add a file to the list of files to be imported.
2495
- def add_import(fn)
2496
- @pending_imports << fn
2497
- end
2498
-
2499
- # Load the pending list of imported files.
2500
- def load_imports
2501
- while fn = @pending_imports.shift
2502
- next if @imported.member?(fn)
2503
- if fn_task = lookup(fn)
2504
- fn_task.invoke
2505
- end
2506
- ext = File.extname(fn)
2507
- loader = @loaders[ext] || @default_loader
2508
- loader.load(fn)
2509
- @imported << fn
2510
- end
2511
- end
2512
-
2513
- # Warn about deprecated use of top level constant names.
2514
- def const_warning(const_name)
2515
- @const_warning ||= false
2516
- if ! @const_warning
2517
- $stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } +
2518
- %{found at: #{rakefile_location}} # '
2519
- $stderr.puts %{ Use --classic-namespace on rake command}
2520
- $stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile}
2521
- end
2522
- @const_warning = true
2523
- end
2524
-
2525
- def rakefile_location
2526
- begin
2527
- fail
2528
- rescue RuntimeError => ex
2529
- ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
2530
- end
2531
- end
2532
- end
2533
- end
2534
-
2535
-
2536
- class Module
2537
- # Rename the original handler to make it available.
2538
- alias :rake_original_const_missing :const_missing
2539
-
2540
- # Check for deprecated uses of top level (i.e. in Object) uses of
2541
- # Rake class names. If someone tries to reference the constant
2542
- # name, display a warning and return the proper object. Using the
2543
- # --classic-namespace command line option will define these
2544
- # constants in Object and avoid this handler.
2545
- def const_missing(const_name)
2546
- case const_name
2547
- when :Task
2548
- Rake.application.const_warning(const_name)
2549
- Rake::Task
2550
- when :FileTask
2551
- Rake.application.const_warning(const_name)
2552
- Rake::FileTask
2553
- when :FileCreationTask
2554
- Rake.application.const_warning(const_name)
2555
- Rake::FileCreationTask
2556
- when :RakeApp
2557
- Rake.application.const_warning(const_name)
2558
- Rake::Application
2559
- else
2560
- rake_original_const_missing(const_name)
2561
- end
2562
- end
2563
- end
67
+ RakeFileUtils = Rake::FileUtilsExt