tty-progressbar 0.13.0 → 0.14.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ffbc5e8dbfe59fffa658892053d84d3f571ae501
4
- data.tar.gz: 2605c62530355c6ddde735c12395f6a7a0d35cbf
3
+ metadata.gz: b9e021f67756883c39075abe088ad0861ef85582
4
+ data.tar.gz: 08b1cd0a9925899b0a7c6ace9dddeef1a1545953
5
5
  SHA512:
6
- metadata.gz: fedfcab4a057cd7d1488f003b4ab300fb33197ac8d3ad8157057d82684d357057b825d9e06fed00186c075a5bca97e73779ec210b191002a57b07dee64d24690
7
- data.tar.gz: c203b0789b771f1bb9aadd1a7a19a4e7933d0d31591d6f2a0e48043013115ed3762d557167d5299098d427d5e003fa0f4d7061ee7c32217c8d0a4fe051f86d12
6
+ metadata.gz: 7719a9ffa8814c51e301dd5e441a4516e87230ee7f66780ba40c3b29556bdd086f5dc18b6ee024b2b54b1344bb52996c51048837bafffcc560164c4b44165f0e
7
+ data.tar.gz: 98974cccbbad3174dcbf24dfd66957db87aca29f79ba94f4f287c6fff789251130a042c6e2ed8ae9831ea1be95380f433c3b14093a9ae01b282d4a4331f0ef97
@@ -7,9 +7,9 @@ script: "bundle exec rake ci"
7
7
  rvm:
8
8
  - 2.0.0
9
9
  - 2.1.10
10
- - 2.2.6
11
- - 2.3.3
12
- - 2.4.1
10
+ - 2.2.8
11
+ - 2.3.6
12
+ - 2.4.3
13
13
  - ruby-head
14
14
  - jruby-9.1.5.0
15
15
  - jruby-head
@@ -1,5 +1,14 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.14.0] - 2017-01-17
4
+
5
+ ### Changed
6
+ * Change to only output to a console and stop output to a file, pipe etc...
7
+ * Change #iterate to accept enumerators as collection type by Victor Shepelev(@zverok)
8
+
9
+ ### Fixed
10
+ * Fix #iterate to take into account progress value in total steps calculation
11
+
3
12
  ## [v0.13.0] - 2017-10-29
4
13
 
5
14
  ### Changed
@@ -151,6 +160,7 @@
151
160
 
152
161
  * Initial implementation and release
153
162
 
163
+ [v0.14.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.13.0...v0.14.0
154
164
  [v0.13.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.12.2...v0.13.0
155
165
  [v0.12.2]: https://github.com/peter-murach/tty-progressbar/compare/v0.12.1...v0.12.2
156
166
  [v0.12.1]: https://github.com/peter-murach/tty-progressbar/compare/v0.12.0...v0.12.1
data/Gemfile CHANGED
@@ -3,13 +3,12 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :test do
6
- gem 'timecop', '~> 0.8.1'
7
- gem 'pastel', '~> 0.7.0'
6
+ gem 'pastel', '~> 0.7.2'
8
7
  gem 'coveralls', '~> 0.8.13'
9
8
  gem 'simplecov', '~> 0.11.2'
10
9
  end
11
10
 
12
11
  group :metrics do
13
- gem 'yard', '~> 0.8.7'
12
+ gem 'yard', '~> 0.9.12'
14
13
  gem 'yardstick', '~> 0.9.9'
15
14
  end
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # TTY::ProgressBar [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
2
+
2
3
  [![Gem Version](https://badge.fury.io/rb/tty-progressbar.svg)][gem]
3
4
  [![Build Status](https://secure.travis-ci.org/piotrmurach/tty-progressbar.svg?branch=master)][travis]
4
5
  [![Build status](https://ci.appveyor.com/api/projects/status/w3jafjeatt1ulufa?svg=true)][appveyor]
5
- [![Code Climate](https://codeclimate.com/github/piotrmurach/tty-progressbar/badges/gpa.svg)][codeclimate]
6
+ [![Maintainability](https://api.codeclimate.com/v1/badges/e85416137d2057169575/maintainability)][codeclimate]
6
7
  [![Coverage Status](https://coveralls.io/repos/github/piotrmurach/tty-progressbar/badge.svg)][coverage]
7
8
  [![Inline docs](http://inch-ci.org/github/piotrmurach/tty-progressbar.svg?branch=master)][inchpages]
8
9
 
@@ -10,7 +11,7 @@
10
11
  [gem]: http://badge.fury.io/rb/tty-progressbar
11
12
  [travis]: http://travis-ci.org/piotrmurach/tty-progressbar
12
13
  [appveyor]: https://ci.appveyor.com/project/piotrmurach/tty-progressbar
13
- [codeclimate]: https://codeclimate.com/github/piotrmurach/tty-progressbar
14
+ [codeclimate]: https://codeclimate.com/github/piotrmurach/tty-progressbar/maintainability
14
15
  [coverage]: https://coveralls.io/github/piotrmurach/tty-progressbar
15
16
  [inchpages]: http://inch-ci.org/github/piotrmurach/tty-progressbar
16
17
 
@@ -62,8 +63,9 @@ Or install it yourself as:
62
63
  * [2.13 on](#213-on)
63
64
  * [3. Configuration](#3-configuration)
64
65
  * [3.1 :head](#31-head)
65
- * [3.2 :frequency](#32-interval)
66
- * [3.3 :interval](#33-interval)
66
+ * [3.2 :output](#32-output)
67
+ * [3.3 :frequency](#33-frequency)
68
+ * [3.4 :interval](#34-interval)
67
69
  * [4. Formatting](#4-formatting)
68
70
  * [4.1 Tokens](#41-tokens)
69
71
  * [4.2 Custom Formatters](#42-custom-formatters)
@@ -150,7 +152,7 @@ To simplify progressing over an enumerable you can use `iterate` which as a firs
150
152
  First, create a progress bar without a total which will be dynamically handled for you:
151
153
 
152
154
  ```ruby
153
- bar = TTY::ProgressBar.new
155
+ bar = TTY::ProgressBar.new("[:bar]")
154
156
  ```
155
157
 
156
158
  Then, either directly iterate over a collection by yielding values to a block:
@@ -159,7 +161,7 @@ Then, either directly iterate over a collection by yielding values to a block:
159
161
  bar.iterate(30.times) { |v| ... }
160
162
  ```
161
163
 
162
- or return an 'Enumerator':
164
+ or return an `Enumerator`:
163
165
 
164
166
  ```ruby
165
167
  progress = bar.iterate(30.times)
@@ -172,6 +174,33 @@ By default, progress bar is advanced by `1` but you can change it by passing sec
172
174
  bar.iterate(30.times, 5)
173
175
  ```
174
176
 
177
+ One particularly useful application of `iterate` are Ruby infamous [lazy enumerators](http://ruby-doc.org/core-2.5.0/Enumerator/Lazy.html), or slowly advancing enumerations, representing complex processes.
178
+
179
+ For example, an `Enumerator` that downloads content from a remote server chunk at a time:
180
+
181
+ ```ruby
182
+ downloader = Enumerator.new do |y|
183
+ start = 0
184
+ loop do
185
+ yield(download_from_server(start, CHUNK_SIZE))
186
+ raise StopIteration if download_finished?
187
+ start += CHUNK_SIZE
188
+ end
189
+ end
190
+ ```
191
+
192
+ would be used with progress bar with the total size matching the content size like so:
193
+
194
+ ```ruby
195
+ bar = TTY::ProgressBar.new("[:bar]", total: content_size)
196
+ # you need to provide the total for the iterate to avoid calling enumerator.count
197
+ response = bar.iterate(downloader, CHUNK_SIZE).to_a.join
198
+ ```
199
+
200
+ This would result in progress bar advancing after each chunk up until all content has been downloaded, returning the result of the download in `response` variable.
201
+
202
+ Please run [slow_process example](examples/slow_process.rb) to see this in action.
203
+
175
204
  ### 2.3 current=
176
205
 
177
206
  **TTY::ProgressBar** allows you to set progress to a given value by calling `current=` method.
@@ -299,10 +328,10 @@ There are number of configuration options that can be provided:
299
328
  * `:width` of the bars display in terminal columns excluding formatting options. Defaults to total steps
300
329
  * `:complete` completion character by default `=`
301
330
  * `:incomplete` incomplete character by default single space
302
- * [:head](#21-head) the head character by default `=`
303
- * `:output` the output stream defaulting to `stderr`
304
- * [:frequency](#22-frequency) used to throttle the output, by default `0`
305
- * [:interval](#23-interval) used to measure the speed, by default `1 sec`
331
+ * [:head](#31-head) the head character by default `=`
332
+ * [:output](#32-output) the output stream defaulting to `stderr`
333
+ * [:frequency](#33-frequency) used to throttle the output, by default `0`
334
+ * [:interval](#34-interval) used to measure the speed, by default `1 sec`
306
335
  * `:hide_cursor` to hide display cursor defaulting to `false`
307
336
  * `:clear` to clear the finished bar defaulting to `false`
308
337
 
@@ -326,7 +355,19 @@ bar = TTY::ProressBar.new("[:bar]", head: '>')
326
355
  # [=======> ]
327
356
  ```
328
357
 
329
- ### 3.2 :frequency
358
+ ### 3.2 :output
359
+
360
+ The progress bar only outputs to a console and when output is redirected to a file or a pipe it does nothing. This is so, for example, your error logs do not overflow with progress bars output.
361
+
362
+ You can change where console output is streamed with `:output` option:
363
+
364
+ ```ruby
365
+ bar = TTY::ProgressBar.new(output: $stdout)
366
+ ```
367
+
368
+ The output stream defaults to `stderr`.
369
+
370
+ ### 3.3 :frequency
330
371
 
331
372
  Each time the `advance` is called it causes the progress bar to repaint. In cases when there is a huge number of updates per second, you may need to limit the rendering process by using the `frequency` option.
332
373
 
@@ -336,7 +377,7 @@ The `frequency` option accepts `integer` representing number of `Hz` units, for
336
377
  TTY::ProgressBar.new("[:bar]", total: 30, frequency: 10) # 10 Hz
337
378
  ```
338
379
 
339
- ### 3.3 :interval
380
+ ### 3.4 :interval
340
381
 
341
382
  For every call of `advance` method the **ProgressBar** takes a sample for speed measurement. By default the samples are grouped per second but you can change that by passing the `interval` option.
342
383
 
@@ -633,4 +674,4 @@ This project is intended to be a safe, welcoming space for collaboration, and co
633
674
 
634
675
  ## Copyright
635
676
 
636
- Copyright (c) 2014-2017 Piotr Murach. See LICENSE for further details.
677
+ Copyright (c) 2014-2018 Piotr Murach. See LICENSE for further details.
@@ -1,8 +1,7 @@
1
- # coding: utf-8
2
-
3
- require 'tty-progressbar'
4
1
  require 'pastel'
5
2
 
3
+ require_relative '../lib/tty-progressbar'
4
+
6
5
  pastel = Pastel.new
7
6
  green = pastel.on_green(" ")
8
7
  red = pastel.on_red(" ")
@@ -1,6 +1,4 @@
1
- # encoding: utf-8
2
-
3
- require 'tty-progressbar'
1
+ require_relative '../lib/tty-progressbar'
4
2
 
5
3
  bar = TTY::ProgressBar.new("downloading [:bar] :percent", head: '>', total: 30)
6
4
  30.times do |i|
@@ -1,7 +1,5 @@
1
- # encoding: utf-8
1
+ require_relative '../lib/tty-progressbar'
2
2
 
3
- require 'tty-progressbar'
4
-
5
- bar = TTY::ProgressBar.new("[:bar]")
3
+ bar = TTY::ProgressBar.new("[:bar]", total: 30)
6
4
 
7
5
  bar.iterate(30.times) { sleep(0.1) }
@@ -0,0 +1,6 @@
1
+ require_relative '../lib/tty-progressbar'
2
+
3
+ bar = TTY::ProgressBar.new("[:bar] :current", total: 10, width: 20)
4
+
5
+ range = 1..Float::INFINITY
6
+ bar.iterate(range.lazy.take(10)) { sleep(0.1) }
@@ -1,6 +1,4 @@
1
- # encoding: utf-8
2
-
3
- require 'tty-progressbar'
1
+ require_relative '../../lib/tty-progressbar'
4
2
 
5
3
  bars = TTY::ProgressBar::Multi.new("main [:bar] :percent")
6
4
 
@@ -1,6 +1,4 @@
1
- # encoding: utf-8
2
-
3
- require 'tty-progressbar'
1
+ require_relative '../../lib/tty-progressbar'
4
2
 
5
3
  bars = TTY::ProgressBar::Multi.new
6
4
 
@@ -1,6 +1,4 @@
1
- # coding: utf-8
2
-
3
- require 'tty-progressbar'
1
+ require_relative '../lib/tty-progressbar'
4
2
 
5
3
  bar = TTY::ProgressBar.new("downloading [:bar] :elapsed :percent", total: 30)
6
4
  30.times do
@@ -0,0 +1,29 @@
1
+ require_relative '../lib/tty-progressbar'
2
+
3
+ CONTENT_SIZE = 2048
4
+ CHUNK_SIZE = 255
5
+
6
+ # Dummy "long responding server"
7
+ def download_from_server(offset, limit)
8
+ sleep(0.1)
9
+ "<chunk #{offset}..#{offset + limit}>"
10
+ end
11
+
12
+ def download_finished?(position)
13
+ position >= CONTENT_SIZE
14
+ end
15
+
16
+ downloader = Enumerator.new do |y|
17
+ start = 0
18
+ loop do
19
+ y.yield(download_from_server(start, CHUNK_SIZE))
20
+ start += CHUNK_SIZE
21
+ raise StopIteration if download_finished?(start)
22
+ end
23
+ end
24
+
25
+ bar = TTY::ProgressBar.new("[:bar] :current_byte/:total_byte", total: CONTENT_SIZE)
26
+
27
+ response = bar.iterate(downloader, CHUNK_SIZE).to_a.join
28
+
29
+ puts response
@@ -1,6 +1,4 @@
1
- # coding: utf-8
2
-
3
- require 'tty-progressbar'
1
+ require_relative '../lib/tty-progressbar'
4
2
 
5
3
  bar = TTY::ProgressBar.new "downloading [:bar] :rate/s :mean_rate/s" do |conf|
6
4
  conf.total = 100
@@ -1,6 +1,4 @@
1
- # encoding: utf-8
2
-
3
- require 'tty-progressbar'
1
+ require_relative '../lib/tty-progressbar'
4
2
 
5
3
  threads = []
6
4
 
@@ -1,6 +1,4 @@
1
- # coding: utf-8
2
-
3
- require 'tty-progressbar'
1
+ require_relative '../lib/tty-progressbar'
4
2
 
5
3
  files = [
6
4
  'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', 'file5.txt',
@@ -155,7 +155,19 @@ module TTY
155
155
  end
156
156
 
157
157
  # Iterate over collection either yielding computation to block
158
- # or provided Enumerator.
158
+ # or provided Enumerator. If the bar's `total` was not set,
159
+ # it would be taken from `collection.count`, otherwise previously
160
+ # set `total` would be used. This allows using the progressbar
161
+ # with infinite, lazy, or slowly-calculated enumerators.
162
+ #
163
+ # @note
164
+ # If `total` is set, iteration will NOT stop after this number of
165
+ # iterations, only when provided Enumerable is finished. It may
166
+ # be convenient in "unsure number of iterations" situations
167
+ # (like downloading in chunks, when server may eventually send
168
+ # more chunks than predicted), but be careful to not pass infinite
169
+ # enumerators without previosly doing `.take(some_finite_number)`
170
+ # on them.
159
171
  #
160
172
  # @example
161
173
  # bar.iterate(30.times) { ... }
@@ -170,14 +182,14 @@ module TTY
170
182
  #
171
183
  # @api public
172
184
  def iterate(collection, progress = 1, &block)
173
- update(total: collection.count)
174
- prog = Enumerator.new do |iter|
185
+ update(total: collection.count * progress) unless total
186
+ progress_enum = Enumerator.new do |iter|
175
187
  collection.each do |elem|
176
188
  advance(progress)
177
189
  iter.yield(elem)
178
190
  end
179
191
  end
180
- block_given? ? prog.each(&block) : prog
192
+ block_given? ? progress_enum.each(&block) : progress_enum
181
193
  end
182
194
 
183
195
  # Update configuration options for this bar
@@ -279,6 +291,8 @@ module TTY
279
291
  #
280
292
  # @api private
281
293
  def write(data, clear_first = false)
294
+ return unless tty? # write only to terminal
295
+
282
296
  move_to_row do
283
297
  output.print(TTY::Cursor.column(1)) if clear_first
284
298
  characters_in = @multibar.line_inset(self) if @multibar
@@ -465,5 +479,14 @@ module TTY
465
479
  callback.call(*args)
466
480
  end
467
481
  end
482
+
483
+ # Check if IO is attached to a terminal
484
+ #
485
+ # return [Boolean]
486
+ #
487
+ # @api public
488
+ def tty?
489
+ output.respond_to?(:tty?) && output.tty?
490
+ end
468
491
  end # ProgressBar
469
492
  end # TTY
@@ -1,5 +1,5 @@
1
1
  module TTY
2
2
  class ProgressBar
3
- VERSION = '0.13.0'
3
+ VERSION = '0.14.0'.freeze
4
4
  end # ProgressBar
5
5
  end # TTY
@@ -16,6 +16,12 @@ end
16
16
  require 'timecop'
17
17
  require 'tty-progressbar'
18
18
 
19
+ class StringIO
20
+ def tty?
21
+ true
22
+ end
23
+ end
24
+
19
25
  RSpec.configure do |config|
20
26
  config.expect_with :rspec do |expectations|
21
27
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
@@ -20,7 +20,8 @@ RSpec.describe TTY::ProgressBar, '#iterate' do
20
20
 
21
21
  it "iterates over a collection with a step" do
22
22
  bar = TTY::ProgressBar.new("[:bar]", output: output)
23
- bar.iterate(20.times, 5) { }
23
+ values = []
24
+ bar.iterate(4.times, 5) { |val| values << val }
24
25
 
25
26
  expect(bar.complete?).to eq(true)
26
27
  output.rewind
@@ -30,6 +31,7 @@ RSpec.describe TTY::ProgressBar, '#iterate' do
30
31
  "\e[1G[=============== ]",
31
32
  "\e[1G[====================]\n"
32
33
  ].join)
34
+ expect(values).to eq([0, 1, 2, 3])
33
35
  end
34
36
 
35
37
  it "iterates over a collection and returns enumerable" do
@@ -43,4 +45,35 @@ RSpec.describe TTY::ProgressBar, '#iterate' do
43
45
 
44
46
  expect(values).to eq([0,1,2,3,4])
45
47
  end
48
+
49
+ it "does not uses collection's count if total is provided" do
50
+ bar = TTY::ProgressBar.new("[:bar]", output: output, total: 5)
51
+ iterable = 5.times
52
+ expect(iterable).not_to receive(:count)
53
+ progress = bar.iterate(iterable)
54
+ values = []
55
+
56
+ progress.each { |v| values << v }
57
+
58
+ expect(values).to eq([0,1,2,3,4])
59
+ end
60
+
61
+ it "iterates over an infinite enumerator and renders bar correctly" do
62
+ bar = TTY::ProgressBar.new("[:bar]", output: output, total: 5)
63
+ infinite_iter = (1..Float::INFINITY).lazy
64
+
65
+ progress = bar.iterate(infinite_iter)
66
+
67
+ 10.times { progress.next }
68
+
69
+ expect(bar.complete?).to eq(true)
70
+ output.rewind
71
+ expect(output.read).to eq([
72
+ "\e[1G[= ]",
73
+ "\e[1G[== ]",
74
+ "\e[1G[=== ]",
75
+ "\e[1G[==== ]",
76
+ "\e[1G[=====]\n"
77
+ ].join)
78
+ end
46
79
  end
@@ -21,9 +21,10 @@ Gem::Specification.new do |spec|
21
21
  spec.required_ruby_version = '>= 2.0.0'
22
22
 
23
23
  spec.add_dependency "tty-cursor", '~> 0.5.0'
24
- spec.add_dependency "tty-screen", '~> 0.6.0'
24
+ spec.add_dependency "tty-screen", '~> 0.6.4'
25
25
 
26
26
  spec.add_development_dependency 'bundler', '>= 1.5.0', '< 2.0'
27
27
  spec.add_development_dependency 'rspec', '~> 3.1'
28
+ spec.add_development_dependency 'timecop', '~> 0.9.1'
28
29
  spec.add_development_dependency 'rake'
29
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-progressbar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-29 00:00:00.000000000 Z
11
+ date: 2018-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-cursor
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.6.0
33
+ version: 0.6.4
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.6.0
40
+ version: 0.6.4
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +72,20 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '3.1'
75
+ - !ruby/object:Gem::Dependency
76
+ name: timecop
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.9.1
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.9.1
75
89
  - !ruby/object:Gem::Dependency
76
90
  name: rake
77
91
  requirement: !ruby/object:Gem::Requirement
@@ -107,9 +121,11 @@ files:
107
121
  - examples/color.rb
108
122
  - examples/failure.rb
109
123
  - examples/iterator.rb
124
+ - examples/lazy.rb
110
125
  - examples/multi/main_bar.rb
111
126
  - examples/multi/simple.rb
112
127
  - examples/simple.rb
128
+ - examples/slow_process.rb
113
129
  - examples/speed.rb
114
130
  - examples/threaded.rb
115
131
  - examples/tokens.rb
@@ -255,4 +271,3 @@ test_files:
255
271
  - spec/unit/stop_spec.rb
256
272
  - spec/unit/update_spec.rb
257
273
  - spec/unit/width_spec.rb
258
- has_rdoc: