rake 10.0.4 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/doc/command_line_usage.rdoc +1 -1
  4. data/doc/rakefile.rdoc +27 -13
  5. data/doc/release_notes/rake-10.1.0.rdoc +61 -0
  6. data/install.rb +5 -15
  7. data/lib/rake/alt_system.rb +3 -4
  8. data/lib/rake/application.rb +115 -68
  9. data/lib/rake/backtrace.rb +9 -8
  10. data/lib/rake/clean.rb +27 -4
  11. data/lib/rake/contrib/ftptools.rb +6 -18
  12. data/lib/rake/contrib/sys.rb +2 -1
  13. data/lib/rake/dsl_definition.rb +2 -1
  14. data/lib/rake/ext/core.rb +2 -1
  15. data/lib/rake/ext/string.rb +1 -3
  16. data/lib/rake/file_list.rb +24 -18
  17. data/lib/rake/file_task.rb +1 -2
  18. data/lib/rake/file_utils.rb +9 -7
  19. data/lib/rake/file_utils_ext.rb +2 -1
  20. data/lib/rake/gempackagetask.rb +2 -1
  21. data/lib/rake/invocation_chain.rb +24 -18
  22. data/lib/rake/linked_list.rb +103 -0
  23. data/lib/rake/packagetask.rb +11 -6
  24. data/lib/rake/pseudo_status.rb +5 -0
  25. data/lib/rake/rdoctask.rb +2 -1
  26. data/lib/rake/ruby182_test_unit_fix.rb +4 -2
  27. data/lib/rake/runtest.rb +2 -2
  28. data/lib/rake/scope.rb +42 -0
  29. data/lib/rake/task.rb +47 -37
  30. data/lib/rake/task_arguments.rb +13 -2
  31. data/lib/rake/task_manager.rb +25 -24
  32. data/lib/rake/tasklib.rb +1 -1
  33. data/lib/rake/testtask.rb +10 -7
  34. data/lib/rake/thread_history_display.rb +1 -1
  35. data/lib/rake/thread_pool.rb +10 -4
  36. data/lib/rake/version.rb +3 -7
  37. data/lib/rake/win32.rb +3 -2
  38. data/lib/rake.rb +2 -0
  39. data/test/helper.rb +36 -470
  40. data/test/support/rakefile_definitions.rb +444 -0
  41. data/test/support/ruby_runner.rb +33 -0
  42. data/test/test_rake_application.rb +14 -12
  43. data/test/test_rake_application_options.rb +7 -5
  44. data/test/test_rake_backtrace.rb +38 -14
  45. data/test/test_rake_clean.rb +36 -4
  46. data/test/test_rake_definitions.rb +2 -3
  47. data/test/test_rake_file_creation_task.rb +2 -2
  48. data/test/test_rake_file_list.rb +23 -24
  49. data/test/test_rake_file_task.rb +4 -4
  50. data/test/test_rake_file_utils.rb +6 -2
  51. data/test/test_rake_ftp_file.rb +28 -13
  52. data/test/test_rake_functional.rb +6 -36
  53. data/test/test_rake_invocation_chain.rb +15 -3
  54. data/test/test_rake_linked_list.rb +84 -0
  55. data/test/test_rake_makefile_loader.rb +3 -1
  56. data/test/test_rake_multi_task.rb +2 -3
  57. data/test/test_rake_name_space.rb +1 -1
  58. data/test/test_rake_path_map.rb +23 -12
  59. data/test/test_rake_rake_test_loader.rb +2 -3
  60. data/test/test_rake_reduce_compat.rb +2 -6
  61. data/test/test_rake_rules.rb +47 -12
  62. data/test/test_rake_scope.rb +44 -0
  63. data/test/test_rake_task.rb +47 -11
  64. data/test/test_rake_task_arguments.rb +35 -2
  65. data/test/test_rake_task_manager.rb +16 -15
  66. data/test/test_rake_task_with_arguments.rb +2 -2
  67. data/test/test_rake_test_task.rb +1 -2
  68. data/test/test_rake_thread_pool.rb +36 -16
  69. data/test/test_thread_history_display.rb +16 -6
  70. data/test/test_trace_output.rb +2 -0
  71. metadata +10 -2
data/lib/rake/task.rb CHANGED
@@ -21,13 +21,6 @@ module Rake
21
21
  # Application owning this task.
22
22
  attr_accessor :application
23
23
 
24
- # Comment for this task. Restricted to a single line of no more than 50
25
- # characters.
26
- attr_reader :comment
27
-
28
- # Full text of the (possibly multi-line) comment.
29
- attr_reader :full_comment
30
-
31
24
  # Array of nested namespaces names used for task lookup by this task.
32
25
  attr_reader :scope
33
26
 
@@ -53,7 +46,7 @@ module Rake
53
46
 
54
47
  # List of prerequisite tasks
55
48
  def prerequisite_tasks
56
- prerequisites.collect { |pre| lookup_prerequisite(pre) }
49
+ prerequisites.map { |pre| lookup_prerequisite(pre) }
57
50
  end
58
51
 
59
52
  def lookup_prerequisite(prerequisite_name)
@@ -91,8 +84,7 @@ module Rake
91
84
  @prerequisites = []
92
85
  @actions = []
93
86
  @already_invoked = false
94
- @full_comment = nil
95
- @comment = nil
87
+ @comments = []
96
88
  @lock = Monitor.new
97
89
  @application = app
98
90
  @scope = app.current_scope
@@ -159,8 +151,7 @@ module Rake
159
151
 
160
152
  # Clear the existing comments on a rake task.
161
153
  def clear_comments
162
- @full_comment = nil
163
- @comment = nil
154
+ @comments = []
164
155
  self
165
156
  end
166
157
 
@@ -190,7 +181,8 @@ module Rake
190
181
  protected :invoke_with_call_chain
191
182
 
192
183
  def add_chain_to(exception, new_chain)
193
- exception.extend(InvocationExceptionMixin) unless exception.respond_to?(:chain)
184
+ exception.extend(InvocationExceptionMixin) unless
185
+ exception.respond_to?(:chain)
194
186
  exception.chain = new_chain if exception.chain.nil?
195
187
  end
196
188
  private :add_chain_to
@@ -208,8 +200,8 @@ module Rake
208
200
  end
209
201
 
210
202
  # Invoke all the prerequisites of a task in parallel.
211
- def invoke_prerequisites_concurrently(task_args, invocation_chain) # :nodoc:
212
- futures = prerequisite_tasks.collect do |p|
203
+ def invoke_prerequisites_concurrently(task_args, invocation_chain)# :nodoc:
204
+ futures = prerequisite_tasks.map do |p|
213
205
  prereq_args = task_args.new_scope(p.arg_names)
214
206
  application.thread_pool.future(p) do |r|
215
207
  r.invoke_with_call_chain(prereq_args, invocation_chain)
@@ -234,9 +226,7 @@ module Rake
234
226
  application.trace "** Execute (dry run) #{name}"
235
227
  return
236
228
  end
237
- if application.options.trace
238
- application.trace "** Execute #{name}"
239
- end
229
+ application.trace "** Execute #{name}" if application.options.trace
240
230
  application.enhance_with_matching_rule(name) if @actions.empty?
241
231
  @actions.each do |act|
242
232
  case act.arity
@@ -262,32 +252,51 @@ module Rake
262
252
  # Add a description to the task. The description can consist of an option
263
253
  # argument list (enclosed brackets) and an optional comment.
264
254
  def add_description(description)
265
- return if ! description
255
+ return unless description
266
256
  comment = description.strip
267
257
  add_comment(comment) if comment && ! comment.empty?
268
258
  end
269
259
 
270
- # Writing to the comment attribute is the same as adding a description.
271
- def comment=(description)
272
- add_description(description)
260
+ def comment=(comment)
261
+ add_comment(comment)
273
262
  end
274
263
 
275
- # Add a comment to the task. If a comment already exists, separate
276
- # the new comment with " / ".
277
264
  def add_comment(comment)
278
- if @full_comment
279
- @full_comment << " / "
280
- else
281
- @full_comment = ''
282
- end
283
- @full_comment << comment
284
- if @full_comment =~ /\A([^.]+?\.)( |$)/
285
- @comment = $1
265
+ @comments << comment unless @comments.include?(comment)
266
+ end
267
+ private :add_comment
268
+
269
+ # Full collection of comments. Multiple comments are separated by
270
+ # newlines.
271
+ def full_comment
272
+ transform_comments("\n")
273
+ end
274
+
275
+ # First line (or sentence) of all comments. Multiple comments are
276
+ # separated by a "/".
277
+ def comment
278
+ transform_comments(" / ") { |c| first_sentence(c) }
279
+ end
280
+
281
+ # Transform the list of comments as specified by the block and
282
+ # join with the separator.
283
+ def transform_comments(separator, &block)
284
+ if @comments.empty?
285
+ nil
286
286
  else
287
- @comment = @full_comment
287
+ block ||= lambda { |c| c }
288
+ @comments.map(&block).join(separator)
288
289
  end
289
290
  end
290
- private :add_comment
291
+ private :transform_comments
292
+
293
+ # Get the first sentence in a string. The sentence is terminated
294
+ # by the first period or the end of the line. Decimal points do
295
+ # not count as periods.
296
+ def first_sentence(string)
297
+ string.split(/\.[ \t]|\.$|\n/).first
298
+ end
299
+ private :first_sentence
291
300
 
292
301
  # Set the names of the arguments for this task. +args+ should be
293
302
  # an array of symbols, one for each argument name.
@@ -305,11 +314,11 @@ module Rake
305
314
  result << "timestamp: #{timestamp}\n"
306
315
  result << "pre-requisites: \n"
307
316
  prereqs = prerequisite_tasks
308
- prereqs.sort! {|a,b| a.timestamp <=> b.timestamp}
317
+ prereqs.sort! { |a, b| a.timestamp <=> b.timestamp }
309
318
  prereqs.each do |p|
310
319
  result << "--#{p.name} (#{p.timestamp})\n"
311
320
  end
312
- latest_prereq = prerequisite_tasks.collect { |pre| pre.timestamp }.max
321
+ latest_prereq = prerequisite_tasks.map { |pre| pre.timestamp }.max
313
322
  result << "latest-prerequisite time: #{latest_prereq}\n"
314
323
  result << "................................\n\n"
315
324
  return result
@@ -360,7 +369,8 @@ module Rake
360
369
  # this kind of task. Generic tasks will accept the scope as
361
370
  # part of the name.
362
371
  def scope_name(scope, task_name)
363
- (scope + [task_name]).join(':')
372
+ # (scope + [task_name]).join(':')
373
+ scope.path_with_task_name(task_name)
364
374
  end
365
375
 
366
376
  end # class << Rake::Task
@@ -15,16 +15,27 @@ module Rake
15
15
  @names = names
16
16
  @parent = parent
17
17
  @hash = {}
18
+ @values = values
18
19
  names.each_with_index { |name, i|
19
20
  @hash[name.to_sym] = values[i] unless values[i].nil?
20
21
  }
21
22
  end
22
23
 
24
+ # Retrive the complete array of sequential values
25
+ def to_a
26
+ @values.dup
27
+ end
28
+
29
+ # Retrive the list of values not associated with named arguments
30
+ def extras
31
+ @values[@names.length..-1] || []
32
+ end
33
+
23
34
  # Create a new argument scope using the prerequisite argument
24
35
  # names.
25
36
  def new_scope(names)
26
- values = names.collect { |n| self[n] }
27
- self.class.new(names, values, self)
37
+ values = names.map { |n| self[n] }
38
+ self.class.new(names, values + extras, self)
28
39
  end
29
40
 
30
41
  # Find an argument value by name or index.
@@ -10,21 +10,21 @@ module Rake
10
10
  super
11
11
  @tasks = Hash.new
12
12
  @rules = Array.new
13
- @scope = Array.new
13
+ @scope = Scope.make
14
14
  @last_description = nil
15
15
  end
16
16
 
17
17
  def create_rule(*args, &block)
18
- pattern, _, deps = resolve_args(args)
18
+ pattern, args, deps = resolve_args(args)
19
19
  pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
20
- @rules << [pattern, deps, block]
20
+ @rules << [pattern, args, deps, block]
21
21
  end
22
22
 
23
23
  def define_task(task_class, *args, &block)
24
24
  task_name, arg_names, deps = resolve_args(args)
25
25
  task_name = task_class.scope_name(@scope, task_name)
26
26
  deps = [deps] unless deps.respond_to?(:to_ary)
27
- deps = deps.collect {|d| d.to_s }
27
+ deps = deps.map { |d| d.to_s }
28
28
  task = intern(task_class, task_name)
29
29
  task.set_arg_names(arg_names) unless arg_names.empty?
30
30
  if Rake::TaskManager.record_task_metadata
@@ -94,7 +94,7 @@ module Rake
94
94
  #
95
95
  def resolve_args_with_dependencies(args, hash) # :nodoc:
96
96
  fail "Task Argument Error" if hash.size != 1
97
- key, value = hash.map { |k, v| [k,v] }.first
97
+ key, value = hash.map { |k, v| [k, v] }.first
98
98
  if args.empty?
99
99
  task_name = key
100
100
  arg_names = []
@@ -116,9 +116,9 @@ module Rake
116
116
  def enhance_with_matching_rule(task_name, level=0)
117
117
  fail Rake::RuleRecursionOverflowError,
118
118
  "Rule Recursion Too Deep" if level >= 16
119
- @rules.each do |pattern, extensions, block|
119
+ @rules.each do |pattern, args, extensions, block|
120
120
  if pattern.match(task_name)
121
- task = attempt_rule(task_name, extensions, block, level)
121
+ task = attempt_rule(task_name, args, extensions, block, level)
122
122
  return task if task
123
123
  end
124
124
  end
@@ -136,7 +136,7 @@ module Rake
136
136
  # List of all the tasks defined in the given scope (and its
137
137
  # sub-scopes).
138
138
  def tasks_in_scope(scope)
139
- prefix = scope.join(":")
139
+ prefix = scope.path
140
140
  tasks.select { |t|
141
141
  /^#{prefix}:/ =~ t.name
142
142
  }
@@ -157,10 +157,10 @@ module Rake
157
157
  initial_scope ||= @scope
158
158
  task_name = task_name.to_s
159
159
  if task_name =~ /^rake:/
160
- scopes = []
160
+ scopes = Scope.make
161
161
  task_name = task_name.sub(/^rake:/, '')
162
162
  elsif task_name =~ /^(\^+)/
163
- scopes = initial_scope[0, initial_scope.size - $1.size]
163
+ scopes = initial_scope.trim($1.size)
164
164
  task_name = task_name.sub(/^(\^+)/, '')
165
165
  else
166
166
  scopes = initial_scope
@@ -170,12 +170,12 @@ module Rake
170
170
 
171
171
  # Lookup the task name
172
172
  def lookup_in_scope(name, scope)
173
- n = scope.size
174
- while n >= 0
175
- tn = (scope[0,n] + [name]).join(':')
173
+ loop do
174
+ tn = scope.path_with_task_name(name)
176
175
  task = @tasks[tn]
177
176
  return task if task
178
- n -= 1
177
+ break if scope.empty?
178
+ scope = scope.tail
179
179
  end
180
180
  nil
181
181
  end
@@ -184,19 +184,19 @@ module Rake
184
184
  # Return the list of scope names currently active in the task
185
185
  # manager.
186
186
  def current_scope
187
- @scope.dup
187
+ @scope
188
188
  end
189
189
 
190
190
  # Evaluate the block in a nested namespace named +name+. Create
191
191
  # an anonymous namespace if +name+ is nil.
192
192
  def in_namespace(name)
193
193
  name ||= generate_name
194
- @scope.push(name)
194
+ @scope = Scope.new(name, @scope)
195
195
  ns = NameSpace.new(self, @scope)
196
196
  yield(ns)
197
197
  ns
198
198
  ensure
199
- @scope.pop
199
+ @scope = @scope.tail
200
200
  end
201
201
 
202
202
  private
@@ -213,7 +213,7 @@ module Rake
213
213
  locations = caller
214
214
  i = 0
215
215
  while locations[i]
216
- return locations[i+1] if locations[i] =~ /rake\/dsl_definition.rb/
216
+ return locations[i + 1] if locations[i] =~ /rake\/dsl_definition.rb/
217
217
  i += 1
218
218
  end
219
219
  nil
@@ -227,18 +227,19 @@ module Rake
227
227
  end
228
228
 
229
229
  def trace_rule(level, message)
230
- options.trace_output.puts "#{" "*level}#{message}" if Rake.application.options.trace_rules
230
+ options.trace_output.puts "#{" " * level}#{message}" if
231
+ Rake.application.options.trace_rules
231
232
  end
232
233
 
233
234
  # Attempt to create a rule given the list of prerequisites.
234
- def attempt_rule(task_name, extensions, block, level)
235
+ def attempt_rule(task_name, args, extensions, block, level)
235
236
  sources = make_sources(task_name, extensions)
236
- prereqs = sources.collect { |source|
237
+ prereqs = sources.map { |source|
237
238
  trace_rule level, "Attempting Rule #{task_name} => #{source}"
238
239
  if File.exist?(source) || Rake::Task.task_defined?(source)
239
240
  trace_rule level, "(#{task_name} => #{source} ... EXIST)"
240
241
  source
241
- elsif parent = enhance_with_matching_rule(source, level+1)
242
+ elsif parent = enhance_with_matching_rule(source, level + 1)
242
243
  trace_rule level, "(#{task_name} => #{source} ... ENHANCE)"
243
244
  parent.name
244
245
  else
@@ -246,7 +247,7 @@ module Rake
246
247
  return nil
247
248
  end
248
249
  }
249
- task = FileTask.define_task({task_name => prereqs}, &block)
250
+ task = FileTask.define_task(task_name, {args => prereqs}, &block)
250
251
  task.sources = prereqs
251
252
  task
252
253
  end
@@ -254,7 +255,7 @@ module Rake
254
255
  # Make a list of sources from the list of file name extensions /
255
256
  # translation procs.
256
257
  def make_sources(task_name, extensions)
257
- result = extensions.collect { |ext|
258
+ result = extensions.map { |ext|
258
259
  case ext
259
260
  when /%/
260
261
  task_name.pathmap(ext)
data/lib/rake/tasklib.rb CHANGED
@@ -14,7 +14,7 @@ module Rake
14
14
  # libraries depend on this so I can't remove it without breaking
15
15
  # other people's code. So for now it stays for backwards
16
16
  # compatibility. BUT DON'T USE IT.
17
- def paste(a,b) # :nodoc:
17
+ def paste(a, b) # :nodoc:
18
18
  (a.to_s + b.to_s).intern
19
19
  end
20
20
  end
data/lib/rake/testtask.rb CHANGED
@@ -93,15 +93,18 @@ module Rake
93
93
 
94
94
  # Create the tasks defined by this task lib.
95
95
  def define
96
- desc "Run tests" + (@name==:test ? "" : " for #{@name}")
96
+ desc "Run tests" + (@name == :test ? "" : " for #{@name}")
97
97
  task @name do
98
98
  FileUtilsExt.verbose(@verbose) do
99
- args = "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}"
99
+ args =
100
+ "#{ruby_opts_string} #{run_code} " +
101
+ "#{file_list_string} #{option_list}"
100
102
  ruby args do |ok, status|
101
103
  if !ok && status.respond_to?(:signaled?) && status.signaled?
102
104
  raise SignalException.new(status.termsig)
103
105
  elsif !ok
104
- fail "Command failed with status (#{status.exitstatus}): [ruby #{args}]"
106
+ fail "Command failed with status (#{status.exitstatus}): " +
107
+ "[ruby #{args}]"
105
108
  end
106
109
  end
107
110
  end
@@ -120,8 +123,8 @@ module Rake
120
123
 
121
124
  def ruby_opts_string
122
125
  opts = @ruby_opts.dup
123
- opts.unshift( "-I\"#{lib_path}\"" ) unless @libs.empty?
124
- opts.unshift( "-w" ) if @warning
126
+ opts.unshift("-I\"#{lib_path}\"") unless @libs.empty?
127
+ opts.unshift("-w") if @warning
125
128
  opts.join(" ")
126
129
  end
127
130
 
@@ -130,12 +133,12 @@ module Rake
130
133
  end
131
134
 
132
135
  def file_list_string
133
- file_list.collect { |fn| "\"#{fn}\"" }.join(' ')
136
+ file_list.map { |fn| "\"#{fn}\"" }.join(' ')
134
137
  end
135
138
 
136
139
  def file_list # :nodoc:
137
140
  if ENV['TEST']
138
- FileList[ ENV['TEST'] ]
141
+ FileList[ENV['TEST']]
139
142
  else
140
143
  result = []
141
144
  result += @test_files.to_a if @test_files
@@ -25,7 +25,7 @@ module Rake
25
25
  (stat[:time] * 1_000_000).round,
26
26
  stat[:thread],
27
27
  stat[:event],
28
- stat[:data].map { |k,v| "#{k}:#{v}" }.join(" "))
28
+ stat[:data].map do |k, v| "#{k}:#{v}" end.join(" "))
29
29
  end
30
30
  end
31
31
 
@@ -50,8 +50,10 @@ module Rake
50
50
  rescue Exception => e
51
51
  stat :joined
52
52
  $stderr.puts e
53
- $stderr.print "Queue contains #{@queue.size} items. Thread pool contains #{@threads.count} threads\n"
54
- $stderr.print "Current Thread #{Thread.current} status = #{Thread.current.status}\n"
53
+ $stderr.print "Queue contains #{@queue.size} items. " +
54
+ "Thread pool contains #{@threads.count} threads\n"
55
+ $stderr.print "Current Thread #{Thread.current} status = " +
56
+ "#{Thread.current.status}\n"
55
57
  $stderr.puts e.backtrace.join("\n")
56
58
  @threads.each do |t|
57
59
  $stderr.print "Thread #{t} status = #{t.status}\n"
@@ -125,8 +127,12 @@ module Rake
125
127
  end
126
128
  end
127
129
  @threads << t
128
- stat :spawned, :new_thread => t.object_id, :thread_count => @threads.count
129
- @total_threads_in_play = @threads.count if @threads.count > @total_threads_in_play
130
+ stat(
131
+ :spawned,
132
+ :new_thread => t.object_id,
133
+ :thread_count => @threads.count)
134
+ @total_threads_in_play = @threads.count if
135
+ @threads.count > @total_threads_in_play
130
136
  end
131
137
  end
132
138
 
data/lib/rake/version.rb CHANGED
@@ -1,13 +1,9 @@
1
1
  module Rake
2
- VERSION = '10.0.4'
2
+ VERSION = '10.1.0'
3
3
 
4
4
  module Version # :nodoc: all
5
- MAJOR, MINOR, BUILD, = Rake::VERSION.split '.'
5
+ MAJOR, MINOR, BUILD, *OTHER = Rake::VERSION.split '.'
6
6
 
7
- NUMBERS = [
8
- MAJOR,
9
- MINOR,
10
- BUILD,
11
- ]
7
+ NUMBERS = [MAJOR, MINOR, BUILD, *OTHER]
12
8
  end
13
9
  end
data/lib/rake/win32.rb CHANGED
@@ -40,8 +40,9 @@ module Rake
40
40
 
41
41
  win32_shared_path ||= ENV['APPDATA']
42
42
  win32_shared_path ||= ENV['USERPROFILE']
43
- raise Win32HomeError, "Unable to determine home path environment variable." if
44
- win32_shared_path.nil? or win32_shared_path.empty?
43
+ raise Win32HomeError,
44
+ "Unable to determine home path environment variable." if
45
+ win32_shared_path.nil? or win32_shared_path.empty?
45
46
  normalize(File.join(win32_shared_path, 'Rake'))
46
47
  end
47
48
 
data/lib/rake.rb CHANGED
@@ -40,6 +40,8 @@ require 'rake/ext/time'
40
40
 
41
41
  require 'rake/win32'
42
42
 
43
+ require 'rake/linked_list'
44
+ require 'rake/scope'
43
45
  require 'rake/task_argument_error'
44
46
  require 'rake/rule_recursion_overflow_error'
45
47
  require 'rake/rake_module'