ruby-progressbar 1.6.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|