progress 3.0.2 → 3.1.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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MTRkZThiZjMwMWU0ZmRiNGE4NDNmYTdiNWQyNjkxYmEzYjNjYjEzNA==
4
+ YmExNzc5ZGQ5Mzc1ZGQzY2Y4Zjg0N2ExNGMyZGNlNzQ0NDhmZTIyYQ==
5
5
  data.tar.gz: !binary |-
6
- ODhlNTFhZTNmMTdlNzI1MTUwN2YzZTU2ODk5OWI2YTAzZmZhYzAyZQ==
6
+ MThiNTU2Yzc1MTAzMGI3ZDY5M2UwNDBhZmZhOTM1ZWI0YzMyNDEyNg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NTNjMGYwYTYwODAxNWZkODE4MWY3ZmExZTNjNWRkMWEyZTFhMDZkMmJmNTUy
10
- M2EwMjRmYmVlNDQwMTliMmEzNTdjMGE0ZGVlMmE5Mjk5YjQ1MWEwZGUwZGVm
11
- YTg3OTFiZDBlMjFmMjY3ODFmMjYwNzk0YzZkZjc5YzMzOWI2NTY=
9
+ MjIxMGI1Y2Q3OGI1MzJhZDZmMzJmNTllZDFjMTE1ODhjZTM0OTliZWQwODhm
10
+ MDdmOWM1NWU5NGM2Y2I1OTFkMjJkYjdhZTE5ZmRlOThmZGNhZDdjYzRhYTJj
11
+ NGNjOTM2YmNkMjdiOThlYWE1ZDNhM2EyZWRhMTgyYTVjMjJlMGU=
12
12
  data.tar.gz: !binary |-
13
- NmI1NTEwOTNjNmFkMDc0OTYwNWE4MzI0ZTFiNzNmODQyM2FlYzEzMjE1YmY5
14
- NDljZDNjOWM5ZWFjZmViZGI0ODMwYmRiZGM0ZDNjNDcyNWMzZDgzNDk4OGQ2
15
- ZGQzODI3ZDVjYmJiZjZhZTZhN2Q0MWE3YTJlMzJmYWNlM2RmOTg=
13
+ ZmE3MDVkNDgxOTY4NmUxMGY1MjAzMjMwMzEwNTkwYmFhYzA3ZmExYjExZGZm
14
+ YjYyZDRiMzc4MDBjOGQ1ZWRiYWZjNDA2NzkwNDk4NjU5NTM0NjljNTE0MjM4
15
+ OTcxOGRlY2U4NjhmZWQzZDUyZDNlNzFkNDljZWIwOWQzYWVkZTI=
@@ -0,0 +1,65 @@
1
+ AllCops:
2
+ Exclude:
3
+ - '*.gemspec'
4
+
5
+ Lint/EndAlignment:
6
+ AlignWith: variable
7
+
8
+ Metrics/AbcSize:
9
+ Max: 30
10
+
11
+ Metrics/ClassLength:
12
+ Max: 150
13
+
14
+ Metrics/CyclomaticComplexity:
15
+ Max: 10
16
+
17
+ Metrics/MethodLength:
18
+ Max: 20
19
+
20
+ Metrics/PerceivedComplexity:
21
+ Max: 10
22
+
23
+ Style/AccessModifierIndentation:
24
+ EnforcedStyle: outdent
25
+
26
+ Style/BracesAroundHashParameters:
27
+ Enabled: false
28
+
29
+ Style/CaseIndentation:
30
+ IndentWhenRelativeTo: end
31
+
32
+ Style/DotPosition:
33
+ EnforcedStyle: trailing
34
+
35
+ Style/DoubleNegation:
36
+ Enabled: false
37
+
38
+ Style/Encoding:
39
+ EnforcedStyle: when_needed
40
+
41
+ Style/HashSyntax:
42
+ EnforcedStyle: hash_rockets
43
+
44
+ Style/IfUnlessModifier:
45
+ MaxLineLength: 40
46
+
47
+ Style/IndentHash:
48
+ EnforcedStyle: consistent
49
+
50
+ Style/PercentLiteralDelimiters:
51
+ PreferredDelimiters:
52
+ '%w': '[]'
53
+ '%W': '[]'
54
+
55
+ Style/Semicolon:
56
+ AllowAsExpressionSeparator: true
57
+
58
+ Style/SpaceBeforeBlockBraces:
59
+ EnforcedStyle: no_space
60
+
61
+ Style/SpaceInsideHashLiteralBraces:
62
+ EnforcedStyle: no_space
63
+
64
+ Style/TrailingComma:
65
+ EnforcedStyleForMultiline: comma
@@ -3,8 +3,19 @@ rvm:
3
3
  - 1.8.7
4
4
  - 1.9.2
5
5
  - 1.9.3
6
- - 2.0.0
6
+ - '2.0'
7
+ - '2.1'
7
8
  - jruby-18mode
8
9
  - jruby-19mode
9
10
  - ree
10
- script: "bundle exec rspec"
11
+ script:
12
+ if [ -z "$RUBOCOP" ]; then
13
+ bundle exec rspec
14
+ ; else
15
+ bundle exec rubocop
16
+ ; fi
17
+ matrix:
18
+ fast_finish: true
19
+ include:
20
+ - env: RUBOCOP=true
21
+ rvm: default
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
@@ -1,9 +1,13 @@
1
+ [![Gem Version](https://img.shields.io/gem/v/progress.svg?style=flat)](https://rubygems.org/gems/progress)
2
+ [![Build Status](https://img.shields.io/travis/toy/progress/master.svg?style=flat)](https://travis-ci.org/toy/progress)
3
+ [![Code Climate](https://img.shields.io/codeclimate/github/toy/progress.svg?style=flat)](https://codeclimate.com/github/toy/progress)
4
+ [![Dependency Status](https://img.shields.io/gemnasium/toy/progress.svg?style=flat)](https://gemnasium.com/toy/progress)
5
+ [![Inch CI](http://inch-ci.org/github/toy/progress.svg?branch=master&style=flat)](http://inch-ci.org/github/toy/progress)
6
+
1
7
  # progress
2
8
 
3
9
  Show progress during console script run.
4
10
 
5
- [![Build Status](https://travis-ci.org/toy/progress.png?branch=master)](https://travis-ci.org/toy/progress)
6
-
7
11
  ## Installation
8
12
 
9
13
  gem install progress
@@ -3,6 +3,15 @@
3
3
  require 'singleton'
4
4
  require 'thread'
5
5
 
6
+ require 'progress/class_methods'
7
+ require 'progress/beeper'
8
+ require 'progress/eta'
9
+
10
+ require 'progress/kernel'
11
+ require 'progress/enumerable'
12
+ require 'progress/integer'
13
+ require 'progress/active_record' if defined?(ActiveRecord::Base)
14
+
6
15
  # ==== Procedural example
7
16
  # Progress.start('Test', 1000)
8
17
  # 1000.times do
@@ -36,13 +45,14 @@ require 'thread'
36
45
  # end
37
46
  class Progress
38
47
  include Singleton
48
+ extend ClassMethods
39
49
 
40
50
  attr_reader :total
41
51
  attr_reader :current
42
52
  attr_reader :title
43
53
  attr_accessor :note
44
54
  def initialize(total, title)
45
- if !total.kind_of?(Numeric) && (title.nil? || title.kind_of?(Numeric))
55
+ if !total.is_a?(Numeric) && (title.nil? || title.is_a?(Numeric))
46
56
  total, title = title, total
47
57
  end
48
58
  total = total && total != 0 ? Float(total) : 1.0
@@ -59,7 +69,7 @@ class Progress
59
69
  end
60
70
 
61
71
  def step(step, note)
62
- if !step.kind_of?(Numeric)
72
+ unless step.is_a?(Numeric)
63
73
  step, note = nil, step
64
74
  end
65
75
  step = 1 if step.nil?
@@ -82,223 +92,4 @@ class Progress
82
92
  end
83
93
  ret
84
94
  end
85
-
86
- @lock = Mutex.new
87
- class << self
88
-
89
- # start progress indication
90
- def start(total = nil, title = nil)
91
- lock do
92
- if running?
93
- unless @started_in == Thread.current
94
- warn 'Can\'t start inner progress in different thread'
95
- if block_given?
96
- return yield
97
- else
98
- return
99
- end
100
- end
101
- else
102
- @started_in = Thread.current
103
- @eta = Eta.new
104
- start_beeper
105
- end
106
- @levels ||= []
107
- @levels.push new(total, title)
108
- end
109
- print_message :force => true
110
- if block_given?
111
- begin
112
- yield
113
- ensure
114
- stop
115
- end
116
- end
117
- end
118
-
119
- # step current progress
120
- def step(step = nil, note = nil, &block)
121
- if running?
122
- ret = @levels.last.step(step, note, &block)
123
- print_message
124
- ret
125
- elsif block
126
- block.call
127
- end
128
- end
129
-
130
- # set value of current progress
131
- def set(new_current, note = nil, &block)
132
- if running?
133
- ret = @levels.last.set(new_current, note, &block)
134
- print_message
135
- ret
136
- elsif block
137
- block.call
138
- end
139
- end
140
-
141
- # stop progress
142
- def stop
143
- if running?
144
- if @levels.length == 1
145
- print_message :force => true, :finish => true
146
- stop_beeper
147
- end
148
- @levels.pop
149
- end
150
- end
151
-
152
- # check if progress was started
153
- def running?
154
- @levels && !@levels.empty?
155
- end
156
-
157
- # set note
158
- def note=(note)
159
- if running?
160
- @levels.last.note = note
161
- end
162
- end
163
-
164
- # stay on one line
165
- def stay_on_line?
166
- @stay_on_line.nil? ? io_tty? : @stay_on_line
167
- end
168
-
169
- # explicitly set staying on one line [true/false/nil]
170
- def stay_on_line=(value)
171
- @stay_on_line = true && value
172
- end
173
-
174
- # highlight output using control characters
175
- def highlight?
176
- @highlight.nil? ? io_tty? : @highlight
177
- end
178
-
179
- # explicitly set highlighting [true/false/nil]
180
- def highlight=(value)
181
- @highlight = true && value
182
- end
183
-
184
- # show progerss in terminal title
185
- def set_terminal_title?
186
- @set_terminal_title.nil? ? io_tty? : @set_terminal_title
187
- end
188
-
189
- # explicitly set showing progress in terminal title [true/false/nil]
190
- def set_terminal_title=(value)
191
- @set_terminal_title = true && value
192
- end
193
-
194
- private
195
-
196
- def lock(force = true)
197
- if force ? @lock.lock : @lock.try_lock
198
- begin
199
- yield
200
- ensure
201
- @lock.unlock
202
- end
203
- end
204
- end
205
-
206
- def io
207
- @io || $stderr
208
- end
209
-
210
- def io_tty?
211
- io.tty? || ENV['PROGRESS_TTY']
212
- end
213
-
214
- def start_beeper
215
- @beeper = Beeper.new(10) do
216
- print_message
217
- end
218
- end
219
-
220
- def stop_beeper
221
- @beeper.stop if @beeper
222
- end
223
-
224
- def restart_beeper
225
- @beeper.restart if @beeper
226
- end
227
-
228
- def time_to_print?
229
- !@next_time_to_print || @next_time_to_print <= Time.now
230
- end
231
-
232
- def eta(current)
233
- @eta.left(current)
234
- end
235
-
236
- def elapsed
237
- @eta.elapsed
238
- end
239
-
240
- def print_message(options = {})
241
- force = options[:force]
242
- lock force do
243
- if force || time_to_print?
244
- @next_time_to_print = Time.now + 0.3
245
- restart_beeper
246
-
247
- current = 0
248
- parts = []
249
- title_parts = []
250
- @levels.reverse.each do |level|
251
- current = level.to_f(current)
252
-
253
- percent = current == 0 ? '......' : "#{'%5.1f' % (current * 100.0)}%"
254
- title = level.title && "#{level.title}: "
255
- if !highlight? || percent == '100.0%'
256
- parts << "#{title}#{percent}"
257
- else
258
- parts << "#{title}\e[1m#{percent}\e[0m"
259
- end
260
- title_parts << "#{title}#{percent}"
261
- end
262
-
263
- timing = if options[:finish]
264
- " (elapsed: #{elapsed})"
265
- elsif eta_ = eta(current)
266
- " (ETA: #{eta_})"
267
- end
268
-
269
- message = "#{parts.reverse * ' > '}#{timing}"
270
- text_message = "#{title_parts.reverse * ' > '}#{timing}"
271
-
272
- if note = running? && @levels.last.note
273
- message << " - #{note}"
274
- text_message << " - #{note}"
275
- end
276
-
277
- message = "\r#{message}\e[K" if stay_on_line?
278
- message << "\n" if !stay_on_line? || options[:finish]
279
- io << message
280
-
281
- if set_terminal_title?
282
- title = options[:finish] ? nil : text_message.to_s.gsub("\a", '␇')
283
- io << "\e]0;#{title}\a"
284
- end
285
- end
286
- end
287
- end
288
-
289
- end
290
- end
291
-
292
- require 'progress/beeper'
293
- require 'progress/eta'
294
-
295
- require 'progress/enumerable'
296
- require 'progress/integer'
297
- require 'progress/active_record' if defined?(ActiveRecord::Base)
298
-
299
- module Kernel
300
- def Progress(*args, &block)
301
- Progress.start(*args, &block)
302
- end
303
- private :Progress
304
95
  end
@@ -1,7 +1,9 @@
1
1
  require 'progress'
2
2
 
3
3
  module ActiveRecord
4
- module BatchesWithProgress
4
+ # Add find_each_with_progress and find_in_batches_with_progress method to
5
+ # ActiveRecord::Base
6
+ class Base
5
7
  # run `find_each` with progress
6
8
  def find_each_with_progress(options = {})
7
9
  Progress.start(name.tableize, count(options)) do
@@ -24,8 +26,4 @@ module ActiveRecord
24
26
  end
25
27
  end
26
28
  end
27
-
28
- class Base
29
- extend BatchesWithProgress
30
- end
31
29
  end
@@ -1,4 +1,5 @@
1
1
  class Progress
2
+ # Repeatedly run block of code after time interval
2
3
  class Beeper
3
4
  def initialize(time, &block)
4
5
  @thread = Thread.new do
@@ -0,0 +1,214 @@
1
+ # encoding: UTF-8
2
+
3
+ class Progress
4
+ # Class methods of Progress
5
+ module ClassMethods
6
+ def self.extended(klass)
7
+ klass.instance_variable_set(:@lock, Mutex.new)
8
+ end
9
+
10
+ # start progress indication
11
+ def start(total = nil, title = nil)
12
+ init(total, title)
13
+ print_message :force => true
14
+ return unless block_given?
15
+ begin
16
+ yield
17
+ ensure
18
+ stop
19
+ end
20
+ end
21
+
22
+ # step current progress
23
+ def step(step = nil, note = nil, &block)
24
+ if running?
25
+ ret = @levels.last.step(step, note, &block)
26
+ print_message
27
+ ret
28
+ elsif block
29
+ block.call
30
+ end
31
+ end
32
+
33
+ # set value of current progress
34
+ def set(new_current, note = nil, &block)
35
+ if running?
36
+ ret = @levels.last.set(new_current, note, &block)
37
+ print_message
38
+ ret
39
+ elsif block
40
+ block.call
41
+ end
42
+ end
43
+
44
+ # stop progress
45
+ def stop
46
+ return unless running?
47
+ if @levels.length == 1
48
+ print_message :force => true, :finish => true
49
+ stop_beeper
50
+ end
51
+ @levels.pop
52
+ end
53
+
54
+ # check if progress was started
55
+ def running?
56
+ @levels && !@levels.empty?
57
+ end
58
+
59
+ # set note
60
+ def note=(note)
61
+ return unless running?
62
+ @levels.last.note = note
63
+ end
64
+
65
+ # stay on one line
66
+ def stay_on_line?
67
+ @stay_on_line.nil? ? io_tty? : @stay_on_line
68
+ end
69
+
70
+ # explicitly set staying on one line [true/false/nil]
71
+ def stay_on_line=(value)
72
+ @stay_on_line = true && value
73
+ end
74
+
75
+ # highlight output using control characters
76
+ def highlight?
77
+ @highlight.nil? ? io_tty? : @highlight
78
+ end
79
+
80
+ # explicitly set highlighting [true/false/nil]
81
+ def highlight=(value)
82
+ @highlight = true && value
83
+ end
84
+
85
+ # show progerss in terminal title
86
+ def terminal_title?
87
+ @terminal_title.nil? ? io_tty? : @terminal_title
88
+ end
89
+
90
+ # explicitly set showing progress in terminal title [true/false/nil]
91
+ def terminal_title=(value)
92
+ @terminal_title = true && value
93
+ end
94
+
95
+ private
96
+
97
+ attr_reader :eta
98
+
99
+ def init(total = nil, title = nil)
100
+ lock do
101
+ if running?
102
+ unless @started_in == Thread.current
103
+ warn 'Can\'t start inner progress in different thread'
104
+ return block_given? ? yield : nil
105
+ end
106
+ else
107
+ @started_in = Thread.current
108
+ @eta = Eta.new
109
+ start_beeper
110
+ end
111
+ @levels ||= []
112
+ @levels.push new(total, title)
113
+ end
114
+ end
115
+
116
+ def lock(force = true)
117
+ if force
118
+ @lock.lock
119
+ else
120
+ return unless @lock.try_lock
121
+ end
122
+
123
+ begin
124
+ yield
125
+ ensure
126
+ @lock.unlock
127
+ end
128
+ end
129
+
130
+ def io
131
+ @io || $stderr
132
+ end
133
+
134
+ def io_tty?
135
+ io.tty? || ENV['PROGRESS_TTY']
136
+ end
137
+
138
+ def start_beeper
139
+ @beeper = Beeper.new(10) do
140
+ print_message
141
+ end
142
+ end
143
+
144
+ def stop_beeper
145
+ @beeper.stop if @beeper
146
+ end
147
+
148
+ def restart_beeper
149
+ @beeper.restart if @beeper
150
+ end
151
+
152
+ def time_to_print?
153
+ !@next_time_to_print || @next_time_to_print <= Time.now
154
+ end
155
+
156
+ def print_message(options = {})
157
+ force = options[:force]
158
+ lock force do
159
+ if force || time_to_print?
160
+ @next_time_to_print = Time.now + 0.3
161
+ restart_beeper
162
+ io << message_for_output(options)
163
+ end
164
+ end
165
+ end
166
+
167
+ def message_for_output(options)
168
+ message = build_message(options)
169
+
170
+ out = ''
171
+ out << "\r" if stay_on_line?
172
+ out << message
173
+ out << "\e[K" if stay_on_line?
174
+ out << "\n" if !stay_on_line? || options[:finish]
175
+
176
+ if terminal_title?
177
+ out << "\e]0;"
178
+ unless options[:finish]
179
+ out << message.gsub(/\e\[\dm/, '').gsub("\a", '␇')
180
+ end
181
+ out << "\a"
182
+ end
183
+
184
+ out
185
+ end
186
+
187
+ def build_message(options)
188
+ current = 0
189
+ message = @levels.reverse.map do |level|
190
+ current = level.to_f(current)
191
+
192
+ part = current.zero? ? '......' : format('%5.1f%%', current * 100.0)
193
+
194
+ if highlight? && part != '100.0%'
195
+ part = "\e[1m#{part}\e[0m"
196
+ end
197
+
198
+ level.title ? "#{level.title}: #{part}" : part
199
+ end.reverse * ' > '
200
+
201
+ if options[:finish]
202
+ message << " (elapsed: #{eta.elapsed})"
203
+ elsif (left = eta.left(current))
204
+ message << " (ETA: #{left})"
205
+ end
206
+
207
+ if running? && (note = @levels.last.note)
208
+ message << " - #{note}"
209
+ end
210
+
211
+ message
212
+ end
213
+ end
214
+ end