tty-progressbar 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
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: