lib/autobuild/reporting.rb in autobuild-1.14.0 vs lib/autobuild/reporting.rb in autobuild-1.14.1
- old
+ new
@@ -1,249 +1,82 @@
require 'autobuild/exceptions'
+require 'pastel'
+
module Autobuild
+ @colorizer = Pastel.new
class << self
- attr_reader :display_lock
+ def color=(flag)
+ @colorizer =
+ if flag.nil?
+ Pastel.new
+ else
+ Pastel.new(enabled: flag)
+ end
+ end
+
+ def color?
+ @colorizer.enabled?
+ end
+ def color(message, *style)
+ @colorizer.decorate(message, *style)
+ end
+ end
+end
+
+require 'tty/cursor'
+require 'tty/screen'
+require 'autobuild/progress_display'
+
+module Autobuild
+ class << self
def silent?
- @silent
+ @display.silent?
end
- attr_writer :silent
+ def silent=(flag)
+ @display.silent = flag
+ end
end
- @display_lock = Mutex.new
- @silent = false
+ @display = ProgressDisplay.new(STDOUT)
- def self.silent
- Autobuild.silent, silent = true, Autobuild.silent?
- yield
- ensure
- Autobuild.silent = silent
+ def self.silent(&block)
+ @display.silent(&block)
end
def self.progress_display_enabled?
- @progress_display_enabled
+ @display.progress_enabled?
end
def self.progress_display_enabled=(value)
- @progress_display_enabled = value
+ @display.progress_enabled = value
end
- @progress_display_enabled = true
- @last_progress_msg = nil
-
- def self.message(*args)
- return if silent?
- display_lock.synchronize do
- display_message(*args)
- end
+ def self.message(*args, **options)
+ @display.message(*args, **options)
end
- def self.display_message(*args)
- io = STDOUT
- if args.last.kind_of?(IO)
- io = args.pop
- end
- msg =
- if args.empty? then ""
- else "#{color(*args)}"
- end
-
- if !Autobuild.progress_display_enabled?
- if !silent?
- io.puts msg
- end
- return
- end
-
- if !silent?
- io.puts "#{clear_line}#{msg}"
- if @last_progress_msg
- io.print @last_progress_msg
- end
- end
- end
-
- class << self
- attr_reader :progress_messages
- end
- @progress_messages = Array.new
-
# Displays an error message
def self.error(message = "")
- message(" ERROR: #{message}", :red, :bold, STDERR)
+ message(" ERROR: #{message}", :red, :bold, io: STDERR)
end
# Displays a warning message
def self.warn(message = "", *style)
- message(" WARN: #{message}", :magenta, *style, STDERR)
+ message(" WARN: #{message}", :magenta, *style, io: STDERR)
end
- # @return [Boolean] true if there is some progress messages for the given
- # key
- def self.has_progress_for?(key)
- progress_messages.any? { |msg_key, _| msg_key == key }
+ def self.progress_start(key, *args, **options, &block)
+ @display.progress_start(key, *args, **options, &block)
end
- def self.clear_line
- "\e[2K\e[1G"
- end
-
- def self.progress_start(key, *args)
- if args.last.kind_of?(Hash)
- options = Kernel.validate_options args.pop, :done_message => nil
- else
- options = Hash.new
- end
-
- progress_done(key)
- display_lock.synchronize do
- progress_messages << [key, color(*args)]
- if Autobuild.progress_display_enabled?
- display_progress
- else
- display_message(" " + color(*args))
- end
- end
-
- if block_given?
- begin
- result = yield
- if options[:done_message] && has_progress_for?(key)
- progress(key, *options[:done_message])
- end
- progress_done(key, true)
- result
- rescue Exception
- progress_done(key, false)
- raise
- end
- end
- end
def self.progress(key, *args)
- found = false
- display_lock.synchronize do
- progress_messages.map! do |msg_key, msg|
- if msg_key == key
- found = true
- [msg_key, color(*args)]
- else
- [msg_key, msg]
- end
- end
- if !found
- progress_messages << [key, color(*args)]
- end
-
- return if !Autobuild.progress_display_enabled?
-
- display_progress
- end
+ @display.progress(key, *args)
end
- def self.progress_done(key, display_last = true)
- found = false
- display_lock.synchronize do
- last_msg = nil
- progress_messages.delete_if do |msg_key, msg|
- if msg_key == key
- found = true
- last_msg = msg
- end
- end
- if found
- if display_last
- display_message(" #{last_msg}")
- end
- if @last_progress_msg
- display_progress
- end
- end
- end
- found
+ def self.progress_done(key, display_last = true, message: nil)
+ @display.progress_done(key, display_last, message: message)
end
- def self.find_common_prefix(msg, other_msg)
- msg = msg.split(" ")
- other_msg = other_msg.split(" ")
- msg.each_with_index do |token, idx|
- if other_msg[idx] != token
- prefix = msg[0..(idx - 1)].join(" ")
- if !prefix.empty?
- prefix << " "
- end
- return prefix
- end
- end
- return msg.join(" ")
- end
-
- def self.format_progress_message(messages)
- messages = messages.sort
-
- groups = Array.new
- groups << ["", (0...messages.size)]
- messages.each_with_index do |msg, idx|
- prefix, grouping = nil, false
- messages[(idx + 1)..-1].each_with_index do |other_msg, other_idx|
- other_idx += idx + 1
- prefix ||= find_common_prefix(msg, other_msg)
- break if !other_msg.start_with?(prefix)
-
- if grouping
- break if prefix != groups.last[0]
- groups.last[1] << other_idx
- else
- current_prefix, current_group = groups.last
- if prefix.size > current_prefix.size # create a new group from there
- groups.last[1] = (current_group.first..[idx-1,current_group.last].min)
- groups << [prefix, [idx, other_idx]]
- grouping = true
- else break
- end
- end
- end
- end
- if groups.last.last.last < messages.size
- groups << ["", (groups.last.last.last + 1)...(messages.size)]
- end
-
- result = []
- groups.each do |prefix, indexes|
- if prefix.empty?
- indexes.each do |index|
- result << messages[index]
- end
- else
- grouped_messages = []
- indexes.each do |index|
- grouped_messages << messages[index][(prefix.size)..-1]
- end
- if !grouped_messages.empty?
- result << "#{prefix}#{grouped_messages.uniq.join(", ")}"
- end
- end
- end
- result.join(" | ")
- end
-
- def self.display_progress
- msg = format_progress_message(progress_messages.map(&:last))
-
- if msg.empty?
- @last_progress_msg = nil
- else
- msg = " #{msg}"
- @last_progress_msg = msg
- end
-
- if !silent?
- if Autobuild.progress_display_enabled?
- print "#{clear_line}#{msg}"
- elsif @last_progress_msg
- puts msg
- end
- end
- end
-
## The reporting module provides the framework # to run commands in
# autobuild and report errors # to the user
#
# It does not use a logging framework like Log4r, but it should ;-)
module Reporting
@@ -287,9 +120,12 @@
# Handle how Reporting.report is meant to finish in case of error(s)
#
# @param [Symbol] on_package_failures how does the reporting should behave.
#
def self.report_finish_on_error(errors, on_package_failures: default_report_on_package_failures, interrupted_by: nil)
+ if not_package_error = errors.find { |e| !e.respond_to?(:fatal?) }
+ raise not_package_error
+ end
if ![:raise, :report_silent, :exit_silent].include?(on_package_failures)
errors.each { |e| error(e) }
end
fatal = errors.any?(&:fatal?)
if !fatal