drake 0.8.2.1.0.4 → 0.8.2.1.0.5

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.
data/CHANGES.drake CHANGED
@@ -1,6 +1,10 @@
1
1
 
2
2
  = Drake Changelog
3
3
 
4
+ == Version 0.8.2.1.0.5
5
+
6
+ * Restored original 'multitask' behavior when -j1 (default)
7
+
4
8
  == Version 0.8.2.1.0.4
5
9
 
6
10
  * Fix 21922: prereqs were not namespace-qualified
data/README CHANGED
@@ -34,10 +34,10 @@ dependency tree has not been properly defined. Consider
34
34
 
35
35
  With single-threaded Rake, _x_,_y_,_z_ will be invoked <em>in that
36
36
  order</em> before _a_ is invoked (assuming there are no other rules
37
- involving these tasks). However with <code>drake --threads=N</code>
38
- (for N > 1), one should not expect any particular order of execution.
39
- Since there is no dependency specified between _x_,_y_,_z_ above,
40
- Drake is free to run them in any order.
37
+ involving these tasks). However with <code>drake -jN</code> (for +N+
38
+ > 1), one should not expect any particular order of execution. Since
39
+ there is no dependency specified between _x_,_y_,_z_ above, Drake is
40
+ free to run them in any order.
41
41
 
42
42
  If you wish _x_,_y_,_z_ to be invoked sequentially, then write
43
43
 
@@ -59,11 +59,13 @@ Package maintainers affectionately call it "not j-safe."
59
59
 
60
60
  === MultiTask
61
61
 
62
- The use of +multitask+ is deprecated. Tasks which may properly be run
63
- in parallel will be run in parallel; those which cannot, will not. It
64
- is not the user's job to decide.
62
+ When more than one thread is given, +multitask+ behaves just like
63
+ +task+. Those tasks which may properly be run in parallel will be run
64
+ in parallel; those which cannot, will not. It is not the user's job
65
+ to decide. In other words, for <tt>-jN</tt> (+N+ > 1), +multitask+ is
66
+ an alias of +task+.
65
67
 
66
- Drake's +multitask+ is an alias of +task+.
68
+ For <tt>-j1</tt> (default), +multitask+ behaves as the original.
67
69
 
68
70
  === Task#invoke inside Task#invoke
69
71
 
@@ -71,7 +73,7 @@ Parallelizing code means surrendering control over the
71
73
  micro-management of its execution. Manually invoking tasks inside
72
74
  other tasks is rather contrary to this notion, throwing a monkey
73
75
  wrench into the system. An exception will be raised when this is
74
- attempted in non-single-threaded mode.
76
+ attempted in multi-threaded mode.
75
77
 
76
78
  == Links
77
79
 
data/Rakefile.drake CHANGED
@@ -46,6 +46,9 @@ task :drake_prerelease => :clean do
46
46
  unless `git status` =~ %r!nothing to commit \(working directory clean\)!
47
47
  raise "Directory not clean"
48
48
  end
49
+ unless `ping -c2 github.com` =~ %r!0% packet loss!i
50
+ raise "No ping for github.com"
51
+ end
49
52
  end
50
53
 
51
54
  task :drake_publish => :rdoc do
data/lib/rake.rb CHANGED
@@ -29,7 +29,7 @@
29
29
  # as a library via a require statement, but it can be distributed
30
30
  # independently as an application.
31
31
 
32
- RAKEVERSION = '0.8.2.1.0.4'
32
+ RAKEVERSION = '0.8.2.1.0.5'
33
33
 
34
34
  require 'rbconfig'
35
35
  require 'getoptlong'
@@ -563,23 +563,23 @@ module Rake
563
563
  self
564
564
  end
565
565
 
566
+ def base_invoke(*args) #:nodoc:
567
+ invoke_with_call_chain(
568
+ TaskArguments.new(arg_names, args),
569
+ InvocationChain::EMPTY)
570
+ end
571
+
566
572
  # Invoke the task if it is needed. Prerequites are invoked first.
567
573
  def invoke(*args)
568
- run_invoke = lambda {
569
- invoke_with_call_chain(
570
- TaskArguments.new(arg_names, args),
571
- InvocationChain::EMPTY)
572
- }
573
-
574
574
  if application.num_threads == 1
575
- run_invoke.call
575
+ base_invoke(*args)
576
576
  else
577
577
  if application.parallel_lock.locked?
578
578
  raise "Calling Task#invoke within a task is not allowed."
579
579
  end
580
580
  application.parallel_lock.synchronize {
581
581
  application.parallel_tasks.clear
582
- run_invoke.call
582
+ base_invoke(*args)
583
583
  application.invoke_parallel_tasks
584
584
  }
585
585
  end
@@ -595,8 +595,13 @@ module Rake
595
595
  end
596
596
  return if @already_invoked
597
597
  @already_invoked = true
598
- prereqs = application.num_threads == 1 ? nil : Array.new
599
- invoke_prerequisites(task_args, new_chain, prereqs)
598
+ prereqs =
599
+ if application.num_threads == 1
600
+ invoke_prerequisites(task_args, new_chain)
601
+ nil
602
+ else
603
+ invoke_prerequisites_parallel(task_args, new_chain)
604
+ end
600
605
  if needed?
601
606
  if application.num_threads == 1
602
607
  execute(task_args)
@@ -609,16 +614,28 @@ module Rake
609
614
  end
610
615
  protected :invoke_with_call_chain
611
616
 
617
+ def invoke_prerequisite(prereq_name, task_args, invocation_chain) #:nodoc:
618
+ prereq = application[prereq_name, @scope]
619
+ prereq_args = task_args.new_scope(prereq.arg_names)
620
+ prereq.invoke_with_call_chain(prereq_args, invocation_chain)
621
+ prereq
622
+ end
623
+
612
624
  # Invoke all the prerequisites of a task.
613
- def invoke_prerequisites(task_args, invocation_chain, accum=nil) #:nodoc:
625
+ def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
614
626
  @prerequisites.each { |n|
615
- prereq = application[n, @scope]
616
- prereq_args = task_args.new_scope(prereq.arg_names)
617
- prereq.invoke_with_call_chain(prereq_args, invocation_chain)
618
- accum << prereq if accum
627
+ invoke_prerequisite(n, task_args, invocation_chain)
619
628
  }
620
629
  end
621
630
 
631
+ # Parallel dry-run accumulator.
632
+ # This also serves to circumvent MultiTask#invoke_prerequisites.
633
+ def invoke_prerequisites_parallel(task_args, invocation_chain) #:nodoc:
634
+ @prerequisites.map { |n|
635
+ invoke_prerequisite(n, task_args, invocation_chain)
636
+ }
637
+ end
638
+
622
639
  # Format the trace flags for display.
623
640
  def format_trace_flags
624
641
  flags = []
@@ -767,10 +784,6 @@ module Rake
767
784
  end # class << Rake::Task
768
785
  end # class Rake::Task
769
786
 
770
- #
771
- # DEPRECATED: do not use MultiTask
772
- #
773
- MultiTask = Task
774
787
 
775
788
  # #########################################################################
776
789
  # A FileTask is a task that includes time based dependencies. If any of a
@@ -834,6 +847,19 @@ module Rake
834
847
  Rake::EARLY
835
848
  end
836
849
  end
850
+
851
+ # #########################################################################
852
+ # Same as a regular task, but the immediate prerequisites are done in
853
+ # parallel using Ruby threads.
854
+ #
855
+ class MultiTask < Task
856
+ def invoke_prerequisites(args, invocation_chain)
857
+ threads = @prerequisites.collect { |p|
858
+ Thread.new(p) { |r| application[r].invoke_with_call_chain(args, invocation_chain) }
859
+ }
860
+ threads.each { |t| t.join }
861
+ end
862
+ end
837
863
  end # module Rake
838
864
 
839
865
  # ###########################################################################
@@ -850,12 +876,6 @@ def task(*args, &block)
850
876
  Rake::Task.define_task(*args, &block)
851
877
  end
852
878
 
853
- #
854
- # DEPRECATED: Do not use 'multitask'
855
- #
856
- def multitask(*args, &block)
857
- task(*args, &block)
858
- end
859
879
 
860
880
  # Declare a file task.
861
881
  #
@@ -893,6 +913,17 @@ def directory(dir)
893
913
  end
894
914
  end
895
915
 
916
+ # Declare a task that performs its prerequisites in parallel. Multitasks does
917
+ # *not* guarantee that its prerequisites will execute in any given order
918
+ # (which is obvious when you think about it)
919
+ #
920
+ # Example:
921
+ # multitask :deploy => [:deploy_gem, :deploy_rdoc]
922
+ #
923
+ def multitask(args, &block)
924
+ Rake::MultiTask.define_task(args, &block)
925
+ end
926
+
896
927
  # Create a new rake namespace and use it for evaluating the given block.
897
928
  # Returns a NameSpace object that can be used to lookup tasks defined in the
898
929
  # namespace.
@@ -2003,22 +2034,6 @@ module Rake
2003
2034
  @tty_output = STDOUT.tty?
2004
2035
  end
2005
2036
 
2006
- #
2007
- # Check for circular dependencies, without invoking.
2008
- #
2009
- def check_circular(task_name)
2010
- helper = lambda { |name, chain|
2011
- if chain.include? name
2012
- raise "Circular dependency detected: " +
2013
- "#{name} => #{chain.last} => #{name}"
2014
- end
2015
- Rake::Task[name].prerequisites.each { |prereq_name|
2016
- helper.call(prereq_name, chain + [name])
2017
- }
2018
- }
2019
- helper.call(task_name, [])
2020
- end
2021
-
2022
2037
  # Run the Rake application. The run method performs the following three steps:
2023
2038
  #
2024
2039
  # * Initialize the command line options (+init+).
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'rake'
5
+
6
+ ######################################################################
7
+ class TestMultiTask < Test::Unit::TestCase
8
+ include Rake
9
+
10
+ def setup
11
+ Task.clear
12
+ @runs = Array.new
13
+ end
14
+
15
+ def test_running_multitasks
16
+ task :a do 3.times do |i| @runs << "A#{i}"; sleep 0.01; end end
17
+ task :b do 3.times do |i| @runs << "B#{i}"; sleep 0.01; end end
18
+ multitask :both => [:a, :b]
19
+ Task[:both].invoke
20
+ assert_equal 6, @runs.size
21
+ assert @runs.index("A0") < @runs.index("A1")
22
+ assert @runs.index("A1") < @runs.index("A2")
23
+ assert @runs.index("B0") < @runs.index("B1")
24
+ assert @runs.index("B1") < @runs.index("B2")
25
+ end
26
+
27
+ def test_all_multitasks_wait_on_slow_prerequisites
28
+ task :slow do 3.times do |i| @runs << "S#{i}"; sleep 0.05 end end
29
+ task :a => [:slow] do 3.times do |i| @runs << "A#{i}"; sleep 0.01 end end
30
+ task :b => [:slow] do 3.times do |i| @runs << "B#{i}"; sleep 0.01 end end
31
+ multitask :both => [:a, :b]
32
+ Task[:both].invoke
33
+ assert_equal 9, @runs.size
34
+ assert @runs.index("S0") < @runs.index("S1")
35
+ assert @runs.index("S1") < @runs.index("S2")
36
+ assert @runs.index("S2") < @runs.index("A0")
37
+ assert @runs.index("S2") < @runs.index("B0")
38
+ assert @runs.index("A0") < @runs.index("A1")
39
+ assert @runs.index("A1") < @runs.index("A2")
40
+ assert @runs.index("B0") < @runs.index("B1")
41
+ assert @runs.index("B1") < @runs.index("B2")
42
+ end
43
+ end
44
+
45
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2.1.0.4
4
+ version: 0.8.2.1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - James M. Lawrence
@@ -96,6 +96,7 @@ files:
96
96
  - test/test_ftp.rb
97
97
  - test/test_invocation_chain.rb
98
98
  - test/test_makefile_loader.rb
99
+ - test/test_multitask.rb
99
100
  - test/test_namespace.rb
100
101
  - test/test_package_task.rb
101
102
  - test/test_parallel.rb