From bd47c2a5998657ad07e610b9873c362b353371cf Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Thu, 3 Mar 2022 13:34:35 +0100 Subject: [PATCH] Add `--error-output stderr` option to only print errors/failures on stderr * See https://github.com/ruby/ruby/pull/5510 and https://github.com/ruby/ruby/pull/5487 --- lib/mspec/commands/mspec.rb | 6 ++++-- lib/mspec/runner/formatters/base.rb | 18 +++++++++++++----- lib/mspec/utils/options.rb | 11 ++++++++++- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/lib/mspec/commands/mspec.rb b/lib/mspec/commands/mspec.rb index 9d82949f..9c38cebc 100755 --- a/lib/mspec/commands/mspec.rb +++ b/lib/mspec/commands/mspec.rb @@ -25,6 +25,7 @@ def options(argv = ARGV) config[:command] = argv.shift if ["ci", "run", "tag"].include?(argv[0]) options = MSpecOptions.new "mspec [COMMAND] [options] (FILE|DIRECTORY|GLOB)+", 30, config + @options = options options.doc " The mspec command sets up and invokes the sub-commands" options.doc " (see below) to enable, for instance, running the specs" @@ -110,8 +111,9 @@ def run if config[:multi] exit multi_exec(argv) else - $stderr.puts "$ #{argv.join(' ')}" - $stderr.flush + log = config[:options].include?('--error-output') ? $stdout : $stderr + log.puts "$ #{argv.join(' ')}" + log.flush exec(*argv, close_others: false) end end diff --git a/lib/mspec/runner/formatters/base.rb b/lib/mspec/runner/formatters/base.rb index 6c075c4d..c7c50c40 100644 --- a/lib/mspec/runner/formatters/base.rb +++ b/lib/mspec/runner/formatters/base.rb @@ -1,6 +1,7 @@ require 'mspec/expectations/expectations' require 'mspec/runner/actions/timer' require 'mspec/runner/actions/tally' +require 'mspec/utils/options' if ENV['CHECK_LEAKS'] require 'mspec/runner/actions/leakchecker' @@ -18,10 +19,17 @@ def initialize(out = nil) @count = 0 # For subclasses - if out.nil? + if out + @out = File.open out, "w" + else @out = $stdout + end + + err = MSpecOptions.latest && MSpecOptions.latest.config[:error_output] + if err + @err = (err == 'stderr') ? $stderr : File.open(err, "w") else - @out = File.open out, "w" + @err = @out end end @@ -115,9 +123,9 @@ def finish def print_exception(exc, count) outcome = exc.failure? ? "FAILED" : "ERROR" - print "\n#{count})\n#{exc.description} #{outcome}\n" - print exc.message, "\n" - print exc.backtrace, "\n" + @err.print "\n#{count})\n#{exc.description} #{outcome}\n" + @err.print exc.message, "\n" + @err.print exc.backtrace, "\n" end # A convenience method to allow printing to different outputs. diff --git a/lib/mspec/utils/options.rb b/lib/mspec/utils/options.rb index bef1dbdd..23a4c9a2 100644 --- a/lib/mspec/utils/options.rb +++ b/lib/mspec/utils/options.rb @@ -32,6 +32,10 @@ class OptionError < Exception; end # Raised if an unrecognized option is encountered. class ParseError < Exception; end + class << self + attr_accessor :latest + end + attr_accessor :config, :banner, :width, :options def initialize(banner = "", width = 30, config = nil) @@ -46,7 +50,7 @@ def initialize(banner = "", width = 30, config = nil) @extra << x } - yield self if block_given? + MSpecOptions.latest = self end # Registers an option. Acceptable formats for arguments are: @@ -311,6 +315,11 @@ def formatters "Write formatter output to FILE") do |f| config[:output] = f end + + on("--error-output", "FILE", + "Write error output of failing specs to FILE, or $stderr if value is 'stderr'.") do |f| + config[:error_output] = f + end end def filters