rbbt-util 5.23.21 → 5.23.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rbbt/persist.rb +3 -3
- data/lib/rbbt/tsv/serializers.rb +7 -0
- data/lib/rbbt/tsv/util.rb +1 -1
- data/lib/rbbt/util/log/progress/report.rb +1 -0
- data/lib/rbbt/util/misc/development.rb +1 -0
- data/lib/rbbt/util/misc/inspect.rb +2 -2
- data/lib/rbbt/util/misc/pipes.rb +3 -3
- data/lib/rbbt/util/open.rb +210 -51
- data/lib/rbbt/workflow/accessor.rb +11 -14
- data/lib/rbbt/workflow/step/dependencies.rb +3 -3
- data/lib/rbbt/workflow/step/run.rb +15 -11
- data/lib/rbbt/workflow/step.rb +22 -11
- data/lib/rbbt/workflow.rb +5 -2
- data/share/rbbt_commands/system/clean +8 -0
- data/share/rbbt_commands/workflow/example +2 -0
- data/share/rbbt_commands/workflow/prov +4 -4
- data/test/rbbt/test_workflow.rb +89 -21
- data/test/rbbt/util/test_open.rb +41 -2
- data/test/test_helper.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f00bbaf07372fc3c72d60b438ce701b6336e21bb
|
4
|
+
data.tar.gz: f5e9cbffdc19992c1f2d606e7cef8963f84df2b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d087babf2c286d041e1585db266cd8abd1a39672eab0a965f772b00b9866eafb0ab27bb36242bb4fe4e344733d4f7a5a26033013a20d4f64524daeae0a493db
|
7
|
+
data.tar.gz: 28b6c11840f431d28c6e6bd32b75d72ce6eced2cf12d4f53661e5d316ff893c6c1e9e8d19d73cc78a235798ed9faf64dd389300e9be6e12decf743b335e31266
|
data/lib/rbbt/persist.rb
CHANGED
@@ -29,8 +29,8 @@ module Persist
|
|
29
29
|
return true if not Open.exists? file
|
30
30
|
path = path.find if Path === path
|
31
31
|
file = file.find if Path === file
|
32
|
-
patht =
|
33
|
-
filet =
|
32
|
+
patht = Open.mtime(path)
|
33
|
+
filet = Open.mtime(file)
|
34
34
|
diff = patht - filet
|
35
35
|
return diff if diff < 0
|
36
36
|
return false
|
@@ -109,7 +109,7 @@ module Persist
|
|
109
109
|
when :string, :text
|
110
110
|
Open.read(path)
|
111
111
|
when :binary
|
112
|
-
f =
|
112
|
+
f = Open.open(path, 'rb')
|
113
113
|
res = f.read
|
114
114
|
f.close
|
115
115
|
res.force_encoding("ASCII-8BIT") if res.respond_to? :force_encoding
|
data/lib/rbbt/tsv/serializers.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'base64'
|
1
2
|
module TSV
|
2
3
|
|
3
4
|
class CleanSerializer
|
@@ -5,6 +6,11 @@ module TSV
|
|
5
6
|
def self.load(o); o end
|
6
7
|
end
|
7
8
|
|
9
|
+
class BinarySerializer
|
10
|
+
def self.dump(o); [o].pack('m'); end
|
11
|
+
def self.load(str); str.unpack('m').first; end
|
12
|
+
end
|
13
|
+
|
8
14
|
class IntegerSerializer
|
9
15
|
def self.dump(i); [i].pack("l"); end
|
10
16
|
def self.load(str); str.unpack("l").first; end
|
@@ -103,6 +109,7 @@ module TSV
|
|
103
109
|
:flat => StringArraySerializer,
|
104
110
|
:double => StringDoubleArraySerializer,
|
105
111
|
:clean => CleanSerializer,
|
112
|
+
:binary => BinarySerializer,
|
106
113
|
:tsv => TSVSerializer,
|
107
114
|
:marshal_tsv => TSVMarshalSerializer
|
108
115
|
}
|
data/lib/rbbt/tsv/util.rb
CHANGED
@@ -45,7 +45,7 @@ module Misc
|
|
45
45
|
when nil
|
46
46
|
"nil"
|
47
47
|
when (defined? Step and Step)
|
48
|
-
"<Step:" << (obj.
|
48
|
+
"<Step:" << (obj.short_path || Misc.fingerprint([obj.task.name, obj.inputs])) << ">"
|
49
49
|
when TrueClass
|
50
50
|
"true"
|
51
51
|
when FalseClass
|
@@ -295,7 +295,7 @@ module Misc
|
|
295
295
|
"<IO:" << obj.path << "--" << mtime_str(obj.path) << ">"
|
296
296
|
end
|
297
297
|
when (defined? Step and Step)
|
298
|
-
"<IO:" << obj.
|
298
|
+
"<IO:" << obj.short_path << ">"
|
299
299
|
when IO
|
300
300
|
if obj.respond_to? :filename and obj.filename
|
301
301
|
"<IO:" << obj.filename << "--" << mtime_str(obj.filename) << ">"
|
data/lib/rbbt/util/misc/pipes.rb
CHANGED
@@ -304,7 +304,7 @@ module Misc
|
|
304
304
|
into = into.find if Path === into
|
305
305
|
if String === into
|
306
306
|
dir = File.dirname(into)
|
307
|
-
|
307
|
+
Open.mkdir dir unless Open.exists?(dir)
|
308
308
|
into_path, into = into, Open.open(into, :mode => 'w')
|
309
309
|
end
|
310
310
|
into.sync = true if IO === into
|
@@ -405,10 +405,10 @@ module Misc
|
|
405
405
|
Open.mv tmp_path, path, lock_options
|
406
406
|
end
|
407
407
|
rescue Exception
|
408
|
-
raise $! unless
|
408
|
+
raise $! unless Open.exists? path
|
409
409
|
end
|
410
410
|
|
411
|
-
|
411
|
+
Open.touch path if Open.exists? path
|
412
412
|
content.join if content.respond_to? :join and not (content.respond_to?(:joined?) and content.joined?)
|
413
413
|
|
414
414
|
Open.notify_write(path)
|
data/lib/rbbt/util/open.rb
CHANGED
@@ -137,11 +137,14 @@ module Open
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
+
def self.clear_dir_repos
|
141
|
+
@@repos.clear if defined? @@repos and @@repos
|
142
|
+
end
|
140
143
|
def self.get_repo_from_dir(dir)
|
141
|
-
|
142
|
-
|
144
|
+
@@repos ||= {}
|
145
|
+
@@repos[dir] ||= begin
|
143
146
|
repo_path = File.join(dir, '.file_repo')
|
144
|
-
Persist.open_tokyocabinet(repo_path, false, :clean,TokyoCabinet::BDB )
|
147
|
+
Persist.open_tokyocabinet(repo_path, false, :clean, TokyoCabinet::BDB )
|
145
148
|
end
|
146
149
|
end
|
147
150
|
|
@@ -149,13 +152,45 @@ module Open
|
|
149
152
|
repo = get_repo_from_dir(dir)
|
150
153
|
repo.read_and_close do
|
151
154
|
content = repo[sub_path]
|
152
|
-
content.nil? ? nil : StringIO.new(content)
|
155
|
+
content.nil? ? nil : StringIO.new(content).tap{|o| o.binmode }
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.get_time_from_repo(dir, sub_path)
|
160
|
+
repo = get_repo_from_dir(dir)
|
161
|
+
time = repo.read_and_close do
|
162
|
+
Time.at(repo['.time.' + sub_path].to_i)
|
163
|
+
end
|
164
|
+
time
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.get_atime_from_repo(dir, sub_path)
|
168
|
+
repo = get_repo_from_dir(dir)
|
169
|
+
File.atime(repo.persistance_path)
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.writable_repo?(dir, sub_path)
|
173
|
+
repo = get_repo_from_dir(dir)
|
174
|
+
begin
|
175
|
+
repo.write_and_close do
|
176
|
+
end
|
177
|
+
true
|
178
|
+
rescue
|
179
|
+
false
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.set_time_from_repo(dir, sub_path)
|
184
|
+
repo = get_repo_from_dir(dir)
|
185
|
+
repo.read_and_close do
|
186
|
+
repo['.time.' + sub_path] = Time.now.to_i.to_s
|
153
187
|
end
|
154
188
|
end
|
155
189
|
|
156
190
|
def self.save_content_in_repo(dir, sub_path, content)
|
157
191
|
repo = get_repo_from_dir(dir)
|
158
192
|
repo.write_and_close do
|
193
|
+
repo['.time.' + sub_path] = Time.now.to_i.to_s
|
159
194
|
repo[sub_path] = content
|
160
195
|
end
|
161
196
|
end
|
@@ -174,15 +209,24 @@ module Open
|
|
174
209
|
def self.exists_in_repo(dir, sub_path, content)
|
175
210
|
repo = get_repo_from_dir(dir)
|
176
211
|
repo.read_and_close do
|
177
|
-
repo.include? sub_path
|
212
|
+
repo.include?(sub_path) && ! repo[sub_path].nil?
|
178
213
|
end
|
179
214
|
end
|
180
215
|
|
181
216
|
def self.find_repo_dir(file)
|
182
217
|
self.repository_dirs.each do |dir|
|
183
|
-
|
184
|
-
|
185
|
-
|
218
|
+
dir = dir + '/' unless dir[-1] == "/"
|
219
|
+
|
220
|
+
begin
|
221
|
+
if file.start_with? dir
|
222
|
+
sub_path = file.to_s[dir.length..-1]
|
223
|
+
return [dir, sub_path]
|
224
|
+
else
|
225
|
+
if Path === file and (ffile = file.find).start_with? dir
|
226
|
+
sub_path = ffile.to_s[dir.length..-1]
|
227
|
+
return [dir, sub_path]
|
228
|
+
end
|
229
|
+
end
|
186
230
|
end
|
187
231
|
end
|
188
232
|
nil
|
@@ -206,7 +250,21 @@ module Open
|
|
206
250
|
|
207
251
|
def self.file_open(file, grep, mode = 'r', invert_grep = false)
|
208
252
|
if (dir_sub_path = find_repo_dir(file))
|
209
|
-
|
253
|
+
if mode.include? 'w'
|
254
|
+
|
255
|
+
stream = StringIO.new
|
256
|
+
class << stream
|
257
|
+
attr_accessor :dir_sub_path
|
258
|
+
def close
|
259
|
+
self.rewind
|
260
|
+
Open.save_content_in_repo(*dir_sub_path, self.read)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
stream.dir_sub_path = dir_sub_path
|
264
|
+
|
265
|
+
else
|
266
|
+
stream = get_stream_from_repo(*dir_sub_path)
|
267
|
+
end
|
210
268
|
else
|
211
269
|
file = file.find if Path === file
|
212
270
|
stream = File.open(file, mode)
|
@@ -237,9 +295,13 @@ module Open
|
|
237
295
|
end
|
238
296
|
|
239
297
|
def self.mkdir(target)
|
240
|
-
|
241
|
-
|
242
|
-
|
298
|
+
if (dir_sub_path = find_repo_dir(target))
|
299
|
+
nil
|
300
|
+
else
|
301
|
+
target = target.find if Path === target
|
302
|
+
if ! File.exists?(target)
|
303
|
+
FileUtils.mkdir_p target
|
304
|
+
end
|
243
305
|
end
|
244
306
|
end
|
245
307
|
|
@@ -279,13 +341,47 @@ module Open
|
|
279
341
|
end
|
280
342
|
end
|
281
343
|
|
344
|
+
#def self.cp(source, target, options = {})
|
345
|
+
# source = source.find if Path === source
|
346
|
+
# target = target.find if Path === target
|
347
|
+
|
348
|
+
# FileUtils.mkdir_p File.dirname(target) unless File.exists?(File.dirname(target))
|
349
|
+
# FileUtils.rm target if File.exists?(target)
|
350
|
+
# FileUtils.cp source, target
|
351
|
+
#end
|
352
|
+
|
282
353
|
def self.cp(source, target, options = {})
|
283
|
-
|
284
|
-
|
354
|
+
dir_sub_path_source = find_repo_dir(source)
|
355
|
+
dir_sub_path_target = find_repo_dir(target)
|
285
356
|
|
286
|
-
|
287
|
-
|
288
|
-
|
357
|
+
if dir_sub_path_source.nil? and dir_sub_path_target.nil?
|
358
|
+
FileUtils.mkdir_p File.dirname(target) unless File.exist? File.dirname(target)
|
359
|
+
tmp_target = File.join(File.dirname(target), '.tmp_mv.' + File.basename(target))
|
360
|
+
FileUtils.cp source, tmp_target
|
361
|
+
FileUtils.cp tmp_target, target
|
362
|
+
return
|
363
|
+
end
|
364
|
+
|
365
|
+
if dir_sub_path_source.nil?
|
366
|
+
save_content_in_repo(dir_sub_path_target[0], dir_sub_path_target[1], Open.read(source, :mode => 'rb', :nofix => true))
|
367
|
+
return nil
|
368
|
+
end
|
369
|
+
|
370
|
+
if dir_sub_path_target.nil?
|
371
|
+
Open.write(target, get_stream_from_repo(dir_sub_path_source))
|
372
|
+
return nil
|
373
|
+
end
|
374
|
+
|
375
|
+
repo_source = get_repo_from_dir(dir_sub_path_source[0])
|
376
|
+
repo_target = get_repo_from_dir(dir_sub_path_target[0])
|
377
|
+
|
378
|
+
repo_source.read_and_close do
|
379
|
+
repo_target.write_and_close do
|
380
|
+
repo_source[dir_sub_path_source[1]] = repo_target[dir_sub_path_target[1]]
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
return nil
|
289
385
|
end
|
290
386
|
|
291
387
|
def self.mv(source, target, options = {})
|
@@ -301,7 +397,7 @@ module Open
|
|
301
397
|
end
|
302
398
|
|
303
399
|
if dir_sub_path_source.nil?
|
304
|
-
save_content_in_repo(dir_sub_path_target[0], dir_sub_path_target[1], Open.read(source))
|
400
|
+
save_content_in_repo(dir_sub_path_target[0], dir_sub_path_target[1], Open.read(source, :mode => 'rb', :nofix => true))
|
305
401
|
return nil
|
306
402
|
end
|
307
403
|
|
@@ -317,6 +413,7 @@ module Open
|
|
317
413
|
repo_target.write_and_close do
|
318
414
|
repo_source[dir_sub_path_source[1]] = repo_target[dir_sub_path_target[1]]
|
319
415
|
end
|
416
|
+
repo_source.delete dir_sub_path_source[1]
|
320
417
|
end
|
321
418
|
|
322
419
|
return nil
|
@@ -331,6 +428,9 @@ module Open
|
|
331
428
|
File.exist?(file) || File.symlink?(file)
|
332
429
|
end
|
333
430
|
end
|
431
|
+
class << self
|
432
|
+
alias exist? exists?
|
433
|
+
end
|
334
434
|
|
335
435
|
def self.lock(file, options = {}, &block)
|
336
436
|
if file and (dir_sub_path = find_repo_dir(file))
|
@@ -485,7 +585,7 @@ module Open
|
|
485
585
|
end
|
486
586
|
|
487
587
|
def self.can_open?(file)
|
488
|
-
String === file and (
|
588
|
+
String === file and (Open.exist?(file) or remote?(file))
|
489
589
|
end
|
490
590
|
|
491
591
|
def self.read(file, options = {}, &block)
|
@@ -511,13 +611,14 @@ module Open
|
|
511
611
|
def self.notify_write(file)
|
512
612
|
begin
|
513
613
|
notification_file = file + '.notify'
|
514
|
-
if
|
614
|
+
if Open.exists? notification_file
|
515
615
|
key = Open.read(notification_file).strip
|
516
616
|
key = nil if key.empty?
|
517
617
|
Misc.notify("Wrote " << file, nil, key)
|
518
|
-
|
618
|
+
Open.rm notification_file
|
519
619
|
end
|
520
620
|
rescue
|
621
|
+
Log.exception $!
|
521
622
|
Log.warn "Error notifying write of #{ file }"
|
522
623
|
end
|
523
624
|
end
|
@@ -528,48 +629,106 @@ module Open
|
|
528
629
|
file = file.find(options[:where]) if Path === file
|
529
630
|
mode = Misc.process_options options, :mode
|
530
631
|
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
632
|
+
if (dir_sub_path = find_repo_dir(file))
|
633
|
+
content = case content
|
634
|
+
when String
|
635
|
+
content
|
636
|
+
when nil
|
637
|
+
if block_given?
|
638
|
+
yield
|
639
|
+
else
|
640
|
+
""
|
641
|
+
end
|
642
|
+
else
|
643
|
+
content.read
|
644
|
+
end
|
645
|
+
dir_sub_path.push content
|
646
|
+
save_content_in_repo(*dir_sub_path)
|
647
|
+
else
|
648
|
+
FileUtils.mkdir_p File.dirname(file)
|
649
|
+
case
|
650
|
+
when block_given?
|
536
651
|
begin
|
537
|
-
|
538
|
-
|
539
|
-
|
652
|
+
f = File.open(file, mode)
|
653
|
+
begin
|
654
|
+
yield f
|
655
|
+
ensure
|
656
|
+
f.close unless f.closed?
|
657
|
+
end
|
658
|
+
rescue Exception
|
659
|
+
FileUtils.rm file if File.exist? file
|
660
|
+
raise $!
|
540
661
|
end
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
while block = content.read(Misc::BLOCK_SIZE)
|
554
|
-
f.write block
|
662
|
+
when content.nil?
|
663
|
+
File.open(file, mode){|f| f.write "" }
|
664
|
+
when String === content
|
665
|
+
file_write(file, content, mode)
|
666
|
+
else
|
667
|
+
begin
|
668
|
+
File.open(file, mode) do |f|
|
669
|
+
f.flock(File::LOCK_EX)
|
670
|
+
while block = content.read(Misc::BLOCK_SIZE)
|
671
|
+
f.write block
|
672
|
+
end
|
673
|
+
f.flock(File::LOCK_UN)
|
555
674
|
end
|
556
|
-
|
675
|
+
rescue Exception
|
676
|
+
FileUtils.rm_rf file if File.exist? file
|
677
|
+
raise $!
|
557
678
|
end
|
558
|
-
|
559
|
-
FileUtils.rm_rf file if File.exist? file
|
560
|
-
raise $!
|
679
|
+
content.close
|
561
680
|
end
|
562
|
-
content.close
|
563
681
|
end
|
682
|
+
|
564
683
|
notify_write(file)
|
565
684
|
end
|
566
685
|
|
567
686
|
def self.writable?(path)
|
568
687
|
path = path.find if Path === path
|
569
|
-
if
|
570
|
-
|
688
|
+
if (dir_sub_path = find_repo_dir(path))
|
689
|
+
writable_repo?(*dir_sub_path)
|
690
|
+
else
|
691
|
+
if File.exists?(path)
|
692
|
+
File.writable?(path)
|
693
|
+
else
|
694
|
+
File.writable?(File.dirname(File.expand_path(path)))
|
695
|
+
end
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
699
|
+
def self.ctime(file)
|
700
|
+
if (dir_sub_path = find_repo_dir(file))
|
701
|
+
get_time_from_repo(*dir_sub_path)
|
702
|
+
else
|
703
|
+
file = file.find if Path === file
|
704
|
+
File.ctime(file)
|
705
|
+
end
|
706
|
+
end
|
707
|
+
|
708
|
+
def self.mtime(file)
|
709
|
+
if (dir_sub_path = find_repo_dir(file))
|
710
|
+
get_time_from_repo(*dir_sub_path)
|
711
|
+
else
|
712
|
+
file = file.find if Path === file
|
713
|
+
File.mtime(file)
|
714
|
+
end
|
715
|
+
end
|
716
|
+
|
717
|
+
def self.atime(file)
|
718
|
+
if (dir_sub_path = find_repo_dir(file))
|
719
|
+
get_atime_from_repo(*dir_sub_path)
|
571
720
|
else
|
572
|
-
|
721
|
+
file = file.find if Path === file
|
722
|
+
File.atime(file)
|
723
|
+
end
|
724
|
+
end
|
725
|
+
|
726
|
+
def self.touch(file)
|
727
|
+
if (dir_sub_path = find_repo_dir(file))
|
728
|
+
set_time_from_repo(*dir_sub_path)
|
729
|
+
else
|
730
|
+
file = file.find if Path === file
|
731
|
+
FileUtils.touch(file)
|
573
732
|
end
|
574
733
|
end
|
575
734
|
end
|
@@ -15,7 +15,6 @@ end
|
|
15
15
|
|
16
16
|
class Step
|
17
17
|
|
18
|
-
|
19
18
|
INFO_SERIALIAZER = Marshal
|
20
19
|
|
21
20
|
def self.wait_for_jobs(jobs)
|
@@ -64,7 +63,7 @@ class Step
|
|
64
63
|
|
65
64
|
def self.step_info(path)
|
66
65
|
begin
|
67
|
-
Open.open(info_file(path)) do |f|
|
66
|
+
Open.open(info_file(path), :mode => 'rb') do |f|
|
68
67
|
INFO_SERIALIAZER.load(f)
|
69
68
|
end
|
70
69
|
rescue Exception
|
@@ -126,7 +125,7 @@ class Step
|
|
126
125
|
begin
|
127
126
|
Misc.insist do
|
128
127
|
begin
|
129
|
-
return @info_cache if @info_cache and @info_cache_time and
|
128
|
+
return @info_cache if @info_cache and @info_cache_time and Open.ctime(info_file) < @info_cache_time
|
130
129
|
rescue Exception
|
131
130
|
raise $!
|
132
131
|
end
|
@@ -138,7 +137,7 @@ class Step
|
|
138
137
|
raise TryAgain, "Info locked" if check_lock and info_lock.locked?
|
139
138
|
info_lock.lock if check_lock and false
|
140
139
|
begin
|
141
|
-
Open.open(info_file) do |file|
|
140
|
+
Open.open(info_file, :mode => 'rb') do |file|
|
142
141
|
INFO_SERIALIAZER.load(file) #|| {}
|
143
142
|
end
|
144
143
|
ensure
|
@@ -179,12 +178,8 @@ class Step
|
|
179
178
|
i = info(false).dup
|
180
179
|
i[key] = value
|
181
180
|
@info_cache = i
|
182
|
-
|
183
|
-
Misc.
|
184
|
-
Open.open(info_file) do |file|
|
185
|
-
INFO_SERIALIAZER.load(file)
|
186
|
-
end
|
187
|
-
end
|
181
|
+
dump = INFO_SERIALIAZER.dump(i)
|
182
|
+
Misc.sensiblewrite(info_file, dump, :force => true, :lock => false)
|
188
183
|
@info_cache_time = Time.now
|
189
184
|
value
|
190
185
|
end
|
@@ -192,12 +187,14 @@ class Step
|
|
192
187
|
|
193
188
|
def merge_info(hash)
|
194
189
|
return nil if @exec or info_file.nil?
|
190
|
+
return nil if ! writable?
|
195
191
|
value = Annotated.purge value if defined? Annotated
|
196
192
|
Open.lock(info_file, :lock => info_lock) do
|
197
193
|
i = info(false)
|
198
194
|
i.merge! hash
|
199
195
|
@info_cache = i
|
200
|
-
|
196
|
+
dump = INFO_SERIALIAZER.dump(i)
|
197
|
+
Misc.sensiblewrite(info_file, dump, :force => true, :lock => false)
|
201
198
|
@info_cache_time = Time.now
|
202
199
|
value
|
203
200
|
end
|
@@ -546,8 +543,8 @@ class Step
|
|
546
543
|
provenance = {}
|
547
544
|
dependencies.each do |dep|
|
548
545
|
next unless dep.path.exists?
|
549
|
-
if
|
550
|
-
provenance[dep.path] = dep.provenance if
|
546
|
+
if Open.exists? dep.info_file
|
547
|
+
provenance[dep.path] = dep.provenance if Open.exists? dep.path
|
551
548
|
else
|
552
549
|
provenance[dep.path] = nil
|
553
550
|
end
|
@@ -558,7 +555,7 @@ class Step
|
|
558
555
|
def provenance_paths
|
559
556
|
provenance = {}
|
560
557
|
dependencies.each do |dep|
|
561
|
-
provenance[dep.path] = dep.provenance_paths if
|
558
|
+
provenance[dep.path] = dep.provenance_paths if Open.exists? dep.path
|
562
559
|
end
|
563
560
|
provenance
|
564
561
|
end
|
@@ -180,7 +180,7 @@ class Step
|
|
180
180
|
raise $!
|
181
181
|
rescue Exception
|
182
182
|
Log.error "Exception in dep. #{ Log.color :red, dependency.task_name.to_s } -- #{$!.message}"
|
183
|
-
raise $!
|
183
|
+
raise $! unless canfail_paths.include? dependency.path
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
@@ -300,9 +300,9 @@ class Step
|
|
300
300
|
end
|
301
301
|
|
302
302
|
def canfail_paths
|
303
|
-
return Set.new if !
|
303
|
+
return Set.new if ! Open.exists?(info_file)
|
304
304
|
|
305
|
-
if info[:canfail_paths]
|
305
|
+
if !relocated && info[:canfail_paths]
|
306
306
|
Set.new(info[:canfail_paths])
|
307
307
|
else
|
308
308
|
canfail_paths = Set.new
|
@@ -145,7 +145,8 @@ class Step
|
|
145
145
|
next unless dep.updatable?
|
146
146
|
|
147
147
|
begin
|
148
|
-
|
148
|
+
|
149
|
+
if dep.done? && self.done? && Open.exists?(dep.path) && Open.exists?(self.path) && (Open.mtime(dep.path) > Open.mtime(self.path))
|
149
150
|
outdated_time << dep
|
150
151
|
end
|
151
152
|
rescue
|
@@ -223,7 +224,7 @@ class Step
|
|
223
224
|
begin
|
224
225
|
run_dependencies
|
225
226
|
rescue Exception
|
226
|
-
|
227
|
+
Open.rm pid_file if Open.exists?(pid_file)
|
227
228
|
stop_dependencies
|
228
229
|
raise $!
|
229
230
|
end
|
@@ -346,7 +347,7 @@ class Step
|
|
346
347
|
ensure
|
347
348
|
Step.purge_stream_cache
|
348
349
|
set_info :pid, nil
|
349
|
-
|
350
|
+
Open.rm pid_file if Open.exist?(pid_file)
|
350
351
|
end
|
351
352
|
end
|
352
353
|
|
@@ -361,7 +362,7 @@ class Step
|
|
361
362
|
rescue
|
362
363
|
stop_dependencies
|
363
364
|
set_info :pid, nil
|
364
|
-
|
365
|
+
Open.rm pid_file if Open.exist?(pid_file)
|
365
366
|
end
|
366
367
|
end
|
367
368
|
|
@@ -381,13 +382,13 @@ class Step
|
|
381
382
|
})
|
382
383
|
log :ending
|
383
384
|
Step.purge_stream_cache
|
384
|
-
|
385
|
+
Open.rm pid_file if Open.exist?(pid_file)
|
385
386
|
end
|
386
387
|
|
387
388
|
set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]}
|
388
389
|
|
389
390
|
if result.nil? && File.exists?(self.tmp_path) && ! File.exists?(self.path)
|
390
|
-
|
391
|
+
Open.mv self.tmp_path, self.path
|
391
392
|
end
|
392
393
|
result
|
393
394
|
end # END PERSIST
|
@@ -415,6 +416,8 @@ class Step
|
|
415
416
|
stop_dependencies
|
416
417
|
raise $!
|
417
418
|
ensure
|
419
|
+
no_load = false unless IO === result
|
420
|
+
Open.rm pid_file if Open.exist?(pid_file) unless no_load
|
418
421
|
set_info :pid, nil unless no_load
|
419
422
|
end
|
420
423
|
end
|
@@ -433,6 +436,7 @@ class Step
|
|
433
436
|
else
|
434
437
|
e = get_exception
|
435
438
|
if e
|
439
|
+
Log.error "Raising exception in produced job #{job.path}: #{e.message}"
|
436
440
|
raise e
|
437
441
|
else
|
438
442
|
raise "Error in job: #{self.path}"
|
@@ -464,7 +468,7 @@ class Step
|
|
464
468
|
Misc.pre_fork
|
465
469
|
begin
|
466
470
|
RbbtSemaphore.wait_semaphore(semaphore) if semaphore
|
467
|
-
|
471
|
+
Open.mkdir File.dirname(path) unless Open.exist?(File.dirname(path))
|
468
472
|
begin
|
469
473
|
@forked = true
|
470
474
|
res = run no_load
|
@@ -626,7 +630,7 @@ class Step
|
|
626
630
|
end
|
627
631
|
|
628
632
|
def soft_grace
|
629
|
-
until done? or
|
633
|
+
until done? or Open.exist?(info_file)
|
630
634
|
sleep 1
|
631
635
|
end
|
632
636
|
self
|
@@ -672,8 +676,8 @@ class Step
|
|
672
676
|
dependencies.each{|dep| dep.join }
|
673
677
|
end
|
674
678
|
|
675
|
-
until (
|
676
|
-
sleep 1
|
679
|
+
until (Open.exists?(path) && status == :done) or error? or aborted? or waiting?
|
680
|
+
sleep 1
|
677
681
|
join_stream if streaming?
|
678
682
|
end
|
679
683
|
|
@@ -682,7 +686,7 @@ class Step
|
|
682
686
|
begin
|
683
687
|
set_info :joined, true
|
684
688
|
rescue
|
685
|
-
end if
|
689
|
+
end if Open.exists?(info_file) && writable?
|
686
690
|
@result = nil
|
687
691
|
end
|
688
692
|
end
|
data/lib/rbbt/workflow/step.rb
CHANGED
@@ -9,6 +9,7 @@ class Step
|
|
9
9
|
attr_accessor :task_name, :overriden
|
10
10
|
attr_accessor :pid
|
11
11
|
attr_accessor :exec
|
12
|
+
attr_accessor :relocated
|
12
13
|
attr_accessor :result, :mutex, :seen
|
13
14
|
|
14
15
|
class << self
|
@@ -252,19 +253,29 @@ class Step
|
|
252
253
|
|
253
254
|
|
254
255
|
def load
|
255
|
-
res =
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
256
|
+
res = begin
|
257
|
+
if @result and not @path == @result
|
258
|
+
res = @result
|
259
|
+
else
|
260
|
+
join if not done?
|
261
|
+
res = @path.exists? ? Persist.load_file(@path, result_type) : exec
|
262
|
+
end
|
263
|
+
|
264
|
+
if result_description
|
265
|
+
entity_info = info.dup
|
266
|
+
entity_info.merge! info[:inputs] if info[:inputs]
|
267
|
+
res = prepare_result res, result_description, entity_info
|
268
|
+
end
|
269
|
+
|
270
|
+
res
|
271
|
+
rescue IOError
|
272
|
+
if @result
|
273
|
+
@result = nil
|
274
|
+
retry
|
275
|
+
end
|
276
|
+
raise $!
|
260
277
|
end
|
261
278
|
|
262
|
-
if result_description
|
263
|
-
entity_info = info.dup
|
264
|
-
entity_info.merge! info[:inputs] if info[:inputs]
|
265
|
-
res = prepare_result res, result_description, entity_info
|
266
|
-
end
|
267
|
-
|
268
279
|
res
|
269
280
|
end
|
270
281
|
|
data/lib/rbbt/workflow.rb
CHANGED
@@ -471,21 +471,24 @@ module Workflow
|
|
471
471
|
preal = real.split(/\/+/)
|
472
472
|
pother = other.split(/\/+/)
|
473
473
|
end_part = pother[-3..-1] * "/"
|
474
|
-
new_path = preal[0..-4] * "/" << end_part
|
474
|
+
new_path = preal[0..-4] * "/" << "/" << end_part
|
475
475
|
return new_path if File.exists? new_path
|
476
476
|
Rbbt.var.jobs[end_part].find
|
477
477
|
end
|
478
478
|
|
479
479
|
def self.load_step(path)
|
480
480
|
step = Step.new path
|
481
|
+
relocated = false
|
481
482
|
step.dependencies = (step.info[:dependencies] || []).collect do |task,name,dep_path|
|
482
|
-
if
|
483
|
+
if Open.exists?(dep_path)
|
483
484
|
Workflow.load_step dep_path
|
484
485
|
else
|
485
486
|
new_path = relocate(path, dep_path)
|
487
|
+
relocated = true if Open.exists?(new_path)
|
486
488
|
Workflow.load_step new_path
|
487
489
|
end
|
488
490
|
end
|
491
|
+
step.relocated = relocated
|
489
492
|
|
490
493
|
step
|
491
494
|
end
|
@@ -103,6 +103,14 @@ TSV.traverse jobs, :_bar => "Checking job status" do |file,i|
|
|
103
103
|
status = :sync if status != "done" and File.exist? file
|
104
104
|
|
105
105
|
status = :dirty if info[:status].to_s == "done" and dirty and Workflow.load_step(file).dirty?
|
106
|
+
if info[:status] == :error
|
107
|
+
begin
|
108
|
+
exception = info[:exception][:class]
|
109
|
+
Kernel.const_get exception
|
110
|
+
status = :non_recoverable if exception.superclass === RbbtException
|
111
|
+
rescue
|
112
|
+
end
|
113
|
+
end
|
106
114
|
|
107
115
|
status = status.to_s
|
108
116
|
end
|
@@ -70,7 +70,7 @@ def report_msg(status, name, path, info = nil)
|
|
70
70
|
task, status, workflow = Log.color(:yellow, info[:task_name]), Log.color(:blue, "file"), Log.color(:magenta, "-")
|
71
71
|
end
|
72
72
|
|
73
|
-
str = if not Open.remote?(path) and (
|
73
|
+
str = if not Open.remote?(path) and (Open.exists?(path) and $main_mtime and ($main_mtime - Open.mtime(path)) < 0)
|
74
74
|
status_msg(status.to_s) << " " << [workflow, task, path].compact * " " << " (#{Log.color(:red, "Mtime out of sync") })"
|
75
75
|
else
|
76
76
|
status_msg(status.to_s) << " " << [workflow, task, path].compact * " "
|
@@ -108,7 +108,7 @@ def report(step, offset = 0, task = nil)
|
|
108
108
|
status = info[:status] || :missing
|
109
109
|
status = "remote" if Open.remote?(path)
|
110
110
|
name = info[:name] || File.basename(path)
|
111
|
-
status = :unsync if status == :done and not
|
111
|
+
status = :unsync if status == :done and not Open.exist? path
|
112
112
|
str = " " * offset
|
113
113
|
str << report_msg(status, name, path, info)
|
114
114
|
step.dependencies.each do |dep|
|
@@ -124,7 +124,7 @@ def report(step, offset = 0, task = nil)
|
|
124
124
|
end
|
125
125
|
|
126
126
|
step = get_step file
|
127
|
-
$main_mtime =
|
127
|
+
$main_mtime = Open.exist?(step.path) ? Open.mtime(step.path) : nil
|
128
128
|
|
129
129
|
def adjacency(step)
|
130
130
|
|
@@ -138,7 +138,7 @@ def adjacency(step)
|
|
138
138
|
workflow, task, name = path.split("/")[-3..-1]
|
139
139
|
end
|
140
140
|
name = name.split(":").last
|
141
|
-
status = :unsync if status == :done and not
|
141
|
+
status = :unsync if status == :done and not Open.exist? path
|
142
142
|
shapes = Hash.new "circle"
|
143
143
|
edge_info = {:status => status, :workflow => workflow, :task => task, :name => name, :label => task, :shape => shapes[workflow], :color => status == 'remote' ? 'blue' : 'green'}
|
144
144
|
id = Misc.digest(path)
|
data/test/rbbt/test_workflow.rb
CHANGED
@@ -129,12 +129,64 @@ for this dependency
|
|
129
129
|
"Hi #{name}"
|
130
130
|
end
|
131
131
|
|
132
|
+
input :num, :integer
|
133
|
+
task :odd => :integer do |num|
|
134
|
+
raise ParameterException, "Not odd" if num % 2 == 0
|
135
|
+
num
|
136
|
+
end
|
137
|
+
|
138
|
+
dep :odd, :num => 10, :compute => :canfail
|
139
|
+
dep :odd, :num => 11, :compute => :canfail
|
140
|
+
dep :odd, :num => 12, :compute => :canfail
|
141
|
+
dep :odd, :num => 13, :compute => :canfail
|
142
|
+
task :sum_odds => :integer do
|
143
|
+
dependencies.inject(0) do |acc, dep|
|
144
|
+
acc += dep.load unless dep.error?
|
145
|
+
acc
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
dep :sum_odds
|
150
|
+
task :sum_odds_str => :string do
|
151
|
+
"Sum odds: " << step(:sum_odds).load.to_s
|
152
|
+
end
|
153
|
+
|
154
|
+
|
132
155
|
end
|
133
156
|
|
134
157
|
TestWF.workdir = Rbbt.tmp.test.workflow
|
135
158
|
|
136
159
|
class TestWorkflow < Test::Unit::TestCase
|
137
160
|
|
161
|
+
|
162
|
+
def test_repo_marshal
|
163
|
+
TmpFile.with_file do |tmpdir|
|
164
|
+
tmpdir = Rbbt.tmp.repo_dir.find
|
165
|
+
repo = File.join(tmpdir, 'repo')
|
166
|
+
|
167
|
+
filename = 'file'
|
168
|
+
Open.repository_dirs.push(repo)
|
169
|
+
|
170
|
+
job = TestWF.job(:call_name, "Miguel")
|
171
|
+
job.run
|
172
|
+
|
173
|
+
obj = job.info
|
174
|
+
Open.write(File.join(repo, filename), Marshal.dump(obj))
|
175
|
+
new =Open.open(File.join(repo, filename)) do |f|
|
176
|
+
Marshal.load(f)
|
177
|
+
end
|
178
|
+
|
179
|
+
assert_equal new, obj
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_in_repo
|
185
|
+
job = TestWF.job(:call_name, "Miguel")
|
186
|
+
assert_equal "Hi Miguel", job.run
|
187
|
+
assert_equal "Miguel", job.clean_name
|
188
|
+
end
|
189
|
+
|
138
190
|
def test_as_jobname
|
139
191
|
job = TestWF.job(:call_name, "Miguel")
|
140
192
|
assert_equal "Hi Miguel", job.run
|
@@ -146,21 +198,22 @@ class TestWorkflow < Test::Unit::TestCase
|
|
146
198
|
end
|
147
199
|
|
148
200
|
def test_update_on_input_dependency_update
|
201
|
+
Open.repository_dirs << File.join(ENV["HOME"],".rbbt/tmp/test/workflow")
|
149
202
|
Log.severity = 0
|
150
203
|
send_input_dep_to_reverse_job = TestWF.job(:send_input_dep_to_reverse, nil, :name => "Miguel")
|
151
204
|
send_input_dep_to_reverse_job.clean
|
152
205
|
send_input_dep_to_reverse_job.run
|
153
206
|
|
154
207
|
input_dep_job = send_input_dep_to_reverse_job.step(:input_dep)
|
155
|
-
mtime_orig =
|
208
|
+
mtime_orig = Open.mtime send_input_dep_to_reverse_job.step(:reverse_input_text).path
|
156
209
|
|
157
|
-
sleep
|
210
|
+
sleep 2
|
158
211
|
input_dep_job.clean
|
159
212
|
input_dep_job.run
|
160
213
|
send_input_dep_to_reverse_job = TestWF.job(:send_input_dep_to_reverse, nil, :name => "Miguel")
|
161
214
|
|
162
215
|
send_input_dep_to_reverse_job.run
|
163
|
-
mtime_new =
|
216
|
+
mtime_new = Open.mtime send_input_dep_to_reverse_job.step(:reverse_input_text).path
|
164
217
|
assert mtime_orig < mtime_new
|
165
218
|
end
|
166
219
|
|
@@ -170,7 +223,7 @@ class TestWorkflow < Test::Unit::TestCase
|
|
170
223
|
|
171
224
|
def test_job
|
172
225
|
str = "TEST"
|
173
|
-
job = TestWF.job(:repeat2, "Default", :number => 3).fork
|
226
|
+
job = TestWF.job(:repeat2, "Default", :number => 3).clean.fork
|
174
227
|
while not job.done?
|
175
228
|
sleep 1
|
176
229
|
end
|
@@ -275,16 +328,6 @@ class TestWorkflow < Test::Unit::TestCase
|
|
275
328
|
assert_equal "CB", TestWF.job(:t3).run
|
276
329
|
end
|
277
330
|
|
278
|
-
def test_relocate
|
279
|
-
listed = '/home/user/.rbbt/var/jobs/TestWF/task1/Default'
|
280
|
-
real = '/usr/local/var/rbbt/jobs/TestWF/task1/Default'
|
281
|
-
other = '/home/user/.rbbt/var/jobs/TestWF/task2/Default'
|
282
|
-
real_other = '/usr/local/var/rbbt/jobs/TestWF/task2/Default'
|
283
|
-
|
284
|
-
assert_equal real_other, Workflow.relocate(real, other)
|
285
|
-
assert_equal real_other, Workflow.relocate(real, other)
|
286
|
-
end
|
287
|
-
|
288
331
|
def test_transplant
|
289
332
|
listed = '/home/user/.rbbt/var/jobs/TestWF/task1/Default'
|
290
333
|
real = '/usr/local/var/rbbt/jobs/TestWF/task1/Default'
|
@@ -295,13 +338,29 @@ class TestWorkflow < Test::Unit::TestCase
|
|
295
338
|
assert_equal real_other, Workflow.transplant(nil, real, other)
|
296
339
|
end
|
297
340
|
|
298
|
-
def
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
341
|
+
def test_relocate
|
342
|
+
TmpFile.with_file do |tmpdir|
|
343
|
+
listed = File.join(tmpdir, '/home/user/.rbbt/var/jobs/TestWF/task1/Default')
|
344
|
+
real = File.join(tmpdir, '/usr/local/var/rbbt/jobs/TestWF/task1/Default')
|
345
|
+
other = File.join(tmpdir, '/home/user/.rbbt/var/jobs/TestWF/task2/Default')
|
346
|
+
real_other = File.join(tmpdir, '/usr/local/var/rbbt/jobs/TestWF/task2/Default')
|
347
|
+
|
348
|
+
Open.write(real_other,'')
|
349
|
+
assert_equal real_other, Workflow.relocate(real, other)
|
350
|
+
assert_equal real_other, Workflow.relocate(real, other)
|
351
|
+
end
|
352
|
+
end
|
303
353
|
|
304
|
-
|
354
|
+
def test_relocate_alt
|
355
|
+
TmpFile.with_file do |tmpdir|
|
356
|
+
listed = File.join(tmpdir, '/scratch/tmp/rbbt/.rbbt/var/jobs/Study/sample_gene_cnvs_focal/Bladder-TCC')
|
357
|
+
real = File.join(tmpdir, '/home/bsc26/bsc26892/.rbbt/var/jobs/Study/sample_gene_cnvs_focal/Bladder-TCC')
|
358
|
+
other = File.join(tmpdir, '/scratch/tmp/rbbt/scratch/bsc26892/rbbt/var/jobs/Sample/gene_cnv_status_focal/PCAWG')
|
359
|
+
real_other = File.join(tmpdir, '/home/bsc26/bsc26892/.rbbt/var/jobs/Sample/gene_cnv_status_focal/PCAWG')
|
360
|
+
Open.write(real_other,'')
|
361
|
+
|
362
|
+
assert_equal real_other, Workflow.relocate(real, other)
|
363
|
+
end
|
305
364
|
end
|
306
365
|
|
307
366
|
def test_delete_dep
|
@@ -317,8 +376,17 @@ class TestWorkflow < Test::Unit::TestCase
|
|
317
376
|
job = TestWF.job(:t3)
|
318
377
|
job.step(:t1).clean
|
319
378
|
Misc.with_env "RBBT_UPDATE_ALL_JOBS", "true" do
|
320
|
-
|
379
|
+
assert job.checks.select{|d| d.task_name.to_s == "t1" }.any?
|
321
380
|
end
|
322
381
|
end
|
323
382
|
|
383
|
+
def test_canfail
|
384
|
+
job = TestWF.job(:sum_odds)
|
385
|
+
assert_equal 24, job.run
|
386
|
+
|
387
|
+
job = TestWF.job(:sum_odds_str)
|
388
|
+
job.recursive_clean
|
389
|
+
assert_equal "Sum odds: 24", job.run
|
390
|
+
end
|
391
|
+
|
324
392
|
end
|
data/test/rbbt/util/test_open.rb
CHANGED
@@ -109,7 +109,7 @@ class TestOpen < Test::Unit::TestCase
|
|
109
109
|
file1 = "TEST"
|
110
110
|
file2 = "TEST" * 1000
|
111
111
|
TmpFile.with_file do |tmpdir|
|
112
|
-
tmpdir =
|
112
|
+
tmpdir = Rbbt.tmp.repo_dir.find
|
113
113
|
normal = File.join(tmpdir, 'normal')
|
114
114
|
repo = File.join(tmpdir, 'repo')
|
115
115
|
|
@@ -135,7 +135,7 @@ class TestOpen < Test::Unit::TestCase
|
|
135
135
|
|
136
136
|
def test_repo_dir2
|
137
137
|
TmpFile.with_file do |tmpdir|
|
138
|
-
tmpdir =
|
138
|
+
tmpdir = Rbbt.tmp.repo_dir.find
|
139
139
|
repo = File.join(tmpdir, 'repo')
|
140
140
|
|
141
141
|
Open.repository_dirs.push(repo)
|
@@ -149,5 +149,44 @@ class TestOpen < Test::Unit::TestCase
|
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
|
+
def test_repo_marshal
|
153
|
+
TmpFile.with_file do |tmpdir|
|
154
|
+
tmpdir = Rbbt.tmp.repo_dir.find
|
155
|
+
repo = File.join(tmpdir, 'repo')
|
156
|
+
|
157
|
+
filename = 'file'
|
158
|
+
Open.repository_dirs.push(repo)
|
159
|
+
|
160
|
+
obj = {:a => "string", :pid => nil, :num => 1000, :p => Rbbt.tmp.foo}
|
161
|
+
Open.write(File.join(repo, filename), Marshal.dump(obj))
|
162
|
+
new =Open.open(File.join(repo, filename)) do |f|
|
163
|
+
Marshal.load(f)
|
164
|
+
end
|
165
|
+
|
166
|
+
assert_equal new, obj
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_write_stream_repo
|
172
|
+
Log.severity = 0
|
173
|
+
TmpFile.with_file do |tmpdir|
|
174
|
+
tmpdir = Rbbt.tmp.repo_dir.find
|
175
|
+
repo = File.join(tmpdir, 'repo')
|
176
|
+
|
177
|
+
file = File.join(repo, 'file')
|
178
|
+
Open.repository_dirs.push(repo)
|
179
|
+
|
180
|
+
text = (["text"] * 5) * "\n"
|
181
|
+
|
182
|
+
Misc.consume_stream(StringIO.new(text), false, file)
|
183
|
+
|
184
|
+
assert_equal text, Open.read(file)
|
185
|
+
assert !File.exists?(file)
|
186
|
+
assert Open.exists? file
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
152
191
|
end
|
153
192
|
|
data/test/test_helper.rb
CHANGED
@@ -25,6 +25,7 @@ class Test::Unit::TestCase
|
|
25
25
|
|
26
26
|
def teardown
|
27
27
|
FileUtils.rm_rf Rbbt.tmp.test.workflow.find
|
28
|
+
#Open.clear_dir_repos
|
28
29
|
#if defined? Persist
|
29
30
|
# FileUtils.rm_rf Path.setup("", 'rbbt').tmp.test.find :user
|
30
31
|
# Persist::CONNECTIONS.values.each do |c| c.close end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbbt-util
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.23.
|
4
|
+
version: 5.23.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|