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 +1 -1
- data/lib/progress.rb +76 -33
- data/progress.gemspec +2 -2
- data/spec/progress_spec.rb +27 -17
- metadata +5 -5
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
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
|
-
|
16
|
-
@
|
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
|
-
|
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
|
-
|
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
|
-
|
82
|
-
|
83
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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-
|
12
|
+
s.date = %q{2010-11-14}
|
13
13
|
s.extra_rdoc_files = [
|
14
14
|
"README.rdoc"
|
15
15
|
]
|
data/spec/progress_spec.rb
CHANGED
@@ -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,
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
|
-
- 0
|
8
|
-
- 4
|
9
7
|
- 1
|
10
|
-
|
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-
|
18
|
+
date: 2010-11-14 00:00:00 +03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|