ruby-progressbar 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/lib/ruby-progressbar.rb +8 -3
- data/lib/ruby-progressbar/base.rb +121 -177
- data/lib/ruby-progressbar/calculators/length.rb +75 -0
- data/lib/ruby-progressbar/calculators/length_spec.rb +9 -0
- data/lib/ruby-progressbar/calculators/running_average.rb +9 -0
- data/lib/ruby-progressbar/components.rb +3 -5
- data/lib/ruby-progressbar/components/bar.rb +79 -43
- data/lib/ruby-progressbar/components/percentage.rb +29 -0
- data/lib/ruby-progressbar/components/rate.rb +34 -62
- data/lib/ruby-progressbar/components/time.rb +103 -0
- data/lib/ruby-progressbar/components/title.rb +13 -0
- data/lib/ruby-progressbar/format.rb +2 -1
- data/lib/ruby-progressbar/format/formatter.rb +27 -0
- data/lib/ruby-progressbar/format/molecule.rb +55 -37
- data/lib/ruby-progressbar/format/string.rb +36 -0
- data/lib/ruby-progressbar/output.rb +61 -0
- data/lib/ruby-progressbar/outputs/non_tty.rb +47 -0
- data/lib/ruby-progressbar/outputs/tty.rb +32 -0
- data/lib/ruby-progressbar/progress.rb +110 -0
- data/lib/ruby-progressbar/throttle.rb +25 -0
- data/lib/ruby-progressbar/time.rb +20 -17
- data/lib/ruby-progressbar/timer.rb +72 -0
- data/lib/ruby-progressbar/version.rb +2 -2
- data/spec/fixtures/benchmark.rb +21 -4
- data/spec/{lib/ruby-progressbar → ruby-progressbar}/base_spec.rb +55 -62
- data/spec/ruby-progressbar/calculators/running_average_spec.rb +19 -0
- data/spec/ruby-progressbar/components/bar_spec.rb +234 -0
- data/spec/ruby-progressbar/components/percentage_spec.rb +9 -0
- data/spec/ruby-progressbar/components/rate_spec.rb +9 -0
- data/spec/ruby-progressbar/components/throttle_spec.rb +157 -0
- data/spec/ruby-progressbar/components/time_spec.rb +308 -0
- data/spec/ruby-progressbar/components/title_spec.rb +12 -0
- data/spec/ruby-progressbar/format/formatter_spec.rb +9 -0
- data/spec/ruby-progressbar/format/molecule_spec.rb +30 -0
- data/spec/ruby-progressbar/format/string_spec.rb +9 -0
- data/spec/ruby-progressbar/output_spec.rb +7 -0
- data/spec/ruby-progressbar/outputs/non_tty_spec.rb +9 -0
- data/spec/ruby-progressbar/outputs/tty_spec.rb +9 -0
- data/spec/ruby-progressbar/progress_spec.rb +150 -0
- data/spec/ruby-progressbar/time_spec.rb +37 -0
- data/spec/ruby-progressbar/timer_spec.rb +7 -0
- data/spec/spec_helper.rb +2 -2
- data/spec/support/time.rb +3 -1
- metadata +55 -35
- data/lib/ruby-progressbar/components/elapsed_timer.rb +0 -25
- data/lib/ruby-progressbar/components/estimated_timer.rb +0 -90
- data/lib/ruby-progressbar/components/progressable.rb +0 -112
- data/lib/ruby-progressbar/components/throttle.rb +0 -21
- data/lib/ruby-progressbar/components/timer.rb +0 -69
- data/lib/ruby-progressbar/format/base.rb +0 -55
- data/lib/ruby-progressbar/formatter.rb +0 -112
- data/lib/ruby-progressbar/length_calculator.rb +0 -64
- data/lib/ruby-progressbar/running_average_calculator.rb +0 -7
- data/spec/lib/ruby-progressbar/components/bar_spec.rb +0 -210
- data/spec/lib/ruby-progressbar/components/elapsed_timer_spec.rb +0 -91
- data/spec/lib/ruby-progressbar/components/estimated_timer_spec.rb +0 -241
- data/spec/lib/ruby-progressbar/components/progressable_spec.rb +0 -47
- data/spec/lib/ruby-progressbar/components/throttle_spec.rb +0 -100
- data/spec/lib/ruby-progressbar/format/molecule_spec.rb +0 -22
- data/spec/lib/ruby-progressbar/running_average_calculator_spec.rb +0 -11
- data/spec/lib/ruby-progressbar/time_spec.rb +0 -49
@@ -1,25 +0,0 @@
|
|
1
|
-
class ProgressBar
|
2
|
-
module Components
|
3
|
-
class ElapsedTimer
|
4
|
-
include Timer
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@started_at = nil
|
8
|
-
@stopped_at = nil
|
9
|
-
end
|
10
|
-
|
11
|
-
def to_s
|
12
|
-
"Time: #{elapsed_time}"
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
def elapsed_time
|
17
|
-
return '--:--:--' unless started?
|
18
|
-
|
19
|
-
hours, minutes, seconds = divide_seconds(elapsed_whole_seconds)
|
20
|
-
|
21
|
-
sprintf TIME_FORMAT, hours, minutes, seconds
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
class ProgressBar
|
2
|
-
module Components
|
3
|
-
class EstimatedTimer
|
4
|
-
include Timer
|
5
|
-
include Progressable
|
6
|
-
|
7
|
-
VALID_OOB_TIME_FORMATS = [:unknown, :friendly, nil]
|
8
|
-
|
9
|
-
def initialize(options = {})
|
10
|
-
@out_of_bounds_time_format = nil
|
11
|
-
@starting_at = nil
|
12
|
-
@stopped_at = nil
|
13
|
-
|
14
|
-
super
|
15
|
-
end
|
16
|
-
|
17
|
-
def start(options = {})
|
18
|
-
as(Timer).start
|
19
|
-
as(Progressable).start(options)
|
20
|
-
end
|
21
|
-
|
22
|
-
def reset
|
23
|
-
as(Timer).reset
|
24
|
-
as(Progressable).reset
|
25
|
-
end
|
26
|
-
|
27
|
-
def out_of_bounds_time_format=(format)
|
28
|
-
raise "Invalid Out Of Bounds time format. Valid formats are #{VALID_OOB_TIME_FORMATS.inspect}" unless VALID_OOB_TIME_FORMATS.include? format
|
29
|
-
|
30
|
-
@out_of_bounds_time_format = format
|
31
|
-
end
|
32
|
-
|
33
|
-
def to_s
|
34
|
-
" ETA: #{estimated_time}"
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
def estimated_time
|
39
|
-
return '??:??:??' if running_average.zero? || total.nil?
|
40
|
-
|
41
|
-
hours, minutes, seconds = *divide_seconds(estimated_seconds_remaining)
|
42
|
-
|
43
|
-
if hours > 99 && @out_of_bounds_time_format
|
44
|
-
out_of_bounds_time
|
45
|
-
else
|
46
|
-
sprintf TIME_FORMAT, hours, minutes, seconds
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def estimated_seconds_remaining
|
51
|
-
(elapsed_seconds * (self.total / self.running_average - 1)).round
|
52
|
-
end
|
53
|
-
|
54
|
-
def out_of_bounds_time
|
55
|
-
case @out_of_bounds_time_format
|
56
|
-
when :unknown
|
57
|
-
'??:??:??'
|
58
|
-
when :friendly
|
59
|
-
'> 4 Days'
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def as(ancestor, &blk)
|
64
|
-
@__as ||= {}
|
65
|
-
unless r = @__as[ancestor]
|
66
|
-
r = (@__as[ancestor] = As.new(self, ancestor))
|
67
|
-
end
|
68
|
-
r.instance_eval(&blk) if block_given?
|
69
|
-
r
|
70
|
-
end
|
71
|
-
|
72
|
-
class As
|
73
|
-
private(*instance_methods.select { |m| m !~ /(^__|^\W|^binding$)/ })
|
74
|
-
|
75
|
-
def initialize(subject, ancestor)
|
76
|
-
@subject = subject
|
77
|
-
@ancestor = ancestor
|
78
|
-
end
|
79
|
-
|
80
|
-
def start(*args, &blk)
|
81
|
-
@ancestor.instance_method(:start).bind(@subject).call(*args,&blk)
|
82
|
-
end
|
83
|
-
|
84
|
-
def method_missing(sym, *args, &blk)
|
85
|
-
@ancestor.instance_method(sym).bind(@subject).call(*args,&blk)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,112 +0,0 @@
|
|
1
|
-
require 'ruby-progressbar/errors/invalid_progress_error'
|
2
|
-
|
3
|
-
class ProgressBar
|
4
|
-
module Components
|
5
|
-
module Progressable
|
6
|
-
DEFAULT_TOTAL = 100
|
7
|
-
DEFAULT_BEGINNING_POSITION = 0
|
8
|
-
DEFAULT_SMOOTHING = 0.1
|
9
|
-
|
10
|
-
attr_reader :total
|
11
|
-
attr_reader :progress
|
12
|
-
attr_accessor :starting_position
|
13
|
-
attr_accessor :running_average
|
14
|
-
attr_accessor :smoothing
|
15
|
-
attr_accessor :autofinish
|
16
|
-
attr_accessor :finished
|
17
|
-
|
18
|
-
def initialize(options = {})
|
19
|
-
self.total = options.fetch(:total, DEFAULT_TOTAL)
|
20
|
-
self.smoothing = options[:smoothing] || DEFAULT_SMOOTHING
|
21
|
-
self.autofinish = options.fetch(:autofinish, true)
|
22
|
-
|
23
|
-
start :at => DEFAULT_BEGINNING_POSITION
|
24
|
-
end
|
25
|
-
|
26
|
-
def start(options = {})
|
27
|
-
self.finished = false
|
28
|
-
self.running_average = 0
|
29
|
-
self.progress = \
|
30
|
-
self.starting_position = options[:at] || self.progress
|
31
|
-
end
|
32
|
-
|
33
|
-
def started?
|
34
|
-
!!self.starting_position
|
35
|
-
end
|
36
|
-
|
37
|
-
def finished?
|
38
|
-
finished || (autofinish && progress == total)
|
39
|
-
end
|
40
|
-
|
41
|
-
def increment
|
42
|
-
warn "WARNING: Your progress bar is currently at #{progress} out of #{total} and cannot be incremented. In v2.0.0 this will become a ProgressBar::InvalidProgressError." if progress == total
|
43
|
-
|
44
|
-
self.progress += 1 unless progress == total
|
45
|
-
end
|
46
|
-
|
47
|
-
def decrement
|
48
|
-
warn "WARNING: Your progress bar is currently at #{progress} out of #{total} and cannot be decremented. In v2.0.0 this will become a ProgressBar::InvalidProgressError." if progress == 0
|
49
|
-
|
50
|
-
self.progress -= 1 unless progress == 0
|
51
|
-
end
|
52
|
-
|
53
|
-
def reset
|
54
|
-
start :at => self.starting_position
|
55
|
-
end
|
56
|
-
|
57
|
-
def progress=(new_progress)
|
58
|
-
validate_progress(new_progress)
|
59
|
-
|
60
|
-
@progress = new_progress
|
61
|
-
|
62
|
-
update_running_average
|
63
|
-
end
|
64
|
-
|
65
|
-
def total=(new_total)
|
66
|
-
validate_total(new_total)
|
67
|
-
@total = new_total
|
68
|
-
end
|
69
|
-
|
70
|
-
def finish
|
71
|
-
self.finished = true
|
72
|
-
self.progress = total
|
73
|
-
end
|
74
|
-
|
75
|
-
def percentage_completed
|
76
|
-
return 100 if total == 0
|
77
|
-
return 0 if total.nil?
|
78
|
-
|
79
|
-
# progress / total * 100
|
80
|
-
#
|
81
|
-
# Doing this way so we can avoid converting each
|
82
|
-
# number to a float and then back to an integer.
|
83
|
-
#
|
84
|
-
(self.progress * 100 / total).to_i
|
85
|
-
end
|
86
|
-
|
87
|
-
def percentage_completed_with_precision
|
88
|
-
return 100.0 if total == 0
|
89
|
-
return 0.0 if total.nil?
|
90
|
-
|
91
|
-
format('%5.2f', (progress.to_f * 100.0 / total * 100.0).floor / 100.0)
|
92
|
-
end
|
93
|
-
|
94
|
-
def progress_made
|
95
|
-
started? ? self.progress - self.starting_position : 0
|
96
|
-
end
|
97
|
-
|
98
|
-
private
|
99
|
-
def validate_total(new_total)
|
100
|
-
(progress.nil? || new_total.nil? || new_total >= progress) || raise(ProgressBar::InvalidProgressError, "You can't set the item's total value to be less than the current progress.")
|
101
|
-
end
|
102
|
-
|
103
|
-
def validate_progress(new_progress)
|
104
|
-
(total.nil? || new_progress <= total) || raise(ProgressBar::InvalidProgressError, "You can't set the item's current value to be greater than the total.")
|
105
|
-
end
|
106
|
-
|
107
|
-
def update_running_average
|
108
|
-
self.running_average = RunningAverageCalculator.calculate(self.running_average, self.progress_made, self.smoothing)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
class ProgressBar
|
2
|
-
module Components
|
3
|
-
class Throttle
|
4
|
-
include Timer
|
5
|
-
|
6
|
-
def initialize(options = {})
|
7
|
-
@period = options.delete(:throttle_rate) { 0.01 } || 0.01
|
8
|
-
@started_at = nil
|
9
|
-
@stopped_at = nil
|
10
|
-
end
|
11
|
-
|
12
|
-
def choke(force = false, &block)
|
13
|
-
if !started? || @period.nil? || force || elapsed_seconds >= @period
|
14
|
-
yield
|
15
|
-
|
16
|
-
start
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'ruby-progressbar/time'
|
2
|
-
|
3
|
-
class ProgressBar
|
4
|
-
module Components
|
5
|
-
module Timer
|
6
|
-
TIME_FORMAT = '%02d:%02d:%02d'
|
7
|
-
|
8
|
-
def start
|
9
|
-
@started_at = stopped? ? now - (@stopped_at - @started_at) : now
|
10
|
-
@stopped_at = nil
|
11
|
-
end
|
12
|
-
|
13
|
-
def stop
|
14
|
-
return unless started?
|
15
|
-
|
16
|
-
@stopped_at = now
|
17
|
-
end
|
18
|
-
|
19
|
-
def pause
|
20
|
-
stop
|
21
|
-
end
|
22
|
-
|
23
|
-
def resume
|
24
|
-
start
|
25
|
-
end
|
26
|
-
|
27
|
-
def started?
|
28
|
-
!!@started_at
|
29
|
-
end
|
30
|
-
|
31
|
-
def stopped?
|
32
|
-
!!@stopped_at
|
33
|
-
end
|
34
|
-
|
35
|
-
def reset
|
36
|
-
@started_at = nil
|
37
|
-
@stopped_at = nil
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
def now
|
42
|
-
ProgressBar::Time.now
|
43
|
-
end
|
44
|
-
|
45
|
-
def elapsed_seconds
|
46
|
-
((@stopped_at || now) - @started_at)
|
47
|
-
end
|
48
|
-
|
49
|
-
def elapsed_whole_seconds
|
50
|
-
elapsed_seconds.floor
|
51
|
-
end
|
52
|
-
|
53
|
-
def elapsed_time
|
54
|
-
return '--:--:--' unless started?
|
55
|
-
|
56
|
-
hours, minutes, seconds = *divide_seconds(elapsed_whole_seconds)
|
57
|
-
|
58
|
-
sprintf TIME_FORMAT, hours, minutes, seconds
|
59
|
-
end
|
60
|
-
|
61
|
-
def divide_seconds(seconds)
|
62
|
-
hours, seconds = seconds.divmod(3600)
|
63
|
-
minutes, seconds = seconds.divmod(60)
|
64
|
-
|
65
|
-
[hours, minutes, seconds]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
class ProgressBar
|
2
|
-
module Format
|
3
|
-
class Base
|
4
|
-
attr_reader :molecules
|
5
|
-
|
6
|
-
def initialize(format_string)
|
7
|
-
@format_string = format_string
|
8
|
-
@molecules = parse(format_string)
|
9
|
-
end
|
10
|
-
|
11
|
-
def process(environment)
|
12
|
-
processed_string = @format_string.dup
|
13
|
-
ansi_sgr_codes = %r{\e\[[\d;]+m}
|
14
|
-
|
15
|
-
non_bar_molecules.each do |molecule|
|
16
|
-
processed_string.gsub!("%#{molecule.key}", environment.send(molecule.method_name).to_s)
|
17
|
-
end
|
18
|
-
|
19
|
-
remaining_molecules = bar_molecules.size
|
20
|
-
placeholder_length = remaining_molecules * 2
|
21
|
-
|
22
|
-
processed_string.gsub! '%%', '%'
|
23
|
-
|
24
|
-
processed_string_length = processed_string.gsub(ansi_sgr_codes, '').length
|
25
|
-
leftover_bar_length = environment.send(:length) - processed_string_length + placeholder_length
|
26
|
-
leftover_bar_length = leftover_bar_length < 0 ? 0 : leftover_bar_length
|
27
|
-
|
28
|
-
bar_molecules.each do |molecule|
|
29
|
-
processed_string.gsub!("%#{molecule.key}", environment.send(molecule.method_name, leftover_bar_length).to_s)
|
30
|
-
end
|
31
|
-
|
32
|
-
processed_string
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
def non_bar_molecules
|
37
|
-
@non_bar_molecules ||= molecules.select { |molecule| !molecule.bar_molecule? }
|
38
|
-
end
|
39
|
-
|
40
|
-
def bar_molecules
|
41
|
-
@bar_molecules ||= molecules.select { |molecule| molecule.bar_molecule? }
|
42
|
-
end
|
43
|
-
|
44
|
-
def parse(format_string)
|
45
|
-
molecules = []
|
46
|
-
|
47
|
-
format_string.scan(/%[a-zA-Z]/) do |match|
|
48
|
-
molecules << Molecule.new(match[1,1])
|
49
|
-
end
|
50
|
-
|
51
|
-
molecules
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,112 +0,0 @@
|
|
1
|
-
class ProgressBar
|
2
|
-
module Formatter
|
3
|
-
DEFAULT_FORMAT_STRING = '%t: |%B|'
|
4
|
-
DEFAULT_NON_TTY_FORMAT_STRING = '%t: |%b|'
|
5
|
-
DEFAULT_TITLE = 'Progress'
|
6
|
-
|
7
|
-
def initialize(options)
|
8
|
-
@format_string = nil
|
9
|
-
self.format_string = options[:format] || DEFAULT_FORMAT_STRING
|
10
|
-
@title = options[:title] || DEFAULT_TITLE
|
11
|
-
|
12
|
-
super(options)
|
13
|
-
end
|
14
|
-
|
15
|
-
def format(new_format_string = DEFAULT_FORMAT_STRING)
|
16
|
-
self.format_string = new_format_string
|
17
|
-
@format.process(self)
|
18
|
-
end
|
19
|
-
|
20
|
-
def title=(title)
|
21
|
-
@title = title
|
22
|
-
end
|
23
|
-
|
24
|
-
def progress
|
25
|
-
@bar.progress
|
26
|
-
end
|
27
|
-
|
28
|
-
def total
|
29
|
-
@bar.total
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
def format_string=(format_string)
|
34
|
-
if @format_string != format_string
|
35
|
-
@format_string = format_string
|
36
|
-
@format = ProgressBar::Format::Base.new(format_string)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# Format Methods
|
41
|
-
def title
|
42
|
-
@title
|
43
|
-
end
|
44
|
-
|
45
|
-
def percentage
|
46
|
-
@bar.percentage_completed
|
47
|
-
end
|
48
|
-
|
49
|
-
def justified_percentage
|
50
|
-
@bar.percentage_completed.to_s.rjust(3)
|
51
|
-
end
|
52
|
-
|
53
|
-
def percentage_with_precision
|
54
|
-
@bar.percentage_completed_with_precision
|
55
|
-
end
|
56
|
-
|
57
|
-
def justified_percentage_with_precision
|
58
|
-
@bar.percentage_completed_with_precision.to_s.rjust(6)
|
59
|
-
end
|
60
|
-
|
61
|
-
def elapsed_time
|
62
|
-
@elapsed_time
|
63
|
-
end
|
64
|
-
|
65
|
-
def estimated_time_with_no_oob
|
66
|
-
@estimated_time.out_of_bounds_time_format = nil
|
67
|
-
estimated_time
|
68
|
-
end
|
69
|
-
|
70
|
-
def estimated_time_with_unknown_oob
|
71
|
-
@estimated_time.out_of_bounds_time_format = :unknown
|
72
|
-
estimated_time
|
73
|
-
end
|
74
|
-
|
75
|
-
def estimated_time_with_friendly_oob
|
76
|
-
@estimated_time.out_of_bounds_time_format = :friendly
|
77
|
-
estimated_time
|
78
|
-
end
|
79
|
-
|
80
|
-
def bar(length)
|
81
|
-
@bar.length = length
|
82
|
-
@bar.standard_complete_string
|
83
|
-
end
|
84
|
-
|
85
|
-
def complete_bar(length)
|
86
|
-
@bar.length = length
|
87
|
-
@bar.to_s
|
88
|
-
end
|
89
|
-
|
90
|
-
def incomplete_space(length)
|
91
|
-
@bar.length = length
|
92
|
-
@bar.empty_string
|
93
|
-
end
|
94
|
-
|
95
|
-
def bar_with_percentage(length)
|
96
|
-
@bar.length = length
|
97
|
-
@bar.integrated_percentage_complete_string
|
98
|
-
end
|
99
|
-
|
100
|
-
def estimated_time
|
101
|
-
finished? ? @elapsed_time : @estimated_time
|
102
|
-
end
|
103
|
-
|
104
|
-
def rate_of_change
|
105
|
-
@rate.to_s
|
106
|
-
end
|
107
|
-
|
108
|
-
def rate_of_change_with_precision
|
109
|
-
@rate.to_s("%.2f")
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|