tty-progressbar 0.14.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +98 -21
- data/LICENSE.txt +1 -1
- data/README.md +511 -119
- data/lib/tty-progressbar.rb +2 -2
- data/lib/tty/progressbar.rb +216 -87
- data/lib/tty/progressbar/configuration.rb +124 -16
- data/lib/tty/progressbar/converter.rb +16 -19
- data/lib/tty/progressbar/formats.rb +120 -0
- data/lib/tty/progressbar/formatter.rb +33 -38
- data/lib/tty/progressbar/formatter/bar.rb +87 -29
- data/lib/tty/progressbar/formatter/byte_rate.rb +6 -20
- data/lib/tty/progressbar/formatter/current.rb +4 -19
- data/lib/tty/progressbar/formatter/current_byte.rb +9 -17
- data/lib/tty/progressbar/formatter/elapsed.rb +9 -18
- data/lib/tty/progressbar/formatter/estimated.rb +14 -18
- data/lib/tty/progressbar/formatter/estimated_time.rb +37 -0
- data/lib/tty/progressbar/formatter/mean_byte.rb +6 -20
- data/lib/tty/progressbar/formatter/mean_rate.rb +6 -20
- data/lib/tty/progressbar/formatter/percent.rb +10 -16
- data/lib/tty/progressbar/formatter/rate.rb +5 -19
- data/lib/tty/progressbar/formatter/total.rb +10 -16
- data/lib/tty/progressbar/formatter/total_byte.rb +14 -18
- data/lib/tty/progressbar/formatters.rb +53 -0
- data/lib/tty/progressbar/meter.rb +2 -2
- data/lib/tty/progressbar/multi.rb +69 -23
- data/lib/tty/progressbar/pipeline.rb +13 -6
- data/lib/tty/progressbar/timer.rb +89 -0
- data/lib/tty/progressbar/version.rb +3 -1
- metadata +65 -151
- data/.codeclimate.yml +0 -11
- data/.gitignore +0 -14
- data/.rspec +0 -3
- data/.travis.yml +0 -25
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -14
- data/Rakefile +0 -8
- data/appveyor.yml +0 -21
- data/examples/color.rb +0 -18
- data/examples/failure.rb +0 -12
- data/examples/iterator.rb +0 -5
- data/examples/lazy.rb +0 -6
- data/examples/multi/main_bar.rb +0 -13
- data/examples/multi/simple.rb +0 -13
- data/examples/simple.rb +0 -7
- data/examples/slow_process.rb +0 -29
- data/examples/speed.rb +0 -11
- data/examples/threaded.rb +0 -14
- data/examples/tokens.rb +0 -12
- data/spec/spec_helper.rb +0 -50
- data/spec/unit/advance_spec.rb +0 -25
- data/spec/unit/clear_spec.rb +0 -17
- data/spec/unit/complete_spec.rb +0 -16
- data/spec/unit/converter/to_bytes_spec.rb +0 -47
- data/spec/unit/converter/to_seconds_spec.rb +0 -15
- data/spec/unit/converter/to_time_spec.rb +0 -19
- data/spec/unit/custom_formatter_spec.rb +0 -26
- data/spec/unit/custom_token_spec.rb +0 -14
- data/spec/unit/events_spec.rb +0 -33
- data/spec/unit/finish_spec.rb +0 -15
- data/spec/unit/formatter/bar_spec.rb +0 -16
- data/spec/unit/formatter/byte_rate_spec.rb +0 -32
- data/spec/unit/formatter/current_byte_spec.rb +0 -16
- data/spec/unit/formatter/current_spec.rb +0 -14
- data/spec/unit/formatter/elapsed_spec.rb +0 -58
- data/spec/unit/formatter/estimated_spec.rb +0 -27
- data/spec/unit/formatter/mean_byte_spec.rb +0 -32
- data/spec/unit/formatter/mean_rate_spec.rb +0 -31
- data/spec/unit/formatter/percent_spec.rb +0 -16
- data/spec/unit/formatter/rate_spec.rb +0 -31
- data/spec/unit/formatter/total_byte_spec.rb +0 -16
- data/spec/unit/formatter/total_spec.rb +0 -16
- data/spec/unit/frequency_spec.rb +0 -27
- data/spec/unit/head_spec.rb +0 -32
- data/spec/unit/hide_cursor_spec.rb +0 -27
- data/spec/unit/inspect_spec.rb +0 -11
- data/spec/unit/iterate_spec.rb +0 -79
- data/spec/unit/log_spec.rb +0 -29
- data/spec/unit/meter_spec.rb +0 -70
- data/spec/unit/multi/advance_spec.rb +0 -123
- data/spec/unit/multi/events_spec.rb +0 -115
- data/spec/unit/multi/finish_spec.rb +0 -41
- data/spec/unit/multi/line_inset_spec.rb +0 -65
- data/spec/unit/multi/register_spec.rb +0 -35
- data/spec/unit/multi/stop_spec.rb +0 -15
- data/spec/unit/new_spec.rb +0 -66
- data/spec/unit/pipeline_spec.rb +0 -19
- data/spec/unit/ratio_spec.rb +0 -31
- data/spec/unit/reset_spec.rb +0 -31
- data/spec/unit/resize_spec.rb +0 -35
- data/spec/unit/set_current_spec.rb +0 -43
- data/spec/unit/start_spec.rb +0 -14
- data/spec/unit/stop_spec.rb +0 -19
- data/spec/unit/update_spec.rb +0 -22
- data/spec/unit/width_spec.rb +0 -21
- data/tasks/console.rake +0 -9
- data/tasks/coverage.rake +0 -9
- data/tasks/spec.rake +0 -27
- data/tty-progressbar.gemspec +0 -30
@@ -1,47 +1,155 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "formats"
|
4
|
+
|
1
5
|
module TTY
|
2
6
|
class ProgressBar
|
3
7
|
class Configuration
|
8
|
+
include TTY::ProgressBar::Formats
|
4
9
|
|
10
|
+
# The total number of steps to completion
|
11
|
+
# @api public
|
5
12
|
attr_reader :total
|
6
13
|
|
14
|
+
# The maximum width for the progress bar except all formatting tokens
|
15
|
+
# @api public
|
7
16
|
attr_accessor :width
|
8
17
|
|
9
|
-
|
18
|
+
# The complete character in progress animation
|
19
|
+
# @api public
|
20
|
+
attr_reader :complete
|
10
21
|
|
11
|
-
|
12
|
-
|
13
|
-
|
22
|
+
# The incomplete character in progress animation
|
23
|
+
# @api public
|
24
|
+
attr_reader :incomplete
|
14
25
|
|
26
|
+
# The head character, defaults to complete
|
27
|
+
# @api public
|
15
28
|
attr_accessor :head
|
16
29
|
|
17
|
-
|
30
|
+
# The unknown character for indeterminate progress animation
|
31
|
+
# @api public
|
32
|
+
attr_reader :unknown
|
18
33
|
|
19
|
-
|
34
|
+
# The amount of indentation before a progress animation
|
35
|
+
# @api private
|
36
|
+
attr_accessor :inset
|
37
|
+
|
38
|
+
# The preconfigured bar format name, defaults to :classic
|
39
|
+
# @api public
|
40
|
+
attr_accessor :bar_format
|
20
41
|
|
42
|
+
# The object that responds to print call, defaults to stderr
|
43
|
+
# @api public
|
21
44
|
attr_accessor :output
|
22
45
|
|
46
|
+
# The frequency with which to display a progress bar per second
|
47
|
+
# @api public
|
23
48
|
attr_accessor :frequency
|
24
49
|
|
50
|
+
# The time interval for sampling of speed measurement, defaults to 1 second
|
51
|
+
# @api public
|
25
52
|
attr_accessor :interval
|
26
53
|
|
54
|
+
# Whether or not to hide the cursor, defaults to false
|
55
|
+
# @api public
|
56
|
+
attr_accessor :hide_cursor
|
57
|
+
|
58
|
+
# Whether or not to clear the progress line, defaults to false
|
59
|
+
# @api public
|
60
|
+
attr_accessor :clear
|
61
|
+
|
62
|
+
# Whether or not to replace head character with complete, defaults to false
|
63
|
+
# @api public
|
64
|
+
attr_accessor :clear_head
|
65
|
+
|
27
66
|
def initialize(options)
|
28
67
|
self.total = options[:total] if options[:total]
|
29
68
|
@width = options.fetch(:width) { total }
|
30
|
-
@
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@
|
35
|
-
@
|
69
|
+
@bar_format = options.fetch(:bar_format, :classic)
|
70
|
+
self.incomplete = options.fetch(:incomplete) { fetch_char(@bar_format, :incomplete) }
|
71
|
+
self.complete = options.fetch(:complete) { fetch_char(@bar_format, :complete) }
|
72
|
+
self.unknown = options.fetch(:unknown) { fetch_char(@bar_format, :unknown) }
|
73
|
+
@head = options.fetch(:head) { @complete || "=" }
|
74
|
+
@clear_head = options.fetch(:clear_head, false)
|
75
|
+
@hide_cursor = options.fetch(:hide_cursor, false)
|
76
|
+
@clear = options.fetch(:clear, false)
|
36
77
|
@output = options.fetch(:output) { $stderr }
|
37
|
-
@frequency = options.fetch(:frequency
|
38
|
-
@interval = options.fetch(:interval
|
78
|
+
@frequency = options.fetch(:frequency, 0) # 0Hz
|
79
|
+
@interval = options.fetch(:interval, 1) # 1 sec
|
80
|
+
@inset = options.fetch(:inset, 0)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Set complete character(s)
|
84
|
+
#
|
85
|
+
# @param [String] value
|
86
|
+
#
|
87
|
+
# @api public
|
88
|
+
def complete=(value)
|
89
|
+
raise_if_empty(:complete, value)
|
90
|
+
|
91
|
+
@complete = value
|
92
|
+
end
|
93
|
+
|
94
|
+
# Set incomplete character(s)
|
95
|
+
#
|
96
|
+
# @param [String] value
|
97
|
+
#
|
98
|
+
# @api public
|
99
|
+
def incomplete=(value)
|
100
|
+
raise_if_empty(:incomplete, value)
|
101
|
+
|
102
|
+
@incomplete = value
|
103
|
+
end
|
104
|
+
|
105
|
+
# Set unknown character(s)
|
106
|
+
#
|
107
|
+
# @param [String] value
|
108
|
+
#
|
109
|
+
# @api public
|
110
|
+
def unknown=(value)
|
111
|
+
raise_if_empty(:unknown, value)
|
112
|
+
|
113
|
+
@unknown = value
|
39
114
|
end
|
40
115
|
|
116
|
+
# Set total and adjust width if unset
|
117
|
+
#
|
118
|
+
# @param [Integer,nil] value
|
119
|
+
#
|
120
|
+
# @api public
|
41
121
|
def total=(value)
|
42
|
-
fail ArgumentError unless value
|
43
122
|
@total = value
|
44
|
-
|
123
|
+
self.width = value if width.nil?
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
# Find bar char by type name and property
|
129
|
+
#
|
130
|
+
# @param [Symbol] name
|
131
|
+
# @param [Symbol] property
|
132
|
+
#
|
133
|
+
# @api private
|
134
|
+
def fetch_char(name, property)
|
135
|
+
if FORMATS.key?(name)
|
136
|
+
FORMATS[name][property]
|
137
|
+
else
|
138
|
+
raise ArgumentError, "unsupported bar format: #{name.inspect}. " \
|
139
|
+
"Available formats are: " \
|
140
|
+
"#{FORMATS.keys.sort.map(&:inspect).join(', ')}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Check whether a parameter's value is empty or not
|
145
|
+
#
|
146
|
+
# @raise [ArgumentError]
|
147
|
+
#
|
148
|
+
# @api private
|
149
|
+
def raise_if_empty(name, value)
|
150
|
+
return value unless value.to_s.empty?
|
151
|
+
|
152
|
+
raise ArgumentError, "cannot provide an empty string for #{name.inspect}"
|
45
153
|
end
|
46
154
|
end # Configuration
|
47
155
|
end # ProgressBar
|
@@ -15,19 +15,21 @@ module TTY
|
|
15
15
|
#
|
16
16
|
# @api public
|
17
17
|
def to_time(seconds)
|
18
|
+
days = (seconds / (24 * HOURSECONDS).to_f).floor
|
19
|
+
seconds -= days * 24 * HOURSECONDS
|
18
20
|
hours = (seconds / HOURSECONDS.to_f).floor
|
19
21
|
seconds -= hours * HOURSECONDS
|
20
22
|
minutes = (seconds / 60).floor
|
21
23
|
seconds -= minutes * 60
|
22
24
|
|
23
|
-
if
|
24
|
-
|
25
|
+
if days > 0 # over 24 hours switch to days
|
26
|
+
format("%dd%2dh%2dm", days, hours, minutes)
|
25
27
|
elsif hours > 0
|
26
|
-
|
28
|
+
format("%2dh%2dm", hours, minutes)
|
27
29
|
elsif minutes > 0
|
28
|
-
|
30
|
+
format("%2dm%2ds", minutes, seconds)
|
29
31
|
else
|
30
|
-
|
32
|
+
format("%2ds", seconds)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
module_function :to_time
|
@@ -41,43 +43,38 @@ module TTY
|
|
41
43
|
# the formatted result
|
42
44
|
#
|
43
45
|
# @api public
|
44
|
-
def to_seconds(seconds, precision
|
46
|
+
def to_seconds(seconds, precision: nil)
|
45
47
|
precision ||= (seconds < 1 && !seconds.zero?) ? 5 : 2
|
46
|
-
|
48
|
+
format "%5.#{precision}f", seconds
|
47
49
|
end
|
48
50
|
module_function :to_seconds
|
49
51
|
|
50
|
-
BYTE_UNITS = %w
|
52
|
+
BYTE_UNITS = %w[b kb mb gb tb pb eb].freeze
|
51
53
|
|
52
54
|
# Convert value to bytes
|
53
55
|
#
|
54
56
|
# @param [Numeric] value
|
55
57
|
# the value to convert to bytes
|
56
|
-
# @param [
|
57
|
-
# @option [Integer] :decimals
|
58
|
+
# @param [Integer] decimals
|
58
59
|
# the number of decimals parts
|
59
|
-
# @
|
60
|
+
# @param [String] separator
|
60
61
|
# the separator to use for thousands in a number
|
61
|
-
# @
|
62
|
+
# @param [String] unit_separator
|
62
63
|
# the separtor to use between number and unit
|
63
64
|
#
|
64
65
|
# @return [String]
|
65
66
|
#
|
66
67
|
# @api public
|
67
|
-
def to_bytes(value,
|
68
|
-
decimals = options.fetch(:decimals) { 2 }
|
69
|
-
separator = options.fetch(:separator) { '.' }
|
70
|
-
unit_separator = options.fetch(:unit_separator) { '' }
|
71
|
-
|
68
|
+
def to_bytes(value, decimals: 2, separator: ".", unit_separator: "")
|
72
69
|
base = 1024
|
73
70
|
pattern = "%.#{decimals}f"
|
74
71
|
|
75
|
-
unit = BYTE_UNITS.find.with_index { |_, i| value < base
|
72
|
+
unit = BYTE_UNITS.find.with_index { |_, i| value < base**(i + 1) }
|
76
73
|
|
77
74
|
if value < base
|
78
75
|
formatted_value = value.to_i.to_s
|
79
76
|
else
|
80
|
-
value_to_size = value / (base
|
77
|
+
value_to_size = value / (base**BYTE_UNITS.index(unit)).to_f
|
81
78
|
formatted_value = format(pattern, value_to_size)
|
82
79
|
end
|
83
80
|
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class ProgressBar
|
5
|
+
module Formats
|
6
|
+
FORMATS = {
|
7
|
+
arrow: { # ▸▸▸▸▸▹▹▹▹▹
|
8
|
+
complete: "▸",
|
9
|
+
incomplete: "▹",
|
10
|
+
unknown: "◂▸"
|
11
|
+
},
|
12
|
+
asterisk: { # ✱✱✱✱✱✳✳✳✳✳
|
13
|
+
complete: "✱",
|
14
|
+
incomplete: "✳",
|
15
|
+
unknown: "✳✱✳"
|
16
|
+
},
|
17
|
+
blade: { # ▰▰▰▰▰▱▱▱▱▱
|
18
|
+
complete: "▰",
|
19
|
+
incomplete: "▱",
|
20
|
+
unknown: "▱▰▱"
|
21
|
+
},
|
22
|
+
block: { # █████░░░░░
|
23
|
+
complete: "█",
|
24
|
+
incomplete: "░",
|
25
|
+
unknown: "█"
|
26
|
+
},
|
27
|
+
box: { # ■■■■■□□□□□
|
28
|
+
complete: "■",
|
29
|
+
incomplete: "□",
|
30
|
+
unknown: "□■□"
|
31
|
+
},
|
32
|
+
bracket: { # ❭❭❭❭❭❭❭❭❭❭
|
33
|
+
complete: "❭",
|
34
|
+
incomplete: " ",
|
35
|
+
unknown: "❬=❭"
|
36
|
+
},
|
37
|
+
burger: { # ≡≡≡≡≡≡≡≡≡≡
|
38
|
+
complete: "≡",
|
39
|
+
incomplete: " ",
|
40
|
+
unknown: "<≡>"
|
41
|
+
},
|
42
|
+
button: { # ⦿⦿⦿⦿⦿⦾⦾⦾⦾⦾
|
43
|
+
complete: "⦿",
|
44
|
+
incomplete: "⦾",
|
45
|
+
unknown: "⦾⦿⦾"
|
46
|
+
},
|
47
|
+
chevron: { # ››››››››››
|
48
|
+
complete: "›",
|
49
|
+
incomplete: " ",
|
50
|
+
unknown: "‹=›"
|
51
|
+
},
|
52
|
+
circle: { # ●●●●●○○○○○
|
53
|
+
complete: "●",
|
54
|
+
incomplete: "○",
|
55
|
+
unknown: "○●○"
|
56
|
+
},
|
57
|
+
classic: { # ==========
|
58
|
+
complete: "=",
|
59
|
+
incomplete: " ",
|
60
|
+
unknown: "<=>"
|
61
|
+
},
|
62
|
+
crate: { # ▣▣▣▣▣⬚⬚⬚⬚⬚
|
63
|
+
complete: "▣",
|
64
|
+
incomplete: "⬚",
|
65
|
+
unknown: "⬚▣⬚"
|
66
|
+
},
|
67
|
+
diamond: { # ♦♦♦♦♦♢♢♢♢♢
|
68
|
+
complete: "♦",
|
69
|
+
incomplete: "♢",
|
70
|
+
unknown: "♢♦♢"
|
71
|
+
},
|
72
|
+
dot: { # ・・・・・・・・・・
|
73
|
+
complete: "・",
|
74
|
+
incomplete: " ",
|
75
|
+
unknown: "・・・"
|
76
|
+
},
|
77
|
+
heart: { # ♥♥♥♥♥♡♡♡♡♡
|
78
|
+
complete: "♥",
|
79
|
+
incomplete: "♡",
|
80
|
+
unknown: "♡♥♡"
|
81
|
+
},
|
82
|
+
rectangle: { # ▮▮▮▮▮▯▯▯▯▯
|
83
|
+
complete: "▮",
|
84
|
+
incomplete: "▯",
|
85
|
+
unknown: "▯▮▯"
|
86
|
+
},
|
87
|
+
square: { # ▪▪▪▪▪▫▫▫▫▫
|
88
|
+
complete: "▪",
|
89
|
+
incomplete: "▫",
|
90
|
+
unknown: "▫▪▫"
|
91
|
+
},
|
92
|
+
star: { # ★★★★★☆☆☆☆☆
|
93
|
+
complete: "★",
|
94
|
+
incomplete: "☆",
|
95
|
+
unknown: "☆★☆"
|
96
|
+
},
|
97
|
+
track: { # ▬▬▬▬▬═════
|
98
|
+
complete: "▬",
|
99
|
+
incomplete: "═",
|
100
|
+
unknown: "═▬═"
|
101
|
+
},
|
102
|
+
tread: { # ❱❱❱❱❱❱❱❱❱❱
|
103
|
+
complete: "❱",
|
104
|
+
incomplete: " ",
|
105
|
+
unknown: "❰=❱"
|
106
|
+
},
|
107
|
+
triangle: { # ▶▶▶▶▶▷▷▷▷▷
|
108
|
+
complete: "▶",
|
109
|
+
incomplete: "▷",
|
110
|
+
unknown: "◀▶"
|
111
|
+
},
|
112
|
+
wave: { # ~~~~~_____
|
113
|
+
complete: "~",
|
114
|
+
incomplete: "_",
|
115
|
+
unknown: "<~>"
|
116
|
+
}
|
117
|
+
}.freeze
|
118
|
+
end # Formats
|
119
|
+
end # ProgressBar
|
120
|
+
end # TTY
|
@@ -1,48 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'pipeline'
|
4
|
-
|
5
|
-
require_relative 'formatter/bar'
|
6
|
-
require_relative 'formatter/current'
|
7
|
-
require_relative 'formatter/current_byte'
|
8
|
-
require_relative 'formatter/elapsed'
|
9
|
-
require_relative 'formatter/estimated'
|
10
|
-
require_relative 'formatter/percent'
|
11
|
-
require_relative 'formatter/rate'
|
12
|
-
require_relative 'formatter/byte_rate'
|
13
|
-
require_relative 'formatter/mean_rate'
|
14
|
-
require_relative 'formatter/mean_byte'
|
15
|
-
require_relative 'formatter/total'
|
16
|
-
require_relative 'formatter/total_byte'
|
17
|
-
|
18
3
|
module TTY
|
19
4
|
class ProgressBar
|
20
|
-
class Formatter
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
def initialize(pipeline = nil)
|
27
|
-
@pipeline = pipeline || TTY::ProgressBar::Pipeline.new
|
5
|
+
class Formatter < ::Module
|
6
|
+
# A helper for declaring a matching token pattern
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
def self.[](token_match)
|
10
|
+
new(token_match)
|
28
11
|
end
|
29
12
|
|
30
|
-
#
|
13
|
+
# Initialize this module with token matching pattern
|
31
14
|
#
|
32
|
-
# @
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
15
|
+
# @param [Regexp] token_match
|
16
|
+
# the token matching pattern
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def initialize(token_match)
|
20
|
+
pattern = token_match
|
21
|
+
|
22
|
+
module_eval do
|
23
|
+
define_method(:initialize) do |progress|
|
24
|
+
@progress = progress
|
25
|
+
end
|
26
|
+
|
27
|
+
define_method(:matcher) { pattern }
|
28
|
+
define_method(:progress) { @progress }
|
29
|
+
|
30
|
+
# Determines whether this formatter is applied or not.
|
31
|
+
#
|
32
|
+
# @param [Object] value
|
33
|
+
#
|
34
|
+
# @return [Boolean]
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
define_method(:matches?) do |value|
|
38
|
+
!!(value.to_s =~ pattern)
|
39
|
+
end
|
40
|
+
end
|
46
41
|
end
|
47
42
|
end # Formatter
|
48
43
|
end # ProgressBar
|