class Sus::Output::Progress
def self.now
def self.now ::Process.clock_gettime(Process::CLOCK_MONOTONIC) end
def average_duration
def average_duration if @current > 0 duration / @current end end
def clear
def clear @lines&.clear end
def duration
def duration Progress.now - @start_time end
def estimated_remaining_time
def estimated_remaining_time if average_duration = self.average_duration average_duration * remaining end end
def expand(amount = 1)
def expand(amount = 1) @total += amount @bar&.update(@current, @total, self.to_s) @lines&.redraw(0) return self end
def formatted_duration(duration)
def formatted_duration(duration) seconds = duration.floor if seconds < 60.0 return "#{seconds}s" end minutes = (duration / 60.0).floor seconds = (seconds - (minutes * 60)).round if minutes < 60.0 return "#{minutes}m#{seconds}s" end hours = (minutes / 60.0).floor minutes = (minutes - (hours * 60)).round if hours < 24.0 return "#{hours}h#{minutes}m" end days = (hours / 24.0).floor hours = (hours - (days * 24)).round return "#{days}d#{hours}h" end
def increment(amount = 1)
def increment(amount = 1) @current += amount @bar&.update(@current, @total, self.to_s) @lines&.redraw(0) return self end
def initialize(output, total = 0, minimum_output_duration: 1.0)
def initialize(output, total = 0, minimum_output_duration: 1.0) @output = output @subject = subject @start_time = Progress.now if @output.interactive? @bar = Bar.new @lines = Lines.new(@output) @lines[0] = @bar end @current = 0 @total = total end
def progress
def progress @current.to_f / @total.to_f end
def remaining
def remaining @total - @current end
def report(index, context, state)
def report(index, context, state) @lines&.[]=(index+1, Status.new(state, context)) return self end
def to_s
def to_s if estimated_remaining_time = self.estimated_remaining_time "#{@current}/#{@total} completed in #{formatted_duration(self.duration)}, #{formatted_duration(estimated_remaining_time)} remaining" else "#{@current}/#{@total} completed" end end