rbbt-util 5.23.7 → 5.23.8

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: 0d76b8cd3df1f148aba3f5d8dd7106ec89e78110
4
- data.tar.gz: 27e02877f0fcc8d75d5a1822edfb4fbd13b9f272
3
+ metadata.gz: f8aaf566bf17aad351fdc54c77e2cff349e23daf
4
+ data.tar.gz: 393fc23341ab6ecb7b7a01ae408e8ca2dea2ef9e
5
5
  SHA512:
6
- metadata.gz: 5115c493080b64334eca39ae4f880df24e8ac4e84b6cb635f25bfb02c7159a93d2a9b79175cb08e5e86e1d56f84e0c55976e619b7538ec5012f87e55f275cf7d
7
- data.tar.gz: 7a92cd8e8660ee5793dd90a699570cd4c97b060d795f316e34ab6eb9dd5f92fc9240f82e015924c4c0fed0a8e459c76b0f1398336093abdcd165faa82a639c7e
6
+ metadata.gz: 729e28c3ed2a19f84c0b702b3eb62f94b141e64b1b305caa0ae0388409fbdf34e53110922ad0ee6499b4364f5bdba8e1735b1fc491fe7c2dc137e559c66c1189
7
+ data.tar.gz: 943598ede0e34302e6784b1dc7201165f44ba8dae6e8bed071a828d568bc7d241f1dab49aa3c46c24c4aa77c989d06bb37a483ba4c379d73b789cb8982b2fffe
@@ -197,7 +197,7 @@ module Persist
197
197
  def self.tee_stream_thread(stream, path, type, callback = nil, abort_callback = nil, lockfile = nil)
198
198
  file, out = Misc.tee_stream(stream)
199
199
 
200
- saver_thread = Thread.new(Thread.current) do |parent|
200
+ saver_thread = Thread.new do
201
201
  begin
202
202
  file.threads = []
203
203
  Thread.current["name"] = "file saver: " + path
@@ -209,7 +209,6 @@ module Persist
209
209
  rescue Exception
210
210
  Log.medium "Persist stream thread exception: #{ Log.color :blue, path }"
211
211
  file.abort if file.respond_to? :abort
212
- #parent.raise $!
213
212
  raise $!
214
213
  rescue Exception
215
214
  Log.exception $!
@@ -71,162 +71,200 @@ module TSV
71
71
  def self.traverse_tsv(tsv, options = {}, &block)
72
72
  callback, bar, join = Misc.process_options options, :callback, :bar, :join
73
73
 
74
- if callback
75
- bar.init if bar
76
- tsv.through options[:key_field], options[:fields] do |k,v|
77
- begin
78
- callback.call yield(k,v)
79
- rescue Exception
80
- Log.exception $!
81
- raise $!
82
- ensure
83
- bar.tick if bar
74
+ begin
75
+ error = false
76
+ if callback
77
+ bar.init if bar
78
+ tsv.through options[:key_field], options[:fields] do |k,v|
79
+ begin
80
+ callback.call yield(k,v)
81
+ rescue Exception
82
+ Log.exception $!
83
+ raise $!
84
+ ensure
85
+ bar.tick if bar
86
+ end
84
87
  end
85
- end
86
- else
87
- bar.init if bar
88
- tsv.through options[:key_field], options[:fields] do |k,v|
89
- begin
90
- yield k,v
91
- ensure
92
- bar.tick if bar
88
+ else
89
+ bar.init if bar
90
+ tsv.through options[:key_field], options[:fields] do |k,v|
91
+ begin
92
+ yield k,v
93
+ ensure
94
+ bar.tick if bar
95
+ end
93
96
  end
94
97
  end
95
- end
96
- Log::ProgressBar.remove_bar(bar) if bar
97
- join.call if join
98
+ rescue
99
+ Log.exception $!
100
+ error = true
101
+ raise $!
102
+ ensure
103
+ Log::ProgressBar.remove_bar(bar) if bar
104
+ join.call(error) if join
105
+ end
98
106
  end
99
107
 
100
108
  def self.traverse_hash(hash, options = {}, &block)
101
109
  callback, bar, join = Misc.process_options options, :callback, :bar, :join
102
110
 
103
- if callback
104
- bar.init if bar
105
- hash.each do |k,v|
106
- begin
107
- callback.call yield(k,v)
108
- ensure
109
- bar.tick if bar
111
+ begin
112
+ error = false
113
+ if callback
114
+ bar.init if bar
115
+ hash.each do |k,v|
116
+ begin
117
+ callback.call yield(k,v)
118
+ ensure
119
+ bar.tick if bar
120
+ end
110
121
  end
111
- end
112
- else
113
- bar.init if bar
114
- hash.each do |k,v|
115
- begin
116
- yield k,v
117
- ensure
118
- bar.tick if bar
122
+ else
123
+ bar.init if bar
124
+ hash.each do |k,v|
125
+ begin
126
+ yield k,v
127
+ ensure
128
+ bar.tick if bar
129
+ end
119
130
  end
120
131
  end
132
+ rescue
133
+ error = true
134
+ raise $!
135
+ ensure
136
+ Log::ProgressBar.remove_bar(bar) if bar
137
+ join.call(error) if join
121
138
  end
122
- Log::ProgressBar.remove_bar(bar) if bar
123
- join.call if join
124
139
  end
125
140
 
126
141
  def self.traverse_array(array, options = {}, &block)
127
142
  callback, bar, join = Misc.process_options options, :callback, :bar, :join
128
143
 
129
- if callback
130
- bar.init if bar
131
- array.each do |e|
132
- begin
133
- callback.call yield(e)
134
- ensure
135
- bar.tick if bar
144
+ begin
145
+ error = false
146
+ if callback
147
+ bar.init if bar
148
+ array.each do |e|
149
+ begin
150
+ callback.call yield(e)
151
+ ensure
152
+ bar.tick if bar
153
+ end
136
154
  end
137
- end
138
- else
139
- bar.init if bar
140
- array.each do |e|
141
- begin
142
- yield e
143
- rescue Exception
144
- Log.exception $!
145
- raise $!
146
- ensure
147
- bar.tick if bar
155
+ else
156
+ bar.init if bar
157
+ array.each do |e|
158
+ begin
159
+ yield e
160
+ rescue Exception
161
+ Log.exception $!
162
+ raise $!
163
+ ensure
164
+ bar.tick if bar
165
+ end
148
166
  end
149
167
  end
168
+
169
+ rescue
170
+ error = true
171
+ raise $!
172
+ ensure
173
+ Log::ProgressBar.remove_bar(bar) if bar
174
+ join.call(error) if join
150
175
  end
151
- Log::ProgressBar.remove_bar(bar) if bar
152
- join.call if join
153
176
  end
154
177
 
155
178
  def self.traverse_io_array(io, options = {}, &block)
156
179
  callback, bar, join = Misc.process_options options, :callback, :bar, :join
157
- if File === io and io.closed?
158
- begin
159
- Log.low{"Rewinding stream #{stream_name(io)}"}
160
- io.reopen io.filename, "r"
161
- rescue
162
- Log.exception $!
163
- raise "File closed and could not reopen #{stream_name(io)}"
180
+ begin
181
+ error = false
182
+ if File === io and io.closed?
183
+ begin
184
+ Log.low{"Rewinding stream #{stream_name(io)}"}
185
+ io.reopen io.filename, "r"
186
+ rescue
187
+ Log.exception $!
188
+ raise "File closed and could not reopen #{stream_name(io)}"
189
+ end
164
190
  end
165
- end
166
191
 
167
- if callback
168
- bar.init if bar
169
- while line = io.gets
170
- if line[-1] != "\n"
171
- while c = io.getc
172
- line << c
173
- break if c=="\n"
192
+ if callback
193
+ bar.init if bar
194
+ while line = io.gets
195
+ if line[-1] != "\n"
196
+ while c = io.getc
197
+ line << c
198
+ break if c=="\n"
199
+ end
200
+ end
201
+ begin
202
+ callback.call yield line.chomp
203
+ ensure
204
+ bar.tick if bar
174
205
  end
175
206
  end
176
- begin
177
- callback.call yield line.chomp
178
- ensure
179
- bar.tick if bar
180
- end
181
- end
182
- else
183
- bar.init if bar
184
- while line = io.gets
185
- begin
186
- yield line.chomp
187
- ensure
188
- bar.tick if bar
207
+ else
208
+ bar.init if bar
209
+ while line = io.gets
210
+ begin
211
+ yield line.chomp
212
+ ensure
213
+ bar.tick if bar
214
+ end
189
215
  end
190
216
  end
217
+ rescue
218
+ error = true
219
+ raise $!
220
+ ensure
221
+ Log::ProgressBar.remove_bar(bar) if bar
222
+ join.call(error) if join
191
223
  end
192
- Log::ProgressBar.remove_bar(bar) if bar
193
- join.call if join
194
224
  end
195
225
 
196
226
  def self.traverse_io(io, options = {}, &block)
197
227
  callback, bar, join = Misc.process_options options, :callback, :bar, :join
198
- if File === io and io.closed?
199
- begin
200
- Log.low{"Rewinding stream #{stream_name(io)}"}
201
- io.reopen io.filename, "r"
202
- rescue
203
- Log.exception $!
204
- raise "File closed and could not reopen #{stream_name(io)}"
205
- end
206
- end
207
228
 
208
- options[:monitor] = bar
209
- if callback
210
- bar.init if bar
211
- exception = nil
212
- begin
213
- TSV::Parser.traverse(io, options) do |k,v|
229
+ begin
230
+ error = false
231
+ if File === io and io.closed?
214
232
  begin
215
- callback.call yield k, v
216
- rescue Exception
217
- exception = $!
218
- raise $!
233
+ Log.low{"Rewinding stream #{stream_name(io)}"}
234
+ io.reopen io.filename, "r"
235
+ rescue
236
+ Log.exception $!
237
+ raise "File closed and could not reopen #{stream_name(io)}"
219
238
  end
220
- bar.tick if bar
221
239
  end
222
- ensure
223
- raise exception if exception
240
+
241
+ options[:monitor] = bar
242
+ if callback
243
+ bar.init if bar
244
+ exception = nil
245
+ begin
246
+ TSV::Parser.traverse(io, options) do |k,v|
247
+ begin
248
+ callback.call yield k, v
249
+ rescue Exception
250
+ exception = $!
251
+ raise $!
252
+ end
253
+ bar.tick if bar
254
+ end
255
+ ensure
256
+ raise exception if exception
257
+ end
258
+ else
259
+ TSV::Parser.traverse(io, options.merge(:monitor => bar), &block)
224
260
  end
225
- else
226
- TSV::Parser.traverse(io, options.merge(:monitor => bar), &block)
261
+ rescue
262
+ error = true
263
+ raise $!
264
+ ensure
265
+ Log::ProgressBar.remove_bar(bar) if bar
266
+ join.call(error) if join
227
267
  end
228
- Log::ProgressBar.remove_bar(bar) if bar
229
- join.call if join
230
268
  end
231
269
 
232
270
  def self.traverse_obj(obj, options = {}, &block)
@@ -261,6 +299,7 @@ module TSV
261
299
  end
262
300
  rescue Aborted
263
301
  obj.abort if obj.respond_to? :abort
302
+ raise $!
264
303
  rescue Exception
265
304
  obj.abort if obj.respond_to? :abort
266
305
  raise $!
@@ -380,6 +419,7 @@ module TSV
380
419
  stream.abort if stream.respond_to? :abort
381
420
  stream = obj_stream(options[:into])
382
421
  stream.abort if stream.respond_to? :abort
422
+ q.join
383
423
  raise "Traversal aborted"
384
424
  rescue Exception
385
425
  error = true
@@ -389,6 +429,7 @@ module TSV
389
429
  stream.abort if stream.respond_to? :abort
390
430
  stream = obj_stream(options[:into])
391
431
  stream.abort if stream.respond_to? :abort
432
+ q.join
392
433
  raise $!
393
434
  ensure
394
435
  if bar
@@ -116,10 +116,16 @@ module CMD
116
116
  in_content.join if in_content.respond_to? :join
117
117
  end
118
118
  rescue
119
- parent.raise $!
120
- Process.kill "INT", pid
121
- ensure
122
- sin.close unless sin.closed?
119
+ Log.exception $!
120
+ raise $!
121
+ # begin
122
+ # Process.kill "INT", pid
123
+ # #parent.raise $!
124
+ # ensure
125
+ # raise $!
126
+ # end
127
+ #ensure
128
+ # #sin.close unless sin.closed?
123
129
  end
124
130
  end
125
131
  else
@@ -135,7 +135,7 @@ class RbbtProcessQueue
135
135
  retry
136
136
  rescue Aborted
137
137
  Log.low "Aborting manager thread #{Process.pid}"
138
- raise Aborted
138
+ raise $!
139
139
  rescue Exception
140
140
  raise Exception
141
141
  end
@@ -254,16 +254,19 @@ class RbbtProcessQueue
254
254
  @callback_thread.join
255
255
  error = false
256
256
  rescue Aborted, Interrupt
257
+ exception = $!
257
258
  Log.exception $!
258
- self.abort
259
259
  error = true
260
+ self.abort
260
261
  Log.high "Process queue #{@master_pid} aborted"
261
262
  retry
262
263
  rescue Errno::ESRCH, Errno::ECHILD
263
264
  retry if Misc.pid_exists? @master_pid
264
265
  error = ! @status.success?
265
266
  rescue ProcessFailed
267
+ exception = $!
266
268
  rescue Exception
269
+ exception = $!
267
270
  Log.exception $!
268
271
  retry
269
272
  ensure
@@ -292,6 +295,12 @@ class RbbtProcessQueue
292
295
  ensure
293
296
  self.clean
294
297
  end
298
+
299
+ if exception
300
+ raise exception
301
+ else
302
+ raise "Process queue #{@master_pid} failed"
303
+ end if error
295
304
  end
296
305
  end
297
306
 
@@ -321,8 +330,12 @@ class RbbtProcessQueue
321
330
 
322
331
  def abort
323
332
  _abort
324
- (@callback_thread.raise(Aborted.new); @callback_thread.join) if @callback_thread and @callback_thread.alive?
333
+ @callback_thread.raise(Aborted.new) if @callback_thread and @callback_thread.alive?
325
334
  @aborted = true
335
+ begin
336
+ _join
337
+ rescue
338
+ end
326
339
  end
327
340
 
328
341
  def clean
@@ -117,24 +117,26 @@ module ConcurrentStream
117
117
  end
118
118
 
119
119
  def join
120
- join_threads
121
- join_pids
122
-
123
- join_callback
124
-
125
- @joined = true
126
-
127
- lockfile.unlock if lockfile and lockfile.locked?
128
- close unless closed?
120
+ begin
121
+ join_threads
122
+ join_pids
123
+ join_callback
124
+ close unless closed?
125
+ ensure
126
+ @joined = true
127
+ lockfile.unlock if lockfile and lockfile.locked?
128
+ end
129
129
  end
130
130
 
131
131
  def abort_threads(exception = nil)
132
132
  return unless @threads and @threads.any?
133
- Log.low "Aborting threads (#{Thread.current.inspect}) #{@threads.collect{|t| t.inspect } * ", "}"
133
+ name = Thread.current.inspect
134
+ name = filename if filename
135
+ Log.low "Aborting threads (#{name}) #{@threads.collect{|t| t.inspect } * ", "}"
134
136
 
135
137
  @threads.each do |t|
136
138
  next if t == Thread.current
137
- Log.debug "Aborting thread #{t.inspect} with exception: #{exception}"
139
+ Log.debug "Aborting thread (#{name}) #{t.inspect} with exception: #{exception}"
138
140
  t.raise((exception.nil? ? Aborted.new : exception))
139
141
  end
140
142
 
@@ -142,14 +144,14 @@ module ConcurrentStream
142
144
  next if t == Thread.current
143
145
  if t.alive?
144
146
  sleep 1
145
- Log.low "Kill thread #{t.inspect}"
147
+ Log.low "Kill thread (#{name}) #{t.inspect}"
146
148
  t.kill
147
149
  end
148
150
  begin
149
151
  t.join unless t == Thread.current
150
152
  rescue Aborted
151
153
  rescue Exception
152
- Log.debug "Thread exception: #{$!.message}"
154
+ Log.debug "Thread (#{name}) exception: #{$!.message}"
153
155
  end
154
156
  end
155
157
  end
@@ -219,11 +221,15 @@ module ConcurrentStream
219
221
  end
220
222
 
221
223
  def raise(exception)
222
- threads.each do |thread|
223
- thread.raise exception
224
- end
224
+ begin
225
+ threads.each do |thread|
226
+ thread.raise exception
227
+ end
225
228
 
226
- self.abort
229
+ self.abort
230
+ ensure
231
+ Kernel.raise $!
232
+ end
227
233
  end
228
234
 
229
235
  end
@@ -155,8 +155,6 @@ def self.add_libdir(dir=nil)
155
155
  rescue StopInsist
156
156
  raise $!.exception
157
157
  rescue Aborted, Interrupt
158
- Log.exception $!
159
- Log.stack caller
160
158
  if msg
161
159
  Log.warn("Not Insisting after Aborted: #{$!.message} -- #{msg}")
162
160
  else
@@ -172,10 +170,6 @@ def self.add_libdir(dir=nil)
172
170
  Log.warn("Insisting after exception: #{$!.class} #{$!.message}")
173
171
  end
174
172
 
175
- Log.stack caller
176
- Log.exception $!
177
-
178
-
179
173
  if sleep and try > 0
180
174
  sleep sleep
181
175
  sleep = sleep_array.shift || sleep if sleep_array
@@ -68,7 +68,7 @@ module Misc
68
68
 
69
69
  if do_fork
70
70
 
71
- parent_pid = Process.pid
71
+ #parent_pid = Process.pid
72
72
  pid = Process.fork {
73
73
  purge_pipes(sin)
74
74
  sout.close
@@ -79,7 +79,7 @@ module Misc
79
79
 
80
80
  rescue Exception
81
81
  Log.exception $!
82
- Process.kill :INT, parent_pid
82
+ #Process.kill :INT, parent_pid
83
83
  Kernel.exit! -1
84
84
  end
85
85
  Kernel.exit! 0
@@ -92,7 +92,7 @@ module Misc
92
92
 
93
93
  ConcurrentStream.setup sin, :pair => sout
94
94
 
95
- thread = Thread.new(Thread.current) do |parent|
95
+ thread = Thread.new do
96
96
  begin
97
97
 
98
98
  yield sin
@@ -104,7 +104,7 @@ module Misc
104
104
  rescue Exception
105
105
  Log.medium "Exception in open_pipe: #{$!.message}"
106
106
  Log.exception $!
107
- parent.raise $!
107
+ sin.close
108
108
  raise $!
109
109
  end
110
110
  end
@@ -442,26 +442,34 @@ module Misc
442
442
 
443
443
  def self.sort_stream(stream, header_hash = "#", cmd_args = "-u")
444
444
  Misc.open_pipe do |sin|
445
- begin
446
- stream = TSV.get_stream stream
445
+ stream = TSV.get_stream stream
447
446
 
447
+ line = stream.gets
448
+ while line =~ /^#{header_hash}/ do
449
+ sin.puts line
448
450
  line = stream.gets
449
- while line =~ /^#{header_hash}/ do
450
- sin.puts line
451
- line = stream.gets
452
- end
451
+ end
453
452
 
454
- line_stream = Misc.open_pipe do |line_stream_in|
455
- line_stream_in.puts line
453
+ line_stream = Misc.open_pipe do |line_stream_in|
454
+ line_stream_in.puts line
455
+ begin
456
456
  Misc.consume_stream(stream, false, line_stream_in)
457
+ rescue
458
+ raise $!
457
459
  end
460
+ end
458
461
 
459
- sorted = CMD.cmd("env LC_ALL=C sort #{cmd_args || ""}", :in => line_stream, :pipe => true)
462
+ sorted = CMD.cmd("env LC_ALL=C sort #{cmd_args || ""}", :in => line_stream, :pipe => true)
460
463
 
464
+ begin
461
465
  Misc.consume_stream(sorted, false, sin)
462
466
  rescue
463
- if defined? step and step
464
- step.abort
467
+ begin
468
+ Log.exception $!
469
+ sorted.abort
470
+ stream.abort
471
+ ensure
472
+ raise $!
465
473
  end
466
474
  end
467
475
  end
@@ -236,29 +236,41 @@ class Step
236
236
  respawn = :always if respawn.nil?
237
237
 
238
238
  Misc.bootstrap(list, cpus, :bar => "Bootstrapping dependencies for #{path} [#{cpus}]", :respawn => respawn) do |dep|
239
- Misc.insist do
240
- begin
241
- dep.produce
242
- Log.warn "Error in bootstrap dependency #{dep.path}: #{dep.messages.last}" if dep.error? or dep.aborted?
243
-
244
- rescue Aborted
239
+ begin
240
+ Signal.trap(:INT) do
245
241
  dep.abort
246
- Log.warn "Aborted bootstrap dependency #{dep.path}: #{dep.messages.last}" if dep.error? or dep.aborted?
247
- raise $!
242
+ raise Aborted
243
+ end
248
244
 
249
- rescue RbbtException
250
- if canfail || dep.canfail?
251
- Log.warn "Allowing failing of #{dep.path}: #{dep.messages.last}"
252
- else
253
- Log.warn "NOT Allowing failing of #{dep.path}: #{dep.messages.last}"
254
- dep.exception $!
255
- if dep.recoverable_error?
256
- raise $!
245
+ Misc.insist do
246
+ begin
247
+ dep.produce
248
+ Log.warn "Error in bootstrap dependency #{dep.path}: #{dep.messages.last}" if dep.error? or dep.aborted?
249
+
250
+ rescue Aborted
251
+ dep.abort
252
+ Log.warn "Aborted bootstrap dependency #{dep.path}: #{dep.messages.last}" if dep.error? or dep.aborted?
253
+ raise $!
254
+
255
+ rescue RbbtException
256
+ if canfail || dep.canfail?
257
+ Log.warn "Allowing failing of #{dep.path}: #{dep.messages.last}"
257
258
  else
258
- raise StopInsist.new($!)
259
+ Log.warn "NOT Allowing failing of #{dep.path}: #{dep.messages.last}"
260
+ dep.exception $!
261
+ if dep.recoverable_error?
262
+ dep.abort
263
+ raise $!
264
+ else
265
+ raise StopInsist.new($!)
266
+ end
259
267
  end
260
268
  end
261
269
  end
270
+ rescue
271
+ iif [:ABORTIN, dep]
272
+ dep.abort
273
+ raise $!
262
274
  end
263
275
  nil
264
276
  end
@@ -416,15 +428,9 @@ class Step
416
428
  next
417
429
  end
418
430
 
419
- begin
420
- next if dep.done? or dep.aborted?
421
- rescue
422
- end
431
+ next if dep.done? or dep.aborted?
423
432
 
424
- begin
425
- dep.abort if dep.running?
426
- rescue
427
- end
433
+ dep.abort if dep.running?
428
434
  end
429
435
  kill_children
430
436
  end
@@ -344,7 +344,6 @@ class Step
344
344
  end
345
345
  _clean_finished
346
346
  rescue
347
- Log.exception $!
348
347
  stop_dependencies
349
348
  set_info :pid, nil
350
349
  FileUtils.rm pid_file if File.exist?(pid_file)
@@ -563,15 +562,16 @@ class Step
563
562
  doretry = true
564
563
  begin
565
564
  return if done?
566
- stop_dependencies
567
- abort_stream
568
565
  abort_pid if running?
566
+ abort_stream
567
+ stop_dependencies
569
568
  rescue Aborted, Interrupt
570
569
  Log.medium{"#{Log.color :red, "Aborting ABORTED RETRY"} #{Log.color :blue, path}"}
571
570
  if doretry
572
571
  doretry = false
573
572
  retry
574
573
  end
574
+ raise $!
575
575
  rescue Exception
576
576
  if doretry
577
577
  doretry = false
@@ -269,4 +269,24 @@ line4
269
269
  assert_equal text, lines.to_a * ""
270
270
  end
271
271
  end
272
+
273
+ def test_sort
274
+ assert_raise RbbtException do
275
+ io = Misc.open_pipe do |sin|
276
+ sin.puts "#START"
277
+ 20.times do
278
+ sin.puts rand(1000).to_s
279
+ sleep 0.1
280
+ end
281
+ raise RbbtException
282
+ end
283
+
284
+ sio = Misc.sort_stream(io)
285
+ begin
286
+ Misc.consume_stream(sio, false, STDOUT)
287
+ rescue
288
+ Log.exception $!
289
+ end
290
+ end
291
+ end
272
292
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbt-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.23.7
4
+ version: 5.23.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez