progress 0.4.1 → 1.0.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 1.0.0
data/lib/progress.rb CHANGED
@@ -12,17 +12,22 @@ class Progress
12
12
  elsif total.nil?
13
13
  total = 1
14
14
  end
15
- total = Float(total)
16
- @title, @current, @total = title, 0.0, total == 0.0 ? 1.0 : total
15
+ @title = title
16
+ @current = 0.0
17
+ @total = total == 0.0 ? 1.0 : Float(total)
17
18
  end
18
19
 
19
20
  def step_if_blank
20
- self.current = 1.0 if current == 0.0 && total == 1.0
21
+ if current == 0.0 && total == 1.0
22
+ self.current = 1.0
23
+ end
21
24
  end
22
25
 
23
26
  def to_f(inner)
24
27
  inner = [inner, 1.0].min
25
- inner *= current_step if current_step
28
+ if current_step
29
+ inner *= current_step
30
+ end
26
31
  (current + inner) / total
27
32
  end
28
33
 
@@ -65,6 +70,10 @@ class Progress
65
70
  # ==== To force highlight
66
71
  # Progress.highlight = true
67
72
  def start(title = nil, total = nil)
73
+ if levels.empty?
74
+ @started_at = Time.now
75
+ @eta = nil
76
+ end
68
77
  levels << new(title, total)
69
78
  print_message(true)
70
79
  if block_given?
@@ -76,32 +85,37 @@ class Progress
76
85
  end
77
86
  end
78
87
 
79
- def step(steps = 1)
88
+ def step(steps = 1, &block)
80
89
  if levels.last
81
- if block_given?
82
- levels.last.step(steps) do
83
- yield
84
- end
85
- end
86
- levels.last.current += Float(steps)
87
- print_message
88
- elsif block_given?
89
- yield
90
+ set(levels.last.current + Float(steps), &block)
91
+ elsif block
92
+ block.call
90
93
  end
91
94
  end
92
95
 
93
- def set(value)
96
+ def set(value, &block)
94
97
  if levels.last
98
+ ret = if block
99
+ levels.last.step(value - levels.last.current, &block)
100
+ end
95
101
  levels.last.current = Float(value)
96
102
  print_message
103
+ ret
104
+ elsif block
105
+ block.call
97
106
  end
98
107
  end
99
108
 
100
109
  def stop
101
110
  if levels.last
102
- print_message(true) if levels.last.step_if_blank || levels.length == 1
111
+ if levels.last.step_if_blank || levels.length == 1
112
+ print_message(true)
113
+ set_title(nil)
114
+ end
103
115
  levels.pop
104
- io.puts if levels.empty?
116
+ if levels.empty?
117
+ io.puts
118
+ end
105
119
  end
106
120
  end
107
121
 
@@ -134,43 +148,72 @@ class Progress
134
148
  end
135
149
 
136
150
  def time_to_print?
137
- if @previous
138
- if @previous < Time.now - 0.3
139
- @previous = Time.now
140
- true
141
- else
142
- false
143
- end
144
- else
151
+ if !@previous || @previous < Time.now - 0.3
145
152
  @previous = Time.now
146
153
  true
147
154
  end
148
155
  end
149
156
 
157
+ def eta(completed)
158
+ now = Time.now
159
+ if now > @started_at && completed > 0
160
+ current_eta = @started_at + (now - @started_at) / completed
161
+ @eta = @eta ? @eta + (current_eta - @eta) * (1 + completed) * 0.5 : current_eta
162
+ seconds = @eta - now
163
+ if seconds > 0
164
+ left = case seconds
165
+ when 0...60
166
+ '%.0fs' % seconds
167
+ when 60...3600
168
+ '%.1fm' % (seconds / 60)
169
+ when 3600...86400
170
+ '%.1fh' % (seconds / 3600)
171
+ else
172
+ '%.1fd' % (seconds / 86400)
173
+ end
174
+ eta_string = " (ETA: #{left})"
175
+ end
176
+ end
177
+ end
178
+
179
+ def set_title(title)
180
+ if io_tty?
181
+ io.print("\e]0;#{title}\a")
182
+ end
183
+ end
184
+
150
185
  def print_message(force = false)
151
186
  if force || time_to_print?
152
- messages = []
153
187
  inner = 0
188
+ parts = []
189
+ parts_cl = []
154
190
  levels.reverse.each do |l|
155
191
  current = l.to_f(inner)
156
192
  value = current == 0 ? '......' : "#{'%5.1f' % (current * 100.0)}%"
157
- messages << "#{"#{l.title}: " if l.title}#{!highlight? || value == '100.0%' ? value : "\e[1m#{value}\e[0m"}"
158
193
  inner = current
194
+
195
+ title = l.title ? "#{l.title}: " : ''
196
+ highlighted = "\e[1m#{value}\e[0m"
197
+ if !highlight? || value == '100.0%'
198
+ parts << "#{title}#{value}"
199
+ else
200
+ parts << "#{title}#{highlighted}"
201
+ end
202
+ parts_cl << "#{title}#{value}"
159
203
  end
160
- message = messages.reverse * ' > '
204
+
205
+ eta_string = eta(inner)
206
+ message = "#{parts.reverse * ' > '}#{eta_string}"
207
+ message_cl = "#{parts_cl.reverse * ' > '}#{eta_string}"
161
208
 
162
209
  unless lines?
163
210
  previous_length = @previous_length || 0
164
- message_cl = if highlight?
165
- message.gsub(/\033\[(0|1)m/, '')
166
- else
167
- message
168
- end
169
211
  @previous_length = message_cl.length
170
212
  message = "#{message}#{' ' * [previous_length - message_cl.length, 0].max}\r"
171
213
  end
172
214
 
173
215
  lines? ? io.puts(message) : io.print(message)
216
+ set_title(message_cl)
174
217
  end
175
218
  end
176
219
  end
data/progress.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{progress}
8
- s.version = "0.4.1"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Boba Fat"]
12
- s.date = %q{2010-11-13}
12
+ s.date = %q{2010-11-14}
13
13
  s.extra_rdoc_files = [
14
14
  "README.rdoc"
15
15
  ]
@@ -15,6 +15,10 @@ describe Progress do
15
15
  s
16
16
  end
17
17
 
18
+ def io_pop_no_eta
19
+ io_pop.sub(/ \(ETA: \d+.\)$/, '')
20
+ end
21
+
18
22
  def verify_output_before_step(i)
19
23
  io_pop.should =~ /#{Regexp.quote(i == 0 ? '......' : (i / 10.0).to_s)}/
20
24
  end
@@ -109,6 +113,18 @@ describe Progress do
109
113
  end.should == 'qwerty'
110
114
  end
111
115
 
116
+ it "should return result from step" do
117
+ Progress.start do
118
+ Progress.step{ 'qwerty' }.should == 'qwerty'
119
+ end
120
+ end
121
+
122
+ it "should return result from set" do
123
+ Progress.start do
124
+ Progress.set(1){ 'qwerty' }.should == 'qwerty'
125
+ end
126
+ end
127
+
112
128
  it "should return result from nested block" do
113
129
  [1, 2, 3].with_progress('a').map do |a|
114
130
  [1, 2, 3].with_progress('b').map do |b|
@@ -132,28 +148,28 @@ describe Progress do
132
148
  end
133
149
  end
134
150
 
135
- [[2, 2000], [20, 200], [200, 20], [2000, 2]].each do |_a, _b|
151
+ [[2, 200], [20, 20], [200, 2]].each do |_a, _b|
136
152
  it "should allow enclosed progress [#{_a}, #{_b}]" do
137
153
  _a.times_with_progress('A') do |a|
138
- io_pop.should == "A: #{a == 0 ? '......' : '%5.1f%%'}\n" % [a / _a.to_f * 100.0]
154
+ io_pop_no_eta.should == "A: #{a == 0 ? '......' : '%5.1f%%'}\n" % [a / _a.to_f * 100.0]
139
155
  _b.times_with_progress('B') do |b|
140
- io_pop.should == "A: #{a == 0 && b == 0 ? '......' : '%5.1f%%'} > B: #{b == 0 ? '......' : '%5.1f%%'}\n" % [(a + b / _b.to_f) / _a.to_f * 100.0, b / _b.to_f * 100.0]
156
+ io_pop_no_eta.should == "A: #{a == 0 && b == 0 ? '......' : '%5.1f%%'} > B: #{b == 0 ? '......' : '%5.1f%%'}\n" % [(a + b / _b.to_f) / _a.to_f * 100.0, b / _b.to_f * 100.0]
141
157
  end
142
- io_pop.should == "A: %5.1f%% > B: 100.0%%\n" % [(a + 1) / _a.to_f * 100.0]
158
+ io_pop_no_eta.should == "A: %5.1f%% > B: 100.0%%\n" % [(a + 1) / _a.to_f * 100.0]
143
159
  end
144
160
  io_pop.should == "A: 100.0%\nA: 100.0%\n\n"
145
161
  end
146
162
 
147
163
  it "should not overlap outer progress if inner exceeds [#{_a}, #{_b}]" do
148
164
  _a.times_with_progress('A') do |a|
149
- io_pop.should == "A: #{a == 0 ? '......' : '%5.1f%%'}\n" % [a / _a.to_f * 100.0]
165
+ io_pop_no_eta.should == "A: #{a == 0 ? '......' : '%5.1f%%'}\n" % [a / _a.to_f * 100.0]
150
166
  Progress.start('B', _b) do
151
167
  (_b * 2).times do |b|
152
- io_pop.should == "A: #{a == 0 && b == 0 ? '......' : '%5.1f%%'} > B: #{b == 0 ? '......' : '%5.1f%%'}\n" % [(a + [b / _b.to_f, 1].min) / _a.to_f * 100.0, b / _b.to_f * 100.0]
168
+ io_pop_no_eta.should == "A: #{a == 0 && b == 0 ? '......' : '%5.1f%%'} > B: #{b == 0 ? '......' : '%5.1f%%'}\n" % [(a + [b / _b.to_f, 1].min) / _a.to_f * 100.0, b / _b.to_f * 100.0]
153
169
  Progress.step
154
170
  end
155
171
  end
156
- io_pop.should == "A: %5.1f%% > B: 200.0%%\n" % [(a + 1) / _a.to_f * 100.0]
172
+ io_pop_no_eta.should == "A: %5.1f%% > B: 200.0%%\n" % [(a + 1) / _a.to_f * 100.0]
157
173
  end
158
174
  io_pop.should == "A: 100.0%\nA: 100.0%\n\n"
159
175
  end
@@ -161,15 +177,15 @@ describe Progress do
161
177
  it "should allow step with block to validly count custom progresses [#{_a}, #{_b}]" do
162
178
  a_step = 99
163
179
  Progress.start('A', _a * 100) do
164
- io_pop.should == "A: ......\n"
180
+ io_pop_no_eta.should == "A: ......\n"
165
181
  _a.times do |a|
166
182
  Progress.step(a_step) do
167
183
  _b.times_with_progress('B') do |b|
168
- io_pop.should == "A: #{a == 0 && b == 0 ? '......' : '%5.1f%%'} > B: #{b == 0 ? '......' : '%5.1f%%'}\n" % [(a * a_step + b / _b.to_f * a_step) / (_a * 100).to_f * 100.0, b / _b.to_f * 100.0]
184
+ io_pop_no_eta.should == "A: #{a == 0 && b == 0 ? '......' : '%5.1f%%'} > B: #{b == 0 ? '......' : '%5.1f%%'}\n" % [(a * a_step + b / _b.to_f * a_step) / (_a * 100).to_f * 100.0, b / _b.to_f * 100.0]
169
185
  end
170
- io_pop.should == "A: %5.1f%% > B: 100.0%\n" % [(a + 1) * a_step.to_f / (100.0 * _a.to_f) * 100.0]
186
+ io_pop_no_eta.should == "A: %5.1f%% > B: 100.0%\n" % [(a + 1) * a_step.to_f / (100.0 * _a.to_f) * 100.0]
171
187
  end
172
- io_pop.should == "A: %5.1f%%\n" % [(a + 1) * a_step.to_f / (100.0 * _a.to_f) * 100.0]
188
+ io_pop_no_eta.should == "A: %5.1f%%\n" % [(a + 1) * a_step.to_f / (100.0 * _a.to_f) * 100.0]
173
189
  end
174
190
  Progress.step _a
175
191
  end
@@ -178,12 +194,6 @@ describe Progress do
178
194
  end
179
195
  end
180
196
 
181
-
182
-
183
-
184
-
185
-
186
-
187
197
  describe Enumerable do
188
198
  before :each do
189
199
  @a = (0...1000).to_a
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: progress
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
- - 0
8
- - 4
9
7
  - 1
10
- version: 0.4.1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Boba Fat
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-13 00:00:00 +03:00
18
+ date: 2010-11-14 00:00:00 +03:00
19
19
  default_executable:
20
20
  dependencies: []
21
21