drake 0.8.2.1.0.4 → 0.8.2.1.0.5

Sign up to get free protection for your applications and to get access to all the features.
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