tty-progressbar 0.14.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 (99) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +98 -21
  3. data/LICENSE.txt +1 -1
  4. data/README.md +511 -119
  5. data/lib/tty-progressbar.rb +2 -2
  6. data/lib/tty/progressbar.rb +216 -87
  7. data/lib/tty/progressbar/configuration.rb +124 -16
  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 +87 -29
  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 +69 -23
  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 +3 -1
  30. metadata +65 -151
  31. data/.codeclimate.yml +0 -11
  32. data/.gitignore +0 -14
  33. data/.rspec +0 -3
  34. data/.travis.yml +0 -25
  35. data/CODE_OF_CONDUCT.md +0 -74
  36. data/Gemfile +0 -14
  37. data/Rakefile +0 -8
  38. data/appveyor.yml +0 -21
  39. data/examples/color.rb +0 -18
  40. data/examples/failure.rb +0 -12
  41. data/examples/iterator.rb +0 -5
  42. data/examples/lazy.rb +0 -6
  43. data/examples/multi/main_bar.rb +0 -13
  44. data/examples/multi/simple.rb +0 -13
  45. data/examples/simple.rb +0 -7
  46. data/examples/slow_process.rb +0 -29
  47. data/examples/speed.rb +0 -11
  48. data/examples/threaded.rb +0 -14
  49. data/examples/tokens.rb +0 -12
  50. data/spec/spec_helper.rb +0 -50
  51. data/spec/unit/advance_spec.rb +0 -25
  52. data/spec/unit/clear_spec.rb +0 -17
  53. data/spec/unit/complete_spec.rb +0 -16
  54. data/spec/unit/converter/to_bytes_spec.rb +0 -47
  55. data/spec/unit/converter/to_seconds_spec.rb +0 -15
  56. data/spec/unit/converter/to_time_spec.rb +0 -19
  57. data/spec/unit/custom_formatter_spec.rb +0 -26
  58. data/spec/unit/custom_token_spec.rb +0 -14
  59. data/spec/unit/events_spec.rb +0 -33
  60. data/spec/unit/finish_spec.rb +0 -15
  61. data/spec/unit/formatter/bar_spec.rb +0 -16
  62. data/spec/unit/formatter/byte_rate_spec.rb +0 -32
  63. data/spec/unit/formatter/current_byte_spec.rb +0 -16
  64. data/spec/unit/formatter/current_spec.rb +0 -14
  65. data/spec/unit/formatter/elapsed_spec.rb +0 -58
  66. data/spec/unit/formatter/estimated_spec.rb +0 -27
  67. data/spec/unit/formatter/mean_byte_spec.rb +0 -32
  68. data/spec/unit/formatter/mean_rate_spec.rb +0 -31
  69. data/spec/unit/formatter/percent_spec.rb +0 -16
  70. data/spec/unit/formatter/rate_spec.rb +0 -31
  71. data/spec/unit/formatter/total_byte_spec.rb +0 -16
  72. data/spec/unit/formatter/total_spec.rb +0 -16
  73. data/spec/unit/frequency_spec.rb +0 -27
  74. data/spec/unit/head_spec.rb +0 -32
  75. data/spec/unit/hide_cursor_spec.rb +0 -27
  76. data/spec/unit/inspect_spec.rb +0 -11
  77. data/spec/unit/iterate_spec.rb +0 -79
  78. data/spec/unit/log_spec.rb +0 -29
  79. data/spec/unit/meter_spec.rb +0 -70
  80. data/spec/unit/multi/advance_spec.rb +0 -123
  81. data/spec/unit/multi/events_spec.rb +0 -115
  82. data/spec/unit/multi/finish_spec.rb +0 -41
  83. data/spec/unit/multi/line_inset_spec.rb +0 -65
  84. data/spec/unit/multi/register_spec.rb +0 -35
  85. data/spec/unit/multi/stop_spec.rb +0 -15
  86. data/spec/unit/new_spec.rb +0 -66
  87. data/spec/unit/pipeline_spec.rb +0 -19
  88. data/spec/unit/ratio_spec.rb +0 -31
  89. data/spec/unit/reset_spec.rb +0 -31
  90. data/spec/unit/resize_spec.rb +0 -35
  91. data/spec/unit/set_current_spec.rb +0 -43
  92. data/spec/unit/start_spec.rb +0 -14
  93. data/spec/unit/stop_spec.rb +0 -19
  94. data/spec/unit/update_spec.rb +0 -22
  95. data/spec/unit/width_spec.rb +0 -21
  96. data/tasks/console.rake +0 -9
  97. data/tasks/coverage.rake +0 -9
  98. data/tasks/spec.rake +0 -27
  99. data/tty-progressbar.gemspec +0 -30
@@ -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
@@ -18,10 +18,12 @@ module TTY
18
18
 
19
19
  def_delegators :@bars, :each, :empty?, :length, :[]
20
20
 
21
+ def_delegators :@top_bar, :width, :width=
22
+
21
23
  DEFAULT_INSET = {
22
- top: Gem.win_platform? ? '+ ' : "\u250c ",
23
- middle: Gem.win_platform? ? '|-- ' : "\u251c\u2500\u2500 ",
24
- 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 "
25
27
  }.freeze
26
28
 
27
29
  # Number of currently occupied rows in terminal display
@@ -51,10 +53,14 @@ module TTY
51
53
  @top_bar = nil
52
54
  @top_bar = register(format, observable: false) if format
53
55
 
56
+ @width = @options[:width]
57
+ @top_bar.update(width: @width) if @top_bar && @width
58
+
54
59
  @callbacks = {
55
60
  progress: [],
56
- stopped: [],
57
- done: []
61
+ stopped: [],
62
+ paused: [],
63
+ done: []
58
64
  }
59
65
  end
60
66
 
@@ -73,7 +79,9 @@ module TTY
73
79
  @bars << bar
74
80
  observe(bar) if observable
75
81
  if @top_bar
76
- @top_bar.update(total: total, width: total)
82
+ @top_bar.update(total: total)
83
+ @top_bar.resume if @top_bar.done?
84
+ @top_bar.update(width: total) unless @width
77
85
  end
78
86
  end
79
87
 
@@ -98,16 +106,17 @@ module TTY
98
106
  def observe(bar)
99
107
  bar.on(:progress, &progress_handler)
100
108
  .on(:done) { emit(:done) if complete? }
101
- .on(:stopped) { emit(:stopped) if stopped? }
109
+ .on(:stopped) { emit(:stopped) if stopped? }
110
+ .on(:paused) { emit(:paused) if paused? }
102
111
  end
103
112
 
104
113
  # Handle the progress event
105
114
  #
106
115
  # @api private
107
116
  def progress_handler
108
- proc do
109
- @top_bar.advance if @top_bar
110
- emit(:progress)
117
+ ->(progress) do
118
+ @top_bar.advance(progress) if @top_bar
119
+ emit(:progress, progress)
111
120
  end
112
121
  end
113
122
 
@@ -133,7 +142,7 @@ module TTY
133
142
  # @api public
134
143
  def total
135
144
  synchronize do
136
- (@bars - [@top_bar]).dup.map(&:total).reduce(&:+)
145
+ (@bars - [@top_bar]).map(&:total).reduce(&:+)
137
146
  end
138
147
  end
139
148
 
@@ -144,7 +153,7 @@ module TTY
144
153
  # @api public
145
154
  def current
146
155
  synchronize do
147
- (@bars - [@top_bar]).dup.map(&:current).reduce(&:+)
156
+ (@bars - [@top_bar]).map(&:current).reduce(&:+)
148
157
  end
149
158
  end
150
159
 
@@ -155,18 +164,40 @@ module TTY
155
164
  # @api public
156
165
  def complete?
157
166
  synchronize do
158
- (@bars - [@top_bar]).dup.all?(&:complete?)
167
+ (@bars - [@top_bar]).all?(&:complete?)
159
168
  end
160
169
  end
161
170
 
162
- # Check if any of the registered progress bars is stopped
171
+ # Check if all of the registered progress bars is stopped
163
172
  #
164
173
  # @return [Boolean]
165
174
  #
166
175
  # @api public
167
176
  def stopped?
168
177
  synchronize do
169
- (@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?)
170
201
  end
171
202
  end
172
203
 
@@ -174,14 +205,28 @@ module TTY
174
205
  #
175
206
  # @api public
176
207
  def stop
177
- @bars.dup.each(&:stop)
208
+ @bars.each(&:stop)
178
209
  end
179
210
 
180
211
  # Finish all progress bars
181
212
  #
182
213
  # @api public
183
214
  def finish
184
- @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)
185
230
  end
186
231
 
187
232
  # Find the number of characters to move into the line
@@ -195,7 +240,7 @@ module TTY
195
240
  #
196
241
  # @api public
197
242
  def line_inset(bar)
198
- return '' if @top_bar.nil?
243
+ return "" if @top_bar.nil?
199
244
 
200
245
  case bar.row
201
246
  when @top_bar.row
@@ -215,8 +260,9 @@ module TTY
215
260
  # @api public
216
261
  def on(name, &callback)
217
262
  unless @callbacks.key?(name)
218
- raise ArgumentError, "The event #{name} does not exist. "\
219
- " Use :progress, :stopped, or :done instead"
263
+ raise ArgumentError, "The event #{name} does not exist. " \
264
+ "Use :progress, :stopped, :paused or " \
265
+ ":done instead"
220
266
  end
221
267
  @callbacks[name] << callback
222
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