rework showing failed command - close #89
This commit is contained in:
parent
ab2fa1662f
commit
bf136e79f2
@ -80,13 +80,14 @@ module Rscons
|
|||||||
# Exit code.
|
# Exit code.
|
||||||
def build(options)
|
def build(options)
|
||||||
begin
|
begin
|
||||||
|
Cache.instance["failed_commands"] = []
|
||||||
@script.build
|
@script.build
|
||||||
Environment.environments.each do |env|
|
Environment.environments.each do |env|
|
||||||
env.process
|
env.process
|
||||||
end
|
end
|
||||||
0
|
0
|
||||||
rescue BuildError => be
|
rescue BuildError => be
|
||||||
$stderr.puts be
|
Ansi.write($stderr, :red, be.message, :reset, "\n")
|
||||||
1
|
1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -137,6 +138,7 @@ module Rscons
|
|||||||
options[:build_dir] ||= "build"
|
options[:build_dir] ||= "build"
|
||||||
options[:prefix] ||= "/usr/local"
|
options[:prefix] ||= "/usr/local"
|
||||||
cache = Cache.instance
|
cache = Cache.instance
|
||||||
|
cache["failed_commands"] = []
|
||||||
cache["configuration_data"] = {}
|
cache["configuration_data"] = {}
|
||||||
if project_name = @script.project_name
|
if project_name = @script.project_name
|
||||||
Ansi.write($stdout, "Configuring ", :cyan, project_name, :reset, "...\n")
|
Ansi.write($stdout, "Configuring ", :cyan, project_name, :reset, "...\n")
|
||||||
|
@ -5,6 +5,7 @@ USAGE = <<EOF
|
|||||||
Usage: #{$0} [global options] [operation] [operation options]
|
Usage: #{$0} [global options] [operation] [operation options]
|
||||||
|
|
||||||
Global options:
|
Global options:
|
||||||
|
-F, --show-failure Show previous failed command(s) and exit
|
||||||
--version Show rscons version and exit
|
--version Show rscons version and exit
|
||||||
-h, --help Show rscons help and exit
|
-h, --help Show rscons help and exit
|
||||||
-r COLOR, --color=COLOR Set color mode (off, auto, force)
|
-r COLOR, --color=COLOR Set color mode (off, auto, force)
|
||||||
@ -86,6 +87,11 @@ module Rscons
|
|||||||
rsconscript = f
|
rsconscript = f
|
||||||
end
|
end
|
||||||
|
|
||||||
|
opts.on("-F", "--show-failure") do
|
||||||
|
show_failure
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
opts.on("--version") do
|
opts.on("--version") do
|
||||||
puts "Rscons version #{Rscons::VERSION}"
|
puts "Rscons version #{Rscons::VERSION}"
|
||||||
exit 0
|
exit 0
|
||||||
@ -157,6 +163,14 @@ module Rscons
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show_failure
|
||||||
|
failed_commands = Cache.instance["failed_commands"]
|
||||||
|
failed_commands.each_with_index do |command, i|
|
||||||
|
Ansi.write($stdout, :red, "Failed command (#{i + 1}/#{failed_commands.size}):", :reset, "\n")
|
||||||
|
$stdout.puts Util.command_to_s(command)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -261,7 +261,7 @@ module Rscons
|
|||||||
unless Cache.instance["configuration_data"]["configured"]
|
unless Cache.instance["configuration_data"]["configured"]
|
||||||
raise "Project must be configured before processing an Environment"
|
raise "Project must be configured before processing an Environment"
|
||||||
end
|
end
|
||||||
@process_failure = nil
|
@process_failures = []
|
||||||
@process_blocking_wait = false
|
@process_blocking_wait = false
|
||||||
@process_commands_waiting_to_run = []
|
@process_commands_waiting_to_run = []
|
||||||
@process_builder_waits = {}
|
@process_builder_waits = {}
|
||||||
@ -269,7 +269,7 @@ module Rscons
|
|||||||
begin
|
begin
|
||||||
while @builder_set.size > 0 or @threads.size > 0 or @process_commands_waiting_to_run.size > 0
|
while @builder_set.size > 0 or @threads.size > 0 or @process_commands_waiting_to_run.size > 0
|
||||||
process_step
|
process_step
|
||||||
if @process_failure
|
unless @process_failures.empty?
|
||||||
# On a build failure, do not start any more builders or commands,
|
# On a build failure, do not start any more builders or commands,
|
||||||
# but let the threads that have already been started complete.
|
# but let the threads that have already been started complete.
|
||||||
@builder_set.clear
|
@builder_set.clear
|
||||||
@ -279,8 +279,12 @@ module Rscons
|
|||||||
ensure
|
ensure
|
||||||
Cache.instance.write
|
Cache.instance.write
|
||||||
end
|
end
|
||||||
if @process_failure
|
unless @process_failures.empty?
|
||||||
raise BuildError.new(@process_failure)
|
msg = @process_failures.join("\n")
|
||||||
|
if Cache.instance["failed_commands"].size > 0
|
||||||
|
msg += "\nRun `#{$0} -F` to see the failed command(s)."
|
||||||
|
end
|
||||||
|
raise BuildError.new(msg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -537,29 +541,8 @@ module Rscons
|
|||||||
Ansi.write($stdout, :cyan, message, :reset, "\n") if message
|
Ansi.write($stdout, :cyan, message, :reset, "\n") if message
|
||||||
end
|
end
|
||||||
|
|
||||||
# Print a failed command.
|
|
||||||
#
|
|
||||||
# @param command [Array<String>]
|
|
||||||
# Builder command.
|
|
||||||
#
|
|
||||||
# @return [void]
|
|
||||||
def print_failed_command(command)
|
|
||||||
Ansi.write($stdout, :red, "Failed command was: #{Util.command_to_s(command)}", :reset, "\n")
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Signal a build failure to the {#process} method.
|
|
||||||
#
|
|
||||||
# @param target [String]
|
|
||||||
# Build target name.
|
|
||||||
#
|
|
||||||
# @return [void]
|
|
||||||
def process_failure(target)
|
|
||||||
@process_failure = "Failed to build #{target}"
|
|
||||||
Ansi.write($stderr, :red, @process_failure, :reset, "\n")
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run a builder and process its return value.
|
# Run a builder and process its return value.
|
||||||
#
|
#
|
||||||
# @param builder [Builder]
|
# @param builder [Builder]
|
||||||
@ -587,7 +570,7 @@ module Rscons
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
when false
|
when false
|
||||||
process_failure(builder.target)
|
@process_failures << "Failed to build #{builder.target}."
|
||||||
when true
|
when true
|
||||||
# Register side-effect files as build targets so that a Cache
|
# Register side-effect files as build targets so that a Cache
|
||||||
# clean operation will remove them.
|
# clean operation will remove them.
|
||||||
@ -644,10 +627,9 @@ module Rscons
|
|||||||
process_remove_wait(completed_command)
|
process_remove_wait(completed_command)
|
||||||
completed_command.status = thread.value
|
completed_command.status = thread.value
|
||||||
unless completed_command.status
|
unless completed_command.status
|
||||||
unless @echo == :command
|
Cache.instance["failed_commands"] << completed_command.command
|
||||||
print_failed_command(completed_command.command)
|
@process_failures << "Failed to build #{builder.target}."
|
||||||
end
|
return
|
||||||
return process_failure(builder.target)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -853,6 +853,25 @@ EOF
|
|||||||
expect(lines(result.stdout)).to include *["MyBuilder foo command"]
|
expect(lines(result.stdout)).to include *["MyBuilder foo command"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "stores the failed command for later display with -F command line option" do
|
||||||
|
test_dir("simple")
|
||||||
|
|
||||||
|
File.open("simple.c", "wb") do |fh|
|
||||||
|
fh.write("foo")
|
||||||
|
end
|
||||||
|
|
||||||
|
result = run_rscons
|
||||||
|
expect(result.stderr).to match /Failed to build/
|
||||||
|
expect(result.stderr).to match /^Run.*-F.*to see the failed command/
|
||||||
|
expect(result.status).to_not eq 0
|
||||||
|
|
||||||
|
result = run_rscons(rscons_args: %w[-F])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(result.stdout).to match %r{Failed command \(1/1\):}
|
||||||
|
expect(result.stdout).to match %r{^gcc -}
|
||||||
|
expect(result.status).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
context "colored output" do
|
context "colored output" do
|
||||||
it "does not output in color with --color=off" do
|
it "does not output in color with --color=off" do
|
||||||
test_dir("simple")
|
test_dir("simple")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user