lib/progress.rb in progress-0.0.9.3 vs lib/progress.rb in progress-0.1.0.0
- old
+ new
@@ -4,149 +4,127 @@
require 'singleton'
class Progress
include Singleton
- # 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
- # Progress.start('Test', 10) do
- # (1..10).to_a.each_slice do |slice|
- # Progress.step(slice.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 self.start(title, total = 1, options = {})
- levels << new(title, total, levels.length, options)
- print_message
- if block_given?
- result = yield
- stop
- result
+ module InstanceMethods # :nodoc:
+ attr_accessor :title, :current, :total
+ def initialize(title, total)
+ @title, @current, @total = title, 0, total.to_f
end
- end
- attr_reader :message, :options
- def initialize(title, total, level, options) # :nodoc:
- @title = title + ': %s'
- @total = total
- @level = level
- @options = options
- @current = 0
- start
- end
+ def step_if_blank
+ self.current = 1 if current == 0 && total == 1
+ end
- def start # :nodoc:
- self.message = '.' * 6
+ def to_f(inner)
+ (current + [inner, 1].min) / total
+ end
end
+ include InstanceMethods
- def step(steps) # :nodoc:
- @current += steps
- self.message = percent
- end
+ 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, total = 1)
+ levels << new(title, total)
+ print_message
+ if block_given?
+ result = yield
+ stop
+ result
+ end
+ end
- def stop # :nodoc:
- self.message = percent
- end
-
-protected
-
- def percent
- '%5.1f%%' % (@current * 100.0 / @total)
- end
-
- def message=(s)
- formatted = s.ljust(6)[0, 6]
- @message = @title % formatted
- end
-
- module ClassMethods
def step(steps = 1)
- levels[-1].step(steps)
+ levels.last.current += steps
print_message
end
+ def set(value)
+ levels.last.current = value
+ print_message
+ end
+
def stop
- levels.pop.stop
- @io.puts if levels.empty?
+ print_message if levels.last.step_if_blank
+ levels.pop
+ io.puts if levels.empty?
end
+ attr_writer :io, :lines, :highlight # :nodoc:
+
+ private
+
+ def levels
+ @levels ||= []
+ end
+
def io
@io ||= $stderr
+ @io.sync = true
+ @io
end
def io_tty?
- ENV['PROGRESS_TTY'] || io.tty?
+ io.tty? || ENV['PROGRESS_TTY']
end
- def io=(io)
- @io = io
- end
-
- def lines=(value)
- @lines = value
- end
def lines?
- if @lines.nil?
- @lines = !io_tty?
- end
- @lines
+ @lines.nil? ? !io_tty? : @lines
end
- def highlight=(value)
- @highlight = value
- end
def highlight?
- if @highlight.nil?
- @highlight = io_tty?
- end
- @highlight
+ @highlight.nil? ? io_tty? : @highlight
end
- protected
-
def print_message
- message = levels.map{ |level| level.message } * ' > '
- io.sync = true
+ messages = []
+ inner = 0
+ levels.reverse.each do |l|
+ current = l.to_f(inner)
+ messages << "#{l.title}: #{(current == 0 ? '......' : '%5.1f%%' % (current * 100.0))[0, 6]}"
+ inner = current
+ end
+ message = messages.reverse * ' > '
unless lines?
previous_length = @previous_length || 0
@previous_length = message.length
message = message.ljust(previous_length, ' ') + "\r"
end
- if highlight?
- message.gsub!(/\d+\.\d+/){ |s| s == '100.0' ? s : "\e[1m#{s}\e[0m" }
- end
+ message.gsub!(/\d+\.\d+/){ |s| s == '100.0' ? s : "\e[1m#{s}\e[0m" } if highlight?
- unless lines?
- io.print message
- else
- io.puts message
- end
+ lines? ? io.puts(message) : io.print(message)
end
-
- def levels
- @levels ||= []
- end
end
- extend ClassMethods
end
require 'progress/with_progress'
require 'progress/enumerable'