tty-spinner 0.2.0 → 0.3.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: 8e04e5566451769e21e19b19e1e737a2a4680529
4
- data.tar.gz: f62fbd9e4da87305573bdf3214f32029d51efd41
3
+ metadata.gz: 9b97fa767937b67b27ecbba2fb06a5b9f69c4d6b
4
+ data.tar.gz: 20dee6fe62ec0e5f431424f54a26848291773245
5
5
  SHA512:
6
- metadata.gz: 36bc537184f487b0d0b1ee2b97075c0179eb07e5bd1e7cdc42036d1a7fc67972b22161fd178577e96dbdd959a498073aa6f4cd7b36aef5c35f8ad7c6a326a81c
7
- data.tar.gz: 02d7cf58e0fd5650249ee89e249211217f10793feee1d9aaa77600a220de2c789ec029150ebc5848e6446a105cdf9db673bfadd29306c31df1bf78de9e79b157
6
+ metadata.gz: bae4dcda349f6d01fe50d39dafbc1519a386e160e0d3568702c588648fcbdd2d673c2e06a8c6508c3b8623cf558ddbe76101c67384892e37d41e7e195f321458
7
+ data.tar.gz: e319158428db89baa850bbcd14dba26caa9ad9230377bb2f65cde8fdfd42c40b53eec9f205962421e8745a44f31d0406b8cd85f67a49f191aa55956d4b82fbfa
data/README.md CHANGED
@@ -1,19 +1,22 @@
1
- # TTY::Spinner
1
+ # TTY::Spinner [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
2
2
  [![Gem Version](https://badge.fury.io/rb/tty-spinner.svg)][gem]
3
- [![Build Status](https://secure.travis-ci.org/peter-murach/tty-spinner.svg?branch=master)][travis]
4
- [![Code Climate](https://codeclimate.com/github/peter-murach/tty-spinner/badges/gpa.png)][codeclimate]
5
- [![Coverage Status](https://coveralls.io/repos/peter-murach/tty-spinner/badge.svg)][coverage]
6
- [![Inline docs](http://inch-ci.org/github/peter-murach/tty-spinner.svg?branch=master)][inchpages]
3
+ [![Build Status](https://secure.travis-ci.org/piotrmurach/tty-spinner.svg?branch=master)][travis]
4
+ [![Code Climate](https://codeclimate.com/github/piotrmurach/tty-spinner/badges/gpa.png)][codeclimate]
5
+ [![Coverage Status](https://coveralls.io/repos/piotrmurach/tty-spinner/badge.svg)][coverage]
6
+ [![Inline docs](http://inch-ci.org/github/piotrmurach/tty-spinner.svg?branch=master)][inchpages]
7
7
 
8
+ [gitter]: https://gitter.im/piotrmurach/tty
8
9
  [gem]: http://badge.fury.io/rb/tty-spinner
9
- [travis]: http://travis-ci.org/peter-murach/tty-spinner
10
- [codeclimate]: https://codeclimate.com/github/peter-murach/tty-spinner
11
- [coverage]: https://coveralls.io/r/peter-murach/tty-spinner
12
- [inchpages]: http://inch-ci.org/github/peter-murach/tty-spinner
10
+ [travis]: http://travis-ci.org/piotrmurach/tty-spinner
11
+ [codeclimate]: https://codeclimate.com/github/piotrmurach/tty-spinner
12
+ [coverage]: https://coveralls.io/r/piotrmurach/tty-spinner
13
+ [inchpages]: http://inch-ci.org/github/piotrmurach/tty-spinner
13
14
 
14
15
  > A terminal spinner for tasks that have non-deterministic time frame.
15
16
 
16
- **TTY::Spinner** provides independent spinner component for [TTY](https://github.com/peter-murach/tty) toolkit.
17
+ **TTY::Spinner** provides independent spinner component for [TTY](https://github.com/piotrmurach/tty) toolkit.
18
+
19
+ ![](demo.gif)
17
20
 
18
21
  ## Installation
19
22
 
@@ -38,8 +41,10 @@ Or install it yourself as:
38
41
  * [2.1 spin](#21-spin)
39
42
  * [2.2 start](#22-start)
40
43
  * [2.3 stop](#23-stop)
41
- * [2.4 success](#24-success)
42
- * [2.5 error](#25-error)
44
+ * [2.3.1 success](#231-success)
45
+ * [2.3.2 error](#232-error)
46
+ * [2.4 run](#24-run)
47
+ * [2.5 update](#25-update)
43
48
  * [2.6 reset](#26-reset)
44
49
  * [2.7 join](#27-join)
45
50
  * [3. Configuration](#3-configuration)
@@ -87,13 +92,21 @@ and when finished output:
87
92
  _ Loading ... Done!
88
93
  ```
89
94
 
90
- For more usage examples please see [examples directory](https://github.com/peter-murach/tty-spinner/tree/master/examples)
95
+ For more usage examples please see [examples directory](https://github.com/piotrmurach/tty-spinner/tree/master/examples)
91
96
 
92
97
  ## 2. API
93
98
 
94
99
  ### 2.1 spin
95
100
 
96
- The main workhorse of the spinner is the `spin` method. Looping over `spin` method will animate a given spinner.
101
+ The main workhorse of the spinner is the `spin` method.
102
+
103
+ Looping over `spin` method will animate a given spinner.
104
+
105
+ ```ruby
106
+ loop do
107
+ spinner.spin
108
+ end
109
+ ```
97
110
 
98
111
  ### 2.2 start
99
112
 
@@ -103,7 +116,7 @@ To perform automatic spinning call `start` method like so:
103
116
  spinner.start
104
117
  ```
105
118
 
106
- The speed with which the spinning happens is determined by the `:interval` parameter. All the spinner formats have their default intervals specified [see](https://github.com/peter-murach/tty-spinner/blob/master/lib/tty/spinner/formats.rb)
119
+ The speed with which the spinning happens is determined by the `:interval` parameter. All the spinner formats have their default intervals specified ([see](https://github.com/piotrmurach/tty-spinner/blob/master/lib/tty/spinner/formats.rb)).
107
120
 
108
121
  ### 2.3 stop
109
122
 
@@ -119,7 +132,7 @@ You can further pass a message to print when animation is finished.
119
132
  spinner.stop('Done!')
120
133
  ```
121
134
 
122
- ### 2.4 success
135
+ #### 2.3.1 success
123
136
 
124
137
  Use `success` call to stop the spinning animation and replace the spinning symbol with checkmark character to indicate successful completion.
125
138
 
@@ -134,7 +147,7 @@ This will produce:
134
147
  [✔] Task name (successful)
135
148
  ```
136
149
 
137
- ### 2.5 error
150
+ #### 2.3.2 error
138
151
 
139
152
  Use `error` call to stop the spining animation and replace the spinning symbol with cross character to indicate error completion.
140
153
 
@@ -149,6 +162,44 @@ This will produce:
149
162
  [✖] Task name (error)
150
163
  ```
151
164
 
165
+ ### 2.4 run
166
+
167
+ Use `run` with a code block that will automatically display spinning animation while the block executes and finish animation when the block terminates. Optionally you can provide a stop message to display when animation is finished.
168
+
169
+ ```ruby
170
+ spinner.run('Done!') { ... }
171
+ ```
172
+
173
+ ### 2.5 update
174
+
175
+ Use `update` call to dynamically change label name(s).
176
+
177
+ Provide an arbitrary token name(s) in the message string, such as `:title`
178
+
179
+ ```ruby
180
+ spinner = TTY::Spinner.new("[:spinner] :title")
181
+ ```
182
+
183
+ and then pass token name and value:
184
+
185
+ ```ruby
186
+ spinner.update(title: 'Downloading file1')
187
+ ```
188
+
189
+ next start animation:
190
+
191
+ ```ruby
192
+ spinner.run { ... }
193
+ # => | Downloading file1
194
+ ```
195
+
196
+ Once animation finishes you can kick start another one with a different name:
197
+
198
+ ```ruby
199
+ spinner.update(title: 'Downloading file2')
200
+ spinner.run { ... }
201
+ ```
202
+
152
203
  ### 2.6 reset
153
204
 
154
205
  In order to reset the spinner to its initial frame do:
@@ -183,7 +234,7 @@ Use one of the predefined spinner styles by passing the formatting token `:forma
183
234
  spinner = TTY::Spinner.new(format: :pulse_2)
184
235
  ```
185
236
 
186
- All spinner formats that **TTY::Spinner** accepts are defined in [/lib/tty/spinner/formats.rb](https://github.com/peter-murach/tty-spinner/blob/master/lib/tty/spinner/formats.rb)
237
+ All spinner formats that **TTY::Spinner** accepts are defined in [/lib/tty/spinner/formats.rb](https://github.com/piotrmurach/tty-spinner/blob/master/lib/tty/spinner/formats.rb)
187
238
 
188
239
  If you wish to see all available formats in action run the `formats.rb` file in examples folder like so:
189
240
 
@@ -279,7 +330,7 @@ spinner.on(:error) { ... }
279
330
 
280
331
  ## Contributing
281
332
 
282
- 1. Fork it ( https://github.com/peter-murach/tty-spinner/fork )
333
+ 1. Fork it ( https://github.com/piotrmurach/tty-spinner/fork )
283
334
  2. Create your feature branch (`git checkout -b my-new-feature`)
284
335
  3. Commit your changes (`git commit -am 'Add some feature'`)
285
336
  4. Push to the branch (`git push origin my-new-feature`)
data/lib/tty/spinner.rb CHANGED
@@ -10,6 +10,9 @@ module TTY
10
10
  class Spinner
11
11
  include Formats
12
12
 
13
+ # @raised when attempting to join dead thread
14
+ NotSpinningError = Class.new(StandardError)
15
+
13
16
  ECMA_ESC = "\x1b".freeze
14
17
  ECMA_CSI = "\x1b[".freeze
15
18
  ECMA_CHA = 'G'.freeze
@@ -19,7 +22,7 @@ module TTY
19
22
  DEC_SET = 'h'.freeze
20
23
  DEC_TCEM = '?25'.freeze
21
24
 
22
- MATCHER = /:spinner/.freeze
25
+ MATCHER = /:spinner/
23
26
  TICK = '✔'.freeze
24
27
  CROSS = '✖'.freeze
25
28
 
@@ -50,6 +53,14 @@ module TTY
50
53
  # @api public
51
54
  attr_reader :message
52
55
 
56
+ # Tokens for the message
57
+ #
58
+ # @return [Hash[Symbol, Object]]
59
+ # the current tokens
60
+ #
61
+ # @api public
62
+ attr_reader :tokens
63
+
53
64
  # Initialize a spinner
54
65
  #
55
66
  # @example
@@ -74,23 +85,27 @@ module TTY
74
85
  def initialize(*args)
75
86
  options = args.last.is_a?(::Hash) ? args.pop : {}
76
87
  @message = args.empty? ? ':spinner' : args.pop
88
+ @tokens = {}
77
89
 
78
90
  @format = options.fetch(:format) { :classic }
79
91
  @output = options.fetch(:output) { $stderr }
80
92
  @hide_cursor = options.fetch(:hide_cursor) { false }
81
- @frames = options.fetch(:frames) {
82
- fetch_format(@format.to_sym, :frames) }
93
+ @frames = options.fetch(:frames) do
94
+ fetch_format(@format.to_sym, :frames)
95
+ end
83
96
  @clear = options.fetch(:clear) { false }
84
97
  @success_mark= options.fetch(:success_mark) { TICK }
85
98
  @error_mark = options.fetch(:error_mark) { CROSS }
86
- @interval = options.fetch(:interval) {
87
- fetch_format(@format.to_sym, :interval) }
99
+ @interval = options.fetch(:interval) do
100
+ fetch_format(@format.to_sym, :interval)
101
+ end
88
102
 
89
103
  @callbacks = Hash.new { |h, k| h[k] = [] }
90
104
  @length = @frames.length
91
105
  @current = 0
92
106
  @done = false
93
107
  @state = :stopped
108
+ @thread = nil
94
109
  end
95
110
 
96
111
  def spinning?
@@ -113,22 +128,41 @@ module TTY
113
128
  self
114
129
  end
115
130
 
116
- # Start automatic spinning
117
- #
131
+ # Start automatic spinning animation
118
132
  #
119
133
  # @api public
120
134
  def start
121
135
  @started_at = Time.now
136
+ @done = false
122
137
  sleep_time = 1.0 / @interval
123
138
 
124
139
  @thread = Thread.new do
125
- while @started_at do
140
+ while @started_at
126
141
  spin
127
142
  sleep(sleep_time)
128
143
  end
129
144
  end
130
145
  end
131
146
 
147
+ # Run spinner while executing job
148
+ #
149
+ # @param [String] stop_message
150
+ # the message displayed when block is finished
151
+ #
152
+ # @yield automatically animate and finish spinner
153
+ #
154
+ # @example
155
+ # spinner.run('Migrated DB') { ... }
156
+ #
157
+ # @api public
158
+ def run(stop_message = nil, &block)
159
+ start
160
+ @work = Thread.new(&block)
161
+ @work.join
162
+ ensure
163
+ stop(stop_message)
164
+ end
165
+
132
166
  # Duration of the spinning animation
133
167
  #
134
168
  # @return [Numeric]
@@ -145,9 +179,9 @@ module TTY
145
179
  #
146
180
  # @api public
147
181
  def join(timeout = nil)
148
- fail NotSpinningError.new(
149
- "Cannot join spinner that is not running"
150
- ) unless @thread
182
+ unless @thread
183
+ raise(NotSpinningError, 'Cannot join spinner that is not running')
184
+ end
151
185
 
152
186
  timeout ? @thread.join(timeout) : @thread.join
153
187
  end
@@ -173,6 +207,7 @@ module TTY
173
207
  end
174
208
 
175
209
  data = message.gsub(MATCHER, @frames[@current])
210
+ data = replace_tokens(data)
176
211
  write(data, true)
177
212
  @current = (@current + 1) % @length
178
213
  @state = :spinning
@@ -186,30 +221,42 @@ module TTY
186
221
  #
187
222
  # @api public
188
223
  def stop(stop_message = '')
189
- if @hide_cursor && spinning?
224
+ return if @done
225
+
226
+ if @hide_cursor
190
227
  write(ECMA_CSI + DEC_TCEM + DEC_SET, false)
191
228
  end
192
- @done = true
193
- @started_at = nil
194
- emit(:done)
195
229
  return clear_line if @clear
196
230
 
197
- char = if success?
198
- @success_mark
199
- elsif error?
200
- @error_mark
201
- else
202
- @frames[@current - 1]
203
- end
204
- data = message.gsub(MATCHER, char)
205
-
231
+ data = message.gsub(MATCHER, next_char)
232
+ data = replace_tokens(data)
206
233
  if !stop_message.empty?
207
234
  data << ' ' + stop_message
208
235
  end
209
236
 
210
237
  write(data, true)
211
238
  write("\n", false) unless @clear
212
- reset
239
+ ensure
240
+ @state = :stopped
241
+ @done = true
242
+ @started_at = nil
243
+ emit(:done)
244
+ kill
245
+ end
246
+
247
+ # Retrieve next character
248
+ #
249
+ # @return [String]
250
+ #
251
+ # @api private
252
+ def next_char
253
+ if success?
254
+ @success_mark
255
+ elsif error?
256
+ @error_mark
257
+ else
258
+ @frames[@current - 1]
259
+ end
213
260
  end
214
261
 
215
262
  # Finish spinning and set state to :success
@@ -237,12 +284,21 @@ module TTY
237
284
  output.print(ECMA_CSI + '0m' + ECMA_CSI + '1000D' + ECMA_CSI + ECMA_CLR)
238
285
  end
239
286
 
287
+ # Update string formatting tokens
288
+ #
289
+ # @param [Hash[Symbol]] tokens
290
+ # the tokens used in formatting string
291
+ #
292
+ # @api public
293
+ def update(tokens)
294
+ @tokens.merge!(tokens)
295
+ end
296
+
240
297
  # Reset the spinner to initial frame
241
298
  #
242
299
  # @api public
243
300
  def reset
244
301
  @current = 0
245
- @state = :stopped
246
302
  end
247
303
 
248
304
  private
@@ -282,5 +338,21 @@ module TTY
282
338
  raise ArgumentError, "Unknown format token `:#{token}`"
283
339
  end
284
340
  end
341
+
342
+ # Replace any token inside string
343
+ #
344
+ # @param [String] string
345
+ # the string containing tokens
346
+ #
347
+ # @return [String]
348
+ #
349
+ # @api private
350
+ def replace_tokens(string)
351
+ data = string.dup
352
+ @tokens.each do |name, val|
353
+ data.gsub!(/\:#{name}/, val)
354
+ end
355
+ data
356
+ end
285
357
  end # Spinner
286
358
  end # TTY
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Spinner
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.0"
6
6
  end # Spinner
7
7
  end # TTY
metadata CHANGED
@@ -1,47 +1,47 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-spinner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.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: 2016-03-13 00:00:00.000000000 Z
11
+ date: 2016-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.5.0
20
- - - <
20
+ - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '2.0'
23
23
  type: :development
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - '>='
27
+ - - ">="
28
28
  - !ruby/object:Gem::Version
29
29
  version: 1.5.0
30
- - - <
30
+ - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '2.0'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rake
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - '>='
37
+ - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0'
40
40
  type: :development
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - '>='
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
47
  description: A terminal spinner for tasks that have non-deterministic time frame.
@@ -51,13 +51,13 @@ executables: []
51
51
  extensions: []
52
52
  extra_rdoc_files: []
53
53
  files:
54
- - lib/tty/spinner/formats.rb
55
- - lib/tty/spinner/version.rb
56
- - lib/tty/spinner.rb
57
- - lib/tty-spinner.rb
58
54
  - LICENSE.txt
59
55
  - README.md
60
- homepage: https://github.com/peter-murach/tty-spinner
56
+ - lib/tty-spinner.rb
57
+ - lib/tty/spinner.rb
58
+ - lib/tty/spinner/formats.rb
59
+ - lib/tty/spinner/version.rb
60
+ homepage: https://github.com/piotrmurach/tty-spinner
61
61
  licenses:
62
62
  - MIT
63
63
  metadata: {}
@@ -67,17 +67,17 @@ require_paths:
67
67
  - lib
68
68
  required_ruby_version: !ruby/object:Gem::Requirement
69
69
  requirements:
70
- - - '>='
70
+ - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: '0'
73
73
  required_rubygems_version: !ruby/object:Gem::Requirement
74
74
  requirements:
75
- - - '>='
75
+ - - ">="
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  requirements: []
79
79
  rubyforge_project:
80
- rubygems_version: 2.0.3
80
+ rubygems_version: 2.5.1
81
81
  signing_key:
82
82
  specification_version: 4
83
83
  summary: A terminal spinner for tasks that have non-deterministic time frame.