rake 0.8.7 → 0.9.0.beta.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rake might be problematic. Click here for more details.

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