drake 0.8.4.1.1.0 → 0.8.4.1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.drake +4 -0
- data/README +2 -85
- data/Rakefile +8 -15
- data/doc/command_line_usage.rdoc +9 -0
- data/doc/parallel.rdoc +112 -0
- data/doc/rakefile.rdoc +6 -0
- data/install.rb +1 -1
- data/lib/rake.rb +59 -96
- data/lib/rake/parallel.rb +137 -32
- data/test/filecreation.rb +12 -0
- data/test/parallel_setup.rb +3 -0
- data/test/rake_test_setup.rb +21 -0
- data/test/serial_setup.rb +3 -0
- data/test/test_application.rb +8 -0
- data/test/test_definitions.rb +6 -2
- data/test/test_file_task.rb +49 -3
- data/test/test_multitask.rb +1 -1
- data/test/test_parallel.rb +177 -38
- data/test/test_require.rb +3 -0
- data/test/test_rules.rb +4 -5
- data/test/test_task_manager.rb +1 -2
- data/test/test_tasks.rb +24 -12
- metadata +25 -21
- data/lib/rake/comp_tree/algorithm.rb +0 -172
- data/lib/rake/comp_tree/comp_tree.rb +0 -42
- data/lib/rake/comp_tree/driver.rb +0 -153
- data/lib/rake/comp_tree/error.rb +0 -23
- data/lib/rake/comp_tree/node.rb +0 -164
- data/test/Rakefile.seq +0 -20
- data/test/Rakefile.simple +0 -18
- data/test/parallel.rb +0 -4
- data/test/single_threaded.rb +0 -3
data/test/test_require.rb
CHANGED
@@ -10,6 +10,7 @@ class TestRequire < Test::Unit::TestCase
|
|
10
10
|
|
11
11
|
def test_can_load_rake_library
|
12
12
|
app = Rake::Application.new
|
13
|
+
app.options.threads = Rake.application.options.threads
|
13
14
|
assert app.instance_eval {
|
14
15
|
rake_require("test2", ['test/data/rakelib'], [])
|
15
16
|
}
|
@@ -17,6 +18,7 @@ class TestRequire < Test::Unit::TestCase
|
|
17
18
|
|
18
19
|
def test_wont_reload_rake_library
|
19
20
|
app = Rake::Application.new
|
21
|
+
app.options.threads = Rake.application.options.threads
|
20
22
|
assert ! app.instance_eval {
|
21
23
|
rake_require("test2", ['test/data/rakelib'], ['test2'])
|
22
24
|
}
|
@@ -24,6 +26,7 @@ class TestRequire < Test::Unit::TestCase
|
|
24
26
|
|
25
27
|
def test_throws_error_if_library_not_found
|
26
28
|
app = Rake::Application.new
|
29
|
+
app.options.threads = Rake.application.options.threads
|
27
30
|
ex = assert_exception(LoadError) {
|
28
31
|
assert app.instance_eval {
|
29
32
|
rake_require("testx", ['test/data/rakelib'], [])
|
data/test/test_rules.rb
CHANGED
@@ -21,7 +21,7 @@ class TestRules < Test::Unit::TestCase
|
|
21
21
|
|
22
22
|
def setup
|
23
23
|
Task.clear
|
24
|
-
@runs =
|
24
|
+
@runs = SerializedArray.new
|
25
25
|
end
|
26
26
|
|
27
27
|
def teardown
|
@@ -41,12 +41,11 @@ class TestRules < Test::Unit::TestCase
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def test_multiple_rules2
|
44
|
-
mutex = Mutex.new
|
45
44
|
create_file(FTNFILE)
|
46
45
|
delete_file(SRCFILE)
|
47
46
|
delete_file(OBJFILE)
|
48
|
-
rule(/\.o$/ => ['.f']) do
|
49
|
-
rule(/\.o$/ => ['.c']) do
|
47
|
+
rule(/\.o$/ => ['.f']) do @runs << :F end
|
48
|
+
rule(/\.o$/ => ['.c']) do @runs << :C end
|
50
49
|
Task[OBJFILE].invoke
|
51
50
|
assert_equal [:F], @runs
|
52
51
|
end
|
@@ -318,7 +317,7 @@ class TestRules < Test::Unit::TestCase
|
|
318
317
|
end
|
319
318
|
|
320
319
|
def test_recursive_rules_will_work_as_long_as_they_terminate
|
321
|
-
actions =
|
320
|
+
actions = SerializedArray.new
|
322
321
|
create_file("testdata/abc.xml")
|
323
322
|
rule '.y' => '.xml' do actions << 'y' end
|
324
323
|
rule '.c' => '.y' do actions << 'c'end
|
data/test/test_task_manager.rb
CHANGED
@@ -13,7 +13,6 @@ class TestTaskManager < Test::Unit::TestCase
|
|
13
13
|
|
14
14
|
def setup
|
15
15
|
@tm = TaskManager.new
|
16
|
-
@tm.num_threads = Rake.application.num_threads
|
17
16
|
end
|
18
17
|
|
19
18
|
def test_create_task_manager
|
@@ -139,7 +138,7 @@ class TestTaskManager < Test::Unit::TestCase
|
|
139
138
|
def test_correctly_scoped_prerequisites_are_invoked
|
140
139
|
values = []
|
141
140
|
@tm = Rake::Application.new
|
142
|
-
@tm.
|
141
|
+
@tm.options.threads = Rake.application.options.threads
|
143
142
|
@tm.define_task(Rake::Task, :z) do values << "top z" end
|
144
143
|
@tm.in_namespace("a") do
|
145
144
|
@tm.define_task(Rake::Task, :z) do values << "next z" end
|
data/test/test_tasks.rb
CHANGED
@@ -35,17 +35,24 @@ class TestTask < Test::Unit::TestCase
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def test_invoke
|
38
|
-
runlist =
|
38
|
+
runlist = SerializedArray.new
|
39
39
|
t1 = task(:t1 => [:t2, :t3]) { |t| runlist << t.name; 3321 }
|
40
40
|
t2 = task(:t2) { |t| runlist << t.name }
|
41
41
|
t3 = task(:t3) { |t| runlist << t.name }
|
42
42
|
assert_equal ["t2", "t3"], t1.prerequisites
|
43
43
|
t1.invoke
|
44
|
-
|
44
|
+
if Rake.application.options.threads == 1
|
45
|
+
assert_equal ["t2", "t3", "t1"], runlist
|
46
|
+
else
|
47
|
+
assert_block {
|
48
|
+
["t2", "t3", "t1"] == runlist or
|
49
|
+
["t3", "t2", "t1"] == runlist
|
50
|
+
}
|
51
|
+
end
|
45
52
|
end
|
46
53
|
|
47
54
|
def test_invoke_with_circular_dependencies
|
48
|
-
runlist =
|
55
|
+
runlist = SerializedArray.new
|
49
56
|
t1 = task(:t1 => [:t2]) { |t| runlist << t.name; 3321 }
|
50
57
|
t2 = task(:t2 => [:t1]) { |t| runlist << t.name }
|
51
58
|
assert_equal ["t2"], t1.prerequisites
|
@@ -59,7 +66,7 @@ class TestTask < Test::Unit::TestCase
|
|
59
66
|
|
60
67
|
def test_dry_run_prevents_actions
|
61
68
|
Rake.application.options.dryrun = true
|
62
|
-
runlist =
|
69
|
+
runlist = SerializedArray.new
|
63
70
|
t1 = task(:t1) { |t| runlist << t.name; 3321 }
|
64
71
|
out = capture_stdout { t1.invoke }
|
65
72
|
assert_match(/execute .*t1/i, out)
|
@@ -76,25 +83,30 @@ class TestTask < Test::Unit::TestCase
|
|
76
83
|
out = capture_stdout {
|
77
84
|
t1.invoke
|
78
85
|
}
|
79
|
-
|
80
|
-
assert_match(/invoke t1/i, out)
|
81
|
-
end
|
86
|
+
assert_match(/invoke t1/i, out)
|
82
87
|
assert_match(/execute t1/i, out)
|
83
88
|
ensure
|
84
89
|
Rake.application.options.trace = false
|
85
90
|
end
|
86
91
|
|
87
92
|
def test_no_double_invoke
|
88
|
-
runlist =
|
93
|
+
runlist = SerializedArray.new
|
89
94
|
t1 = task(:t1 => [:t2, :t3]) { |t| runlist << t.name; 3321 }
|
90
95
|
t2 = task(:t2 => [:t3]) { |t| runlist << t.name }
|
91
96
|
t3 = task(:t3) { |t| runlist << t.name }
|
92
97
|
t1.invoke
|
93
|
-
|
98
|
+
if Rake.application.options.threads == 1
|
99
|
+
assert_equal ["t3", "t2", "t1"], runlist
|
100
|
+
else
|
101
|
+
assert_block {
|
102
|
+
["t2", "t3", "t1"] == runlist or
|
103
|
+
["t3", "t2", "t1"] == runlist
|
104
|
+
}
|
105
|
+
end
|
94
106
|
end
|
95
107
|
|
96
108
|
def test_can_double_invoke_with_reenable
|
97
|
-
runlist =
|
109
|
+
runlist = SerializedArray.new
|
98
110
|
t1 = task(:t1) { |t| runlist << t.name }
|
99
111
|
t1.invoke
|
100
112
|
t1.reenable
|
@@ -136,7 +148,7 @@ class TestTask < Test::Unit::TestCase
|
|
136
148
|
end
|
137
149
|
|
138
150
|
def test_multi_invocations
|
139
|
-
runs =
|
151
|
+
runs = SerializedArray.new
|
140
152
|
p = proc do |t| runs << t.name end
|
141
153
|
task({:t1=>[:t2,:t3]}, &p)
|
142
154
|
task({:t2=>[:t3]}, &p)
|
@@ -284,7 +296,7 @@ class TestTaskWithArguments < Test::Unit::TestCase
|
|
284
296
|
end
|
285
297
|
|
286
298
|
def test_actions_of_various_arity_are_ok_with_args
|
287
|
-
notes =
|
299
|
+
notes = SerializedArray.new
|
288
300
|
t = task(:t, :x) do
|
289
301
|
notes << :a
|
290
302
|
end
|
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.4.1.
|
4
|
+
version: 0.8.4.1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James M. Lawrence
|
@@ -9,10 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-04-
|
12
|
+
date: 2009-04-13 00:00:00 -04:00
|
13
13
|
default_executable: drake
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: comp_tree
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.7.1
|
24
|
+
version:
|
16
25
|
description: Rake is a Make-like program implemented in Ruby. Tasks and dependencies are specified in standard Ruby syntax.
|
17
26
|
email: quixoticsycophant@gmail.com
|
18
27
|
executables:
|
@@ -26,6 +35,7 @@ extra_rdoc_files:
|
|
26
35
|
- CHANGES
|
27
36
|
- doc/command_line_usage.rdoc
|
28
37
|
- doc/glossary.rdoc
|
38
|
+
- doc/parallel.rdoc
|
29
39
|
- doc/proto_rake.rdoc
|
30
40
|
- doc/rakefile.rdoc
|
31
41
|
- doc/rational.rdoc
|
@@ -48,19 +58,14 @@ files:
|
|
48
58
|
- CHANGES
|
49
59
|
- CHANGES.drake
|
50
60
|
- MIT-LICENSE
|
61
|
+
- README
|
51
62
|
- Rakefile
|
52
63
|
- Rakefile.drake
|
53
|
-
- README
|
54
64
|
- TODO
|
55
65
|
- bin/drake
|
56
66
|
- lib/rake/alt_system.rb
|
57
67
|
- lib/rake/classic_namespace.rb
|
58
68
|
- lib/rake/clean.rb
|
59
|
-
- lib/rake/comp_tree/algorithm.rb
|
60
|
-
- lib/rake/comp_tree/comp_tree.rb
|
61
|
-
- lib/rake/comp_tree/driver.rb
|
62
|
-
- lib/rake/comp_tree/error.rb
|
63
|
-
- lib/rake/comp_tree/node.rb
|
64
69
|
- lib/rake/contrib/compositepublisher.rb
|
65
70
|
- lib/rake/contrib/ftptools.rb
|
66
71
|
- lib/rake/contrib/publisher.rb
|
@@ -88,22 +93,22 @@ files:
|
|
88
93
|
- test/filecreation.rb
|
89
94
|
- test/functional.rb
|
90
95
|
- test/in_environment.rb
|
91
|
-
- test/
|
96
|
+
- test/parallel_setup.rb
|
92
97
|
- test/rake_test_setup.rb
|
93
98
|
- test/reqfile.rb
|
94
99
|
- test/reqfile2.rb
|
100
|
+
- test/serial_setup.rb
|
95
101
|
- test/session_functional.rb
|
96
102
|
- test/shellcommand.rb
|
97
|
-
- test/single_threaded.rb
|
98
103
|
- test/test_application.rb
|
99
104
|
- test/test_clean.rb
|
100
105
|
- test/test_definitions.rb
|
101
106
|
- test/test_earlytime.rb
|
102
107
|
- test/test_extension.rb
|
103
|
-
- test/test_filelist.rb
|
104
|
-
- test/test_fileutils.rb
|
105
108
|
- test/test_file_creation_task.rb
|
106
109
|
- test/test_file_task.rb
|
110
|
+
- test/test_filelist.rb
|
111
|
+
- test/test_fileutils.rb
|
107
112
|
- test/test_ftp.rb
|
108
113
|
- test/test_invocation_chain.rb
|
109
114
|
- test/test_makefile_loader.rb
|
@@ -117,10 +122,10 @@ files:
|
|
117
122
|
- test/test_rdoc_task.rb
|
118
123
|
- test/test_require.rb
|
119
124
|
- test/test_rules.rb
|
120
|
-
- test/test_tasklib.rb
|
121
|
-
- test/test_tasks.rb
|
122
125
|
- test/test_task_arguments.rb
|
123
126
|
- test/test_task_manager.rb
|
127
|
+
- test/test_tasklib.rb
|
128
|
+
- test/test_tasks.rb
|
124
129
|
- test/test_test_task.rb
|
125
130
|
- test/test_top_level_functions.rb
|
126
131
|
- test/test_win32.rb
|
@@ -135,18 +140,17 @@ files:
|
|
135
140
|
- test/data/namespace/Rakefile
|
136
141
|
- test/data/statusreturn/Rakefile
|
137
142
|
- test/data/unittest/Rakefile
|
138
|
-
- test/Rakefile.seq
|
139
|
-
- test/Rakefile.simple
|
140
143
|
- test/data/unittest/subdir
|
141
144
|
- doc/command_line_usage.rdoc
|
142
145
|
- doc/example
|
146
|
+
- doc/example/Rakefile1
|
147
|
+
- doc/example/Rakefile2
|
143
148
|
- doc/example/a.c
|
144
149
|
- doc/example/b.c
|
145
150
|
- doc/example/main.c
|
146
|
-
- doc/example/Rakefile1
|
147
|
-
- doc/example/Rakefile2
|
148
151
|
- doc/glossary.rdoc
|
149
152
|
- doc/jamis.rb
|
153
|
+
- doc/parallel.rdoc
|
150
154
|
- doc/proto_rake.rdoc
|
151
155
|
- doc/rake.1.gz
|
152
156
|
- doc/rakefile.rdoc
|
@@ -196,6 +200,6 @@ rubyforge_project: drake
|
|
196
200
|
rubygems_version: 1.3.1
|
197
201
|
signing_key:
|
198
202
|
specification_version: 2
|
199
|
-
summary: A
|
203
|
+
summary: A branch of Rake supporting automatic parallelizing of tasks.
|
200
204
|
test_files: []
|
201
205
|
|
@@ -1,172 +0,0 @@
|
|
1
|
-
|
2
|
-
module Rake end
|
3
|
-
module Rake::CompTree
|
4
|
-
module Algorithm
|
5
|
-
module_function
|
6
|
-
|
7
|
-
def loop_with(leave, again)
|
8
|
-
catch(leave) {
|
9
|
-
while true
|
10
|
-
catch(again) {
|
11
|
-
yield
|
12
|
-
}
|
13
|
-
end
|
14
|
-
}
|
15
|
-
end
|
16
|
-
|
17
|
-
def compute_multithreaded(root, num_threads)
|
18
|
-
#trace "Computing #{root.name} with #{num_threads} threads"
|
19
|
-
finished = nil
|
20
|
-
tree_mutex = Mutex.new
|
21
|
-
node_finished_condition = ConditionVariable.new
|
22
|
-
thread_wake_condition = ConditionVariable.new
|
23
|
-
num_threads_in_use = 0
|
24
|
-
|
25
|
-
threads = (0...num_threads).map { |thread_index|
|
26
|
-
Thread.new {
|
27
|
-
#
|
28
|
-
# wait for main thread
|
29
|
-
#
|
30
|
-
tree_mutex.synchronize {
|
31
|
-
#trace "Thread #{thread_index} waiting to start"
|
32
|
-
num_threads_in_use += 1
|
33
|
-
thread_wake_condition.wait(tree_mutex)
|
34
|
-
}
|
35
|
-
|
36
|
-
loop_with(:leave, :again) {
|
37
|
-
node = tree_mutex.synchronize {
|
38
|
-
#trace "Thread #{thread_index} acquired tree lock; begin search"
|
39
|
-
if finished
|
40
|
-
#trace "Thread #{thread_index} detected finish"
|
41
|
-
num_threads_in_use -= 1
|
42
|
-
throw :leave
|
43
|
-
else
|
44
|
-
#
|
45
|
-
# Find a node. The node we obtain, if any, will be locked.
|
46
|
-
#
|
47
|
-
node = find_node(root)
|
48
|
-
if node
|
49
|
-
#trace "Thread #{thread_index} found node #{node.name}"
|
50
|
-
node
|
51
|
-
else
|
52
|
-
#trace "Thread #{thread_index}: no node found; sleeping."
|
53
|
-
thread_wake_condition.wait(tree_mutex)
|
54
|
-
throw :again
|
55
|
-
end
|
56
|
-
end
|
57
|
-
}
|
58
|
-
|
59
|
-
#trace "Thread #{thread_index} computing node"
|
60
|
-
#debug {
|
61
|
-
# node.trace_compute
|
62
|
-
#}
|
63
|
-
node.compute
|
64
|
-
#trace "Thread #{thread_index} node computed; waiting for tree lock"
|
65
|
-
|
66
|
-
tree_mutex.synchronize {
|
67
|
-
#trace "Thread #{thread_index} acquired tree lock"
|
68
|
-
#debug {
|
69
|
-
# name = "#{node.name}" + ((node == root) ? " (ROOT NODE)" : "")
|
70
|
-
# initial = "Thread #{thread_index} compute result for #{name}: "
|
71
|
-
# status = node.computed.is_a?(Exception) ? "error" : "success"
|
72
|
-
# trace initial + status
|
73
|
-
# trace "Thread #{thread_index} node result: #{node.result}"
|
74
|
-
#}
|
75
|
-
|
76
|
-
if node.computed.is_a? Exception
|
77
|
-
#
|
78
|
-
# An error occurred; we are done.
|
79
|
-
#
|
80
|
-
finished = node.computed
|
81
|
-
elsif node == root
|
82
|
-
#
|
83
|
-
# Root node was computed; we are done.
|
84
|
-
#
|
85
|
-
finished = true
|
86
|
-
end
|
87
|
-
|
88
|
-
#
|
89
|
-
# remove locks for this node (shared lock and own lock)
|
90
|
-
#
|
91
|
-
node.unlock
|
92
|
-
|
93
|
-
#
|
94
|
-
# Tell the main thread that another node was computed.
|
95
|
-
#
|
96
|
-
node_finished_condition.signal
|
97
|
-
}
|
98
|
-
}
|
99
|
-
#trace "Thread #{thread_index} exiting"
|
100
|
-
}
|
101
|
-
}
|
102
|
-
|
103
|
-
#trace "Main: waiting for threads to launch and block."
|
104
|
-
until tree_mutex.synchronize { num_threads_in_use == num_threads }
|
105
|
-
Thread.pass
|
106
|
-
end
|
107
|
-
|
108
|
-
tree_mutex.synchronize {
|
109
|
-
#trace "Main: entering main loop"
|
110
|
-
until num_threads_in_use == 0
|
111
|
-
#trace "Main: waking threads"
|
112
|
-
thread_wake_condition.broadcast
|
113
|
-
|
114
|
-
if finished
|
115
|
-
#trace "Main: detected finish."
|
116
|
-
break
|
117
|
-
end
|
118
|
-
|
119
|
-
#trace "Main: waiting for a node"
|
120
|
-
node_finished_condition.wait(tree_mutex)
|
121
|
-
#trace "Main: got a node"
|
122
|
-
end
|
123
|
-
}
|
124
|
-
|
125
|
-
#trace "Main: waiting for threads to finish."
|
126
|
-
loop_with(:leave, :again) {
|
127
|
-
tree_mutex.synchronize {
|
128
|
-
if threads.all? { |thread| thread.status == false }
|
129
|
-
throw :leave
|
130
|
-
end
|
131
|
-
thread_wake_condition.broadcast
|
132
|
-
}
|
133
|
-
Thread.pass
|
134
|
-
}
|
135
|
-
|
136
|
-
#trace "Main: computation done."
|
137
|
-
if finished.is_a? Exception
|
138
|
-
raise finished
|
139
|
-
else
|
140
|
-
root.result
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def find_node(node)
|
145
|
-
# --- only called inside shared tree mutex
|
146
|
-
#trace "Looking for a node, starting with #{node.name}"
|
147
|
-
if node.computed
|
148
|
-
#
|
149
|
-
# already computed
|
150
|
-
#
|
151
|
-
#trace "#{node.name} has been computed"
|
152
|
-
nil
|
153
|
-
elsif (children_results = node.find_children_results) and node.try_lock
|
154
|
-
#
|
155
|
-
# Node is not computed and its children are computed;
|
156
|
-
# and we have the lock. Ready to compute.
|
157
|
-
#
|
158
|
-
node.children_results = children_results
|
159
|
-
node
|
160
|
-
else
|
161
|
-
#
|
162
|
-
# locked or children not computed; recurse to children
|
163
|
-
#
|
164
|
-
#trace "Checking #{node.name}'s children"
|
165
|
-
node.each_child { |child|
|
166
|
-
next_node = find_node(child) and return next_node
|
167
|
-
}
|
168
|
-
nil
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|