rbbt-util 5.13.37 → 5.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|