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 +4 -0
- data/README +11 -9
- data/Rakefile.drake +3 -0
- data/lib/rake.rb +57 -42
- data/test/test_multitask.rb +45 -0
- metadata +2 -1
data/CHANGES.drake
CHANGED
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
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
63
|
-
|
64
|
-
is not the user's job
|
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
|
-
|
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
|
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.
|
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
|
-
|
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
|
-
|
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 =
|
599
|
-
|
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
|
625
|
+
def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
|
614
626
|
@prerequisites.each { |n|
|
615
|
-
|
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
|
+
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
|