tty-spinner 0.2.0 → 0.3.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: 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.