wait for in-progress subcommands to complete on build failure - close #39

This commit is contained in:
Josh Holtrop 2017-06-26 22:44:49 -04:00
parent 15e52e488c
commit 2a96495e83
4 changed files with 48 additions and 6 deletions

View File

@ -0,0 +1,20 @@
class Fail < Rscons::Builder
def run(options)
target, cache, env, vars = options.values_at(:target, :cache, :env, :vars)
wait_time = env.expand_varref("${wait_time}", vars)
ruby_command = %[sleep #{wait_time}; exit 2]
command = %W[ruby -e #{ruby_command}]
standard_threaded_build("Fail #{target}", target, command, [], env, cache)
end
def finalize(options)
standard_finalize(options)
end
end
Rscons::Environment.new do |env|
env.add_builder(Fail.new)
4.times do |i|
wait_time = i + 1
env.Fail("foo_#{wait_time}", [], "wait_time" => wait_time.to_s)
end
end

View File

@ -70,7 +70,6 @@ module Rscons
begin
load rsconsfile
rescue Rscons::BuildError => e
$stderr.puts e.message
exit 1
end

View File

@ -302,13 +302,19 @@ module Rscons
# @return [void]
def process
cache = Cache.instance
failure = nil
begin
while @job_set.size > 0 or @threaded_commands.size > 0
targets_still_building = @threaded_commands.map do |tc|
tc.build_operation[:target]
if failure
@job_set.clear!
job = nil
else
targets_still_building = @threaded_commands.map do |tc|
tc.build_operation[:target]
end
job = @job_set.get_next_job_to_run(targets_still_building)
end
job = @job_set.get_next_job_to_run(targets_still_building)
# TODO: have Cache determine when checksums may be invalid based on
# file size and/or timestamp.
@ -323,7 +329,9 @@ module Rscons
allow_delayed_execution: true,
setup_info: job[:setup_info])
unless result
raise BuildError.new("Failed to build #{job[:target]}")
failure = "Failed to build #{job[:target]}"
$stderr.puts failure
next
end
end
@ -351,7 +359,9 @@ module Rscons
unless @echo == :command
$stdout.puts "Failed command was: #{command_to_s(tc.command)}"
end
raise BuildError.new("Failed to build #{tc.build_operation[:target]}")
failure = "Failed to build #{tc.build_operation[:target]}"
$stderr.puts failure
break
end
end
@ -359,6 +369,9 @@ module Rscons
ensure
cache.write
end
if failure
raise BuildError.new(failure)
end
end
# Clear all targets registered for the Environment.

View File

@ -752,6 +752,16 @@ EOF
expect(result.stderr).to eq ""
end
it "waits for all parallelized builds to complete if one fails" do
test_dir("simple")
result = run_test(rsconsfile: "wait_for_builds_on_failure.rb", rscons_args: %w[-j4])
expect(result.status).to_not eq 0
expect(result.stderr).to match /Failed to build foo_1/
expect(result.stderr).to match /Failed to build foo_2/
expect(result.stderr).to match /Failed to build foo_3/
expect(result.stderr).to match /Failed to build foo_4/
end
context "backward compatibility" do
it "allows a builder to call Environment#run_builder in a non-threaded manner" do
test_dir("simple")