tty-progressbar 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +492 -126
  5. data/lib/tty-progressbar.rb +2 -2
  6. data/lib/tty/progressbar.rb +168 -68
  7. data/lib/tty/progressbar/configuration.rb +121 -27
  8. data/lib/tty/progressbar/converter.rb +16 -19
  9. data/lib/tty/progressbar/formats.rb +120 -0
  10. data/lib/tty/progressbar/formatter.rb +33 -38
  11. data/lib/tty/progressbar/formatter/bar.rb +74 -27
  12. data/lib/tty/progressbar/formatter/byte_rate.rb +6 -20
  13. data/lib/tty/progressbar/formatter/current.rb +4 -19
  14. data/lib/tty/progressbar/formatter/current_byte.rb +9 -17
  15. data/lib/tty/progressbar/formatter/elapsed.rb +9 -18
  16. data/lib/tty/progressbar/formatter/estimated.rb +14 -18
  17. data/lib/tty/progressbar/formatter/estimated_time.rb +37 -0
  18. data/lib/tty/progressbar/formatter/mean_byte.rb +6 -20
  19. data/lib/tty/progressbar/formatter/mean_rate.rb +6 -20
  20. data/lib/tty/progressbar/formatter/percent.rb +10 -16
  21. data/lib/tty/progressbar/formatter/rate.rb +5 -19
  22. data/lib/tty/progressbar/formatter/total.rb +10 -16
  23. data/lib/tty/progressbar/formatter/total_byte.rb +14 -18
  24. data/lib/tty/progressbar/formatters.rb +53 -0
  25. data/lib/tty/progressbar/meter.rb +2 -2
  26. data/lib/tty/progressbar/multi.rb +61 -21
  27. data/lib/tty/progressbar/pipeline.rb +13 -6
  28. data/lib/tty/progressbar/timer.rb +89 -0
  29. data/lib/tty/progressbar/version.rb +1 -1
  30. metadata +44 -103
  31. data/Rakefile +0 -8
  32. data/examples/color.rb +0 -18
  33. data/examples/failure.rb +0 -12
  34. data/examples/iterator.rb +0 -5
  35. data/examples/lazy.rb +0 -6
  36. data/examples/multi/main_bar.rb +0 -13
  37. data/examples/multi/simple.rb +0 -13
  38. data/examples/multi/width.rb +0 -13
  39. data/examples/simple.rb +0 -7
  40. data/examples/slow_process.rb +0 -29
  41. data/examples/speed.rb +0 -11
  42. data/examples/threaded.rb +0 -14
  43. data/examples/tokens.rb +0 -12
  44. data/examples/unicode.rb +0 -7
  45. data/spec/spec_helper.rb +0 -53
  46. data/spec/unit/advance_spec.rb +0 -25
  47. data/spec/unit/clear_spec.rb +0 -17
  48. data/spec/unit/complete_spec.rb +0 -16
  49. data/spec/unit/converter/to_bytes_spec.rb +0 -47
  50. data/spec/unit/converter/to_seconds_spec.rb +0 -15
  51. data/spec/unit/converter/to_time_spec.rb +0 -19
  52. data/spec/unit/custom_formatter_spec.rb +0 -26
  53. data/spec/unit/custom_token_spec.rb +0 -14
  54. data/spec/unit/events_spec.rb +0 -33
  55. data/spec/unit/finish_spec.rb +0 -15
  56. data/spec/unit/formatter/bar_spec.rb +0 -33
  57. data/spec/unit/formatter/byte_rate_spec.rb +0 -32
  58. data/spec/unit/formatter/current_byte_spec.rb +0 -16
  59. data/spec/unit/formatter/current_spec.rb +0 -14
  60. data/spec/unit/formatter/elapsed_spec.rb +0 -58
  61. data/spec/unit/formatter/estimated_spec.rb +0 -27
  62. data/spec/unit/formatter/mean_byte_spec.rb +0 -32
  63. data/spec/unit/formatter/mean_rate_spec.rb +0 -31
  64. data/spec/unit/formatter/percent_spec.rb +0 -16
  65. data/spec/unit/formatter/rate_spec.rb +0 -31
  66. data/spec/unit/formatter/total_byte_spec.rb +0 -16
  67. data/spec/unit/formatter/total_spec.rb +0 -16
  68. data/spec/unit/frequency_spec.rb +0 -27
  69. data/spec/unit/head_spec.rb +0 -32
  70. data/spec/unit/hide_cursor_spec.rb +0 -27
  71. data/spec/unit/inspect_spec.rb +0 -11
  72. data/spec/unit/iterate_spec.rb +0 -79
  73. data/spec/unit/log_spec.rb +0 -29
  74. data/spec/unit/meter_spec.rb +0 -70
  75. data/spec/unit/multi/advance_spec.rb +0 -123
  76. data/spec/unit/multi/events_spec.rb +0 -115
  77. data/spec/unit/multi/finish_spec.rb +0 -41
  78. data/spec/unit/multi/line_inset_spec.rb +0 -65
  79. data/spec/unit/multi/register_spec.rb +0 -35
  80. data/spec/unit/multi/reset_spec.rb +0 -28
  81. data/spec/unit/multi/stop_spec.rb +0 -15
  82. data/spec/unit/multi/width_spec.rb +0 -118
  83. data/spec/unit/new_spec.rb +0 -76
  84. data/spec/unit/pipeline_spec.rb +0 -19
  85. data/spec/unit/ratio_spec.rb +0 -31
  86. data/spec/unit/render_spec.rb +0 -25
  87. data/spec/unit/reset_spec.rb +0 -31
  88. data/spec/unit/resize_spec.rb +0 -35
  89. data/spec/unit/set_current_spec.rb +0 -43
  90. data/spec/unit/start_spec.rb +0 -14
  91. data/spec/unit/stop_spec.rb +0 -19
  92. data/spec/unit/update_spec.rb +0 -22
  93. data/spec/unit/width_spec.rb +0 -86
  94. data/tasks/console.rake +0 -9
  95. data/tasks/coverage.rake +0 -9
  96. data/tasks/spec.rake +0 -27
  97. data/tty-progressbar.gemspec +0 -32
@@ -1,31 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../formatter"
4
+
3
5
  module TTY
4
6
  class ProgressBar
5
7
  # Used by {Pipeline} to format :percent token
6
8
  #
7
9
  # @api private
8
10
  class PercentFormatter
9
- MATCHER = /:percent\b/.freeze
10
-
11
- def initialize(progress, *args, &block)
12
- @progress = progress
13
- end
11
+ include TTY::ProgressBar::Formatter[/:percent\b/.freeze]
14
12
 
15
- # Determines whether this formatter is applied or not.
13
+ # Format :percent token
16
14
  #
17
- # @param [Object] value
15
+ # @param [String] value
16
+ # the value to format
18
17
  #
19
- # @return [Boolean]
20
- #
21
- # @api private
22
- def matches?(value)
23
- !!(value.to_s =~ MATCHER)
24
- end
25
-
26
- def format(value)
18
+ # @api public
19
+ def call(value)
27
20
  percent = @progress.width == 0 ? 100 : (@progress.ratio * 100).to_i
28
- value.gsub(MATCHER, percent.to_s + '%')
21
+ display = @progress.indeterminate? ? "-" : percent.to_s
22
+ value.gsub(matcher, "#{display}%")
29
23
  end
30
24
  end # PercentFormatter
31
25
  end # ProgressBar
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../converter'
3
+ require_relative "../converter"
4
+ require_relative "../formatter"
4
5
 
5
6
  module TTY
6
7
  class ProgressBar
@@ -8,22 +9,7 @@ module TTY
8
9
  #
9
10
  # @api private
10
11
  class RateFormatter
11
- MATCHER = /:rate/i.freeze
12
-
13
- def initialize(progress)
14
- @progress = progress
15
- end
16
-
17
- # Determines whether this formatter is applied or not.
18
- #
19
- # @param [Object] value
20
- #
21
- # @return [Boolean]
22
- #
23
- # @api private
24
- def matches?(value)
25
- !!(value.to_s =~ MATCHER)
26
- end
12
+ include TTY::ProgressBar::Formatter[/:rate/i.freeze]
27
13
 
28
14
  # Format :rate token
29
15
  #
@@ -31,9 +17,9 @@ module TTY
31
17
  # the value being formatted
32
18
  #
33
19
  # @api public
34
- def format(value)
20
+ def call(value)
35
21
  formatted = Converter.to_seconds(@progress.rate)
36
- value.gsub(MATCHER, formatted)
22
+ value.gsub(matcher, formatted)
37
23
  end
38
24
  end # RateFormatter
39
25
  end # ProgressBar
@@ -1,30 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../formatter"
4
+
3
5
  module TTY
4
6
  class ProgressBar
5
7
  # Used by {Pipeline} to format :total token
6
8
  #
7
9
  # @api private
8
10
  class TotalFormatter
9
- MATCHER = /:total\b/i.freeze
10
-
11
- def initialize(progress, *args, &block)
12
- @progress = progress
13
- end
11
+ include TTY::ProgressBar::Formatter[/:total\b/i.freeze]
14
12
 
15
- # Determines whether this formatter is applied or not.
13
+ # Format :total token
16
14
  #
17
- # @param [Object] value
15
+ # @param [String] value
16
+ # the value to format
18
17
  #
19
- # @return [Boolean]
20
- #
21
- # @api private
22
- def matches?(value)
23
- !!(value.to_s =~ MATCHER)
24
- end
25
-
26
- def format(value)
27
- value.gsub(MATCHER, @progress.total.to_s)
18
+ # @api public
19
+ def call(value)
20
+ display = @progress.indeterminate? ? "-" : @progress.total.to_s
21
+ value.gsub(matcher, display)
28
22
  end
29
23
  end # TotalFormatter
30
24
  end # ProgressBar
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../converter'
3
+ require_relative "../converter"
4
+ require_relative "../formatter"
4
5
 
5
6
  module TTY
6
7
  class ProgressBar
@@ -8,26 +9,21 @@ module TTY
8
9
  #
9
10
  # @api private
10
11
  class TotalByteFormatter
11
- MATCHER = /:total_byte/i.freeze
12
+ include TTY::ProgressBar::Formatter[/:total_byte/i.freeze]
12
13
 
13
- def initialize(progress, *args, &block)
14
- @progress = progress
15
- end
16
-
17
- # Determines whether this formatter is applied or not.
18
- #
19
- # @param [Object] value
14
+ # Format :total_byte token
20
15
  #
21
- # @return [Boolean]
16
+ # @param [String] value
17
+ # the value to format
22
18
  #
23
- # @api private
24
- def matches?(value)
25
- !!(value.to_s =~ MATCHER)
26
- end
27
-
28
- def format(value)
29
- bytes = Converter.to_bytes(@progress.total)
30
- value.gsub(MATCHER, bytes)
19
+ # @api public
20
+ def call(value)
21
+ bytes = if @progress.indeterminate?
22
+ "-B"
23
+ else
24
+ Converter.to_bytes(@progress.total)
25
+ end
26
+ value.gsub(matcher, bytes)
31
27
  end
32
28
  end # TotalByteFormatter
33
29
  end # ProgressBar
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ require_relative "pipeline"
6
+
7
+ require_relative "formatter/bar"
8
+ require_relative "formatter/current"
9
+ require_relative "formatter/current_byte"
10
+ require_relative "formatter/elapsed"
11
+ require_relative "formatter/estimated"
12
+ require_relative "formatter/estimated_time"
13
+ require_relative "formatter/percent"
14
+ require_relative "formatter/rate"
15
+ require_relative "formatter/byte_rate"
16
+ require_relative "formatter/mean_rate"
17
+ require_relative "formatter/mean_byte"
18
+ require_relative "formatter/total"
19
+ require_relative "formatter/total_byte"
20
+
21
+ module TTY
22
+ class ProgressBar
23
+ class Formatters
24
+ extend Forwardable
25
+
26
+ def_delegators :@pipeline, :decorate, :use
27
+
28
+ # @api private
29
+ def initialize(pipeline = nil)
30
+ @pipeline = pipeline || TTY::ProgressBar::Pipeline.new
31
+ end
32
+
33
+ # Prepare default pipeline formatters
34
+ #
35
+ # @api private
36
+ def load(progress)
37
+ @pipeline.use TTY::ProgressBar::CurrentFormatter.new(progress)
38
+ @pipeline.use TTY::ProgressBar::TotalFormatter.new(progress)
39
+ @pipeline.use TTY::ProgressBar::TotalByteFormatter.new(progress)
40
+ @pipeline.use TTY::ProgressBar::ElapsedFormatter.new(progress)
41
+ @pipeline.use TTY::ProgressBar::EstimatedTimeFormatter.new(progress)
42
+ @pipeline.use TTY::ProgressBar::EstimatedFormatter.new(progress)
43
+ @pipeline.use TTY::ProgressBar::PercentFormatter.new(progress)
44
+ @pipeline.use TTY::ProgressBar::ByteFormatter.new(progress)
45
+ @pipeline.use TTY::ProgressBar::ByteRateFormatter.new(progress)
46
+ @pipeline.use TTY::ProgressBar::RateFormatter.new(progress)
47
+ @pipeline.use TTY::ProgressBar::MeanRateFormatter.new(progress)
48
+ @pipeline.use TTY::ProgressBar::MeanByteFormatter.new(progress)
49
+ @pipeline.use TTY::ProgressBar::BarFormatter.new(progress)
50
+ end
51
+ end # Formatters
52
+ end # ProgressBar
53
+ end # TTY
@@ -5,7 +5,7 @@ module TTY
5
5
  # Used by {ProgressBar} to measure progress rate per interval
6
6
  # by default 1s
7
7
  #
8
- # @api privatek
8
+ # @api private
9
9
  class Meter
10
10
  # Create Meter
11
11
  #
@@ -103,7 +103,7 @@ module TTY
103
103
  last_value / (last_at - @start_time)
104
104
  end
105
105
  end
106
- alias_method :avg_rate, :mean_rate
106
+ alias avg_rate mean_rate
107
107
 
108
108
  # Reset the meter by clearing out it's metrics
109
109
  #
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'forwardable'
4
- require 'monitor'
3
+ require "forwardable"
4
+ require "monitor"
5
5
 
6
- require_relative '../progressbar'
6
+ require_relative "../progressbar"
7
7
 
8
8
  module TTY
9
9
  class ProgressBar
@@ -21,9 +21,9 @@ module TTY
21
21
  def_delegators :@top_bar, :width, :width=
22
22
 
23
23
  DEFAULT_INSET = {
24
- top: Gem.win_platform? ? '+ ' : "\u250c ",
25
- middle: Gem.win_platform? ? '|-- ' : "\u251c\u2500\u2500 ",
26
- bottom: Gem.win_platform? ? '|__ ' : "\u2514\u2500\u2500 "
24
+ top: Gem.win_platform? ? "+ " : "\u250c ",
25
+ middle: Gem.win_platform? ? "|-- " : "\u251c\u2500\u2500 ",
26
+ bottom: Gem.win_platform? ? "|__ " : "\u2514\u2500\u2500 "
27
27
  }.freeze
28
28
 
29
29
  # Number of currently occupied rows in terminal display
@@ -54,12 +54,13 @@ module TTY
54
54
  @top_bar = register(format, observable: false) if format
55
55
 
56
56
  @width = @options[:width]
57
- @top_bar.update(width: @width) if @width
57
+ @top_bar.update(width: @width) if @top_bar && @width
58
58
 
59
59
  @callbacks = {
60
60
  progress: [],
61
- stopped: [],
62
- done: []
61
+ stopped: [],
62
+ paused: [],
63
+ done: []
63
64
  }
64
65
  end
65
66
 
@@ -79,6 +80,7 @@ module TTY
79
80
  observe(bar) if observable
80
81
  if @top_bar
81
82
  @top_bar.update(total: total)
83
+ @top_bar.resume if @top_bar.done?
82
84
  @top_bar.update(width: total) unless @width
83
85
  end
84
86
  end
@@ -104,14 +106,15 @@ module TTY
104
106
  def observe(bar)
105
107
  bar.on(:progress, &progress_handler)
106
108
  .on(:done) { emit(:done) if complete? }
107
- .on(:stopped) { emit(:stopped) if stopped? }
109
+ .on(:stopped) { emit(:stopped) if stopped? }
110
+ .on(:paused) { emit(:paused) if paused? }
108
111
  end
109
112
 
110
113
  # Handle the progress event
111
114
  #
112
115
  # @api private
113
116
  def progress_handler
114
- -> (progress) do
117
+ ->(progress) do
115
118
  @top_bar.advance(progress) if @top_bar
116
119
  emit(:progress, progress)
117
120
  end
@@ -139,7 +142,7 @@ module TTY
139
142
  # @api public
140
143
  def total
141
144
  synchronize do
142
- (@bars - [@top_bar]).dup.map(&:total).reduce(&:+)
145
+ (@bars - [@top_bar]).map(&:total).reduce(&:+)
143
146
  end
144
147
  end
145
148
 
@@ -150,7 +153,7 @@ module TTY
150
153
  # @api public
151
154
  def current
152
155
  synchronize do
153
- (@bars - [@top_bar]).dup.map(&:current).reduce(&:+)
156
+ (@bars - [@top_bar]).map(&:current).reduce(&:+)
154
157
  end
155
158
  end
156
159
 
@@ -161,18 +164,40 @@ module TTY
161
164
  # @api public
162
165
  def complete?
163
166
  synchronize do
164
- (@bars - [@top_bar]).dup.all?(&:complete?)
167
+ (@bars - [@top_bar]).all?(&:complete?)
165
168
  end
166
169
  end
167
170
 
168
- # Check if any of the registered progress bars is stopped
171
+ # Check if all of the registered progress bars is stopped
169
172
  #
170
173
  # @return [Boolean]
171
174
  #
172
175
  # @api public
173
176
  def stopped?
174
177
  synchronize do
175
- (@bars - [@top_bar]).dup.any?(&:stopped?)
178
+ (@bars - [@top_bar]).all?(&:stopped?)
179
+ end
180
+ end
181
+
182
+ # Check if all bars are stopped or finished
183
+ #
184
+ # @return [Boolean]
185
+ #
186
+ # @api public
187
+ def done?
188
+ synchronize do
189
+ (@bars - [@top_bar]).all?(&:done?)
190
+ end
191
+ end
192
+
193
+ # Check if all bars are paused
194
+ #
195
+ # @return [Boolean]
196
+ #
197
+ # @api public
198
+ def paused?
199
+ synchronize do
200
+ (@bars - [@top_bar]).all?(&:paused?)
176
201
  end
177
202
  end
178
203
 
@@ -180,14 +205,28 @@ module TTY
180
205
  #
181
206
  # @api public
182
207
  def stop
183
- @bars.dup.each(&:stop)
208
+ @bars.each(&:stop)
184
209
  end
185
210
 
186
211
  # Finish all progress bars
187
212
  #
188
213
  # @api public
189
214
  def finish
190
- @bars.dup.each(&:finish)
215
+ @bars.each(&:finish)
216
+ end
217
+
218
+ # Pause all progress bars
219
+ #
220
+ # @api public
221
+ def pause
222
+ @bars.each(&:pause)
223
+ end
224
+
225
+ # Resume all progress bars
226
+ #
227
+ # @api public
228
+ def resume
229
+ @bars.each(&:resume)
191
230
  end
192
231
 
193
232
  # Find the number of characters to move into the line
@@ -201,7 +240,7 @@ module TTY
201
240
  #
202
241
  # @api public
203
242
  def line_inset(bar)
204
- return '' if @top_bar.nil?
243
+ return "" if @top_bar.nil?
205
244
 
206
245
  case bar.row
207
246
  when @top_bar.row
@@ -221,8 +260,9 @@ module TTY
221
260
  # @api public
222
261
  def on(name, &callback)
223
262
  unless @callbacks.key?(name)
224
- raise ArgumentError, "The event #{name} does not exist. "\
225
- " Use :progress, :stopped, or :done instead"
263
+ raise ArgumentError, "The event #{name} does not exist. " \
264
+ "Use :progress, :stopped, :paused or " \
265
+ ":done instead"
226
266
  end
227
267
  @callbacks[name] << callback
228
268
  self
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TTY
2
4
  class ProgressBar
3
5
  # Used by {ProgressBar} to decorate format string
@@ -17,24 +19,29 @@ module TTY
17
19
  # Add a new formatter
18
20
  #
19
21
  # @example
20
- # use(TTY::ProgressBar::TotalFormatter)
22
+ # use(TTY::ProgressBar::TotalFormatter.new(progress_bar))
21
23
  #
22
24
  # @api public
23
25
  def use(formatter)
24
- formatters << proc { |progress| formatter.new(progress) }
26
+ formatters << formatter
25
27
  end
26
28
 
27
29
  # Decorate the tokenized string with actual values
28
30
  #
31
+ # @example
32
+ # decorate("[:bar] :current :elapsed")
33
+ #
34
+ # @param [String] tokenized
35
+ # the string with tokens
36
+ #
29
37
  # @return [nil]
30
38
  #
31
39
  # @api private
32
- def decorate(progress, tokenized)
40
+ def decorate(tokenized)
33
41
  base = tokenized.dup
34
42
  formatters.inject(base) do |formatted, formatter|
35
- instance = formatter.call(progress)
36
- if instance.respond_to?(:matches?) && instance.matches?(formatted)
37
- instance.format(formatted)
43
+ if formatter.respond_to?(:matches?) && formatter.matches?(formatted)
44
+ formatter.(formatted)
38
45
  else
39
46
  formatted
40
47
  end