tty-progressbar 0.5.1 → 0.6.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: 2f2cf9c0a69a06ce555230e540d06eb2ead51d7b
4
- data.tar.gz: 658a14537dd201fbab6378aa4acc27c6e8cc216e
3
+ metadata.gz: 054aa5020aa87b8cd5b5899fb2f6eb512f0d3f4f
4
+ data.tar.gz: dbb0d52019b12e27b032bb61d3a839034e319e98
5
5
  SHA512:
6
- metadata.gz: 89b95358acafece957b2f627dfde1e70ba4455acde5c1f186555db8f669437521d53d9e266980c0cf4d2d1d5c838cc71decd1ef90e08c3ea53abafac6c031e62
7
- data.tar.gz: 974c483f4a929549136c981213eefe26dd378eeadfcfc7cae6f97e7033f4593f8c321afbfbfdca50f25bc58f366197274168176892e0550a567f789ed5bf73ba
6
+ metadata.gz: f4b8f93d30a0ad12bd80ecf94541b4fbd574d5aa1c6ab063dfacf439116f2258586560bcc236f6d91b25e6c77f19d89ee148edfa8fa7b96acb0c2bbb90505e3e
7
+ data.tar.gz: cd3020b089d687a5ccca2d1b4d5d7193bdad58bed77eec7864550121964e5b3e62776e2e758becf6736e3c5677cda2e297082475dca5d379745409e5da128232
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ 0.6.0 (June 27, 2015)
2
+
3
+ * Add ability to add custom tokens
4
+ * Internal cleanup of parameters for formatters and pipeline
5
+ * Fix ratio to avoid division by zero by @sleewoo issue #9
6
+
1
7
  0.5.1 (May 31, 2015)
2
8
 
3
9
  * Update tty-screen dependency with bug fixes
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ gemspec
4
4
 
5
5
  group :development do
6
6
  gem 'rake', '~> 10.3.2'
7
- gem 'rspec', '~> 3.1.0'
7
+ gem 'rspec', '~> 3.3.0'
8
8
  gem 'yard', '~> 0.8.7'
9
9
  gem 'timecop', '~> 0.7.1'
10
10
  gem 'pastel', '~> 0.4.0'
data/README.md CHANGED
@@ -54,7 +54,8 @@ Or install it yourself as:
54
54
  * [2.2 Interval](#22-interval)
55
55
  * [3. Formatting](#3-formatting)
56
56
  * [3.1 Tokens](#31-tokens)
57
- * [3.2 Custom Formatters](#31-custom-formatters)
57
+ * [3.2 Custom Formatters](#32-custom-formatters)
58
+ * [3.3 Custom Tokens](#33-custom-tokens)
58
59
  * [4. Logging](#4-logging)
59
60
  * [5. Examples](#5-examples)
60
61
  * [5.1 Color](#51-color)
@@ -224,29 +225,23 @@ These are the tokens that are currently supported:
224
225
 
225
226
  ### 3.2 Custom Formatters
226
227
 
227
- If the provided tokens do not meet your needs, you can write your own formatter and instrument formatting pipeline to use a formatter you prefer.
228
+ If the provided tokens do not meet your needs, you can write your own formatter and instrument formatting pipeline to use a formatter you prefer. This option is preferred if you are going to rely on progress bar internal data such as `rate`, `current` etc. which will all be available on the passed in progress bar instance.
228
229
 
229
230
  For example, begin by creating custom formatter called `TimeFormatter` that will dynamicly update `:time` token in format string. The methods that you need to specify are `initialize`, `matches?` and `format` like follows:
230
231
 
231
232
  ```ruby
232
233
  class TimeFormatter
233
234
  def initialize(progress)
234
- @progress = progress
235
+ @progress = progress # current progress bar instance
235
236
  end
236
237
 
237
- def matches?(value) # specify condition to match for
238
+ def matches?(value) # specify condition to match for in display string
238
239
  value.to_s =~ /:time/
239
240
  end
240
241
 
241
- def format(value) # specify how value is formatted
242
- transformed = transform(value)
243
- value.gsub(/:time/, transformed.to_s) # => :time token
244
- end
245
-
246
- private
247
-
248
- def transfrom
249
- value * (Time.now - @progress.start_at).to_i
242
+ def format(value) # specify how display string is formatted
243
+ transformed = (Time.now - @progress.start_at).to_s
244
+ value.gsub(/:time/, transformed) # => :time token replacement
250
245
  end
251
246
  end
252
247
  ```
@@ -265,6 +260,29 @@ Then add `TimeFormatter` to the pipeline like so:
265
260
  bar.use TimeFormatter
266
261
  ```
267
262
 
263
+ and then invoke progression:
264
+
265
+ ```ruby
266
+ bar.advance
267
+ ```
268
+
269
+ ### 3.3 Custom Tokens
270
+
271
+ You can define custom tokens by passing pairs `name: value` to `advance` method in order to dynamically update formatted bar. This option is useful for lightweight content replacement such as titles that doesn't depend on the internal data of progressbar. For example:
272
+
273
+ ```ruby
274
+ bar = TTY::ProgressBar.new("(:current) :title", total: 4)
275
+ bar.advance(title: 'Hello Piotr!')
276
+ bar.advance(3, title: 'Bye Piotr!')
277
+ ```
278
+
279
+ which outputs:
280
+
281
+ ```ruby
282
+ (1) Hello Piotr!
283
+ (4) Bye Piotr!
284
+ ```
285
+
268
286
  ## 4. Logging
269
287
 
270
288
  If you want to print messages out to terminal along with the progress bar use the `log` method. The messages will appear above the progress bar and will continue scrolling up as more are logged out.
data/examples/color.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # coding: utf-8
2
+
1
3
  require 'tty-progressbar'
2
4
  require 'pastel'
3
5
 
data/examples/simple.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # coding: utf-8
2
+
1
3
  require 'tty-progressbar'
2
4
 
3
5
  bar = TTY::ProgressBar.new("downloading [:bar] :elapsed :percent", total: 30)
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+
3
+ require 'tty-progressbar'
4
+
5
+ files = [
6
+ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', 'file5.txt',
7
+ 'file6.txt', 'file7.txt', 'file8.txt', 'file9.txt', 'file10.txt'
8
+ ]
9
+
10
+ bar = TTY::ProgressBar.new("downloading :file :percent", total: files.size)
11
+ 10.times do |num|
12
+ sleep(0.1)
13
+ bar.advance(file: files[num])
14
+ end
@@ -51,6 +51,8 @@ module TTY
51
51
  # the object that responds to print call defaulting to stderr
52
52
  # @option options [Number] :frequency
53
53
  # the frequency with which to display bars
54
+ # @option options [Number] :interval
55
+ # the period for sampling of speed measurement
54
56
  #
55
57
  # @api public
56
58
  def initialize(format, options = {})
@@ -67,6 +69,7 @@ module TTY
67
69
  @done = false
68
70
  @start_at = Time.now
69
71
  @started = false
72
+ @tokens = {}
70
73
  @formatter = TTY::ProgressBar::Formatter.new
71
74
  @meter = Meter.new(options.fetch(:interval, 1))
72
75
 
@@ -78,8 +81,8 @@ module TTY
78
81
  #
79
82
  # @api public
80
83
  def start
81
- @started = true
82
- @started_at = Time.now
84
+ @started = true
85
+ @start_at = Time.now
83
86
  @meter.start
84
87
 
85
88
  advance(0)
@@ -90,12 +93,16 @@ module TTY
90
93
  # @param [Object|Number] progress
91
94
  #
92
95
  # @api public
93
- def advance(progress = 1)
96
+ def advance(progress = 1, tokens = {})
94
97
  return if @done
95
98
 
99
+ if progress.respond_to?(:to_hash)
100
+ tokens, progress = progress, 1
101
+ end
96
102
  @start_at = Time.now if @current.zero? && !@started
97
103
  @readings += 1
98
104
  @current += progress
105
+ @tokens = tokens
99
106
  @meter.sample(Time.now, progress)
100
107
 
101
108
  if !no_width && @current >= total
@@ -136,7 +143,7 @@ module TTY
136
143
  #
137
144
  # @api public
138
145
  def ratio
139
- proportion = (@current.to_f / total)
146
+ proportion = total > 0 ? (@current.to_f / total) : 0
140
147
  [[proportion, 0].max, 1].min
141
148
  end
142
149
 
@@ -150,6 +157,9 @@ module TTY
150
157
  end
151
158
 
152
159
  formatted = @formatter.decorate(self, @format)
160
+ @tokens.each do |token, val|
161
+ formatted = formatted.gsub(":#{token}", val)
162
+ end
153
163
  write(formatted, true)
154
164
 
155
165
  @last_render_time = Time.now
@@ -9,7 +9,7 @@ module TTY
9
9
 
10
10
  # @api private
11
11
  def initialize(pipeline = nil)
12
- @pipeline = TTY::ProgressBar::Pipeline.new
12
+ @pipeline = pipeline || TTY::ProgressBar::Pipeline.new
13
13
  end
14
14
 
15
15
  # Prepare default pipeline formatters
@@ -8,7 +8,7 @@ module TTY
8
8
  class BarFormatter
9
9
  MATCHER = /:bar/.freeze
10
10
 
11
- def initialize(progress, *args, &block)
11
+ def initialize(progress)
12
12
  @progress = progress
13
13
  end
14
14
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module TTY
4
4
  class ProgressBar
5
- # Used by {Pipeline} to format :current token
5
+ # Used by {Pipeline} to format :byte_rate token
6
6
  #
7
7
  # @api private
8
8
  class ByteRateFormatter
@@ -2,11 +2,12 @@
2
2
 
3
3
  module TTY
4
4
  class ProgressBar
5
+ # Used by {Pipeline} to format :byte and :current_byte tokens
6
+ #
7
+ # @api private
5
8
  class ByteFormatter
6
9
  MATCHER = /(:current_byte|:byte)\b/i.freeze
7
- # Used by {Pipeline} to format :byte token
8
- #
9
- # @api private
10
+
10
11
  def initialize(progress)
11
12
  @progress = progress
12
13
  @converter = Converter.new
@@ -8,7 +8,7 @@ module TTY
8
8
  class ElapsedFormatter
9
9
  MATCHER = /:elapsed/.freeze
10
10
 
11
- def initialize(progress, *args, &block)
11
+ def initialize(progress)
12
12
  @progress = progress
13
13
  @converter = Converter.new
14
14
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module TTY
4
4
  class ProgressBar
5
- # Used by {Pipeline} to format :current token
5
+ # Used by {Pipeline} to format :mean_byte token
6
6
  #
7
7
  # @api private
8
8
  class MeanByteFormatter
@@ -2,7 +2,7 @@
2
2
 
3
3
  module TTY
4
4
  class ProgressBar
5
- # Used by {Pipeline} to format :current token
5
+ # Used by {Pipeline} to format :mean_rate token
6
6
  #
7
7
  # @api private
8
8
  class MeanRateFormatter
@@ -2,7 +2,7 @@
2
2
 
3
3
  module TTY
4
4
  class ProgressBar
5
- # Used by {Pipeline} to format :current token
5
+ # Used by {Pipeline} to format :rate token
6
6
  #
7
7
  # @api private
8
8
  class RateFormatter
@@ -2,6 +2,9 @@
2
2
 
3
3
  module TTY
4
4
  class ProgressBar
5
+ # Used by {Pipeline} to format :total token
6
+ #
7
+ # @api private
5
8
  class TotalFormatter
6
9
  MATCHER = /:total\b/i.freeze
7
10
 
@@ -22,6 +22,9 @@ module TTY
22
22
  @last_sample_at = @start_time
23
23
  end
24
24
 
25
+ # Start sampling timer
26
+ #
27
+ # @api public
25
28
  def start
26
29
  @start_time = Time.now.to_f
27
30
  @last_sample_at = @start_time
@@ -31,7 +34,7 @@ module TTY
31
34
  #
32
35
  # @api public
33
36
  def sample(at, value)
34
- if @interval < at.to_f - @last_sample_at
37
+ if @interval < (at.to_f - @last_sample_at)
35
38
  @marker += 1
36
39
  end
37
40
  @samples[@marker] << value
@@ -39,7 +42,10 @@ module TTY
39
42
  @last_sample_at = at.to_f
40
43
  end
41
44
 
42
- # The rate of sampling
45
+ # The current rate of sampling for a given interval
46
+ #
47
+ # @return [Number]
48
+ # the current rate in decimal or 0 if cannot be determined
43
49
  #
44
50
  # @api public
45
51
  def rate
@@ -57,7 +63,10 @@ module TTY
57
63
  end
58
64
  end
59
65
 
60
- # The mean rate
66
+ # The mean rate of all the sampled rates
67
+ #
68
+ # @return [Number]
69
+ # the mean rate
61
70
  #
62
71
  # @api public
63
72
  def mean_rate
@@ -8,17 +8,29 @@ module TTY
8
8
  class Pipeline
9
9
  include Enumerable
10
10
 
11
+ # Create formatting pipeline
12
+ #
13
+ # @api private
11
14
  def initialize(formatters = [])
12
15
  @formatters = formatters
16
+ freeze
13
17
  end
14
18
 
15
- # Add new formatter
19
+ # Add a new formatter
20
+ #
21
+ # @example
22
+ # use(TTY::ProgressBar::TotalFormatter)
16
23
  #
17
- # @ api public
18
- def use(formatter, *args, &block)
19
- formatters << proc { |progress| formatter.new(progress, *args, &block) }
24
+ # @api public
25
+ def use(formatter)
26
+ formatters << proc { |progress| formatter.new(progress) }
20
27
  end
21
28
 
29
+ # Decorate the tokenized string with actual values
30
+ #
31
+ # @return [nil]
32
+ #
33
+ # @api private
22
34
  def decorate(progress, tokenized)
23
35
  base = tokenized.dup
24
36
  formatters.inject(base) do |formatted, formatter|
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class ProgressBar
5
- VERSION = '0.5.1'
5
+ VERSION = '0.6.0'
6
6
  end # ProgressBar
7
7
  end # TTY
@@ -1,10 +1,14 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'spec_helper'
4
-
5
3
  RSpec.describe TTY::ProgressBar, '.advance' do
6
4
  let(:output) { StringIO.new('', 'w+') }
7
5
 
6
+ it "advances by custom value" do
7
+ progress = TTY::ProgressBar.new("[:bar]", output: output, total: 10)
8
+ progress.advance(8)
9
+ expect(progress.current).to eq(8)
10
+ end
11
+
8
12
  it "allows to go back" do
9
13
  progress = TTY::ProgressBar.new("[:bar]", output: output, total: 10)
10
14
  5.times { progress.advance(1) }
@@ -1,14 +1,12 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'spec_helper'
4
-
5
- RSpec.describe TTY::ProgressBar, 'custom' do
3
+ RSpec.describe TTY::ProgressBar, 'custom formatter' do
6
4
  let(:output) { StringIO.new('', 'w+') }
7
5
 
8
6
  it "allows for custom tag" do
9
7
  progress = TTY::ProgressBar.new(":hi", output: output, total: 10)
10
8
 
11
- HiFormatter = Class.new do
9
+ stub_const("HiFormatter", Class.new do
12
10
  def initialize(progress)
13
11
  @progress = progress
14
12
  end
@@ -20,7 +18,7 @@ RSpec.describe TTY::ProgressBar, 'custom' do
20
18
  def format(value)
21
19
  value.gsub(/:hi/, "Hello")
22
20
  end
23
- end
21
+ end)
24
22
 
25
23
  progress.use(HiFormatter)
26
24
  progress.advance
@@ -0,0 +1,16 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::ProgressBar, 'custom token' do
4
+ let(:output) { StringIO.new('', 'w+') }
5
+
6
+ it "allows to specify custom tokens" do
7
+ progress = TTY::ProgressBar.new("(:current) :title", output: output, total: 4)
8
+ progress.advance(title: 'Hello Piotr!')
9
+ progress.advance(3, title: 'Bye Piotr!')
10
+ output.rewind
11
+ expect(output.read).to eq([
12
+ "\e[1G(1) Hello Piotr!",
13
+ "\e[1G(4) Bye Piotr!\n"
14
+ ].join)
15
+ end
16
+ end
@@ -1,8 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'spec_helper'
4
-
5
- RSpec.describe TTY::ProgressBar::Meter, '' do
3
+ RSpec.describe TTY::ProgressBar::Meter, '.rate' do
6
4
 
7
5
  before { Timecop.safe_mode = false }
8
6
 
@@ -69,4 +67,3 @@ RSpec.describe TTY::ProgressBar::Meter, '' do
69
67
  expect(meter.rate).to eq(0)
70
68
  end
71
69
  end
72
-
@@ -1,8 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'spec_helper'
4
-
5
- RSpec.describe TTY::ProgressBar, 'ratio=' do
3
+ RSpec.describe TTY::ProgressBar, '.ratio=' do
6
4
  let(:output) { StringIO.new('', 'w+') }
7
5
 
8
6
  it "allows to set ratio" do
@@ -20,4 +18,16 @@ RSpec.describe TTY::ProgressBar, 'ratio=' do
20
18
  progress.ratio = 0.5
21
19
  expect(progress.current).to eq(1)
22
20
  end
21
+
22
+ it "doesn't allow to set wrong ratio" do
23
+ progress = TTY::ProgressBar.new("[:bar]", output: output, total: 3)
24
+ progress.ratio = 3.2
25
+ expect(progress.current).to eq(3)
26
+ expect(progress.complete?).to eq(true)
27
+ end
28
+
29
+ it "avoids division by zero" do
30
+ progress = TTY::ProgressBar.new("[:bar]", output: output, total: 0)
31
+ expect(progress.ratio).to eq(0)
32
+ end
23
33
  end
data/tasks/console.rake CHANGED
@@ -8,3 +8,4 @@ task :console do
8
8
  ARGV.clear
9
9
  IRB.start
10
10
  end
11
+ task :c => :console
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.5.1
4
+ version: 0.6.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: 2015-05-31 00:00:00.000000000 Z
11
+ date: 2015-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-screen
@@ -57,6 +57,7 @@ files:
57
57
  - examples/color.rb
58
58
  - examples/simple.rb
59
59
  - examples/speed.rb
60
+ - examples/tokens.rb
60
61
  - lib/tty-progressbar.rb
61
62
  - lib/tty/progressbar.rb
62
63
  - lib/tty/progressbar/configuration.rb
@@ -85,6 +86,7 @@ files:
85
86
  - spec/unit/converter/to_seconds_spec.rb
86
87
  - spec/unit/converter/to_time_spec.rb
87
88
  - spec/unit/custom_formatter_spec.rb
89
+ - spec/unit/custom_token_spec.rb
88
90
  - spec/unit/finish_spec.rb
89
91
  - spec/unit/formatter/bar_spec.rb
90
92
  - spec/unit/formatter/byte_rate_spec.rb
@@ -147,6 +149,7 @@ test_files:
147
149
  - spec/unit/converter/to_seconds_spec.rb
148
150
  - spec/unit/converter/to_time_spec.rb
149
151
  - spec/unit/custom_formatter_spec.rb
152
+ - spec/unit/custom_token_spec.rb
150
153
  - spec/unit/finish_spec.rb
151
154
  - spec/unit/formatter/bar_spec.rb
152
155
  - spec/unit/formatter/byte_rate_spec.rb