progress-monitor 2.0.2 → 2.1.2
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/lib/progress-bar.rb +77 -0
- data/lib/progress-monitor.rb +169 -238
- metadata +20 -7
data/lib/progress-bar.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
module Progress
|
2
|
+
class Progress::Bar
|
3
|
+
|
4
|
+
# Creates a new instance. Max is the total number of iterations of the
|
5
|
+
# loop. The depth represents how many other loops are above this one,
|
6
|
+
# this information is used to find the place to print the progress
|
7
|
+
# report.
|
8
|
+
#
|
9
|
+
def initialize(max,depth, num_reports, desc)
|
10
|
+
@max = max
|
11
|
+
@max = 1 if @max < 1
|
12
|
+
@current = 0
|
13
|
+
@time = Time.now
|
14
|
+
@last_report = -1
|
15
|
+
@num_reports = num_reports
|
16
|
+
@depth = depth
|
17
|
+
@desc = desc
|
18
|
+
end
|
19
|
+
|
20
|
+
# Used to register a new completed loop iteration.
|
21
|
+
#
|
22
|
+
def tick(step = nil)
|
23
|
+
|
24
|
+
if step.nil?
|
25
|
+
@current += 1
|
26
|
+
else
|
27
|
+
@current = step
|
28
|
+
end
|
29
|
+
|
30
|
+
percent = @current.to_f/ @max.to_f
|
31
|
+
if percent - @last_report > 1.to_f/@num_reports.to_f
|
32
|
+
report
|
33
|
+
@last_report=percent
|
34
|
+
end
|
35
|
+
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# Prints de progress report. It backs up as many lines as the meters
|
40
|
+
# depth. Prints the progress as a line of dots, a percentage, time
|
41
|
+
# spent, and time left. And then goes moves the cursor back to its
|
42
|
+
# original line. Everything is printed to stderr.
|
43
|
+
#
|
44
|
+
def report
|
45
|
+
|
46
|
+
percent = @current.to_f/ @max.to_f
|
47
|
+
percent = 0.001 if percent < 0.001
|
48
|
+
if @desc != ""
|
49
|
+
indicator = @desc + ": "
|
50
|
+
else
|
51
|
+
indicator = "Progress "
|
52
|
+
end
|
53
|
+
indicator += "["
|
54
|
+
10.times{|i|
|
55
|
+
if i < percent * 10 then
|
56
|
+
indicator += "."
|
57
|
+
else
|
58
|
+
indicator += " "
|
59
|
+
end
|
60
|
+
}
|
61
|
+
indicator += "] done #{(percent * 100).to_i}% "
|
62
|
+
|
63
|
+
eta = (Time.now - @time)/percent * (1-percent)
|
64
|
+
eta = eta.to_i
|
65
|
+
eta = [eta/3600, eta/60 % 60, eta % 60].map{|t| t.to_s.rjust(2, '0')}.join(':')
|
66
|
+
|
67
|
+
used = (Time.now - @time).to_i
|
68
|
+
used = [used/3600, used/60 % 60, used % 60].map{|t| t.to_s.rjust(2, '0')}.join(':')
|
69
|
+
|
70
|
+
indicator += " (Time left #{eta} seconds) (Started #{used} seconds ago)"
|
71
|
+
|
72
|
+
STDERR.print("\033[#{@depth + 1}F\033[2K" + indicator + "\n\033[#{@depth + 2}E")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
data/lib/progress-monitor.rb
CHANGED
@@ -6,247 +6,178 @@
|
|
6
6
|
# License:: MIT
|
7
7
|
#
|
8
8
|
|
9
|
+
require 'progress-bar'
|
10
|
+
|
9
11
|
# Tracks the progress of a loop. It holds information about how many
|
10
12
|
# iterations it has to go through and how many have been executed
|
11
13
|
# already. Every now and then, it prints the progress report.
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
@max = max
|
180
|
-
@max = 1 if @max < 1
|
181
|
-
@current = 0
|
182
|
-
@time = Time.now
|
183
|
-
@last_report = -1
|
184
|
-
@num_reports = @@num_reports
|
185
|
-
@depth = depth
|
186
|
-
@desc = @@desc
|
187
|
-
@@monitor = false
|
188
|
-
end
|
189
|
-
|
190
|
-
# Used to register a new completed loop iteration.
|
191
|
-
#
|
192
|
-
def tick(step = nil)
|
193
|
-
|
194
|
-
if step.nil?
|
195
|
-
@current += 1
|
196
|
-
else
|
197
|
-
@current = step
|
198
|
-
end
|
199
|
-
|
200
|
-
percent = @current.to_f/ @max.to_f
|
201
|
-
if percent - @last_report > 1.to_f/@num_reports.to_f
|
202
|
-
report
|
203
|
-
@last_report=percent
|
204
|
-
end
|
205
|
-
|
206
|
-
nil
|
207
|
-
end
|
208
|
-
|
209
|
-
# Prints de progress report. It backs up as many lines as the meters
|
210
|
-
# depth. Prints the progress as a line of dots, a percentage, time
|
211
|
-
# spent, and time left. And then goes moves the cursor back to its
|
212
|
-
# original line. Everything is printed to stderr.
|
213
|
-
#
|
214
|
-
def report
|
215
|
-
|
216
|
-
percent = @current.to_f/ @max.to_f
|
217
|
-
percent = 0.001 if percent < 0.001
|
218
|
-
if @desc != ""
|
219
|
-
indicator = @desc + ": "
|
220
|
-
else
|
221
|
-
indicator = "Progress "
|
222
|
-
end
|
223
|
-
indicator += "["
|
224
|
-
10.times{|i|
|
225
|
-
if i < percent * 10 then
|
226
|
-
indicator += "."
|
227
|
-
else
|
228
|
-
indicator += " "
|
229
|
-
end
|
230
|
-
}
|
231
|
-
indicator += "] done #{(percent * 100).to_i}% "
|
232
|
-
|
233
|
-
eta = (Time.now - @time)/percent * (1-percent)
|
234
|
-
eta = eta.to_i
|
235
|
-
eta = [eta/3600, eta/60 % 60, eta % 60].map{|t| t.to_s.rjust(2, '0')}.join(':')
|
236
|
-
|
237
|
-
used = (Time.now - @time).to_i
|
238
|
-
used = [used/3600, used/60 % 60, used % 60].map{|t| t.to_s.rjust(2, '0')}.join(':')
|
239
|
-
|
240
|
-
indicator += " (Time left #{eta} seconds) (Started #{used} seconds ago)"
|
241
|
-
|
242
|
-
$stderr.print("\033[#{@depth + 1}F\033[2K" + indicator + "\033[#{@depth + 1}E")
|
243
|
-
end
|
244
|
-
|
245
|
-
def self.print_announcement(message = nil)
|
246
|
-
return if message.nil?
|
247
|
-
total_depth = @@progress_meters.length + 1
|
248
|
-
$stderr.print("\033[#{total_depth}F\033[2K" + message + "\033[#{total_depth}E")
|
249
|
-
end
|
14
|
+
module Progress
|
15
|
+
|
16
|
+
module Progress::MonitorableProgress
|
17
|
+
|
18
|
+
def monitorable1(method_name)
|
19
|
+
module_eval{
|
20
|
+
orig_name = ('orig_' + method_name.to_s).to_sym
|
21
|
+
|
22
|
+
eval "alias #{ orig_name } #{ method_name }"
|
23
|
+
|
24
|
+
define_method(method_name) do |&block|
|
25
|
+
if Progress.active?
|
26
|
+
progress_meter = Progress.add_progress_meter(self.monitor_size) if Progress.monitor?
|
27
|
+
announcement = Progress.get_announcement if Progress.announce?
|
28
|
+
|
29
|
+
monitor_step = nil unless defined? monitor_step
|
30
|
+
|
31
|
+
res = self.send(orig_name.to_sym) {|v|
|
32
|
+
progress_meter.tick(monitor_step) if progress_meter
|
33
|
+
Progress.print_announcement(announcement.call(v)) if announcement
|
34
|
+
block.call(v)
|
35
|
+
}
|
36
|
+
|
37
|
+
Progress.remove_last_meter
|
38
|
+
res
|
39
|
+
else
|
40
|
+
self.send(orig_name.to_sym) {|v| block.call(v)}
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def monitorable2(method_name)
|
48
|
+
module_eval{
|
49
|
+
orig_name = ('orig_' + method_name.to_s).to_sym
|
50
|
+
|
51
|
+
eval "alias #{ orig_name } #{ method_name }"
|
52
|
+
|
53
|
+
define_method(method_name) do |&block|
|
54
|
+
if Progress.active?
|
55
|
+
progress_meter = Progress.add_progress_meter(self.monitor_size) if Progress.monitor?
|
56
|
+
announcement = Progress.get_announcement if Progress.announce?
|
57
|
+
|
58
|
+
monitor_step = nil unless defined? monitor_step
|
59
|
+
|
60
|
+
res = self.send(orig_name.to_sym) {|v1,v2|
|
61
|
+
progress_meter.tick(monitor_step) if progress_meter
|
62
|
+
Progress.print_announcement(announcement.call(v1,v2)) if announcement
|
63
|
+
block.call(v1,v2);
|
64
|
+
}
|
65
|
+
|
66
|
+
Progress.remove_last_meter
|
67
|
+
res
|
68
|
+
else
|
69
|
+
self.send(orig_name.to_sym) {|v1,v2| block.call(v1,v2) }
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
@@progress_meters = Array.new
|
79
|
+
def self.progress_meters
|
80
|
+
@@progress_meters
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.caller_info(callers, depth = 0)
|
84
|
+
return [nil, nil] if callers.length <= depth
|
85
|
+
|
86
|
+
line = callers[depth]
|
87
|
+
if line.match(/(.*):\d+(?::in `(.*)')/)
|
88
|
+
return [$1, $2]
|
89
|
+
end
|
90
|
+
|
91
|
+
if line.match(/(.*):\d+/)
|
92
|
+
return [$1, nil ]
|
93
|
+
end
|
94
|
+
|
95
|
+
info
|
96
|
+
end
|
97
|
+
|
98
|
+
@@monitor = false
|
99
|
+
@@announce = false
|
100
|
+
|
101
|
+
def self.process_options(options)
|
102
|
+
@@stack_depth = options[:stack_depth]
|
103
|
+
@@skip = options[:skip] || 0
|
104
|
+
|
105
|
+
if options[:announcement]
|
106
|
+
@@announce = true
|
107
|
+
@@announcement = options[:announcement]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# This function will activate monitoring of the next _supported_ loop.
|
112
|
+
#
|
113
|
+
# If a description is given as a parameter it will show at the
|
114
|
+
# beginning of the progress report.
|
115
|
+
def self.monitor(desc = "", options = {})
|
116
|
+
@@monitor = true
|
117
|
+
@@desc = desc
|
118
|
+
@@num_reports = options[:num_reports] || 100
|
119
|
+
@@call_info = caller_info(caller)
|
120
|
+
process_options(options)
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.announce(announcement, options = {})
|
124
|
+
@@announce = true
|
125
|
+
@@call_info = caller_info(caller)
|
126
|
+
@@announcement = announcement
|
127
|
+
process_options(options)
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.get_announcement
|
131
|
+
@@announce = false
|
132
|
+
@@announcement
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.this_loop?
|
136
|
+
if @@stack_depth != nil
|
137
|
+
call_info = caller_info(caller, @@stack_depth + 2)
|
138
|
+
return false if call_info != @@call_info
|
139
|
+
end
|
140
|
+
|
141
|
+
if @@skip > 0
|
142
|
+
@@skip -= 1
|
143
|
+
return false
|
144
|
+
else
|
145
|
+
return true
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Returns true if next loop must be monitored.
|
150
|
+
#
|
151
|
+
def self.monitor?
|
152
|
+
return @@monitor
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.announce?
|
156
|
+
return @@announce
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.active?
|
160
|
+
return (monitor? || announce?) && this_loop?
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.add_progress_meter(max)
|
164
|
+
progress_meter = Bar.new(max, progress_meters.size, @@num_reports, @@desc)
|
165
|
+
@@monitor = false
|
166
|
+
|
167
|
+
progress_meters.push(progress_meter)
|
168
|
+
|
169
|
+
progress_meter
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.remove_last_meter
|
173
|
+
progress_meters.pop
|
174
|
+
end
|
175
|
+
|
176
|
+
def self.print_announcement(message = nil)
|
177
|
+
return if message.nil?
|
178
|
+
total_depth = @@progress_meters.length + 1
|
179
|
+
$stderr.print("\033[#{total_depth}F\033[2K" + message + "\033[#{total_depth}E")
|
180
|
+
end
|
250
181
|
end
|
251
182
|
|
252
183
|
class Integer
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: progress-monitor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 15
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 2
|
8
|
+
- 1
|
9
|
+
- 2
|
10
|
+
version: 2.1.2
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Miguel Vazquez
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2011-10-03 00:00:00 +02:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -23,6 +29,7 @@ extra_rdoc_files:
|
|
23
29
|
- LICENSE
|
24
30
|
- README.rdoc
|
25
31
|
files:
|
32
|
+
- lib/progress-bar.rb
|
26
33
|
- lib/progress-monitor.rb
|
27
34
|
- samples/announce.rb
|
28
35
|
- samples/announce_monitor.rb
|
@@ -40,26 +47,32 @@ homepage: http://github.com/mikisvaz/progress-monitor
|
|
40
47
|
licenses: []
|
41
48
|
|
42
49
|
post_install_message:
|
43
|
-
rdoc_options:
|
44
|
-
|
50
|
+
rdoc_options: []
|
51
|
+
|
45
52
|
require_paths:
|
46
53
|
- lib
|
47
54
|
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
48
56
|
requirements:
|
49
57
|
- - ">="
|
50
58
|
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
51
62
|
version: "0"
|
52
|
-
version:
|
53
63
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
54
65
|
requirements:
|
55
66
|
- - ">="
|
56
67
|
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
57
71
|
version: "0"
|
58
|
-
version:
|
59
72
|
requirements: []
|
60
73
|
|
61
74
|
rubyforge_project:
|
62
|
-
rubygems_version: 1.
|
75
|
+
rubygems_version: 1.6.2
|
63
76
|
signing_key:
|
64
77
|
specification_version: 3
|
65
78
|
summary: Monitor Progress in the Command Line
|