scout-gear 7.3.0 → 8.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.
- checksums.yaml +4 -4
- data/.vimproject +20 -9
- data/VERSION +1 -1
- data/bin/scout +6 -3
- data/lib/rbbt-scout.rb +1 -0
- data/lib/scout/cmd.rb +1 -1
- data/lib/scout/concurrent_stream.rb +26 -23
- data/lib/scout/config.rb +1 -1
- data/lib/scout/log/color.rb +4 -1
- data/lib/scout/log/progress/report.rb +1 -1
- data/lib/scout/log/progress/util.rb +58 -54
- data/lib/scout/log/progress.rb +1 -1
- data/lib/scout/log/trap.rb +107 -0
- data/lib/scout/log.rb +56 -21
- data/lib/scout/meta_extension.rb +13 -6
- data/lib/scout/misc/digest.rb +1 -1
- data/lib/scout/misc/format.rb +12 -0
- data/lib/scout/misc/insist.rb +1 -1
- data/lib/scout/misc/monitor.rb +11 -0
- data/lib/scout/misc/system.rb +10 -0
- data/lib/scout/named_array.rb +65 -3
- data/lib/scout/open/lock/lockfile.rb +587 -0
- data/lib/scout/open/lock.rb +28 -2
- data/lib/scout/open/remote.rb +4 -0
- data/lib/scout/open/stream.rb +90 -15
- data/lib/scout/open/util.rb +13 -3
- data/lib/scout/path/find.rb +9 -1
- data/lib/scout/path/util.rb +35 -0
- data/lib/scout/persist/serialize.rb +18 -5
- data/lib/scout/persist.rb +28 -12
- data/lib/scout/resource/path.rb +53 -0
- data/lib/scout/resource/produce.rb +0 -8
- data/lib/scout/resource/util.rb +2 -1
- data/lib/scout/tmpfile.rb +7 -8
- data/lib/scout/tsv/attach.rb +177 -0
- data/lib/scout/tsv/change_id.rb +40 -0
- data/lib/scout/tsv/dumper.rb +72 -46
- data/lib/scout/tsv/index.rb +69 -13
- data/lib/scout/tsv/open.rb +138 -84
- data/lib/scout/tsv/parser.rb +135 -80
- data/lib/scout/tsv/path.rb +1 -2
- data/lib/scout/tsv/persist/adapter.rb +15 -45
- data/lib/scout/tsv/persist/fix_width_table.rb +3 -0
- data/lib/scout/tsv/persist/tokyocabinet.rb +4 -1
- data/lib/scout/tsv/persist.rb +4 -0
- data/lib/scout/tsv/transformer.rb +141 -0
- data/lib/scout/tsv/traverse.rb +96 -92
- data/lib/scout/tsv/util/filter.rb +9 -0
- data/lib/scout/tsv/util/reorder.rb +81 -0
- data/lib/scout/tsv/util/select.rb +78 -33
- data/lib/scout/tsv/util/unzip.rb +86 -0
- data/lib/scout/tsv/util.rb +60 -11
- data/lib/scout/tsv.rb +26 -3
- data/lib/scout/work_queue/socket.rb +6 -1
- data/lib/scout/work_queue/worker.rb +5 -2
- data/lib/scout/work_queue.rb +15 -8
- data/lib/scout/workflow/definition.rb +21 -2
- data/lib/scout/workflow/step/dependencies.rb +24 -4
- data/lib/scout/workflow/step/info.rb +36 -5
- data/lib/scout/workflow/step/provenance.rb +8 -7
- data/lib/scout/workflow/step/status.rb +45 -0
- data/lib/scout/workflow/step.rb +100 -34
- data/lib/scout/workflow/task/inputs.rb +14 -20
- data/lib/scout/workflow/task.rb +81 -46
- data/lib/scout/workflow/usage.rb +8 -6
- data/scout-gear.gemspec +24 -20
- data/scout_commands/workflow/task +34 -7
- data/test/scout/open/test_stream.rb +60 -58
- data/test/scout/path/test_find.rb +10 -1
- data/test/scout/resource/test_produce.rb +15 -0
- data/test/scout/test_meta_extension.rb +25 -0
- data/test/scout/test_named_array.rb +18 -0
- data/test/scout/test_persist.rb +6 -0
- data/test/scout/test_tsv.rb +212 -2
- data/test/scout/test_work_queue.rb +21 -19
- data/test/scout/tsv/persist/test_adapter.rb +1 -1
- data/test/scout/tsv/persist/test_tokyocabinet.rb +29 -1
- data/test/scout/tsv/test_attach.rb +227 -0
- data/test/scout/tsv/test_change_id.rb +98 -0
- data/test/scout/tsv/test_dumper.rb +1 -1
- data/test/scout/tsv/test_index.rb +35 -3
- data/test/scout/tsv/test_open.rb +160 -2
- data/test/scout/tsv/test_parser.rb +19 -2
- data/test/scout/tsv/test_persist.rb +2 -0
- data/test/scout/tsv/test_transformer.rb +108 -0
- data/test/scout/tsv/test_traverse.rb +88 -3
- data/test/scout/tsv/test_util.rb +1 -0
- data/test/scout/tsv/util/test_reorder.rb +94 -0
- data/test/scout/tsv/util/test_select.rb +25 -11
- data/test/scout/tsv/util/test_unzip.rb +112 -0
- data/test/scout/work_queue/test_socket.rb +0 -1
- data/test/scout/workflow/step/test_status.rb +31 -0
- data/test/scout/workflow/task/test_inputs.rb +14 -14
- data/test/scout/workflow/test_step.rb +3 -3
- data/test/scout/workflow/test_task.rb +168 -32
- data/test/scout/workflow/test_usage.rb +33 -6
- metadata +20 -6
data/lib/scout/open/stream.rb
CHANGED
@@ -56,6 +56,7 @@ module Open
|
|
56
56
|
|
57
57
|
while c = io.read(BLOCK_SIZE)
|
58
58
|
into << c if into
|
59
|
+
last_c = c if c
|
59
60
|
break if io.closed?
|
60
61
|
end
|
61
62
|
|
@@ -65,13 +66,15 @@ module Open
|
|
65
66
|
into.close if into and into_close and not into.closed?
|
66
67
|
block.call if block_given?
|
67
68
|
|
68
|
-
|
69
|
+
last_c
|
69
70
|
rescue Aborted
|
71
|
+
Thread.current["exception"] = true
|
70
72
|
Log.low "Consume stream Aborted #{Log.fingerprint io} into #{into_path || into}"
|
71
73
|
io.abort $! if io.respond_to? :abort
|
72
74
|
into.close if into.respond_to?(:closed?) && ! into.closed?
|
73
75
|
FileUtils.rm into_path if into_path and File.exist?(into_path)
|
74
76
|
rescue Exception
|
77
|
+
Thread.current["exception"] = true
|
75
78
|
Log.low "Consume stream Exception reading #{Log.fingerprint io} into #{into_path || into} - #{$!.message}"
|
76
79
|
exception = (io.respond_to?(:stream_exception) && io.stream_exception) ? io.stream_exception : $!
|
77
80
|
io.abort exception if io.respond_to? :abort
|
@@ -109,7 +112,6 @@ module Open
|
|
109
112
|
FileUtils.mkdir_p File.dirname(tmp_path) unless File.directory?(File.dirname(tmp_path))
|
110
113
|
FileUtils.rm_f tmp_path if File.exist? tmp_path
|
111
114
|
begin
|
112
|
-
|
113
115
|
case
|
114
116
|
when block_given?
|
115
117
|
File.open(tmp_path, 'wb', &block)
|
@@ -117,7 +119,6 @@ module Open
|
|
117
119
|
File.open(tmp_path, 'wb') do |f| f.write content end
|
118
120
|
when (IO === content or StringIO === content or File === content)
|
119
121
|
Open.write(tmp_path) do |f|
|
120
|
-
#f.sync = true
|
121
122
|
while block = content.read(BLOCK_SIZE)
|
122
123
|
f.write block
|
123
124
|
break if content.closed?
|
@@ -139,14 +140,15 @@ module Open
|
|
139
140
|
content.join if content.respond_to?(:join) and not Path === content and not (content.respond_to?(:joined?) && content.joined?)
|
140
141
|
|
141
142
|
Open.notify_write(path)
|
143
|
+
Log.debug "Done sensible write: [#{Process.pid}] -- #{ path }"
|
142
144
|
rescue Aborted
|
143
|
-
Log.low "Aborted sensible_write -- #{ Log.reset <<
|
145
|
+
Log.low "Aborted sensible_write -- #{ Log.reset << path }"
|
144
146
|
content.abort if content.respond_to? :abort
|
145
147
|
Open.rm path if File.exist? path
|
146
148
|
rescue Exception
|
147
149
|
exception = (AbortedStream === content and content.exception) ? content.exception : $!
|
148
|
-
Log.low "Exception in sensible_write: [#{Process.pid}] #{exception.message} -- #{
|
149
|
-
content.abort if content.respond_to? :abort
|
150
|
+
Log.low "Exception in sensible_write: [#{Process.pid}] #{exception.message} -- #{ path }"
|
151
|
+
content.abort(exception) if content.respond_to? :abort
|
150
152
|
Open.rm path if File.exist? path
|
151
153
|
raise exception
|
152
154
|
rescue
|
@@ -187,7 +189,7 @@ module Open
|
|
187
189
|
FileUtils.rm path if erase && File.exist?(path)
|
188
190
|
end
|
189
191
|
end
|
190
|
-
|
192
|
+
|
191
193
|
def self.release_pipes(*pipes)
|
192
194
|
PIPE_MUTEX.synchronize do
|
193
195
|
pipes.flatten.each do |pipe|
|
@@ -239,7 +241,7 @@ module Open
|
|
239
241
|
begin
|
240
242
|
Thread.current.report_on_exception = false
|
241
243
|
Thread.current["name"] = "Pipe input #{Log.fingerprint sin} => #{Log.fingerprint sout}"
|
242
|
-
|
244
|
+
|
243
245
|
yield sin
|
244
246
|
|
245
247
|
sin.close if close and not sin.closed? and not sin.aborted?
|
@@ -306,9 +308,16 @@ module Open
|
|
306
308
|
stream.close unless stream.closed?
|
307
309
|
in_pipes.first.close unless in_pipes.first.closed?
|
308
310
|
rescue Aborted, Interrupt
|
309
|
-
stream.abort if stream.respond_to?
|
310
|
-
out_pipes.each do |sout|
|
311
|
-
sout.
|
311
|
+
stream.abort if stream.respond_to?(:abort) && ! stream.aborted?
|
312
|
+
out_pipes.reverse.each do |sout|
|
313
|
+
sout.threads.delete(Thread.current)
|
314
|
+
begin
|
315
|
+
sout.abort($!) if sout.respond_to?(:abort) && ! sout.aborted?
|
316
|
+
rescue
|
317
|
+
end
|
318
|
+
end
|
319
|
+
in_pipes.each do |sin|
|
320
|
+
sin.close unless sin.closed?
|
312
321
|
end
|
313
322
|
Log.low "Tee aborting #{Log.fingerprint stream}"
|
314
323
|
raise $!
|
@@ -327,12 +336,14 @@ module Open
|
|
327
336
|
end
|
328
337
|
Log.low "Tee exception #{Log.fingerprint stream}"
|
329
338
|
rescue
|
330
|
-
Log.exception $!
|
331
339
|
ensure
|
332
|
-
|
333
|
-
|
340
|
+
begin
|
341
|
+
in_pipes.each do |sin|
|
342
|
+
sin.close unless sin.closed?
|
343
|
+
end
|
344
|
+
ensure
|
345
|
+
raise $!
|
334
346
|
end
|
335
|
-
raise $!
|
336
347
|
end
|
337
348
|
end
|
338
349
|
end
|
@@ -425,5 +436,69 @@ module Open
|
|
425
436
|
end
|
426
437
|
end
|
427
438
|
|
439
|
+
def self.process_stream(s)
|
440
|
+
begin
|
441
|
+
yield s
|
442
|
+
s.close if s.respond_to?(:close) && ! s.closed?
|
443
|
+
s.join if s.respond_to?(:join)
|
444
|
+
rescue
|
445
|
+
s.abort($!) if s.respond_to? :abort
|
446
|
+
raise $!
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
|
451
|
+
def self.collapse_stream(s, line: nil, sep: "\t", header: nil, &block)
|
452
|
+
sep ||= "\t"
|
453
|
+
Open.open_pipe do |sin|
|
454
|
+
sin.puts header if header
|
455
|
+
process_stream(s) do |s|
|
456
|
+
line ||= s.gets
|
457
|
+
|
458
|
+
current_parts = []
|
459
|
+
while line
|
460
|
+
key, *parts = line.chomp.split(sep, -1)
|
461
|
+
case
|
462
|
+
when key.nil?
|
463
|
+
when current_parts.nil?
|
464
|
+
current_parts = parts
|
465
|
+
current_key = key
|
466
|
+
when current_key == key
|
467
|
+
parts.each_with_index do |part,i|
|
468
|
+
if current_parts[i].nil?
|
469
|
+
current_parts[i] = "|" << part
|
470
|
+
else
|
471
|
+
current_parts[i] = current_parts[i] << "|" << part
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
(parts.length..current_parts.length-1).to_a.each do |pos|
|
476
|
+
current_parts[pos] = current_parts[pos] << "|" << ""
|
477
|
+
end
|
478
|
+
when current_key.nil?
|
479
|
+
current_key = key
|
480
|
+
current_parts = parts
|
481
|
+
when current_key != key
|
482
|
+
if block_given?
|
483
|
+
res = block.call(current_parts)
|
484
|
+
sin.puts [current_key, res] * sep
|
485
|
+
else
|
486
|
+
sin.puts [current_key, current_parts].flatten * sep
|
487
|
+
end
|
488
|
+
current_key = key
|
489
|
+
current_parts = parts
|
490
|
+
end
|
491
|
+
line = s.gets
|
492
|
+
end
|
493
|
+
|
494
|
+
if block_given?
|
495
|
+
res = block.call(current_parts)
|
496
|
+
sin.puts [current_key, res] * sep
|
497
|
+
else
|
498
|
+
sin.puts [current_key, current_parts].flatten * sep
|
499
|
+
end unless current_key.nil?
|
500
|
+
end
|
501
|
+
end
|
502
|
+
end
|
428
503
|
|
429
504
|
end
|
data/lib/scout/open/util.rb
CHANGED
@@ -94,6 +94,11 @@ module Open
|
|
94
94
|
File.symlink?(path) && ! File.exist?(File.readlink(path))
|
95
95
|
end
|
96
96
|
|
97
|
+
def self.directory?(file)
|
98
|
+
file = file.find if Path === file
|
99
|
+
File.directory?(file)
|
100
|
+
end
|
101
|
+
|
97
102
|
def self.exists?(file)
|
98
103
|
file = file.find if Path === file
|
99
104
|
File.exist?(file)
|
@@ -111,7 +116,7 @@ module Open
|
|
111
116
|
end
|
112
117
|
|
113
118
|
def self.rm(file)
|
114
|
-
FileUtils.rm(file) if File.exist?(file)
|
119
|
+
FileUtils.rm(file) if File.exist?(file) || Open.broken_link?(file)
|
115
120
|
end
|
116
121
|
|
117
122
|
def self.rm_rf(file)
|
@@ -155,7 +160,7 @@ module Open
|
|
155
160
|
begin
|
156
161
|
if File.symlink?(file) || File.stat(file).nlink > 1
|
157
162
|
if File.exist?(file + '.info') && defined?(Step)
|
158
|
-
done =
|
163
|
+
done = Persist.load(file + '.info', Step::SERIALIZER)[:done]
|
159
164
|
return done if done
|
160
165
|
end
|
161
166
|
|
@@ -173,7 +178,7 @@ module Open
|
|
173
178
|
target = target.find if Path === target
|
174
179
|
|
175
180
|
FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
|
176
|
-
FileUtils.
|
181
|
+
FileUtils.rm_rf target if File.exist?(target)
|
177
182
|
FileUtils.cp_r source, target
|
178
183
|
end
|
179
184
|
|
@@ -222,4 +227,9 @@ module Open
|
|
222
227
|
end
|
223
228
|
nil
|
224
229
|
end
|
230
|
+
|
231
|
+
def self.list(file)
|
232
|
+
file = file.produce_and_find if Path === file
|
233
|
+
Open.read(file).split("\n")
|
234
|
+
end
|
225
235
|
end
|
data/lib/scout/path/find.rb
CHANGED
@@ -10,8 +10,10 @@ module Path
|
|
10
10
|
file =~ /(?:scout|rbbt)\/(?:.*\/)?path\.rb/ or
|
11
11
|
file =~ /(?:scout|rbbt)\/(?:.*\/)?path\/(?:find|refactor|util)\.rb/ or
|
12
12
|
file =~ /(?:scout|rbbt)\/persist.rb/ or
|
13
|
+
file =~ /scout\/resource\/produce.rb/ or
|
13
14
|
file =~ /modules\/rbbt-util/
|
14
15
|
end
|
16
|
+
return nil if file.nil?
|
15
17
|
file = file.sub(/\.rb[^\w].*/,'.rb')
|
16
18
|
end
|
17
19
|
|
@@ -38,7 +40,7 @@ module Path
|
|
38
40
|
sub('{SUBPATH}', path._subpath).
|
39
41
|
sub('{BASENAME}', File.basename(path)).
|
40
42
|
sub('{PATH}', path).
|
41
|
-
sub('{LIBDIR}', path.libdir || (path.pkgdir.respond_to?(:libdir) && path.pkgdir.libdir) || Path.caller_lib_dir).
|
43
|
+
sub('{LIBDIR}', path.libdir || (path.pkgdir.respond_to?(:libdir) && path.pkgdir.libdir) || Path.caller_lib_dir || "NOLIBDIR").
|
42
44
|
sub('{MAPNAME}', map_name.to_s).
|
43
45
|
sub('{REMOVE}/', '').
|
44
46
|
sub('{REMOVE}', '').gsub(/\/+/,'/')
|
@@ -188,4 +190,10 @@ module Path
|
|
188
190
|
.select{|file| file.exist? }.uniq
|
189
191
|
end
|
190
192
|
|
193
|
+
def find_with_extension(extension, *args)
|
194
|
+
found = self.find(*args)
|
195
|
+
return found if found.exists?
|
196
|
+
found_with_extension = self.set_extension(extension).find
|
197
|
+
found_with_extension.exists? ? found_with_extension : found
|
198
|
+
end
|
191
199
|
end
|
data/lib/scout/path/util.rb
CHANGED
@@ -12,6 +12,23 @@ module Path
|
|
12
12
|
return false
|
13
13
|
end
|
14
14
|
|
15
|
+
def self.sanitize_filename(filename, length = 254)
|
16
|
+
if filename.length > length
|
17
|
+
if filename =~ /(\..{2,9})$/
|
18
|
+
extension = $1
|
19
|
+
else
|
20
|
+
extension = ''
|
21
|
+
end
|
22
|
+
|
23
|
+
post_fix = "--#{filename.length}@#{length}_#{Misc.digest(filename)[0..4]}" + extension
|
24
|
+
|
25
|
+
filename = filename[0..(length - post_fix.length - 1)] << post_fix
|
26
|
+
else
|
27
|
+
filename
|
28
|
+
end
|
29
|
+
filename
|
30
|
+
end
|
31
|
+
|
15
32
|
def directory?
|
16
33
|
return nil unless self.exist?
|
17
34
|
File.directory?(self.find)
|
@@ -64,4 +81,22 @@ module Path
|
|
64
81
|
def set_extension(extension)
|
65
82
|
self.annotate(self + ".#{extension}")
|
66
83
|
end
|
84
|
+
|
85
|
+
# Is 'file' newer than 'path'? return non-true if path is newer than file
|
86
|
+
def self.newer?(path, file, by_link = false)
|
87
|
+
return true if not Open.exists?(file)
|
88
|
+
path = path.find if Path === path
|
89
|
+
file = file.find if Path === file
|
90
|
+
if by_link
|
91
|
+
patht = File.exist?(path) ? File.lstat(path).mtime : nil
|
92
|
+
filet = File.exist?(file) ? File.lstat(file).mtime : nil
|
93
|
+
else
|
94
|
+
patht = Open.mtime(path)
|
95
|
+
filet = Open.mtime(file)
|
96
|
+
end
|
97
|
+
return true if patht.nil? || filet.nil?
|
98
|
+
diff = patht - filet
|
99
|
+
return diff if diff < 0
|
100
|
+
return false
|
101
|
+
end
|
67
102
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative '../open'
|
2
2
|
require_relative 'open'
|
3
|
+
require 'set'
|
3
4
|
|
4
5
|
module Persist
|
5
6
|
TRUE_STRINGS = Set.new ["true", "True", "TRUE", "t", "T", "1", "yes", "Yes", "YES", "y", "Y", "ON", "on"] unless defined? TRUE_STRINGS
|
@@ -19,7 +20,7 @@ module Persist
|
|
19
20
|
type = type.to_sym if String === type
|
20
21
|
type = SERIALIZER if type == :serializer
|
21
22
|
case type
|
22
|
-
when nil, :string, :integer, :float, :boolean, :file, :path
|
23
|
+
when nil, :string, :integer, :float, :boolean, :file, :path, :select, :folder
|
23
24
|
if IO === content || StringIO === content
|
24
25
|
content.read
|
25
26
|
else
|
@@ -46,8 +47,9 @@ module Persist
|
|
46
47
|
def self.deserialize(serialized, type)
|
47
48
|
type = type.to_sym if String === type
|
48
49
|
type = SERIALIZER if type == :serializer
|
50
|
+
|
49
51
|
case type
|
50
|
-
when nil, :string, :file, :stream
|
52
|
+
when nil, :string, :file, :stream, :select, :folder
|
51
53
|
serialized
|
52
54
|
when :path
|
53
55
|
Path.setup(serialized)
|
@@ -99,9 +101,18 @@ module Persist
|
|
99
101
|
return save_drivers[type].call(file, content)
|
100
102
|
end
|
101
103
|
end
|
102
|
-
|
103
|
-
|
104
|
-
|
104
|
+
|
105
|
+
if type == :binary
|
106
|
+
content.force_encoding("ASCII-8BIT") if content.respond_to? :force_encoding
|
107
|
+
Open.open(path, :mode => 'wb') do |f|
|
108
|
+
f.puts content
|
109
|
+
end
|
110
|
+
content
|
111
|
+
else
|
112
|
+
serialized = serialize(content, type)
|
113
|
+
Open.sensible_write(file, serialized, :force => true)
|
114
|
+
return nil
|
115
|
+
end
|
105
116
|
end
|
106
117
|
|
107
118
|
def self.load(file, type = :serializer)
|
@@ -118,6 +129,8 @@ module Persist
|
|
118
129
|
end
|
119
130
|
|
120
131
|
case type
|
132
|
+
when :binary
|
133
|
+
Open.read(file, :mode => 'rb')
|
121
134
|
when :yaml
|
122
135
|
Open.yaml(file)
|
123
136
|
when :json
|
data/lib/scout/persist.rb
CHANGED
@@ -21,7 +21,9 @@ module Persist
|
|
21
21
|
def self.persistence_path(name, options = {})
|
22
22
|
options = IndiferentHash.add_defaults options, :dir => Persist.cache_dir
|
23
23
|
other_options = IndiferentHash.pull_keys options, :other
|
24
|
-
|
24
|
+
name = name.filename if name.respond_to?(:filename) && name.filename
|
25
|
+
persist_options = {}
|
26
|
+
TmpFile.tmp_for_file(name, options.merge(persist_options), other_options)
|
25
27
|
end
|
26
28
|
|
27
29
|
MEMORY_CACHE = {}
|
@@ -31,25 +33,31 @@ module Persist
|
|
31
33
|
return yield if FalseClass === persist_options[:persist]
|
32
34
|
file = persist_options[:path] || options[:path] || persistence_path(name, options)
|
33
35
|
|
34
|
-
lockfile = persist_options[:lockfile] || options[:lockfile] || Persist.persistence_path(file + '.persist', {:dir => Persist.lock_dir})
|
35
|
-
|
36
|
-
update = options[:update] || persist_options[:update]
|
37
|
-
update = Open.mtime(update) if Path === update
|
38
|
-
update = Open.mtime(file) >= update ? false : true if Time === update
|
39
|
-
|
40
36
|
if type == :memory
|
41
37
|
repo = options[:memory] || options[:repo] || MEMORY_CACHE
|
42
38
|
repo[file] ||= yield
|
43
39
|
return repo[file]
|
44
40
|
end
|
45
41
|
|
42
|
+
update = options[:update] || persist_options[:update]
|
43
|
+
update = Open.mtime(update) if Path === update
|
44
|
+
update = Open.mtime(file) >= update ? false : true if Time === update
|
45
|
+
|
46
|
+
lockfile = persist_options[:lockfile] || options[:lockfile] || Persist.persistence_path(file + '.persist', {:dir => Persist.lock_dir})
|
47
|
+
|
46
48
|
Open.lock lockfile do |lock|
|
47
49
|
if Open.exist?(file) && ! update
|
48
50
|
Persist.load(file, type)
|
49
51
|
else
|
50
|
-
return yield(file) if block.arity == 1
|
51
|
-
res = yield
|
52
52
|
begin
|
53
|
+
file = file.find if Path === file
|
54
|
+
return yield(file) if block.arity == 1
|
55
|
+
res = yield
|
56
|
+
|
57
|
+
if res.nil?
|
58
|
+
return Persist.load(file, type)
|
59
|
+
end
|
60
|
+
|
53
61
|
Open.rm(file)
|
54
62
|
|
55
63
|
if IO === res || StringIO === res
|
@@ -73,16 +81,24 @@ module Persist
|
|
73
81
|
res = pres unless pres.nil?
|
74
82
|
end
|
75
83
|
rescue
|
84
|
+
Thread.handle_interrupt(Exception => :never) do
|
85
|
+
if Open.exist?(file)
|
86
|
+
Log.debug "Failed persistence #{file} - erasing"
|
87
|
+
Open.rm file
|
88
|
+
else
|
89
|
+
Log.debug "Failed persistence #{file}"
|
90
|
+
end
|
91
|
+
end
|
76
92
|
raise $! unless options[:canfail]
|
77
|
-
Log.debug "Could not persist #{type} on #{file}"
|
78
93
|
end
|
79
94
|
res
|
80
95
|
end
|
81
96
|
end
|
82
97
|
end
|
83
98
|
|
84
|
-
def self.memory(name,
|
85
|
-
|
99
|
+
def self.memory(name, options = {}, &block)
|
100
|
+
options[:persist_path] ||= options[:path] ||= [name, options[:key]].compact * ":"
|
101
|
+
self.persist(name, :memory, options, &block)
|
86
102
|
end
|
87
103
|
|
88
104
|
end
|
data/lib/scout/resource/path.rb
CHANGED
@@ -1,4 +1,47 @@
|
|
1
1
|
module Path
|
2
|
+
def produce(force = false)
|
3
|
+
return self if ! force && (Open.exist?(self) || @produced)
|
4
|
+
begin
|
5
|
+
if Resource === self.pkgdir
|
6
|
+
self.pkgdir.produce self
|
7
|
+
else
|
8
|
+
false
|
9
|
+
end
|
10
|
+
rescue ResourceNotFound
|
11
|
+
false
|
12
|
+
rescue
|
13
|
+
message = $!.message
|
14
|
+
message = "No exception message" if message.nil? || message.empty?
|
15
|
+
Log.warn "Error producing #{self}: #{message}"
|
16
|
+
false
|
17
|
+
ensure
|
18
|
+
@produced = true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def produce_with_extension(extension, *args)
|
23
|
+
begin
|
24
|
+
self.produce(*args)
|
25
|
+
rescue Exception
|
26
|
+
exception = $!
|
27
|
+
begin
|
28
|
+
self.set_extension(extension).produce(*args)
|
29
|
+
rescue Exception
|
30
|
+
raise exception
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def produce_and_find(extension = nil, *args)
|
36
|
+
if extension
|
37
|
+
found = find_with_extension(extension, *args)
|
38
|
+
found.exists? ? found : produce_with_extension(extension, *args)
|
39
|
+
else
|
40
|
+
found = find
|
41
|
+
found.exists? ? found : produce(*args)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
2
45
|
def relocate
|
3
46
|
return self if Open.exists?(self)
|
4
47
|
Resource.relocate(self)
|
@@ -17,4 +60,14 @@ module Path
|
|
17
60
|
def write(*args, &block)
|
18
61
|
Open.write(self.find, *args, &block)
|
19
62
|
end
|
63
|
+
|
64
|
+
def list
|
65
|
+
found = produce_and_find('list')
|
66
|
+
Open.list(found)
|
67
|
+
end
|
68
|
+
|
69
|
+
def exists?
|
70
|
+
return true if Open.exists?(self.find)
|
71
|
+
self.produce
|
72
|
+
end
|
20
73
|
end
|
data/lib/scout/resource/util.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module Resource
|
2
2
|
def identify(path)
|
3
3
|
return path unless path.start_with?("/")
|
4
|
-
path_maps = path.path_maps
|
4
|
+
path_maps = path.path_maps if Path === path
|
5
|
+
path_maps ||= self.path_maps || Path.path_maps
|
5
6
|
path = File.expand_path(path)
|
6
7
|
path += "/" if File.directory?(path)
|
7
8
|
|
data/lib/scout/tmpfile.rb
CHANGED
@@ -93,19 +93,18 @@ module TmpFile
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
+
SLASH_REPLACE = '·'
|
96
97
|
def self.tmp_for_file(file, tmp_options = {}, other_options = {})
|
97
|
-
tmp_for_file = IndiferentHash.process_options tmp_options, :file
|
98
|
+
tmp_for_file, prefix, key, persistence_dir = IndiferentHash.process_options tmp_options, :file, :prefix, :key, :dir
|
98
99
|
return tmp_for_file unless tmp_for_file.nil?
|
99
100
|
|
100
|
-
prefix = IndiferentHash.process_options tmp_options, :prefix
|
101
|
-
|
102
101
|
if prefix.nil?
|
103
|
-
perfile = file.to_s.
|
102
|
+
perfile = file.to_s.sub(/\.b?gz$/,'')
|
104
103
|
else
|
105
|
-
perfile = prefix.to_s + ":" + file.to_s.
|
104
|
+
perfile = prefix.to_s + ":" + file.to_s.sub(/\.b?gz$/,'')
|
106
105
|
end
|
107
106
|
|
108
|
-
perfile
|
107
|
+
perfile += "[#{ key }]" if key
|
109
108
|
|
110
109
|
if other_options.include? :filters
|
111
110
|
other_options[:filters].each do |match,value|
|
@@ -113,10 +112,10 @@ module TmpFile
|
|
113
112
|
end
|
114
113
|
end
|
115
114
|
|
116
|
-
persistence_dir =
|
115
|
+
persistence_dir = TmpFile.tmpdir if persistence_dir.nil?
|
117
116
|
Path.setup(persistence_dir) unless Path === persistence_dir
|
118
117
|
|
119
|
-
filename = perfile.gsub(/\s/,'_').gsub(
|
118
|
+
filename = perfile.gsub(/\s/,'_').gsub('/', SLASH_REPLACE)
|
120
119
|
clean_options = other_options.dup
|
121
120
|
clean_options.delete :unnamed
|
122
121
|
clean_options.delete "unnamed"
|