lib/progress.rb in progress-1.1.1 vs lib/progress.rb in progress-1.1.2
- old
+ new
@@ -1,100 +1,95 @@
require 'singleton'
+# ==== Procedural example
+# Progress.start('Test', 1000)
+# 1000.times{ Progress.step }
+# Progress.stop
+# ==== Block example
+# Progress.start('Test', 1000) do
+# 1000.times{ Progress.step }
+# end
+# ==== Step must not always be one
+# symbols = []
+# Progress.start('Input 100 symbols', 100) do
+# while symbols.length < 100
+# input = gets.scan(/\S/)
+# symbols += input
+# Progress.step input.length
+# end
+# end
+# ==== Enclosed block example
+# [1, 2, 3].each_with_progress('1 2 3') do |one_of_1_2_3|
+# 10.times_with_progress('10') do |one_of_10|
+# sleep(0.001)
+# end
+# end
class Progress
include Singleton
- module InstanceMethods # :nodoc:
- attr_accessor :title, :current, :total, :note
- attr_reader :current_step
- def initialize(title, total)
- if title.is_a?(Numeric) && total.nil?
- title, total = nil, title
- elsif total.nil?
- total = 1
- end
- @title = title
- @current = 0.0
- @total = total == 0.0 ? 1.0 : Float(total)
+ attr_accessor :title, :current, :total, :note
+ attr_reader :current_step
+ def initialize(title, total)
+ if title.is_a?(Numeric) && total.nil?
+ title, total = nil, title
+ elsif total.nil?
+ total = 1
end
+ @title = title
+ @current = 0.0
+ @total = total == 0.0 ? 1.0 : Float(total)
+ end
- def step_if_blank
- if current == 0.0 && total == 1.0
- self.current = 1.0
- end
+ def step_if_blank
+ if current == 0.0 && total == 1.0
+ self.current = 1.0
end
+ end
- def to_f(inner)
- inner = [inner, 1.0].min
- if current_step
- inner *= current_step
- end
- (current + inner) / total
+ def to_f(inner)
+ inner = [inner, 1.0].min
+ if current_step
+ inner *= current_step
end
+ (current + inner) / total
+ end
- def step(steps)
- @current_step = steps
- yield
- ensure
- @current_step = nil
- end
+ def step(steps)
+ @current_step = steps
+ yield
+ ensure
+ @current_step = nil
end
- include InstanceMethods
class << self
# start progress indication
- # ==== Procedural example
- # Progress.start('Test', 1000)
- # 1000.times{ Progress.step }
- # Progress.stop
- # ==== Block example
- # Progress.start('Test', 1000) do
- # 1000.times{ Progress.step }
- # end
- # ==== Step must not always be one
- # symbols = []
- # Progress.start('Input 100 symbols', 100) do
- # while symbols.length < 100
- # input = gets.scan(/\S/)
- # symbols += input
- # Progress.step input.length
- # end
- # end
- # ==== Enclosed block example
- # [1, 2, 3].each_with_progress('1 2 3') do |one_of_1_2_3|
- # 10.times_with_progress('10') do |one_of_10|
- # sleep(0.001)
- # end
- # end
- # ==== To output progress as lines (not trying to stay on line)
- # Progress.lines = true
- # ==== To force highlight
- # Progress.highlight = true
def start(title = nil, total = nil)
if levels.empty?
@started_at = Time.now
@eta = nil
end
levels << new(title, total)
- print_message(true)
+ print_message true
if block_given?
begin
yield
ensure
stop
end
end
end
+ # step current progress by `num / den`
def step(num = 1, den = 1, &block)
if levels.last
set(levels.last.current + Float(num) / den, &block)
elsif block
block.call
end
end
+ # set current progress to `value`
def set(value, &block)
if levels.last
ret = if block
levels.last.step(value - levels.last.current, &block)
end
@@ -107,31 +102,39 @@
elsif block
block.call
end
end
+ # stop progress
def stop
if levels.last
if levels.last.step_if_blank || levels.length == 1
- print_message(true)
- set_title(nil)
+ print_message true
+ set_title nil
end
levels.pop
if levels.empty?
io.puts
end
end
end
+ # set note (will be shown after progress message)
def note=(s)
if levels.last
levels.last.note = s
end
end
- attr_writer :lines, :highlight # :nodoc:
+ # output progress as lines (not trying to stay on line)
+ # Progress.lines = true
+ attr_writer :lines
+ # force highlight
+ # Progress.highlight = true
+ attr_writer :highlight
+
private
def levels
@levels ||= []
end
@@ -185,30 +188,27 @@
end
end
def set_title(title)
if io_tty?
- io.print("\e]0;#{title}\a")
+ io.print "\e]0;#{title}\a"
end
end
def print_message(force = false)
if force || time_to_print?
inner = 0
- parts = []
- parts_cl = []
- levels.reverse.each do |l|
- current = l.to_f(inner)
- value = current == 0 ? '......' : "#{'%5.1f' % (current * 100.0)}%"
- inner = current
+ parts, parts_cl = [], []
+ levels.reverse.each do |level|
+ inner = current = level.to_f(inner)
+ value = current.zero? ? '......' : "#{'%5.1f' % (current * 100.0)}%"
- title = l.title ? "#{l.title}: " : ''
- highlighted = "\e[1m#{value}\e[0m"
+ title = level.title ? "#{level.title}: " : nil
if !highlight? || value == '100.0%'
parts << "#{title}#{value}"
else
- parts << "#{title}#{highlighted}"
+ parts << "#{title}\e[1m#{value}\e[0m"
end
parts_cl << "#{title}#{value}"
end
eta_string = eta(inner)
@@ -218,17 +218,16 @@
if note = levels.last && levels.last.note
message << " - #{note}"
message_cl << " - #{note}"
end
- unless lines?
- previous_length = @previous_length || 0
- @previous_length = message_cl.length
- message << "#{' ' * [previous_length - message_cl.length, 0].max}\r"
+ if lines?
+ io.puts message
+ else
+ io << message << "\e[K\r"
end
- lines? ? io.puts(message) : io.print(message)
- set_title(message_cl)
+ set_title message_cl
end
end
end
end