class InteractiveLogger

A logger that shows activity for each step without spamming to stdout.

Public Class Methods

new(debug: false) click to toggle source
# File lib/interactive-logger.rb, line 11
def initialize(debug: false)
  @debug = debug
  @current_step = nil
  @draw_mutex = Mutex.new
end

Public Instance Methods

debug(str) click to toggle source

Post a debug message above the current step output, if debugging is enabled.

# File lib/interactive-logger.rb, line 75
def debug(str)
  return unless debug?

  @draw_mutex.synchronize do
    @current_step.blank if @current_step
    print '--> '.yellow
    puts str
    @current_step.repaint if @current_step
  end
end
debug?() click to toggle source
# File lib/interactive-logger.rb, line 17
def debug?; @debug == true end
error(str) click to toggle source

Post an error message above the current step output.

# File lib/interactive-logger.rb, line 97
def error(str)
  @draw_mutex.synchronize do
    @current_step.blank if @current_step
    print '--> '.red
    puts str
    @current_step.repaint if @current_step
  end
end
info(str) click to toggle source

Post an informative message above the current step output.

# File lib/interactive-logger.rb, line 87
def info(str)
  @draw_mutex.synchronize do
    @current_step.blank if @current_step
    print '--> '.green
    puts str
    @current_step.repaint if @current_step
  end
end
msg(str) click to toggle source

Post a single message, without any progress tracking.

# File lib/interactive-logger.rb, line 107
def msg(str)
  c = Step.new(str)
  c.success
  print "\n"
end
start(str) { |current_step| ... } click to toggle source

Start a step.

# File lib/interactive-logger.rb, line 20
def start(str)
  @current_step = Step.new(str)
  yield @current_step
  print "\n"
rescue => e
  @current_step.failure "Error while performing step: #{str}\n  #{e.class}: #{e.message}"
  print "\n"
  raise
ensure
  @current_step = nil
end
start_threaded(str) { |threaded_step_interface| ... } click to toggle source

Use a threaded interface, to keep the UI updated even on a long-running process.

# File lib/interactive-logger.rb, line 34
def start_threaded(str)
  @current_step = Step.new(str)
  queue = Queue.new

  Thread.abort_on_exception = true
  child = Thread.new do
    yield ThreadedStepInterface.new(queue)
  end

  loop do
    if queue.empty?
      @draw_mutex.synchronize do
        @current_step.continue # Keep the UI updating regardless of actual process.
      end
    else
      until queue.empty?
        msg = queue.pop

        @draw_mutex.synchronize do
          @current_step.send(msg.shift, *msg)
        end
      end
    end

    break unless child.alive?
    sleep 0.5
  end

  puts
  child.join

  @current_step.nil?
rescue => e
  @current_step.failure "Error while performing step: #{str}\n  #{e.class}: #{e.message}"
  print "\n"
  raise
ensure
  @current_step = nil
end