rbbt-util 5.13.37 → 5.14.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/bin/rbbt +6 -1
- data/lib/rbbt/fix_width_table.rb +21 -9
- data/lib/rbbt/monitor.rb +1 -1
- data/lib/rbbt/packed_index.rb +19 -5
- data/lib/rbbt/persist/tsv.rb +9 -1
- data/lib/rbbt/persist/tsv/fix_width_table.rb +1 -1
- data/lib/rbbt/persist/tsv/packed_index.rb +101 -0
- data/lib/rbbt/persist/tsv/sharder.rb +11 -3
- data/lib/rbbt/resource/path.rb +1 -1
- data/lib/rbbt/resource/rake.rb +1 -0
- data/lib/rbbt/tsv/accessor.rb +18 -13
- data/lib/rbbt/tsv/dumper.rb +2 -6
- data/lib/rbbt/tsv/manipulate.rb +6 -4
- data/lib/rbbt/tsv/parallel/traverse.rb +7 -6
- data/lib/rbbt/tsv/parser.rb +20 -16
- data/lib/rbbt/tsv/stream.rb +87 -76
- data/lib/rbbt/tsv/util.rb +8 -3
- data/lib/rbbt/util/R.rb +1 -1
- data/lib/rbbt/util/cmd.rb +0 -3
- data/lib/rbbt/util/concurrency/processes.rb +3 -0
- data/lib/rbbt/util/concurrency/processes/worker.rb +0 -1
- data/lib/rbbt/util/log.rb +45 -18
- data/lib/rbbt/util/log/progress/report.rb +3 -2
- data/lib/rbbt/util/log/progress/util.rb +1 -1
- data/lib/rbbt/util/misc/concurrent_stream.rb +12 -6
- data/lib/rbbt/util/misc/development.rb +10 -4
- data/lib/rbbt/util/misc/lock.rb +1 -1
- data/lib/rbbt/util/misc/omics.rb +2 -0
- data/lib/rbbt/util/misc/pipes.rb +90 -87
- data/lib/rbbt/workflow.rb +6 -2
- data/lib/rbbt/workflow/accessor.rb +70 -40
- data/lib/rbbt/workflow/definition.rb +23 -0
- data/lib/rbbt/workflow/step.rb +15 -3
- data/lib/rbbt/workflow/step/run.rb +18 -13
- data/lib/rbbt/workflow/usage.rb +3 -0
- data/share/Rlib/util.R +1 -1
- data/share/rbbt_commands/tsv/get +0 -2
- data/share/rbbt_commands/tsv/info +13 -5
- data/share/rbbt_commands/tsv/subset +1 -1
- data/share/rbbt_commands/workflow/info +32 -0
- data/share/rbbt_commands/workflow/task +0 -2
- data/test/rbbt/persist/tsv/test_sharder.rb +44 -0
- data/test/rbbt/test_fix_width_table.rb +1 -0
- data/test/rbbt/test_packed_index.rb +3 -0
- data/test/rbbt/tsv/test_stream.rb +55 -2
- data/test/rbbt/util/misc/test_pipes.rb +8 -6
- data/test/rbbt/workflow/test_step.rb +7 -6
- metadata +3 -2
data/lib/rbbt/workflow.rb
CHANGED
@@ -275,14 +275,18 @@ module Workflow
|
|
275
275
|
Workflow.resolve_locals(inputs)
|
276
276
|
|
277
277
|
task_inputs = task_info(taskname)[:inputs]
|
278
|
-
defaults = task_info(taskname)[:input_defaults]
|
278
|
+
defaults = IndiferentHash.setup(task_info(taskname)[:input_defaults])
|
279
279
|
|
280
280
|
dependencies = real_dependencies(task, jobname, defaults.merge(inputs), task_dependencies[taskname] || [])
|
281
281
|
|
282
282
|
real_inputs = {}
|
283
283
|
|
284
284
|
inputs.each do |k,v|
|
285
|
-
|
285
|
+
default = defaults[k]
|
286
|
+
if (task_inputs.include?(k.to_sym) or task_inputs.include?(k.to_s)) and
|
287
|
+
(defaults[k].to_s != v.to_s and not (FalseClass === v and defaults[k].nil?))
|
288
|
+
real_inputs[k] = v
|
289
|
+
end
|
286
290
|
end
|
287
291
|
|
288
292
|
if real_inputs.empty?
|
@@ -2,7 +2,8 @@ require 'rbbt/util/open'
|
|
2
2
|
require 'yaml'
|
3
3
|
|
4
4
|
class Step
|
5
|
-
|
5
|
+
|
6
|
+
|
6
7
|
INFO_SERIALIAZER = Marshal
|
7
8
|
|
8
9
|
def self.started?
|
@@ -12,7 +13,7 @@ class Step
|
|
12
13
|
def self.wait_for_jobs(jobs)
|
13
14
|
begin
|
14
15
|
threads = []
|
15
|
-
jobs.each do |j| threads << Thread.new{j.
|
16
|
+
jobs.each do |j| threads << Thread.new{j.join} end
|
16
17
|
threads.each{|t| t.join }
|
17
18
|
rescue Exception
|
18
19
|
threads.each{|t| t.exit }
|
@@ -66,33 +67,40 @@ class Step
|
|
66
67
|
@info_file ||= Step.info_file(path)
|
67
68
|
end
|
68
69
|
|
69
|
-
def
|
70
|
+
def info_lock
|
71
|
+
@info_lock ||= begin
|
72
|
+
path = Persist.persistence_path(info_file + '.lock', {:dir => Step.lock_dir})
|
73
|
+
Lockfile.new path
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def info(check_lock = true)
|
70
78
|
return {} if info_file.nil? or not Open.exists? info_file
|
71
79
|
begin
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
80
|
+
begin
|
81
|
+
return @info_cache if @info_cache and File.ctime(info_file) < @info_cache_time
|
82
|
+
rescue Exception
|
83
|
+
raise $!
|
84
|
+
end
|
78
85
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
+
begin
|
87
|
+
@info_cache = Misc.insist(2, 3, info_file) do
|
88
|
+
Misc.insist(2, 1, info_file) do
|
89
|
+
Misc.insist(3, 0.2, info_file) do
|
90
|
+
raise TryAgain, "Info locked" if check_lock and info_lock.locked?
|
91
|
+
Open.open(info_file) do |file|
|
92
|
+
INFO_SERIALIAZER.load(file) #|| {}
|
86
93
|
end
|
87
94
|
end
|
88
95
|
end
|
89
|
-
@info_cache_time = Time.now
|
90
|
-
@info_cache
|
91
96
|
end
|
97
|
+
@info_cache_time = Time.now
|
98
|
+
@info_cache
|
92
99
|
end
|
93
100
|
rescue Exception
|
94
101
|
Log.debug{"Error loading info file: " + info_file}
|
95
|
-
|
102
|
+
Log.exception $!
|
103
|
+
Open.sensiblewrite(info_file, INFO_SERIALIAZER.dump({:status => :error, :messages => ["Info file lost"]}))
|
96
104
|
raise $!
|
97
105
|
end
|
98
106
|
end
|
@@ -100,12 +108,11 @@ class Step
|
|
100
108
|
def set_info(key, value)
|
101
109
|
return nil if @exec or info_file.nil?
|
102
110
|
value = Annotated.purge value if defined? Annotated
|
103
|
-
|
104
|
-
|
105
|
-
i = info
|
111
|
+
Open.lock(info_file, :lock => info_lock) do
|
112
|
+
i = info(false)
|
106
113
|
i[key] = value
|
107
114
|
@info_cache = i
|
108
|
-
|
115
|
+
Misc.sensiblewrite(info_file, INFO_SERIALIAZER.dump(i), :force => true)
|
109
116
|
@info_cache_time = Time.now
|
110
117
|
value
|
111
118
|
end
|
@@ -114,12 +121,11 @@ class Step
|
|
114
121
|
def merge_info(hash)
|
115
122
|
return nil if @exec or info_file.nil?
|
116
123
|
value = Annotated.purge value if defined? Annotated
|
117
|
-
|
118
|
-
|
119
|
-
i = info
|
124
|
+
Open.lock(info_file, :lock => info_lock) do
|
125
|
+
i = info(false)
|
120
126
|
i.merge! hash
|
121
127
|
@info_cache = i
|
122
|
-
|
128
|
+
Misc.sensiblewrite(info_file, INFO_SERIALIAZER.dump(i), :force => true)
|
123
129
|
@info_cache_time = Time.now
|
124
130
|
value
|
125
131
|
end
|
@@ -416,10 +422,11 @@ module Workflow
|
|
416
422
|
|
417
423
|
def rec_dependencies(taskname)
|
418
424
|
if task_dependencies.include? taskname
|
419
|
-
deps = task_dependencies[taskname]
|
420
|
-
all_deps = deps.
|
425
|
+
deps = task_dependencies[taskname]
|
426
|
+
all_deps = deps.select{|dep| String === dep or Symbol === dep or Array === dep}
|
421
427
|
deps.each do |dep|
|
422
|
-
|
428
|
+
case dep
|
429
|
+
when Array
|
423
430
|
dep.first.rec_dependencies(dep.last).each do |d|
|
424
431
|
if Array === d
|
425
432
|
all_deps << d
|
@@ -427,8 +434,10 @@ module Workflow
|
|
427
434
|
all_deps << [dep.first, d]
|
428
435
|
end
|
429
436
|
end
|
430
|
-
|
437
|
+
when String, Symbol
|
431
438
|
all_deps.concat rec_dependencies(dep.to_sym)
|
439
|
+
when DependencyBlock
|
440
|
+
all_deps << dep.dependency
|
432
441
|
end
|
433
442
|
end
|
434
443
|
all_deps.uniq
|
@@ -437,28 +446,49 @@ module Workflow
|
|
437
446
|
end
|
438
447
|
end
|
439
448
|
|
449
|
+
def task_from_dep(dep)
|
450
|
+
case dep
|
451
|
+
when Array
|
452
|
+
dep.first.tasks[dep.last]
|
453
|
+
when String
|
454
|
+
tasks[dep.to_sym]
|
455
|
+
when Symbol
|
456
|
+
tasks[dep.to_sym]
|
457
|
+
else
|
458
|
+
raise "Unknown dependency: #{Misc.fingerprint dep}"
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
440
462
|
def rec_inputs(taskname)
|
441
|
-
[taskname].concat(rec_dependencies(taskname)).inject([]){|acc, tn| acc.concat((
|
463
|
+
[taskname].concat(rec_dependencies(taskname)).inject([]){|acc, tn| acc.concat(task_from_dep(tn).inputs) }.uniq
|
442
464
|
end
|
443
465
|
|
444
466
|
def rec_input_defaults(taskname)
|
445
|
-
[taskname].concat(rec_dependencies(taskname)).inject({}){|acc, tn|
|
446
|
-
|
467
|
+
[taskname].concat(rec_dependencies(taskname)).inject(IndiferentHash.setup({})){|acc, tn|
|
468
|
+
new = (Array === tn ? tn.first.tasks[tn.last.to_sym] : tasks[tn.to_sym]).input_defaults
|
469
|
+
acc = new.merge(acc)
|
470
|
+
}.tap{|h| IndiferentHash.setup(h)}
|
447
471
|
end
|
448
472
|
|
449
473
|
def rec_input_types(taskname)
|
450
|
-
[taskname].concat(rec_dependencies(taskname)).inject({}){|acc, tn|
|
451
|
-
|
474
|
+
[taskname].concat(rec_dependencies(taskname)).inject({}){|acc, tn|
|
475
|
+
new = (Array === tn ? tn.first.tasks[tn.last.to_sym] : tasks[tn.to_sym]).input_types
|
476
|
+
acc = new.merge(acc)
|
477
|
+
}.tap{|h| IndiferentHash.setup(h)}
|
452
478
|
end
|
453
479
|
|
454
480
|
def rec_input_descriptions(taskname)
|
455
|
-
[taskname].concat(rec_dependencies(taskname)).inject({}){|acc, tn|
|
456
|
-
|
481
|
+
[taskname].concat(rec_dependencies(taskname)).inject({}){|acc, tn|
|
482
|
+
new = (Array === tn ? tn.first.tasks[tn.last.to_sym] : tasks[tn.to_sym]).input_descriptions
|
483
|
+
acc = new.merge(acc)
|
484
|
+
}.tap{|h| IndiferentHash.setup(h)}
|
457
485
|
end
|
458
486
|
|
459
487
|
def rec_input_options(taskname)
|
460
|
-
[taskname].concat(rec_dependencies(taskname)).inject({}){|acc, tn|
|
461
|
-
|
488
|
+
[taskname].concat(rec_dependencies(taskname)).inject({}){|acc, tn|
|
489
|
+
new = (Array === tn ? tn.first.tasks[tn.last.to_sym] : tasks[tn.to_sym]).input_options
|
490
|
+
acc = new.merge(acc)
|
491
|
+
}.tap{|h| IndiferentHash.setup(h)}
|
462
492
|
end
|
463
493
|
|
464
494
|
def real_dependencies(task, jobname, inputs, dependencies)
|
@@ -4,6 +4,15 @@ require 'rbbt/workflow/annotate'
|
|
4
4
|
module Workflow
|
5
5
|
include AnnotatedModule
|
6
6
|
|
7
|
+
module DependencyBlock
|
8
|
+
attr_accessor :dependency
|
9
|
+
def self.setup(block, dependency)
|
10
|
+
block.extend DependencyBlock
|
11
|
+
block.dependency = dependency
|
12
|
+
block
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
7
16
|
AnnotatedModule.add_consummable_annotation(self,
|
8
17
|
:result_description => "",
|
9
18
|
:result_type => nil,
|
@@ -36,6 +45,20 @@ module Workflow
|
|
36
45
|
end
|
37
46
|
end
|
38
47
|
|
48
|
+
def dep(*dependency, &block)
|
49
|
+
@dependencies ||= []
|
50
|
+
if block_given?
|
51
|
+
DependencyBlock.setup block, dependency if dependency.any?
|
52
|
+
@dependencies << block
|
53
|
+
else
|
54
|
+
if Module === dependency.first
|
55
|
+
@dependencies << dependency
|
56
|
+
else
|
57
|
+
@dependencies.concat dependency
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
39
62
|
def task(name, &block)
|
40
63
|
if Hash === name
|
41
64
|
type = name.first.last
|
data/lib/rbbt/workflow/step.rb
CHANGED
@@ -14,7 +14,11 @@ class Step
|
|
14
14
|
attr_accessor :lock_dir
|
15
15
|
|
16
16
|
def lock_dir
|
17
|
-
@lock_dir ||=
|
17
|
+
@lock_dir ||= begin
|
18
|
+
dir = Rbbt.tmp.step_info_locks.find
|
19
|
+
FileUtils.mkdir_p dir unless Open.exists? dir
|
20
|
+
dir
|
21
|
+
end
|
18
22
|
end
|
19
23
|
end
|
20
24
|
|
@@ -35,11 +39,18 @@ class Step
|
|
35
39
|
@mutex = Mutex.new
|
36
40
|
@info_mutex = Mutex.new
|
37
41
|
@inputs = inputs || []
|
38
|
-
NamedArray.setup @inputs, task.inputs if task
|
42
|
+
NamedArray.setup @inputs, task.inputs.collect{|s| s.to_s} if task and task.inputs
|
39
43
|
end
|
40
44
|
|
41
45
|
def inputs
|
42
|
-
|
46
|
+
if @inputs.nil? and task and task.respond_to? :inputs
|
47
|
+
@inputs = info[:inputs].values_at *task.inputs.collect{|name| name.to_s}
|
48
|
+
end
|
49
|
+
|
50
|
+
if task.inputs and not NamedArray === @inputs
|
51
|
+
NamedArray.setup @inputs, task.inputs
|
52
|
+
end
|
53
|
+
|
43
54
|
@inputs
|
44
55
|
end
|
45
56
|
|
@@ -188,6 +199,7 @@ class Step
|
|
188
199
|
else
|
189
200
|
end
|
190
201
|
end
|
202
|
+
self
|
191
203
|
end
|
192
204
|
|
193
205
|
def step(name)
|
@@ -100,17 +100,21 @@ class Step
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def kill_children
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
103
|
+
begin
|
104
|
+
children_pids = info[:children_pids]
|
105
|
+
if children_pids and children_pids.any?
|
106
|
+
Log.medium("Killing children: #{ children_pids * ", " }")
|
107
|
+
children_pids.each do |pid|
|
108
|
+
Log.medium("Killing child #{ pid }")
|
109
|
+
begin
|
110
|
+
Process.kill "INT", pid
|
111
|
+
rescue Exception
|
112
|
+
Log.medium("Exception killing child #{ pid }: #{$!.message}")
|
113
|
+
end
|
112
114
|
end
|
113
115
|
end
|
116
|
+
rescue
|
117
|
+
Log.medium("Exception finding children")
|
114
118
|
end
|
115
119
|
end
|
116
120
|
|
@@ -276,9 +280,10 @@ class Step
|
|
276
280
|
Misc.pre_fork
|
277
281
|
begin
|
278
282
|
RbbtSemaphore.wait_semaphore(semaphore) if semaphore
|
279
|
-
FileUtils.mkdir_p File.dirname(path) unless
|
283
|
+
FileUtils.mkdir_p File.dirname(path) unless File.exists? File.dirname(path)
|
280
284
|
begin
|
281
285
|
res = run true
|
286
|
+
set_info :forked, true
|
282
287
|
rescue Aborted
|
283
288
|
Log.debug{"Forked process aborted: #{path}"}
|
284
289
|
log :aborted, "Job aborted (#{Process.pid})"
|
@@ -306,15 +311,15 @@ class Step
|
|
306
311
|
end
|
307
312
|
rescue Exception
|
308
313
|
Log.debug("Exception waiting for children: #{$!.message}")
|
309
|
-
|
314
|
+
RbbtSemaphore.post_semaphore(semaphore) if semaphore
|
315
|
+
Kernel.exit! -1
|
310
316
|
end
|
311
317
|
set_info :pid, nil
|
312
|
-
exit 0
|
313
318
|
ensure
|
314
319
|
RbbtSemaphore.post_semaphore(semaphore) if semaphore
|
315
320
|
end
|
321
|
+
Kernel.exit! 0
|
316
322
|
end
|
317
|
-
set_info :forked, true
|
318
323
|
Process.detach(@pid)
|
319
324
|
self
|
320
325
|
end
|
data/lib/rbbt/workflow/usage.rb
CHANGED
@@ -27,7 +27,10 @@ module Task
|
|
27
27
|
if deps and deps.any?
|
28
28
|
puts Log.color(:magenta, "Inputs from dependencies:")
|
29
29
|
puts
|
30
|
+
seen = []
|
30
31
|
deps.each do |dep|
|
32
|
+
next if seen.include? dep.name
|
33
|
+
seen << dep.name
|
31
34
|
puts " #{Log.color :yellow, dep.name.to_s}:"
|
32
35
|
puts
|
33
36
|
puts SOPT.input_doc((dep.inputs - self.inputs), dep.input_types, dep.input_descriptions, dep.input_defaults, true)
|
data/share/Rlib/util.R
CHANGED
@@ -77,7 +77,7 @@ rbbt.tsv <- function(filename, sep = "\t", comment.char ="#", row.names=1, check
|
|
77
77
|
data=read.table(file=filename, sep=sep, fill=fill, as.is=as.is, quote=quote, row.names= row.names, comment.char = comment.char, ...);
|
78
78
|
f = file(filename, 'r');
|
79
79
|
headers = readLines(f, 1);
|
80
|
-
if (length(grep("^#:
|
80
|
+
if (length(grep("^#:", headers)) > 0){
|
81
81
|
headers = readLines(f, 1);
|
82
82
|
}
|
83
83
|
if (length(grep("^#", headers)) > 0){
|
data/share/rbbt_commands/tsv/get
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
#"!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rbbt-util'
|
4
4
|
require 'rbbt/util/simpleopt'
|
@@ -18,6 +18,7 @@ Display summary information. Works with Tokyocabinet HDB and BDB as well.
|
|
18
18
|
-hh--header_hash* Change the character used to mark the header line (defaults to #)
|
19
19
|
-k--key_field* Change the key field
|
20
20
|
-f--fields* Change the fields to load
|
21
|
+
-s--sep* Change the fields separator (default TAB)
|
21
22
|
-h--help Help
|
22
23
|
EOF
|
23
24
|
|
@@ -31,6 +32,7 @@ raise ParameterException, "Please specify the tsv file as argument" if file.nil?
|
|
31
32
|
|
32
33
|
options[:fields] = options[:fields].split(/,\|/) if options[:fields]
|
33
34
|
options[:header_hash] = options["header_hash"]
|
35
|
+
options[:sep] = options["sep"]
|
34
36
|
|
35
37
|
case
|
36
38
|
when options[:tokyocabinet]
|
@@ -53,10 +55,16 @@ else
|
|
53
55
|
puts " - #{Log.color :cyan, i + 1}: " << Log.color(:yellow, f)
|
54
56
|
end
|
55
57
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
58
|
+
|
59
|
+
if String === file and not Open.remote? file and File.exists? file
|
60
|
+
rows = `wc -l '#{ file }' 2>/dev/null|cut -f 1 -d' '`
|
61
|
+
else
|
62
|
+
rows = "Could not get rows of #{Misc.fingerprint file}"
|
63
|
+
end
|
64
|
+
puts "Rows: #{Log.color :blue, rows}"
|
65
|
+
parts = []
|
66
|
+
header.first_line.split(header.sep).each_with_index{|p,i| parts << (Log.color(:cyan, "(#{i}) ") << p.strip) }
|
67
|
+
puts parts * "\t"
|
60
68
|
puts
|
61
69
|
end
|
62
70
|
|
@@ -15,7 +15,7 @@ Subsets entries from a TSV file from a given list. Works with Tokyocabinet HDB a
|
|
15
15
|
-tch--tokyocabinet File is a TC HDB
|
16
16
|
-tcb--tokyocabinet_bd File is a TC BDB
|
17
17
|
-hh--header_hash* Change the character used to mark the header line (defaults to #)
|
18
|
-
-s--subset* Subset of
|
18
|
+
-s--subset* Subset of keys (Comma-separated or file)
|
19
19
|
-h--help Help
|
20
20
|
EOF
|
21
21
|
|
@@ -14,11 +14,13 @@ Examine the info of a job result
|
|
14
14
|
$ rbbt workflow info <job-result>
|
15
15
|
|
16
16
|
-h--help Help
|
17
|
+
-a--all Print all info entries
|
17
18
|
EOF
|
18
19
|
|
19
20
|
SOPT.usage if options[:help]
|
20
21
|
|
21
22
|
file = ARGV.shift
|
23
|
+
all = options.delete :all
|
22
24
|
|
23
25
|
def get_step(file)
|
24
26
|
file = file.sub(/\.(info|files)/,'')
|
@@ -39,6 +41,19 @@ def status_msg(status)
|
|
39
41
|
Log.color(color, status)
|
40
42
|
end
|
41
43
|
|
44
|
+
def pid_msg(pid, done = false)
|
45
|
+
color = if pid and (done or Misc.pid_exists? pid)
|
46
|
+
:green
|
47
|
+
else
|
48
|
+
:red
|
49
|
+
end
|
50
|
+
if pid.nil?
|
51
|
+
""
|
52
|
+
else
|
53
|
+
Log.color(color, pid)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
42
57
|
step = get_step file
|
43
58
|
|
44
59
|
info = step.info
|
@@ -47,9 +62,14 @@ inputs = info[:inputs]
|
|
47
62
|
status = info[:status]
|
48
63
|
time = info[:time_elapsed]
|
49
64
|
messages = info[:messages]
|
65
|
+
backtrace = info[:backtrace]
|
66
|
+
pid = info[:pid]
|
67
|
+
exception = info[:exception]
|
68
|
+
rest = info.keys - [:inputs, :dependencies, :status, :time_elapsed, :messages, :backtrace, :exception, :pid]
|
50
69
|
|
51
70
|
puts Log.color(:magenta, "File") << ": " << step.path
|
52
71
|
puts Log.color(:magenta, "Status") << ": " << status_msg(status)
|
72
|
+
puts Log.color(:magenta, "Pid") << ": " << pid_msg(pid, status.to_s == "done")
|
53
73
|
puts Log.color(:magenta, "Time") << ": " << time.to_i.to_s << " sec." if time
|
54
74
|
if inputs and inputs.any?
|
55
75
|
puts Log.color(:magenta, "Inputs")
|
@@ -81,3 +101,15 @@ if messages and messages.any?
|
|
81
101
|
puts " " << msg
|
82
102
|
end
|
83
103
|
end
|
104
|
+
|
105
|
+
if status == :error
|
106
|
+
puts Log.color(:magenta, "Backtrace") << ": "
|
107
|
+
puts Log.color_stack backtrace
|
108
|
+
end
|
109
|
+
|
110
|
+
if all
|
111
|
+
puts Log.color(:magenta, "Other entries") << ": "
|
112
|
+
rest.each do |key|
|
113
|
+
puts Misc.format_definition_list_item(key, info[key].to_s)
|
114
|
+
end
|
115
|
+
end
|