rake 0.9.6 → 10.0.0.beta.1

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 (54) hide show
  1. data/README.rdoc +12 -0
  2. data/Rakefile +0 -1
  3. data/doc/command_line_usage.rdoc +17 -60
  4. data/doc/release_notes/rake-0.9.3.rdoc +23 -70
  5. data/lib/rake.rb +0 -1
  6. data/lib/rake/application.rb +23 -63
  7. data/lib/rake/backtrace.rb +2 -3
  8. data/lib/rake/contrib/ftptools.rb +2 -2
  9. data/lib/rake/dsl_definition.rb +0 -26
  10. data/lib/rake/ext/module.rb +0 -39
  11. data/lib/rake/ext/string.rb +1 -2
  12. data/lib/rake/ext/time.rb +1 -2
  13. data/lib/rake/file_list.rb +1 -8
  14. data/lib/rake/file_utils.rb +1 -1
  15. data/lib/rake/phony.rb +2 -4
  16. data/lib/rake/rake_module.rb +7 -0
  17. data/lib/rake/ruby182_test_unit_fix.rb +0 -0
  18. data/lib/rake/runtest.rb +1 -2
  19. data/lib/rake/task.rb +8 -9
  20. data/lib/rake/task_manager.rb +0 -11
  21. data/lib/rake/testtask.rb +1 -4
  22. data/lib/rake/thread_history_display.rb +4 -7
  23. data/lib/rake/thread_pool.rb +76 -42
  24. data/lib/rake/version.rb +6 -7
  25. data/test/helper.rb +4 -44
  26. data/test/test_rake_application.rb +0 -47
  27. data/test/test_rake_application_options.rb +6 -39
  28. data/test/test_rake_backtrace.rb +11 -33
  29. data/test/test_rake_dsl.rb +0 -37
  30. data/test/test_rake_file_task.rb +4 -4
  31. data/test/test_rake_functional.rb +8 -32
  32. data/test/test_rake_rake_test_loader.rb +1 -1
  33. data/test/test_rake_reduce_compat.rb +5 -33
  34. data/test/test_rake_task_manager_argument_resolution.rb +0 -5
  35. data/test/test_rake_task_with_arguments.rb +6 -17
  36. data/test/test_rake_thread_pool.rb +24 -1
  37. data/test/test_rake_top_level_functions.rb +0 -40
  38. data/test/test_thread_history_display.rb +14 -14
  39. metadata +3 -22
  40. data/doc/release_notes/rake-0.9.2.2.rdoc +0 -55
  41. data/doc/release_notes/rake-0.9.4.rdoc +0 -110
  42. data/doc/release_notes/rake-0.9.5.rdoc +0 -114
  43. data/doc/release_notes/rake-0.9.6.rdoc +0 -127
  44. data/lib/rake/classic_namespace.rb +0 -11
  45. data/lib/rake/contrib/sys.rb +0 -192
  46. data/lib/rake/gempackagetask.rb +0 -15
  47. data/lib/rake/private_reader.rb +0 -20
  48. data/lib/rake/promise.rb +0 -99
  49. data/lib/rake/rdoctask.rb +0 -234
  50. data/lib/rake/trace_output.rb +0 -19
  51. data/test/test_private_reader.rb +0 -42
  52. data/test/test_rake_rdoc_task.rb +0 -83
  53. data/test/test_sys.rb +0 -20
  54. data/test/test_trace_output.rb +0 -43
@@ -2,12 +2,11 @@ module Rake
2
2
  module Backtrace
3
3
  SUPPRESSED_PATHS =
4
4
  RbConfig::CONFIG.values_at(*RbConfig::CONFIG.
5
- keys.grep(/(prefix|libdir)/)).uniq + [
5
+ keys.grep(/(prefix|libdir)/)) + [
6
6
  File.join(File.dirname(__FILE__), ".."),
7
7
  ].map { |f| Regexp.quote(File.expand_path(f)) }
8
- SUPPRESSED_PATHS.reject! { |s| s.nil? || s =~ /^ *$/ }
9
8
 
10
- SUPPRESS_PATTERN = %r!(\A#{SUPPRESSED_PATHS.join('|')}|bin/rake:\d+)!i
9
+ SUPPRESS_PATTERN = %r!(\A#{SUPPRESSED_PATHS.join('|')}|bin/rake:\d+)!
11
10
 
12
11
  def self.collapse(backtrace)
13
12
  pattern = Rake.application.options.suppress_backtrace_pattern ||
@@ -5,7 +5,6 @@
5
5
 
6
6
  require 'date'
7
7
  require 'net/ftp'
8
- require 'rake/file_list'
9
8
 
10
9
  module Rake # :nodoc:
11
10
 
@@ -128,7 +127,8 @@ module Rake # :nodoc:
128
127
  # Upload all files matching +wildcard+ to the uploader's root
129
128
  # path.
130
129
  def upload_files(wildcard)
131
- FileList.glob(wildcard).each do |fn|
130
+ fail "OUCH"
131
+ Rake.glob(wildcard).each do |fn|
132
132
  upload(fn)
133
133
  end
134
134
  end
@@ -32,7 +32,6 @@ module Rake
32
32
  Rake::Task.define_task(*args, &block)
33
33
  end
34
34
 
35
-
36
35
  # Declare a file task.
37
36
  #
38
37
  # Example:
@@ -147,31 +146,7 @@ module Rake
147
146
  Rake.application.add_import(fn)
148
147
  end
149
148
  end
150
-
151
149
  end
152
-
153
- DeprecatedCommands = Object.new.extend(DSL)
154
-
155
- module DeprecatedObjectDSL # :nodoc:
156
- DSL.private_instance_methods(false).each do |name|
157
- line = __LINE__+1
158
- class_eval %{
159
- def #{name}(*args, &block)
160
- unless Rake.application.options.ignore_deprecate
161
- unless @rake_dsl_warning
162
- $stderr.puts "WARNING: Global access to Rake DSL methods is deprecated. Please include"
163
- $stderr.puts " ... Rake::DSL into classes and modules which use the Rake DSL methods."
164
- @rake_dsl_warning = true
165
- end
166
- $stderr.puts "WARNING: DSL method \#{self.class}##{name} called at \#{caller.first}"
167
- end
168
- Rake::DeprecatedCommands.send(:#{name}, *args, &block)
169
- end
170
- private :#{name}
171
- }, __FILE__, line
172
- end
173
- end unless defined? Rake::REDUCE_COMPAT
174
-
175
150
  extend FileUtilsExt
176
151
  end
177
152
 
@@ -179,4 +154,3 @@ end
179
154
  # calls to task, etc. to work from a Rakefile without polluting the
180
155
  # object inheritance tree.
181
156
  self.extend Rake::DSL
182
- include Rake::DeprecatedObjectDSL unless defined? Rake::REDUCE_COMPAT
@@ -1,39 +0,0 @@
1
- require 'rake/ext/core'
2
- require 'rake/task'
3
- require 'rake/file_task'
4
- require 'rake/file_creation_task'
5
- require 'rake/application'
6
- require 'rake/task_manager'
7
-
8
- ######################################################################
9
- # Rake extensions to Module.
10
- #
11
- class Module
12
-
13
- # Rename the original handler to make it available.
14
- alias :rake_original_const_missing :const_missing
15
-
16
- # Check for deprecated uses of top level (i.e. in Object) uses of
17
- # Rake class names. If someone tries to reference the constant
18
- # name, display a warning and return the proper object. Using the
19
- # --classic-namespace command line option will define these
20
- # constants in Object and avoid this handler.
21
- def const_missing(const_name)
22
- case const_name
23
- when :Task
24
- Rake.application.const_warning(const_name)
25
- Rake::Task
26
- when :FileTask
27
- Rake.application.const_warning(const_name)
28
- Rake::FileTask
29
- when :FileCreationTask
30
- Rake.application.const_warning(const_name)
31
- Rake::FileCreationTask
32
- when :RakeApp
33
- Rake.application.const_warning(const_name)
34
- Rake::Application
35
- else
36
- rake_original_const_missing(const_name)
37
- end
38
- end
39
- end unless defined? Rake::REDUCE_COMPAT
@@ -4,7 +4,6 @@ require 'rake/ext/core'
4
4
  # Rake extension methods for String.
5
5
  #
6
6
  class String
7
-
8
7
  rake_extension("ext") do
9
8
  # Replace the file extension with +newext+. If there is no extension on
10
9
  # the string, append the new extension to the end. If the new extension
@@ -164,5 +163,5 @@ class String
164
163
  result
165
164
  end
166
165
  end
166
+ end # class String
167
167
 
168
- end
@@ -1,8 +1,6 @@
1
1
  #--
2
2
  # Extensions to time to allow comparisons with an early time class.
3
3
 
4
- require 'rake/early_time'
5
-
6
4
  class Time
7
5
  alias rake_original_time_compare :<=>
8
6
  def <=>(other)
@@ -13,3 +11,4 @@ class Time
13
11
  end
14
12
  end
15
13
  end
14
+
@@ -340,7 +340,7 @@ module Rake
340
340
 
341
341
  # Add matching glob patterns.
342
342
  def add_matching(pattern)
343
- FileList.glob(pattern).each do |fn|
343
+ Rake.glob(pattern).each do |fn|
344
344
  self << fn unless exclude?(fn)
345
345
  end
346
346
  end
@@ -383,13 +383,6 @@ module Rake
383
383
  def [](*args)
384
384
  new(*args)
385
385
  end
386
-
387
- # Get a sorted list of files matching the pattern. This method
388
- # should be prefered to Dir[pattern] and Dir.glob(pattern) because
389
- # the files returned are guaranteed to be sorted.
390
- def glob(pattern, *args)
391
- Dir.glob(pattern, *args).sort
392
- end
393
386
  end
394
387
  end
395
388
  end
@@ -6,7 +6,7 @@ require 'fileutils'
6
6
  # added to the FileUtils utility functions.
7
7
  module FileUtils
8
8
  # Path to the currently running Ruby program
9
- RUBY = ENV['RUBY'] || File.join(
9
+ RUBY = File.join(
10
10
  RbConfig::CONFIG['bindir'],
11
11
  RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT']).
12
12
  sub(/.*\s.*/m, '"\&"')
@@ -8,8 +8,6 @@ require 'rake'
8
8
 
9
9
  task :phony
10
10
 
11
- Rake::Task[:phony].tap do |task|
12
- def task.timestamp # :nodoc:
13
- Time.at 0
14
- end
11
+ def (Rake::Task[:phony]).timestamp
12
+ Time.at 0
15
13
  end
@@ -32,6 +32,13 @@ module Rake
32
32
  application.options.rakelib << file
33
33
  end
34
34
  end
35
+
36
+ # Get a sorted list of files matching the pattern. This method
37
+ # should be prefered to Dir[pattern] and Dir.glob[pattern] because
38
+ # the files returned are guaranteed to be sorted.
39
+ def glob(pattern, *args)
40
+ Dir.glob(pattern, *args).sort
41
+ end
35
42
  end
36
43
 
37
44
  end
File without changes
@@ -1,12 +1,11 @@
1
1
  require 'test/unit'
2
2
  require 'test/unit/assertions'
3
- require 'rake/file_list'
4
3
 
5
4
  module Rake
6
5
  include Test::Unit::Assertions
7
6
 
8
7
  def run_tests(pattern='test/test*.rb', log_enabled=false)
9
- FileList.glob(pattern).each { |fn|
8
+ Rake.glob(pattern).each { |fn|
10
9
  $stderr.puts fn if log_enabled
11
10
  begin
12
11
  require fn
@@ -105,7 +105,7 @@ module Rake
105
105
 
106
106
  # Argument description (nil if none).
107
107
  def arg_description # :nodoc:
108
- @arg_names ? "[#{arg_names.join(',')}]" : nil
108
+ @arg_names ? "[#{(arg_names || []).join(',')}]" : nil
109
109
  end
110
110
 
111
111
  # Name of arguments for this task.
@@ -182,22 +182,21 @@ module Rake
182
182
  if application.options.always_multitask
183
183
  invoke_prerequisites_concurrently(task_args, invocation_chain)
184
184
  else
185
- prerequisite_tasks.each { |p|
186
- prereq_args = task_args.new_scope(p.arg_names)
187
- p.invoke_with_call_chain(prereq_args, invocation_chain)
185
+ prerequisite_tasks.each { |prereq|
186
+ prereq_args = task_args.new_scope(prereq.arg_names)
187
+ prereq.invoke_with_call_chain(prereq_args, invocation_chain)
188
188
  }
189
189
  end
190
190
  end
191
191
 
192
192
  # Invoke all the prerequisites of a task in parallel.
193
- def invoke_prerequisites_concurrently(task_args, invocation_chain) # :nodoc:
194
- futures = prerequisite_tasks.collect do |p|
195
- prereq_args = task_args.new_scope(p.arg_names)
193
+ def invoke_prerequisites_concurrently(args, invocation_chain) # :nodoc:
194
+ futures = @prerequisites.collect do |p|
196
195
  application.thread_pool.future(p) do |r|
197
- r.invoke_with_call_chain(prereq_args, invocation_chain)
196
+ application[r, @scope].invoke_with_call_chain(args, invocation_chain)
198
197
  end
199
198
  end
200
- futures.each { |f| f.value }
199
+ futures.each { |f| f.call }
201
200
  end
202
201
 
203
202
  # Format the trace flags for display.
@@ -72,7 +72,6 @@ module Rake
72
72
  #
73
73
  # task :t
74
74
  # task :t, [:a]
75
- # task :t, :a (deprecated)
76
75
  #
77
76
  def resolve_args_without_dependencies(args)
78
77
  task_name = args.shift
@@ -92,8 +91,6 @@ module Rake
92
91
  #
93
92
  # task :t => [:d]
94
93
  # task :t, [a] => [:d]
95
- # task :t, :needs => [:d] (deprecated)
96
- # task :t, :a, :needs => [:d] (deprecated)
97
94
  #
98
95
  def resolve_args_with_dependencies(args, hash) # :nodoc:
99
96
  fail "Task Argument Error" if hash.size != 1
@@ -102,14 +99,6 @@ module Rake
102
99
  task_name = key
103
100
  arg_names = []
104
101
  deps = value
105
- elsif key == :needs
106
- Rake.application.deprecate(
107
- "task :t, arg, :needs => [deps]",
108
- "task :t, [args] => [deps]",
109
- caller.detect { |c| c !~ /\blib\/rake\b/ })
110
- task_name = args.shift
111
- arg_names = args
112
- deps = value
113
102
  else
114
103
  task_name = args.shift
115
104
  arg_names = key
@@ -96,12 +96,9 @@ module Rake
96
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}"
100
- ruby args do |ok, status|
99
+ ruby "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}" do |ok, status|
101
100
  if !ok && status.respond_to?(:signaled?) && status.signaled?
102
101
  raise SignalException.new(status.termsig)
103
- elsif !ok
104
- fail "Command failed with status (#{status.exitstatus}): [ruby #{args}]"
105
102
  end
106
103
  end
107
104
  end
@@ -1,11 +1,8 @@
1
- require 'rake/private_reader'
2
-
3
1
  module Rake
4
2
 
5
- class ThreadHistoryDisplay # :nodoc: all
6
- include Rake::PrivateReader
7
-
8
- private_reader :stats, :items, :threads
3
+ class ThreadHistoryDisplay
4
+ attr_reader :stats, :items, :threads
5
+ private :stats, :items, :threads
9
6
 
10
7
  def initialize(stats)
11
8
  @stats = stats
@@ -16,7 +13,7 @@ module Rake
16
13
  def show
17
14
  puts "Job History:"
18
15
  stats.each do |stat|
19
- stat[:data] ||= {}
16
+ stat[:data] ||= []
20
17
  rename(stat, :thread, threads)
21
18
  rename(stat[:data], :item_id, items)
22
19
  rename(stat[:data], :new_thread, threads)
@@ -1,8 +1,6 @@
1
1
  require 'thread'
2
2
  require 'set'
3
3
 
4
- require 'rake/promise'
5
-
6
4
  module Rake
7
5
 
8
6
  class ThreadPool # :nodoc: all
@@ -30,12 +28,63 @@ module Rake
30
28
  # pool. Sending <tt>#value</tt> to the object will sleep the
31
29
  # current thread until the future is finished and will return the
32
30
  # result (or raise an exception thrown from the future)
33
- def future(*args, &block)
34
- promise = Promise.new(args, &block)
35
- promise.recorder = lambda { |*stats| stat(*stats) }
31
+ def future(*args,&block)
32
+ # capture the local args for the block (like Thread#start)
33
+ local_args = args.collect { |a| begin; a.dup; rescue; a; end }
34
+
35
+ promise_mutex = Mutex.new
36
+ promise_result = promise_error = NOT_SET
37
+
38
+ # (promise code builds on Ben Lavender's public-domain 'promise' gem)
39
+ promise = lambda do
40
+ # return immediately if the future has been executed
41
+ unless promise_result.equal?(NOT_SET) && promise_error.equal?(NOT_SET)
42
+ return promise_error.equal?(NOT_SET) ? promise_result : raise(promise_error)
43
+ end
44
+
45
+ # try to get the lock and execute the promise, otherwise, sleep.
46
+ if promise_mutex.try_lock
47
+ if promise_result.equal?(NOT_SET) && promise_error.equal?(NOT_SET)
48
+ #execute the promise
49
+ begin
50
+ promise_result = block.call(*local_args)
51
+ rescue Exception => e
52
+ promise_error = e
53
+ end
54
+ block = local_args = nil # GC can now clean these up
55
+ end
56
+ promise_mutex.unlock
57
+ else
58
+ # Even if we didn't get the lock, we need to sleep until the
59
+ # promise has finished executing. If, however, the current
60
+ # thread is part of the thread pool, we need to free up a
61
+ # new thread in the pool so there will always be a thread
62
+ # doing work.
63
+
64
+ wait_for_promise = lambda {
65
+ stat :waiting, item_id: promise.object_id
66
+ promise_mutex.synchronize {}
67
+ stat :continue, item_id: promise.object_id
68
+ }
69
+
70
+ unless @threads_mon.synchronize { @threads.include? Thread.current }
71
+ wait_for_promise.call
72
+ else
73
+ @threads_mon.synchronize { @max_active_threads += 1 }
74
+ start_thread
75
+ wait_for_promise.call
76
+ @threads_mon.synchronize { @max_active_threads -= 1 }
77
+ end
78
+ end
79
+ promise_error.equal?(NOT_SET) ? promise_result : raise(promise_error)
80
+ end
81
+
82
+ def promise.value
83
+ call
84
+ end
36
85
 
37
86
  @queue.enq promise
38
- stat :queued, :item_id => promise.object_id
87
+ stat :item_queued, item_id: promise.object_id
39
88
  start_thread
40
89
  promise
41
90
  end
@@ -44,18 +93,14 @@ module Rake
44
93
  def join
45
94
  @threads_mon.synchronize do
46
95
  begin
47
- stat :joining
48
- @join_cond.wait unless @threads.empty?
49
- stat :joined
96
+ @join_cond.wait unless @threads.empty?
50
97
  rescue Exception => e
51
- stat :joined
52
98
  $stderr.puts e
53
99
  $stderr.print "Queue contains #{@queue.size} items. Thread pool contains #{@threads.count} threads\n"
54
100
  $stderr.print "Current Thread #{Thread.current} status = #{Thread.current.status}\n"
55
101
  $stderr.puts e.backtrace.join("\n")
56
102
  @threads.each do |t|
57
103
  $stderr.print "Thread #{t} status = #{t.status}\n"
58
- # 1.8 doesn't support Thread#backtrace
59
104
  $stderr.puts t.backtrace.join("\n") if t.respond_to? :backtrace
60
105
  end
61
106
  raise e
@@ -74,58 +119,45 @@ module Rake
74
119
  # (see #gather_history). Best to call this when the job is
75
120
  # complete (i.e. after ThreadPool#join is called).
76
121
  def history # :nodoc:
77
- @history_mon.synchronize { @history.dup }.
78
- sort_by { |i| i[:time] }.
79
- each { |i| i[:time] -= @history_start_time }
122
+ @history_mon.synchronize { @history.dup }
80
123
  end
81
124
 
82
125
  # Return a hash of always collected statistics for the thread pool.
83
126
  def statistics # :nodoc:
84
127
  {
85
- :total_threads_in_play => @total_threads_in_play,
86
- :max_active_threads => @max_active_threads,
128
+ total_threads_in_play: @total_threads_in_play,
129
+ max_active_threads: @max_active_threads,
87
130
  }
88
131
  end
89
132
 
90
133
  private
91
134
 
92
- # processes one item on the queue. Returns true if there was an
93
- # item to process, false if there was no item
94
- def process_queue_item #:nodoc:
95
- return false if @queue.empty?
96
-
97
- # Even though we just asked if the queue was empty, it
98
- # still could have had an item which by this statement
99
- # is now gone. For this reason we pass true to Queue#deq
100
- # because we will sleep indefinitely if it is empty.
101
- promise = @queue.deq(true)
102
- stat :dequeued, :item_id => promise.object_id
103
- promise.work
104
- return true
105
-
106
- rescue ThreadError # this means the queue is empty
107
- false
108
- end
109
-
110
135
  def start_thread # :nodoc:
111
136
  @threads_mon.synchronize do
112
137
  next unless @threads.count < @max_active_threads
113
138
 
114
139
  t = Thread.new do
115
140
  begin
116
- while @threads.count <= @max_active_threads
117
- break unless process_queue_item
141
+ while @threads.count <= @max_active_threads && !@queue.empty? do
142
+ # Even though we just asked if the queue was empty, it
143
+ # still could have had an item which by this statement
144
+ # is now gone. For this reason we pass true to Queue#deq
145
+ # because we will sleep indefinitely if it is empty.
146
+ block = @queue.deq(true)
147
+ stat :item_dequeued, item_id: block.object_id
148
+ block.call
118
149
  end
150
+ rescue ThreadError # this means the queue is empty
119
151
  ensure
120
152
  @threads_mon.synchronize do
121
153
  @threads.delete Thread.current
122
- stat :ended, :thread_count => @threads.count
154
+ stat :thread_deleted, deleted_thread: Thread.current.object_id, thread_count: @threads.count
123
155
  @join_cond.broadcast if @threads.empty?
124
156
  end
125
157
  end
126
158
  end
127
159
  @threads << t
128
- stat :spawned, :new_thread => t.object_id, :thread_count => @threads.count
160
+ stat :thread_created, new_thread: t.object_id, thread_count: @threads.count
129
161
  @total_threads_in_play = @threads.count if @threads.count > @total_threads_in_play
130
162
  end
131
163
  end
@@ -133,10 +165,10 @@ module Rake
133
165
  def stat(event, data=nil) # :nodoc:
134
166
  return if @history_start_time.nil?
135
167
  info = {
136
- :event => event,
137
- :data => data,
138
- :time => Time.now,
139
- :thread => Thread.current.object_id,
168
+ event: event,
169
+ data: data,
170
+ time: (Time.now-@history_start_time),
171
+ thread: Thread.current.object_id,
140
172
  }
141
173
  @history_mon.synchronize { @history << info }
142
174
  end
@@ -150,6 +182,8 @@ module Rake
150
182
  def __threads__ # :nodoc:
151
183
  @threads.dup
152
184
  end
185
+
186
+ NOT_SET = Object.new.freeze # :nodoc:
153
187
  end
154
188
 
155
189
  end