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,7 +1,5 @@
|
|
1
|
-
require 'ruby-progressbar/components/timer'
|
2
|
-
require 'ruby-progressbar/components/progressable'
|
3
1
|
require 'ruby-progressbar/components/bar'
|
4
|
-
require 'ruby-progressbar/components/
|
5
|
-
require 'ruby-progressbar/components/elapsed_timer'
|
6
|
-
require 'ruby-progressbar/components/throttle'
|
2
|
+
require 'ruby-progressbar/components/percentage'
|
7
3
|
require 'ruby-progressbar/components/rate'
|
4
|
+
require 'ruby-progressbar/components/time'
|
5
|
+
require 'ruby-progressbar/components/title'
|
@@ -1,60 +1,96 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
###
|
2
|
+
# UPA = Unknown Progress Animation
|
3
|
+
#
|
4
|
+
class ProgressBar
|
5
|
+
module Components
|
6
|
+
class Bar
|
7
|
+
DEFAULT_PROGRESS_MARK = '='
|
8
|
+
DEFAULT_REMAINDER_MARK = ' '
|
9
|
+
DEFAULT_UPA_STEPS = ['=---', '-=--', '--=-', '---=']
|
5
10
|
|
6
|
-
|
7
|
-
|
8
|
-
|
11
|
+
attr_accessor :progress_mark,
|
12
|
+
:remainder_mark,
|
13
|
+
:length,
|
14
|
+
:progress,
|
15
|
+
:upa_steps
|
9
16
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
17
|
+
def initialize(options = {})
|
18
|
+
self.upa_steps = options[:unknown_progress_animation_steps] || DEFAULT_UPA_STEPS
|
19
|
+
self.progress_mark = options[:progress_mark] || DEFAULT_PROGRESS_MARK
|
20
|
+
self.remainder_mark = options[:remainder_mark] || DEFAULT_REMAINDER_MARK
|
21
|
+
self.progress = options[:progress]
|
22
|
+
self.length = options[:length]
|
23
|
+
end
|
14
24
|
|
15
|
-
|
16
|
-
|
25
|
+
def to_s(options = { :format => :standard })
|
26
|
+
if progress.unknown?
|
27
|
+
unknown_string
|
28
|
+
elsif options[:format] == :standard
|
29
|
+
"#{standard_complete_string}#{incomplete_string}"
|
30
|
+
elsif options[:format] == :integrated_percentage
|
31
|
+
"#{integrated_percentage_complete_string}#{incomplete_string}"
|
32
|
+
end
|
33
|
+
end
|
17
34
|
|
18
|
-
|
19
|
-
self.progress_mark = options[:progress_mark] || DEFAULT_PROGRESS_MARK
|
20
|
-
self.remainder_mark = options[:remainder_mark] || DEFAULT_REMAINDER_MARK
|
21
|
-
end
|
35
|
+
private
|
22
36
|
|
23
|
-
|
24
|
-
|
37
|
+
def integrated_percentage_complete_string
|
38
|
+
return standard_complete_string if completed_length < 5
|
25
39
|
|
26
|
-
|
27
|
-
|
40
|
+
" #{progress.percentage_completed} ".to_s.center(completed_length, progress_mark)
|
41
|
+
end
|
28
42
|
|
29
|
-
|
30
|
-
|
43
|
+
def standard_complete_string
|
44
|
+
progress_mark * completed_length
|
45
|
+
end
|
31
46
|
|
32
|
-
|
33
|
-
|
47
|
+
def incomplete_string
|
48
|
+
remainder_mark * (length - completed_length)
|
49
|
+
end
|
34
50
|
|
35
|
-
|
36
|
-
|
37
|
-
end
|
51
|
+
def bar(length)
|
52
|
+
self.length = length
|
38
53
|
|
39
|
-
|
40
|
-
|
54
|
+
standard_complete_string
|
55
|
+
end
|
56
|
+
|
57
|
+
def complete_bar(length)
|
58
|
+
self.length = length
|
41
59
|
|
42
|
-
|
43
|
-
|
44
|
-
animation_graphic = unknown_progress_animation_steps[current_animation_step]
|
60
|
+
to_s
|
61
|
+
end
|
45
62
|
|
46
|
-
|
63
|
+
def unknown_string
|
64
|
+
unknown_frame_string = unknown_progress_frame * ((length / upa_steps.size) + 2)
|
65
|
+
|
66
|
+
unknown_frame_string[0, length]
|
67
|
+
end
|
47
68
|
|
48
|
-
|
49
|
-
|
50
|
-
remainder_mark * incomplete_length
|
51
|
-
end
|
52
|
-
end
|
69
|
+
def incomplete_space(length)
|
70
|
+
self.length = length
|
53
71
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
72
|
+
if progress.unknown?
|
73
|
+
unknown_string
|
74
|
+
else
|
75
|
+
incomplete_string
|
58
76
|
end
|
59
77
|
end
|
78
|
+
|
79
|
+
def bar_with_percentage(length)
|
80
|
+
self.length = length
|
81
|
+
|
82
|
+
integrated_percentage_complete_string
|
83
|
+
end
|
84
|
+
|
85
|
+
def completed_length
|
86
|
+
(length * progress.percentage_completed / 100).floor
|
87
|
+
end
|
88
|
+
|
89
|
+
def unknown_progress_frame
|
90
|
+
current_animation_step = progress.progress % upa_steps.size
|
91
|
+
|
92
|
+
upa_steps[current_animation_step]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
60
96
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class ProgressBar
|
2
|
+
module Components
|
3
|
+
class Percentage
|
4
|
+
attr_accessor :progress
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
self.progress = options[:progress]
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def percentage
|
13
|
+
progress.percentage_completed
|
14
|
+
end
|
15
|
+
|
16
|
+
def justified_percentage
|
17
|
+
progress.percentage_completed.to_s.rjust(3)
|
18
|
+
end
|
19
|
+
|
20
|
+
def percentage_with_precision
|
21
|
+
progress.percentage_completed_with_precision
|
22
|
+
end
|
23
|
+
|
24
|
+
def justified_percentage_with_precision
|
25
|
+
progress.percentage_completed_with_precision.to_s.rjust(6)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,71 +1,43 @@
|
|
1
|
-
class
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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 to_s(format_string = "%i")
|
28
|
-
elapsed = elapsed_whole_seconds.to_f
|
29
|
-
return 0 unless elapsed > 0
|
30
|
-
|
31
|
-
base_rate = (progress_made / elapsed)
|
32
|
-
|
33
|
-
if rate_scale
|
34
|
-
scaled_rate = rate_scale.call(base_rate)
|
35
|
-
else
|
36
|
-
scaled_rate = base_rate
|
37
|
-
end
|
1
|
+
class ProgressBar
|
2
|
+
module Components
|
3
|
+
class Rate
|
4
|
+
attr_accessor :rate_scale,
|
5
|
+
:started_at,
|
6
|
+
:stopped_at,
|
7
|
+
:timer,
|
8
|
+
:progress
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
self.rate_scale = options[:rate_scale] || lambda { |x| x }
|
12
|
+
self.started_at = nil
|
13
|
+
self.stopped_at = nil
|
14
|
+
self.timer = options[:timer]
|
15
|
+
self.progress = options[:progress]
|
16
|
+
end
|
38
17
|
|
39
|
-
|
40
|
-
end
|
18
|
+
private
|
41
19
|
|
42
|
-
|
20
|
+
def rate_of_change(format_string = '%i')
|
21
|
+
return 0 unless elapsed_seconds > 0
|
43
22
|
|
44
|
-
|
45
|
-
|
46
|
-
unless r = @__as[ancestor]
|
47
|
-
r = (@__as[ancestor] = As.new(self, ancestor))
|
48
|
-
end
|
49
|
-
r.instance_eval(&blk) if block_given?
|
50
|
-
r
|
51
|
-
end
|
23
|
+
format_string % scaled_rate
|
24
|
+
end
|
52
25
|
|
53
|
-
|
54
|
-
|
26
|
+
def rate_of_change_with_precision
|
27
|
+
rate_of_change('%.2f')
|
28
|
+
end
|
55
29
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
30
|
+
def scaled_rate
|
31
|
+
rate_scale.call(base_rate)
|
32
|
+
end
|
60
33
|
|
61
|
-
|
62
|
-
|
63
|
-
|
34
|
+
def base_rate
|
35
|
+
progress.absolute / elapsed_seconds
|
36
|
+
end
|
64
37
|
|
65
|
-
|
66
|
-
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
38
|
+
def elapsed_seconds
|
39
|
+
timer.elapsed_whole_seconds.to_f
|
70
40
|
end
|
71
41
|
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
###
|
2
|
+
# OOB = 'Out of Bounds'
|
3
|
+
#
|
4
|
+
class ProgressBar
|
5
|
+
module Components
|
6
|
+
class Time
|
7
|
+
TIME_FORMAT = '%02d:%02d:%02d'
|
8
|
+
OOB_TIME_FORMATS = [:unknown, :friendly, nil]
|
9
|
+
OOB_LIMIT_IN_HOURS = 99
|
10
|
+
OOB_UNKNOWN_TIME_TEXT = '??:??:??'
|
11
|
+
OOB_FRIENDLY_TIME_TEXT = '> 4 Days'
|
12
|
+
NO_TIME_ELAPSED_TEXT = '--:--:--'
|
13
|
+
ESTIMATED_LABEL = ' ETA'
|
14
|
+
ELAPSED_LABEL = 'Time'
|
15
|
+
|
16
|
+
def initialize(options = {})
|
17
|
+
self.out_of_bounds_time_format = options[:out_of_bounds_time_format]
|
18
|
+
self.timer = options[:timer]
|
19
|
+
self.progress = options[:progress]
|
20
|
+
end
|
21
|
+
|
22
|
+
def estimated_with_label
|
23
|
+
"#{ESTIMATED_LABEL}: #{estimated}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def elapsed_with_label
|
27
|
+
"#{ELAPSED_LABEL}: #{elapsed}"
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def estimated_with_no_oob
|
33
|
+
self.out_of_bounds_time_format = nil
|
34
|
+
|
35
|
+
estimated_with_elapsed_fallback
|
36
|
+
end
|
37
|
+
|
38
|
+
def estimated_with_unknown_oob
|
39
|
+
self.out_of_bounds_time_format = :unknown
|
40
|
+
|
41
|
+
estimated_with_elapsed_fallback
|
42
|
+
end
|
43
|
+
|
44
|
+
def estimated_with_friendly_oob
|
45
|
+
self.out_of_bounds_time_format = :friendly
|
46
|
+
|
47
|
+
estimated_with_elapsed_fallback
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_accessor :out_of_bounds_time_format,
|
51
|
+
:timer,
|
52
|
+
:progress
|
53
|
+
|
54
|
+
def out_of_bounds_time_format=(format)
|
55
|
+
unless OOB_TIME_FORMATS.include? format
|
56
|
+
fail 'Invalid Out Of Bounds time format. Valid formats are ' +
|
57
|
+
OOB_TIME_FORMATS.inspect
|
58
|
+
end
|
59
|
+
|
60
|
+
@out_of_bounds_time_format = format
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def estimated
|
66
|
+
return OOB_UNKNOWN_TIME_TEXT if progress.unknown? || progress.none? || timer.stopped?
|
67
|
+
|
68
|
+
hours, minutes, seconds = timer.divide_seconds(estimated_seconds_remaining)
|
69
|
+
|
70
|
+
if hours > OOB_LIMIT_IN_HOURS && out_of_bounds_time_format
|
71
|
+
out_of_bounds_time
|
72
|
+
else
|
73
|
+
TIME_FORMAT % [hours, minutes, seconds]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def elapsed
|
78
|
+
return NO_TIME_ELAPSED_TEXT unless timer.started?
|
79
|
+
|
80
|
+
hours, minutes, seconds = timer.divide_seconds(timer.elapsed_whole_seconds)
|
81
|
+
|
82
|
+
TIME_FORMAT % [hours, minutes, seconds]
|
83
|
+
end
|
84
|
+
|
85
|
+
def estimated_with_elapsed_fallback
|
86
|
+
progress.finished? ? elapsed_with_label : estimated_with_label
|
87
|
+
end
|
88
|
+
|
89
|
+
def estimated_seconds_remaining
|
90
|
+
(timer.elapsed_seconds * (progress.total / progress.running_average - 1)).round
|
91
|
+
end
|
92
|
+
|
93
|
+
def out_of_bounds_time
|
94
|
+
case out_of_bounds_time_format
|
95
|
+
when :unknown
|
96
|
+
OOB_UNKNOWN_TIME_TEXT
|
97
|
+
when :friendly
|
98
|
+
OOB_FRIENDLY_TIME_TEXT
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class ProgressBar
|
2
|
+
module Format
|
3
|
+
class Formatter
|
4
|
+
def self.process(format_string, max_length, bar)
|
5
|
+
processed_string = format_string.dup
|
6
|
+
|
7
|
+
format_string.non_bar_molecules.each do |molecule|
|
8
|
+
processed_string.gsub!(molecule.full_key, molecule.lookup_value(bar, nil))
|
9
|
+
end
|
10
|
+
|
11
|
+
processed_string.gsub!(/%%/, '%')
|
12
|
+
|
13
|
+
bar_length = max_length -
|
14
|
+
processed_string.displayable_length +
|
15
|
+
format_string.bar_molecule_placeholder_length
|
16
|
+
bar_length = bar_length < 0 ? 0 : bar_length
|
17
|
+
|
18
|
+
format_string.bar_molecules.each do |molecule|
|
19
|
+
processed_string.gsub!(molecule.full_key,
|
20
|
+
molecule.lookup_value(bar, bar_length))
|
21
|
+
end
|
22
|
+
|
23
|
+
processed_string
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|