scout-gear 8.0.0 → 8.1.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 +26 -9
- data/Rakefile +6 -1
- data/VERSION +1 -1
- data/bin/scout +15 -4
- data/doc/lib/scout/path.md +35 -0
- data/doc/lib/scout/workflow/task.md +13 -0
- data/lib/scout/cmd.rb +23 -24
- data/lib/scout/concurrent_stream.rb +36 -19
- data/lib/scout/exceptions.rb +10 -0
- data/lib/scout/log/color.rb +11 -11
- data/lib/scout/log/progress/report.rb +7 -5
- data/lib/scout/log/progress/util.rb +3 -0
- data/lib/scout/log/trap.rb +3 -3
- data/lib/scout/log.rb +64 -36
- data/lib/scout/meta_extension.rb +34 -0
- data/lib/scout/misc/digest.rb +11 -2
- data/lib/scout/misc/format.rb +12 -7
- data/lib/scout/misc/monitor.rb +11 -0
- data/lib/scout/misc/system.rb +48 -0
- data/lib/scout/named_array.rb +8 -0
- data/lib/scout/offsite/ssh.rb +171 -0
- data/lib/scout/offsite/step.rb +83 -0
- data/lib/scout/offsite/sync.rb +55 -0
- data/lib/scout/offsite.rb +3 -0
- data/lib/scout/open/lock.rb +5 -24
- data/lib/scout/open/remote.rb +12 -1
- data/lib/scout/open/stream.rb +110 -122
- data/lib/scout/open/util.rb +9 -0
- data/lib/scout/open.rb +5 -4
- data/lib/scout/path/find.rb +15 -10
- data/lib/scout/path/util.rb +5 -0
- data/lib/scout/persist/serialize.rb +3 -3
- data/lib/scout/persist.rb +1 -1
- data/lib/scout/resource/path.rb +4 -0
- data/lib/scout/resource/util.rb +10 -4
- data/lib/scout/tsv/dumper.rb +2 -0
- data/lib/scout/tsv/index.rb +28 -86
- data/lib/scout/tsv/open.rb +35 -14
- data/lib/scout/tsv/parser.rb +9 -2
- data/lib/scout/tsv/persist/tokyocabinet.rb +2 -0
- data/lib/scout/tsv/stream.rb +204 -0
- data/lib/scout/tsv/transformer.rb +11 -0
- data/lib/scout/tsv.rb +9 -2
- data/lib/scout/work_queue/worker.rb +2 -2
- data/lib/scout/work_queue.rb +36 -12
- data/lib/scout/workflow/definition.rb +2 -1
- data/lib/scout/workflow/deployment/orchestrator.rb +245 -0
- data/lib/scout/workflow/deployment.rb +1 -0
- data/lib/scout/workflow/step/dependencies.rb +37 -11
- data/lib/scout/workflow/step/file.rb +5 -0
- data/lib/scout/workflow/step/info.rb +5 -3
- data/lib/scout/workflow/step/load.rb +1 -1
- data/lib/scout/workflow/step/provenance.rb +1 -0
- data/lib/scout/workflow/step/status.rb +6 -8
- data/lib/scout/workflow/step.rb +75 -30
- data/lib/scout/workflow/task/dependencies.rb +114 -0
- data/lib/scout/workflow/task/inputs.rb +27 -13
- data/lib/scout/workflow/task.rb +9 -108
- data/lib/scout/workflow/usage.rb +40 -12
- data/lib/scout/workflow.rb +4 -2
- data/lib/scout-gear.rb +2 -0
- data/lib/scout.rb +6 -0
- data/scout-gear.gemspec +32 -7
- data/scout_commands/doc +37 -0
- data/scout_commands/find +1 -0
- data/scout_commands/offsite +30 -0
- data/scout_commands/update +29 -0
- data/scout_commands/workflow/info +15 -3
- data/scout_commands/workflow/install +102 -0
- data/scout_commands/workflow/task +26 -5
- data/test/scout/offsite/test_ssh.rb +15 -0
- data/test/scout/offsite/test_step.rb +33 -0
- data/test/scout/offsite/test_sync.rb +36 -0
- data/test/scout/offsite/test_task.rb +0 -0
- data/test/scout/resource/test_path.rb +6 -0
- data/test/scout/test_named_array.rb +6 -0
- data/test/scout/test_persist.rb +3 -2
- data/test/scout/test_tsv.rb +17 -0
- data/test/scout/test_work_queue.rb +63 -41
- data/test/scout/tsv/persist/test_adapter.rb +1 -1
- data/test/scout/tsv/test_index.rb +14 -0
- data/test/scout/tsv/test_parser.rb +14 -0
- data/test/scout/tsv/test_stream.rb +200 -0
- data/test/scout/tsv/test_transformer.rb +12 -0
- data/test/scout/workflow/deployment/test_orchestrator.rb +272 -0
- data/test/scout/workflow/step/test_dependencies.rb +68 -0
- data/test/scout/workflow/step/test_info.rb +18 -0
- data/test/scout/workflow/step/test_status.rb +0 -1
- data/test/scout/workflow/task/test_dependencies.rb +355 -0
- data/test/scout/workflow/task/test_inputs.rb +53 -0
- data/test/scout/workflow/test_definition.rb +18 -0
- data/test/scout/workflow/test_documentation.rb +24 -0
- data/test/scout/workflow/test_step.rb +109 -0
- data/test/scout/workflow/test_task.rb +0 -287
- data/test/test_scout.rb +9 -0
- metadata +83 -5
- data/scout_commands/workflow/task_old +0 -706
data/lib/scout/open/lock.rb
CHANGED
@@ -4,27 +4,13 @@ require_relative '../exceptions'
|
|
4
4
|
require_relative 'lock/lockfile'
|
5
5
|
|
6
6
|
module Open
|
7
|
-
def self.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def self.unlock_thread(t, exception = nil)
|
12
|
-
while t.alive? && t.backtrace.select{|l| l.include?("lockfile") }.any?
|
13
|
-
iii :UNLOCK
|
14
|
-
t.raise(exception)
|
15
|
-
Log.stack t.backtrace
|
16
|
-
locks = t["locks"]
|
17
|
-
return if locks.nil? || locks.empty?
|
18
|
-
locks.each do |lock|
|
19
|
-
lock.unlock if lock.locked?
|
20
|
-
Open.rm(lock.path)
|
21
|
-
end
|
22
|
-
iii Thread.current
|
23
|
-
Thread.list.each{|t| iii [t, t["locks"]]; Log.stack t.backtrace }
|
24
|
-
Log.stack t.backtrace
|
25
|
-
end
|
7
|
+
def self.init_lock
|
8
|
+
Lockfile.refresh = 2
|
9
|
+
Lockfile.max_age = 30
|
10
|
+
Lockfile.suspend = 4
|
26
11
|
end
|
27
12
|
|
13
|
+
self.init_lock
|
28
14
|
|
29
15
|
def self.lock(file, unlock = true, options = {})
|
30
16
|
unlock, options = true, unlock if Hash === unlock
|
@@ -57,9 +43,6 @@ module Open
|
|
57
43
|
raise LockInterrupted
|
58
44
|
end
|
59
45
|
|
60
|
-
iii Thread.current["lock_exception"] if Thread.current["lock_exception"]
|
61
|
-
raise Thread.current["lock_exception"] if Thread.current["lock_exception"]
|
62
|
-
|
63
46
|
res = nil
|
64
47
|
|
65
48
|
begin
|
@@ -73,8 +56,6 @@ module Open
|
|
73
56
|
if lockfile.locked?
|
74
57
|
lockfile.unlock
|
75
58
|
end
|
76
|
-
iii Thread.current["lock_exception"] if Thread.current["lock_exception"]
|
77
|
-
raise Thread.current["lock_exception"] if Thread.current["lock_exception"]
|
78
59
|
rescue Exception
|
79
60
|
Log.warn "Exception unlocking: #{lockfile.path}"
|
80
61
|
Log.exception $!
|
data/lib/scout/open/remote.rb
CHANGED
@@ -23,7 +23,11 @@ module Open
|
|
23
23
|
m = file.match(/ssh:\/\/([^:]+):(.*)/)
|
24
24
|
server = m[1]
|
25
25
|
file = m[2]
|
26
|
-
|
26
|
+
if server == 'localhost'
|
27
|
+
Open.open(file)
|
28
|
+
else
|
29
|
+
CMD.cmd("ssh '#{server}' cat '#{file}'", :pipe => true, :autojoin => true)
|
30
|
+
end
|
27
31
|
end
|
28
32
|
|
29
33
|
def self.wget(url, options = {})
|
@@ -121,4 +125,11 @@ module Open
|
|
121
125
|
filename = cache_file(url, options)
|
122
126
|
Open.open(filename)
|
123
127
|
end
|
128
|
+
|
129
|
+
def self.scp(source_file, target_file, target: nil, source: nil)
|
130
|
+
CMD.cmd_log("ssh #{target} mkdir -p #{File.dirname(target_file)}")
|
131
|
+
target_file = [target, target_file] * ":" if target && ! target_file.start_with?(target+":")
|
132
|
+
source_file = [source, source_file] * ":" if source && ! source_file.start_with?(source+":")
|
133
|
+
CMD.cmd_log("scp -r '#{ source_file }' #{target_file}")
|
134
|
+
end
|
124
135
|
end
|
data/lib/scout/open/stream.rb
CHANGED
@@ -3,7 +3,7 @@ module Open
|
|
3
3
|
|
4
4
|
class << self
|
5
5
|
attr_accessor :sensible_write_lock_dir
|
6
|
-
|
6
|
+
|
7
7
|
def sensible_write_lock_dir
|
8
8
|
@sensible_write_lock_dir ||= Path.setup("tmp/sensible_write_locks").find
|
9
9
|
end
|
@@ -18,7 +18,7 @@ module Open
|
|
18
18
|
|
19
19
|
def self.consume_stream(io, in_thread = false, into = nil, into_close = true, &block)
|
20
20
|
return if Path === io
|
21
|
-
return unless io.respond_to? :read
|
21
|
+
return unless io.respond_to? :read
|
22
22
|
|
23
23
|
if io.respond_to? :closed? and io.closed?
|
24
24
|
io.join if io.respond_to? :join
|
@@ -46,12 +46,12 @@ module Open
|
|
46
46
|
begin
|
47
47
|
into = into.find if Path === into
|
48
48
|
|
49
|
-
if String === into
|
49
|
+
if String === into
|
50
50
|
dir = File.dirname(into)
|
51
51
|
Open.mkdir dir unless File.exist?(dir)
|
52
|
-
into_path, into = into, File.open(into, 'w')
|
52
|
+
into_path, into = into, File.open(into, 'w')
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
into_close = false unless into.respond_to? :close
|
56
56
|
|
57
57
|
while c = io.read(BLOCK_SIZE)
|
@@ -66,6 +66,7 @@ module Open
|
|
66
66
|
into.close if into and into_close and not into.closed?
|
67
67
|
block.call if block_given?
|
68
68
|
|
69
|
+
Log.debug "Consume stream done #{Log.fingerprint io} -> #{Log.fingerprint(into_path ||into)}"
|
69
70
|
last_c
|
70
71
|
rescue Aborted
|
71
72
|
Thread.current["exception"] = true
|
@@ -81,7 +82,7 @@ module Open
|
|
81
82
|
into.close if into.respond_to?(:closed?) && ! into.closed?
|
82
83
|
into_path = into if into_path.nil? && String === into
|
83
84
|
if into_path and File.exist?(into_path)
|
84
|
-
FileUtils.rm into_path
|
85
|
+
FileUtils.rm into_path
|
85
86
|
end
|
86
87
|
raise exception
|
87
88
|
end
|
@@ -92,7 +93,7 @@ module Open
|
|
92
93
|
force = IndiferentHash.process_options options, :force
|
93
94
|
|
94
95
|
if File.exist?(path) and not force
|
95
|
-
Open.consume_stream content
|
96
|
+
Open.consume_stream content
|
96
97
|
return
|
97
98
|
end
|
98
99
|
|
@@ -107,10 +108,11 @@ module Open
|
|
107
108
|
|
108
109
|
if File.exist? path and not force
|
109
110
|
Log.warn "Path exists in sensible_write, not forcing update: #{ path }"
|
110
|
-
Open.consume_stream content
|
111
|
+
Open.consume_stream content
|
111
112
|
else
|
112
113
|
FileUtils.mkdir_p File.dirname(tmp_path) unless File.directory?(File.dirname(tmp_path))
|
113
114
|
FileUtils.rm_f tmp_path if File.exist? tmp_path
|
115
|
+
Log.low "Sensible write stream #{Log.fingerprint content} -> #{Log.fingerprint path}" if IO === content
|
114
116
|
begin
|
115
117
|
case
|
116
118
|
when block_given?
|
@@ -122,7 +124,7 @@ module Open
|
|
122
124
|
while block = content.read(BLOCK_SIZE)
|
123
125
|
f.write block
|
124
126
|
break if content.closed?
|
125
|
-
end
|
127
|
+
end
|
126
128
|
end
|
127
129
|
else
|
128
130
|
File.open(tmp_path, 'wb') do |f| end
|
@@ -139,8 +141,7 @@ module Open
|
|
139
141
|
Open.touch path if File.exist? path
|
140
142
|
content.join if content.respond_to?(:join) and not Path === content and not (content.respond_to?(:joined?) && content.joined?)
|
141
143
|
|
142
|
-
Open.notify_write(path)
|
143
|
-
Log.debug "Done sensible write: [#{Process.pid}] -- #{ path }"
|
144
|
+
Open.notify_write(path)
|
144
145
|
rescue Aborted
|
145
146
|
Log.low "Aborted sensible_write -- #{ Log.reset << path }"
|
146
147
|
content.abort if content.respond_to? :abort
|
@@ -174,7 +175,7 @@ module Open
|
|
174
175
|
|
175
176
|
[sout, sin]
|
176
177
|
end
|
177
|
-
Log.
|
178
|
+
Log.low{"Creating pipe #{[Log.fingerprint(res.last), Log.fingerprint(res.first)] * " -> "}"}
|
178
179
|
res
|
179
180
|
end
|
180
181
|
|
@@ -214,14 +215,13 @@ module Open
|
|
214
215
|
|
215
216
|
if do_fork
|
216
217
|
|
217
|
-
#parent_pid = Process.pid
|
218
218
|
pid = Process.fork {
|
219
219
|
begin
|
220
220
|
purge_pipes(sin)
|
221
221
|
sout.close
|
222
222
|
|
223
223
|
yield sin
|
224
|
-
sin.close if close and not sin.closed?
|
224
|
+
sin.close if close and not sin.closed?
|
225
225
|
|
226
226
|
rescue Exception
|
227
227
|
Log.exception $!
|
@@ -237,34 +237,20 @@ module Open
|
|
237
237
|
ConcurrentStream.setup sin, :pair => sout
|
238
238
|
ConcurrentStream.setup sout, :pair => sin
|
239
239
|
|
240
|
-
thread = Thread.new do
|
240
|
+
thread = Thread.new do
|
241
241
|
begin
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
yield sin
|
242
|
+
ConcurrentStream.process_stream(sin, :message => "Open pipe") do
|
243
|
+
Thread.current.report_on_exception = false
|
244
|
+
Thread.current["name"] = "Pipe input #{Log.fingerprint sin} => #{Log.fingerprint sout}"
|
246
245
|
|
247
|
-
|
248
|
-
rescue Aborted
|
249
|
-
Log.low "Aborted open_pipe: #{$!.message}"
|
250
|
-
raise $!
|
251
|
-
rescue Exception
|
252
|
-
Log.low "Exception in open_pipe: #{$!.message}"
|
253
|
-
begin
|
254
|
-
sout.threads.delete(Thread.current)
|
255
|
-
sout.pair = []
|
256
|
-
sout.abort($!) if sout.respond_to?(:abort)
|
257
|
-
sin.threads.delete(Thread.current)
|
258
|
-
sin.pair = []
|
259
|
-
sin.abort($!) if sin.respond_to?(:abort)
|
260
|
-
ensure
|
261
|
-
raise $!
|
246
|
+
yield sin
|
262
247
|
end
|
263
248
|
end
|
264
249
|
end
|
265
250
|
|
266
251
|
sin.threads = [thread]
|
267
252
|
sout.threads = [thread]
|
253
|
+
|
268
254
|
Thread.pass until thread["name"]
|
269
255
|
end
|
270
256
|
|
@@ -274,12 +260,14 @@ module Open
|
|
274
260
|
def self.tee_stream_thread_multiple(stream, num = 2)
|
275
261
|
in_pipes = []
|
276
262
|
out_pipes = []
|
277
|
-
num.times do
|
263
|
+
num.times do
|
278
264
|
sout, sin = Open.pipe
|
279
265
|
in_pipes << sin
|
280
266
|
out_pipes << sout
|
281
267
|
end
|
282
268
|
|
269
|
+
Log.low("Tee stream #{Log.fingerprint stream} -> #{Log.fingerprint out_pipes}")
|
270
|
+
|
283
271
|
filename = stream.filename if stream.respond_to? :filename
|
284
272
|
|
285
273
|
splitter_thread = Thread.new(Thread.current) do |parent|
|
@@ -291,7 +279,7 @@ module Open
|
|
291
279
|
while block = stream.read(BLOCK_SIZE)
|
292
280
|
|
293
281
|
in_pipes.each_with_index do |sin,i|
|
294
|
-
begin
|
282
|
+
begin
|
295
283
|
sin.write block
|
296
284
|
rescue IOError
|
297
285
|
Log.warn("Tee stream #{i} #{Log.fingerprint stream} IOError: #{$!.message} (#{Log.fingerprint sin})");
|
@@ -299,13 +287,12 @@ module Open
|
|
299
287
|
rescue
|
300
288
|
Log.warn("Tee stream #{i} #{Log.fingerprint stream} Exception: #{$!.message} (#{Log.fingerprint sin})");
|
301
289
|
raise $!
|
302
|
-
end unless skip[i]
|
290
|
+
end unless skip[i]
|
303
291
|
end
|
304
292
|
break if stream.closed?
|
305
293
|
end
|
306
294
|
|
307
295
|
stream.join if stream.respond_to? :join
|
308
|
-
stream.close unless stream.closed?
|
309
296
|
in_pipes.first.close unless in_pipes.first.closed?
|
310
297
|
rescue Aborted, Interrupt
|
311
298
|
stream.abort if stream.respond_to?(:abort) && ! stream.aborted?
|
@@ -348,18 +335,32 @@ module Open
|
|
348
335
|
end
|
349
336
|
end
|
350
337
|
|
351
|
-
out_pipes.each do |sout|
|
352
|
-
ConcurrentStream.setup sout, :threads => splitter_thread, :filename => filename, :pair => stream
|
353
|
-
end
|
354
338
|
Thread.pass until splitter_thread["name"]
|
355
339
|
|
356
340
|
main_pipe = out_pipes.first
|
357
|
-
main_pipe.autojoin = true
|
358
341
|
|
359
|
-
main_pipe
|
360
|
-
|
361
|
-
|
362
|
-
|
342
|
+
ConcurrentStream.setup(main_pipe, :threads => [splitter_thread], :filename => filename, :autojoin => true)
|
343
|
+
|
344
|
+
out_pipes[1..-1].each do |sout|
|
345
|
+
ConcurrentStream.setup sout, :filename => filename, :threads => [splitter_thread]
|
346
|
+
end
|
347
|
+
|
348
|
+
main_pipe.callback = proc do
|
349
|
+
begin
|
350
|
+
stream.join if stream.respond_to?(:join) && ! stream.joined?
|
351
|
+
in_pipes[1..-1].each do |sin|
|
352
|
+
sin.close unless sin.closed?
|
353
|
+
end
|
354
|
+
rescue
|
355
|
+
main_pipe.abort_callback.call($!)
|
356
|
+
raise $!
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
main_pipe.abort_callback = proc do |exception|
|
361
|
+
stream.abort(exception)
|
362
|
+
out_pipes[1..-1].each do |sout|
|
363
|
+
sout.abort(exception)
|
363
364
|
end
|
364
365
|
end
|
365
366
|
|
@@ -378,7 +379,7 @@ module Open
|
|
378
379
|
str = nil
|
379
380
|
Thread.pass while IO.select([stream],nil,nil,1).nil?
|
380
381
|
while not str = stream.read(size)
|
381
|
-
IO.select([stream],nil,nil,1)
|
382
|
+
IO.select([stream],nil,nil,1)
|
382
383
|
Thread.pass
|
383
384
|
raise ClosedStream if stream.eof?
|
384
385
|
end
|
@@ -403,102 +404,89 @@ module Open
|
|
403
404
|
str
|
404
405
|
end
|
405
406
|
|
406
|
-
def self.sort_stream(stream, header_hash
|
407
|
-
Open.open_pipe do |sin|
|
408
|
-
|
409
|
-
while line =~ /^#{header_hash}/ do
|
410
|
-
sin.puts line
|
407
|
+
def self.sort_stream(stream, header_hash: "#", cmd_args: "-u", memory: false)
|
408
|
+
sout = Open.open_pipe do |sin|
|
409
|
+
ConcurrentStream.process_stream(stream) do
|
411
410
|
line = stream.gets
|
412
|
-
|
411
|
+
while line && line.start_with?(header_hash) do
|
412
|
+
sin.puts line
|
413
|
+
line = stream.gets
|
414
|
+
end
|
413
415
|
|
414
|
-
|
415
|
-
|
416
|
-
begin
|
416
|
+
line_stream = Open.open_pipe do |line_stream_in|
|
417
|
+
line_stream_in.puts line if line
|
417
418
|
Open.consume_stream(stream, false, line_stream_in)
|
418
|
-
rescue
|
419
|
-
raise $!
|
420
419
|
end
|
421
|
-
|
420
|
+
Log.low "Sub-sort stream #{Log.fingerprint stream} -> #{Log.fingerprint line_stream}"
|
422
421
|
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
sorted.raise($!) if sorted.respond_to? :raise
|
431
|
-
stream.raise($!) if stream.respond_to? :raise
|
432
|
-
ensure
|
433
|
-
raise $!
|
422
|
+
if memory
|
423
|
+
line_stream.read.split("\n").sort.each do |line|
|
424
|
+
sin.puts line
|
425
|
+
end
|
426
|
+
else
|
427
|
+
io = CMD.cmd("env LC_ALL=C sort #{cmd_args || ""}", :in => line_stream, :pipe => true)
|
428
|
+
Open.consume_stream(io, false, sin)
|
434
429
|
end
|
435
430
|
end
|
436
431
|
end
|
432
|
+
Log.low "Sort #{Log.fingerprint stream} -> #{Log.fingerprint sout}"
|
433
|
+
sout
|
437
434
|
end
|
438
435
|
|
439
|
-
def self.
|
440
|
-
|
441
|
-
|
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
|
-
|
436
|
+
#def self.sort_stream(stream, header_hash = "#", cmd_args = "-u")
|
437
|
+
# StringIO.new stream.read.split("\n").sort.uniq * "\n"
|
438
|
+
#end
|
450
439
|
|
451
440
|
def self.collapse_stream(s, line: nil, sep: "\t", header: nil, &block)
|
452
441
|
sep ||= "\t"
|
453
442
|
Open.open_pipe do |sin|
|
443
|
+
|
454
444
|
sin.puts header if header
|
455
|
-
process_stream(s) do |s|
|
456
|
-
line ||= s.gets
|
457
445
|
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
446
|
+
line ||= s.gets
|
447
|
+
|
448
|
+
current_parts = []
|
449
|
+
while line
|
450
|
+
key, *parts = line.chomp.split(sep, -1)
|
451
|
+
case
|
452
|
+
when key.nil?
|
453
|
+
when current_parts.nil?
|
454
|
+
current_parts = parts
|
455
|
+
current_key = key
|
456
|
+
when current_key == key
|
457
|
+
parts.each_with_index do |part,i|
|
458
|
+
if current_parts[i].nil?
|
459
|
+
current_parts[i] = "|" << part
|
460
|
+
else
|
461
|
+
current_parts[i] = current_parts[i] << "|" << part
|
473
462
|
end
|
463
|
+
end
|
474
464
|
|
475
|
-
|
476
|
-
|
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
|
465
|
+
(parts.length..current_parts.length-1).to_a.each do |pos|
|
466
|
+
current_parts[pos] = current_parts[pos] << "|" << ""
|
490
467
|
end
|
491
|
-
|
468
|
+
when current_key.nil?
|
469
|
+
current_key = key
|
470
|
+
current_parts = parts
|
471
|
+
when current_key != key
|
472
|
+
if block_given?
|
473
|
+
res = block.call(current_parts)
|
474
|
+
sin.puts [current_key, res] * sep
|
475
|
+
else
|
476
|
+
sin.puts [current_key, current_parts].flatten * sep
|
477
|
+
end
|
478
|
+
current_key = key
|
479
|
+
current_parts = parts
|
492
480
|
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?
|
481
|
+
line = s.gets
|
500
482
|
end
|
483
|
+
|
484
|
+
if block_given?
|
485
|
+
res = block.call(current_parts)
|
486
|
+
sin.puts [current_key, res] * sep
|
487
|
+
else
|
488
|
+
sin.puts [current_key, current_parts].flatten * sep
|
489
|
+
end unless current_key.nil?
|
501
490
|
end
|
502
491
|
end
|
503
|
-
|
504
492
|
end
|
data/lib/scout/open/util.rb
CHANGED
@@ -68,6 +68,15 @@ module Open
|
|
68
68
|
!! (file =~ /\.zip$/)
|
69
69
|
end
|
70
70
|
|
71
|
+
def self.is_stream?(obj)
|
72
|
+
IO === obj || StringIO === obj
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.has_stream?(obj)
|
76
|
+
obj.respond_to?(:stream)
|
77
|
+
end
|
78
|
+
|
79
|
+
|
71
80
|
def self.notify_write(file)
|
72
81
|
begin
|
73
82
|
notification_file = file + '.notify'
|
data/lib/scout/open.rb
CHANGED
@@ -21,6 +21,8 @@ module Open
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def self.get_stream(file, mode = 'r')
|
24
|
+
return file if Open.is_stream?(file)
|
25
|
+
return file.stream if Open.has_stream?(file)
|
24
26
|
file = file.find if Path === file
|
25
27
|
|
26
28
|
return Open.ssh(file) if Open.ssh?(file)
|
@@ -56,11 +58,11 @@ module Open
|
|
56
58
|
def self.open(file, options = {})
|
57
59
|
if IO === file || StringIO === file
|
58
60
|
if block_given?
|
59
|
-
res = yield file
|
61
|
+
res = yield file
|
60
62
|
file.close
|
61
63
|
return res
|
62
64
|
else
|
63
|
-
return file
|
65
|
+
return file
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
@@ -163,7 +165,6 @@ module Open
|
|
163
165
|
raise "Content unknown #{Log.fingerprint content}"
|
164
166
|
end
|
165
167
|
|
166
|
-
notify_write(file)
|
168
|
+
notify_write(file)
|
167
169
|
end
|
168
|
-
|
169
170
|
end
|
data/lib/scout/path/find.rb
CHANGED
@@ -34,6 +34,7 @@ module Path
|
|
34
34
|
|
35
35
|
def self.follow(path, map, map_name = nil)
|
36
36
|
file = map.sub('{PKGDIR}', path.pkgdir.respond_to?(:pkgdir) ? path.pkgdir.pkgdir || Path.default_pkgdir : path.pkgdir || Path.default_pkgdir).
|
37
|
+
sub('{HOME}', ENV["HOME"]).
|
37
38
|
sub('{RESOURCE}', path.pkgdir.to_s).
|
38
39
|
sub('{PWD}', FileUtils.pwd).
|
39
40
|
sub('{TOPLEVEL}', path._toplevel).
|
@@ -59,16 +60,17 @@ module Path
|
|
59
60
|
|
60
61
|
def self.path_maps
|
61
62
|
@@path_maps ||= IndiferentHash.setup({
|
62
|
-
:current =>
|
63
|
-
:user =>
|
64
|
-
:global =>
|
65
|
-
:usr =>
|
66
|
-
:local =>
|
67
|
-
:fast =>
|
68
|
-
:cache =>
|
69
|
-
:bulk =>
|
70
|
-
:lib =>
|
71
|
-
:
|
63
|
+
:current => "{PWD}/{TOPLEVEL}/{SUBPATH}",
|
64
|
+
:user => "{HOME}/.{PKGDIR}/{TOPLEVEL}/{SUBPATH}",
|
65
|
+
:global => '/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
66
|
+
:usr => '/usr/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
67
|
+
:local => '/usr/local/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
68
|
+
:fast => '/fast/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
69
|
+
:cache => '/cache/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
70
|
+
:bulk => '/bulk/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
|
71
|
+
:lib => '{LIBDIR}/{TOPLEVEL}/{SUBPATH}',
|
72
|
+
:scout_gear => File.join(Path.caller_lib_dir(__FILE__), "{TOPLEVEL}/{SUBPATH}"),
|
73
|
+
:tmp => '/tmp/{PKGDIR}/{TOPLEVEL}/{SUBPATH}',
|
72
74
|
:default => :user
|
73
75
|
})
|
74
76
|
end
|
@@ -127,6 +129,9 @@ module Path
|
|
127
129
|
def follow(map_name = :default, annotate = true)
|
128
130
|
IndiferentHash.setup(path_maps)
|
129
131
|
map = path_maps[map_name] || Path.path_maps[map_name]
|
132
|
+
if map.nil? && String === map_name
|
133
|
+
map = File.join(map_name, '{TOPLEVEL}/{SUBPATH}')
|
134
|
+
end
|
130
135
|
raise "Map not found #{Log.fingerprint map_name} not in #{Log.fingerprint path_maps.keys}" if map.nil?
|
131
136
|
while Symbol === map
|
132
137
|
map_name = map
|
data/lib/scout/path/util.rb
CHANGED
@@ -82,6 +82,11 @@ module Path
|
|
82
82
|
self.annotate(self + ".#{extension}")
|
83
83
|
end
|
84
84
|
|
85
|
+
def unset_extension
|
86
|
+
self.annotate(self.split(".")[0..-2] * ".")
|
87
|
+
end
|
88
|
+
|
89
|
+
|
85
90
|
# Is 'file' newer than 'path'? return non-true if path is newer than file
|
86
91
|
def self.newer?(path, file, by_link = false)
|
87
92
|
return true if not Open.exists?(file)
|
@@ -20,7 +20,7 @@ module Persist
|
|
20
20
|
type = type.to_sym if String === type
|
21
21
|
type = SERIALIZER if type == :serializer
|
22
22
|
case type
|
23
|
-
when nil, :string, :integer, :float, :boolean, :file, :path, :select, :folder
|
23
|
+
when nil, :string, :text, :integer, :float, :boolean, :file, :path, :select, :folder, :binary
|
24
24
|
if IO === content || StringIO === content
|
25
25
|
content.read
|
26
26
|
else
|
@@ -49,7 +49,7 @@ module Persist
|
|
49
49
|
type = SERIALIZER if type == :serializer
|
50
50
|
|
51
51
|
case type
|
52
|
-
when nil, :string, :file, :stream, :select, :folder
|
52
|
+
when nil, :string, :text, :file, :stream, :select, :folder
|
53
53
|
serialized
|
54
54
|
when :path
|
55
55
|
Path.setup(serialized)
|
@@ -58,7 +58,7 @@ module Persist
|
|
58
58
|
when :float
|
59
59
|
serialized.to_f
|
60
60
|
when :boolean
|
61
|
-
TRUE_STRINGS.include? serialized
|
61
|
+
TRUE_STRINGS.include? serialized.strip
|
62
62
|
when :array
|
63
63
|
serialized.split("\n")
|
64
64
|
when :yaml
|
data/lib/scout/persist.rb
CHANGED