tty-progressbar 0.17.0 → 0.18.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.
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