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 +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
|