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
@@ -0,0 +1,329 @@
1
+ module Rake
2
+
3
+ # The TaskManager module is a mixin for managing tasks.
4
+ module TaskManager
5
+ # Track the last comment made in the Rakefile.
6
+ attr_accessor :last_description
7
+ alias :last_comment :last_description # Backwards compatibility
8
+
9
+ def initialize
10
+ super
11
+ @tasks = Hash.new
12
+ @rules = Array.new
13
+ @scope = Array.new
14
+ @last_description = nil
15
+ end
16
+
17
+ def create_rule(*args, &block)
18
+ pattern, _, deps = resolve_args(args)
19
+ pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
20
+ @rules << [pattern, deps, block]
21
+ end
22
+
23
+ def define_task(task_class, *args, &block)
24
+ task_name, arg_names, deps = resolve_args(args)
25
+ task_name = task_class.scope_name(@scope, task_name)
26
+ deps = [deps] unless deps.respond_to?(:to_ary)
27
+ deps = deps.collect {|d| d.to_s }
28
+ task = intern(task_class, task_name)
29
+ task.set_arg_names(arg_names) unless arg_names.empty?
30
+ if Rake::TaskManager.record_task_metadata
31
+ add_location(task)
32
+ task.add_description(get_description(task))
33
+ end
34
+ task.enhance(deps, &block)
35
+ end
36
+
37
+ # Lookup a task. Return an existing task if found, otherwise
38
+ # create a task of the current type.
39
+ def intern(task_class, task_name)
40
+ @tasks[task_name.to_s] ||= task_class.new(task_name, self)
41
+ end
42
+
43
+ # Find a matching task for +task_name+.
44
+ def [](task_name, scopes=nil)
45
+ task_name = task_name.to_s
46
+ self.lookup(task_name, scopes) or
47
+ enhance_with_matching_rule(task_name) or
48
+ synthesize_file_task(task_name) or
49
+ fail "Don't know how to build task '#{task_name}'"
50
+ end
51
+
52
+ def synthesize_file_task(task_name)
53
+ return nil unless File.exist?(task_name)
54
+ define_task(Rake::FileTask, task_name)
55
+ end
56
+
57
+ # Resolve the arguments for a task/rule. Returns a triplet of
58
+ # [task_name, arg_name_list, prerequisites].
59
+ def resolve_args(args)
60
+ if args.last.is_a?(Hash)
61
+ deps = args.pop
62
+ resolve_args_with_dependencies(args, deps)
63
+ else
64
+ resolve_args_without_dependencies(args)
65
+ end
66
+ end
67
+
68
+ # Resolve task arguments for a task or rule when there are no
69
+ # dependencies declared.
70
+ #
71
+ # The patterns recognized by this argument resolving function are:
72
+ #
73
+ # task :t
74
+ # task :t, [:a]
75
+ # task :t, :a (deprecated)
76
+ #
77
+ def resolve_args_without_dependencies(args)
78
+ task_name = args.shift
79
+ if args.size == 1 && args.first.respond_to?(:to_ary)
80
+ arg_names = args.first.to_ary
81
+ else
82
+ arg_names = args
83
+ end
84
+ [task_name, arg_names, []]
85
+ end
86
+ private :resolve_args_without_dependencies
87
+
88
+ # Resolve task arguments for a task or rule when there are
89
+ # dependencies declared.
90
+ #
91
+ # The patterns recognized by this argument resolving function are:
92
+ #
93
+ # task :t => [:d]
94
+ # task :t, [a] => [:d]
95
+ # task :t, :needs => [:d] (deprecated)
96
+ # task :t, :a, :needs => [:d] (deprecated)
97
+ #
98
+ def resolve_args_with_dependencies(args, hash) # :nodoc:
99
+ fail "Task Argument Error" if hash.size != 1
100
+ key, value = hash.map { |k, v| [k,v] }.first
101
+ if args.empty?
102
+ task_name = key
103
+ arg_names = []
104
+ deps = value
105
+ elsif key == :needs
106
+ task_name = args.shift
107
+ arg_names = args
108
+ deps = value
109
+ else
110
+ task_name = args.shift
111
+ arg_names = key
112
+ deps = value
113
+ end
114
+ deps = [deps] unless deps.respond_to?(:to_ary)
115
+ [task_name, arg_names, deps]
116
+ end
117
+ private :resolve_args_with_dependencies
118
+
119
+ # If a rule can be found that matches the task name, enhance the
120
+ # task with the prerequisites and actions from the rule. Set the
121
+ # source attribute of the task appropriately for the rule. Return
122
+ # the enhanced task or nil of no rule was found.
123
+ def enhance_with_matching_rule(task_name, level=0)
124
+ fail Rake::RuleRecursionOverflowError,
125
+ "Rule Recursion Too Deep" if level >= 16
126
+ @rules.each do |pattern, extensions, block|
127
+ if pattern.match(task_name)
128
+ task = attempt_rule(task_name, extensions, block, level)
129
+ return task if task
130
+ end
131
+ end
132
+ nil
133
+ rescue Rake::RuleRecursionOverflowError => ex
134
+ ex.add_target(task_name)
135
+ fail ex
136
+ end
137
+
138
+ # List of all defined tasks in this application.
139
+ def tasks
140
+ @tasks.values.sort_by { |t| t.name }
141
+ end
142
+
143
+ # List of all the tasks defined in the given scope (and its
144
+ # sub-scopes).
145
+ def tasks_in_scope(scope)
146
+ prefix = scope.join(":")
147
+ tasks.select { |t|
148
+ /^#{prefix}:/ =~ t.name
149
+ }
150
+ end
151
+
152
+ # Clear all tasks in this application.
153
+ def clear
154
+ @tasks.clear
155
+ @rules.clear
156
+ end
157
+
158
+ # Lookup a task, using scope and the scope hints in the task name.
159
+ # This method performs straight lookups without trying to
160
+ # synthesize file tasks or rules. Special scope names (e.g. '^')
161
+ # are recognized. If no scope argument is supplied, use the
162
+ # current scope. Return nil if the task cannot be found.
163
+ def lookup(task_name, initial_scope=nil)
164
+ initial_scope ||= @scope
165
+ task_name = task_name.to_s
166
+ if task_name =~ /^rake:/
167
+ scopes = []
168
+ task_name = task_name.sub(/^rake:/, '')
169
+ elsif task_name =~ /^(\^+)/
170
+ scopes = initial_scope[0, initial_scope.size - $1.size]
171
+ task_name = task_name.sub(/^(\^+)/, '')
172
+ else
173
+ scopes = initial_scope
174
+ end
175
+ lookup_in_scope(task_name, scopes)
176
+ end
177
+
178
+ # Lookup the task name
179
+ def lookup_in_scope(name, scope)
180
+ n = scope.size
181
+ while n >= 0
182
+ tn = (scope[0,n] + [name]).join(':')
183
+ task = @tasks[tn]
184
+ return task if task
185
+ n -= 1
186
+ end
187
+ nil
188
+ end
189
+ private :lookup_in_scope
190
+
191
+ # Return the list of scope names currently active in the task
192
+ # manager.
193
+ def current_scope
194
+ @scope.dup
195
+ end
196
+
197
+ # Evaluate the block in a nested namespace named +name+. Create
198
+ # an anonymous namespace if +name+ is nil.
199
+ def in_namespace(name)
200
+ name ||= generate_name
201
+ @scope.push(name)
202
+ ns = NameSpace.new(self, @scope)
203
+ yield(ns)
204
+ ns
205
+ ensure
206
+ @scope.pop
207
+ end
208
+
209
+ private
210
+
211
+ # Add a location to the locations field of the given task.
212
+ def add_location(task)
213
+ loc = find_location
214
+ task.locations << loc if loc
215
+ task
216
+ end
217
+
218
+ # Find the location that called into the dsl layer.
219
+ def find_location
220
+ locations = caller
221
+ i = 0
222
+ while locations[i]
223
+ return locations[i+1] if locations[i] =~ /rake\/dsl_definition.rb/
224
+ i += 1
225
+ end
226
+ nil
227
+ end
228
+
229
+ # Generate an anonymous namespace name.
230
+ def generate_name
231
+ @seed ||= 0
232
+ @seed += 1
233
+ "_anon_#{@seed}"
234
+ end
235
+
236
+ def trace_rule(level, message)
237
+ $stderr.puts "#{" "*level}#{message}" if
238
+ Rake.application.options.trace_rules
239
+ end
240
+
241
+ # Attempt to create a rule given the list of prerequisites.
242
+ def attempt_rule(task_name, extensions, block, level)
243
+ sources = make_sources(task_name, extensions)
244
+ prereqs = sources.collect { |source|
245
+ trace_rule level, "Attempting Rule #{task_name} => #{source}"
246
+ if File.exist?(source) || Rake::Task.task_defined?(source)
247
+ trace_rule level, "(#{task_name} => #{source} ... EXIST)"
248
+ source
249
+ elsif parent = enhance_with_matching_rule(source, level+1)
250
+ trace_rule level, "(#{task_name} => #{source} ... ENHANCE)"
251
+ parent.name
252
+ else
253
+ trace_rule level, "(#{task_name} => #{source} ... FAIL)"
254
+ return nil
255
+ end
256
+ }
257
+ task = FileTask.define_task({task_name => prereqs}, &block)
258
+ task.sources = prereqs
259
+ task
260
+ end
261
+
262
+ # Make a list of sources from the list of file name extensions /
263
+ # translation procs.
264
+ def make_sources(task_name, extensions)
265
+ extensions.collect { |ext|
266
+ case ext
267
+ when /%/
268
+ task_name.pathmap(ext)
269
+ when %r{/}
270
+ ext
271
+ when /^\./
272
+ task_name.ext(ext)
273
+ when String
274
+ ext
275
+ when Proc
276
+ if ext.arity == 1
277
+ ext.call(task_name)
278
+ else
279
+ ext.call
280
+ end
281
+ else
282
+ fail "Don't know how to handle rule dependent: #{ext.inspect}"
283
+ end
284
+ }.flatten
285
+ end
286
+
287
+
288
+ private
289
+
290
+ # Return the current description. If there isn't one, try to find it
291
+ # by reading in the source file and looking for a comment immediately
292
+ # prior to the task definition
293
+ def get_description(task)
294
+ desc = @last_description || find_preceding_comment_for_task(task)
295
+ @last_description = nil
296
+ desc
297
+ end
298
+
299
+ def find_preceding_comment_for_task(task)
300
+ loc = task.locations.last
301
+ file_name, line = parse_location(loc)
302
+ return nil unless file_name
303
+ comment_from_file(file_name, line)
304
+ end
305
+
306
+ def parse_location(loc)
307
+ if loc =~ /^(.*):(\d+)/
308
+ [ $1, Integer($2) ]
309
+ else
310
+ nil
311
+ end
312
+ end
313
+
314
+ def comment_from_file(file_name, line)
315
+ return if file_name == '(eval)'
316
+ @file_cache ||= {}
317
+ content = (@file_cache[file_name] ||= File.readlines(file_name))
318
+ line -= 2
319
+ return nil unless content[line] =~ /^\s*#\s*(.*)/
320
+ $1
321
+ end
322
+
323
+ class << self
324
+ attr_accessor :record_task_metadata
325
+ TaskManager.record_task_metadata = false
326
+ end
327
+ end
328
+
329
+ end
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env ruby
2
-
3
1
  require 'rake'
4
2
 
5
3
  module Rake
@@ -7,6 +5,7 @@ module Rake
7
5
  # Base class for Task Libraries.
8
6
  class TaskLib
9
7
  include Cloneable
8
+ include Rake::DSL
10
9
 
11
10
  # Make a symbol by pasting two strings together.
12
11
  #
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env ruby
2
-
3
1
  # Define a task library for running unit tests.
4
2
 
5
3
  require 'rake'
@@ -10,7 +8,7 @@ module Rake
10
8
  # Create a task that runs a set of tests.
11
9
  #
12
10
  # Example:
13
- #
11
+ #
14
12
  # Rake::TestTask.new do |t|
15
13
  # t.libs << "test"
16
14
  # t.test_files = FileList['test/test*.rb']
@@ -63,7 +61,7 @@ module Rake
63
61
  # * :rake -- Rake provided test loading script (default).
64
62
  # * :testrb -- Ruby provided test loading script.
65
63
  # * :direct -- Load tests using command line loader.
66
- #
64
+ #
67
65
  attr_accessor :loader
68
66
 
69
67
  # Array of commandline options to pass to ruby when running test loader.
@@ -95,26 +93,10 @@ module Rake
95
93
 
96
94
  # Create the tasks defined by this task lib.
97
95
  def define
98
- lib_path = @libs.join(File::PATH_SEPARATOR)
99
96
  desc "Run tests" + (@name==:test ? "" : " for #{@name}")
100
97
  task @name do
101
- run_code = ''
102
- RakeFileUtils.verbose(@verbose) do
103
- run_code =
104
- case @loader
105
- when :direct
106
- "-e 'ARGV.each{|f| load f}'"
107
- when :testrb
108
- "-S testrb #{fix}"
109
- when :rake
110
- rake_loader
111
- end
112
- @ruby_opts.unshift( "-I\"#{lib_path}\"" )
113
- @ruby_opts.unshift( "-w" ) if @warning
114
- ruby @ruby_opts.join(" ") +
115
- " \"#{run_code}\" " +
116
- file_list.collect { |fn| "\"#{fn}\"" }.join(' ') +
117
- " #{option_list}"
98
+ FileUtilsExt.verbose(@verbose) do
99
+ ruby "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}"
118
100
  end
119
101
  end
120
102
  self
@@ -124,26 +106,56 @@ module Rake
124
106
  ENV['TESTOPTS'] || @options || ""
125
107
  end
126
108
 
109
+ def ruby_opts_string
110
+ opts = @ruby_opts.dup
111
+ opts.unshift( "-I\"#{lib_path}\"" ) unless @libs.empty?
112
+ opts.unshift( "-w" ) if @warning
113
+ opts.join(" ")
114
+ end
115
+
116
+ def lib_path
117
+ @libs.join(File::PATH_SEPARATOR)
118
+ end
119
+
120
+ def file_list_string
121
+ file_list.collect { |fn| "\"#{fn}\"" }.join(' ')
122
+ end
123
+
127
124
  def file_list # :nodoc:
128
125
  if ENV['TEST']
129
126
  FileList[ ENV['TEST'] ]
130
127
  else
131
128
  result = []
132
129
  result += @test_files.to_a if @test_files
133
- result += FileList[ @pattern ].to_a if @pattern
134
- FileList[result]
130
+ result << @pattern if @pattern
131
+ result
135
132
  end
136
133
  end
137
134
 
138
135
  def fix # :nodoc:
139
- case RUBY_VERSION
136
+ case ruby_version
140
137
  when '1.8.2'
141
- find_file 'rake/ruby182_test_unit_fix'
138
+ "\"#{find_file 'rake/ruby182_test_unit_fix'}\""
142
139
  else
143
140
  nil
144
141
  end || ''
145
142
  end
146
143
 
144
+ def ruby_version
145
+ RUBY_VERSION
146
+ end
147
+
148
+ def run_code
149
+ case @loader
150
+ when :direct
151
+ "-e \"ARGV.each{|f| require f}\""
152
+ when :testrb
153
+ "-S testrb #{fix}"
154
+ when :rake
155
+ "-I\"#{rake_lib_dir}\" \"#{rake_loader}\""
156
+ end
157
+ end
158
+
147
159
  def rake_loader # :nodoc:
148
160
  find_file('rake/rake_test_loader') or
149
161
  fail "unable to find rake test loader"
@@ -157,5 +169,18 @@ module Rake
157
169
  nil
158
170
  end
159
171
 
172
+ def rake_lib_dir # :nodoc:
173
+ find_dir('rake') or
174
+ fail "unable to find rake lib"
175
+ end
176
+
177
+ def find_dir(fn) # :nodoc:
178
+ $LOAD_PATH.each do |path|
179
+ file_path = File.join(path, "#{fn}.rb")
180
+ return path if File.exist? file_path
181
+ end
182
+ nil
183
+ end
184
+
160
185
  end
161
186
  end