rbbt-util 5.25.38 → 5.25.39
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 +12 -8
- data/lib/rbbt/hpc.rb +2 -2
- data/lib/rbbt/util/config.rb +5 -0
- data/lib/rbbt/util/simpleopt/get.rb +2 -0
- data/lib/rbbt/workflow/accessor.rb +1 -1
- data/lib/rbbt/workflow/provenance.rb +93 -0
- data/lib/rbbt/workflow/step/dependencies.rb +14 -7
- data/lib/rbbt/workflow/step/run.rb +4 -0
- data/share/rbbt_commands/workflow/prov +2 -92
- data/share/rbbt_commands/workflow/task +6 -6
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f56f0578a67dbc452f235f6ccc30c8c9c97dbfb
|
|
4
|
+
data.tar.gz: 0c333ea486edd8afead278153fec7a4c81e2a12e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4839d7df1d9ac6bdaadaad1dca2b4f57d3aefedb55323f1edccb8de3d9fedc49c44eecd26db5ea8d2469c8fe073b34bb513f37a62ad7268ac2dfcd536a2524a5
|
|
7
|
+
data.tar.gz: 3bde4b44aeceac13e2129f5b236e72fe0c411f7f0b1f0d8cf339584030a64e64aa07b1d360a4f1707d5aa125dbce65d96ab6eb28d050397a00112dd6eb08042f
|
data/bin/rbbt
CHANGED
|
@@ -98,15 +98,19 @@ if mem_dump = options.delete(:dump_mem)
|
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
if options[:config_keys]
|
|
101
|
-
options[:config_keys].
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
if Misc.is_filename?(options[:config_keys]) && File.exists?(options[:config_keys])
|
|
102
|
+
Rbbt::Config.load_file(options[:config_keys])
|
|
103
|
+
else
|
|
104
|
+
options[:config_keys].split(",").each do |config|
|
|
105
|
+
key, value, *tokens = config.split(/\s/)
|
|
106
|
+
tokens = ['key:' << key << '::0'] if tokens.empty?
|
|
107
|
+
tokens = tokens.collect do |tok|
|
|
108
|
+
tok, _sep, prio = tok.partition("::")
|
|
109
|
+
prio = "0" if prio.nil? or prio.empty?
|
|
110
|
+
[tok, prio] * "::"
|
|
111
|
+
end
|
|
112
|
+
Rbbt::Config.set({key => value}, *tokens)
|
|
108
113
|
end
|
|
109
|
-
Rbbt::Config.set({key => value}, *tokens)
|
|
110
114
|
end
|
|
111
115
|
end
|
|
112
116
|
|
data/lib/rbbt/hpc.rb
CHANGED
|
@@ -43,7 +43,7 @@ module Marenostrum
|
|
|
43
43
|
rbbt_cmd << " --config_keys='#{config_keys}'"
|
|
44
44
|
|
|
45
45
|
queue = options[:queue] || 'bsc_ls'
|
|
46
|
-
|
|
46
|
+
task_cpus = options[:task_cpus] || 1
|
|
47
47
|
nodes = options[:nodes] || 1
|
|
48
48
|
time = options[:time] || "0:00:10"
|
|
49
49
|
|
|
@@ -71,7 +71,7 @@ module Marenostrum
|
|
|
71
71
|
#SBATCH --workdir="#{Dir.pwd}"
|
|
72
72
|
#SBATCH --output="#{fout}"
|
|
73
73
|
#SBATCH --error="#{ferr}"
|
|
74
|
-
#SBATCH --
|
|
74
|
+
#SBATCH --cpus-per-task="#{task_cpus}"
|
|
75
75
|
#SBATCH --time="#{time}"
|
|
76
76
|
#SBATCH --nodes="#{nodes}"
|
|
77
77
|
EOF
|
data/lib/rbbt/util/config.rb
CHANGED
|
@@ -5,6 +5,8 @@ module Rbbt::Config
|
|
|
5
5
|
|
|
6
6
|
CACHE = IndiferentHash.setup({})
|
|
7
7
|
|
|
8
|
+
GOT_KEYS=[]
|
|
9
|
+
|
|
8
10
|
def self.add_entry(key, value, tokens)
|
|
9
11
|
CACHE[key.to_s] ||= []
|
|
10
12
|
CACHE[key.to_s] << [tokens, value]
|
|
@@ -110,7 +112,10 @@ module Rbbt::Config
|
|
|
110
112
|
|
|
111
113
|
value = priorities.empty? ? default : priorities.sort_by{|p,v| p}.first.last.first
|
|
112
114
|
value = false if value == 'false'
|
|
115
|
+
|
|
113
116
|
Log.debug "Value #{value.inspect} for config key '#{ key }': #{tokens * ", "}"
|
|
117
|
+
GOT_KEYS << [key, value, tokens]
|
|
118
|
+
|
|
114
119
|
value
|
|
115
120
|
end
|
|
116
121
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
class Step
|
|
2
|
+
def self.prov_status_msg(status)
|
|
3
|
+
color = case status.to_sym
|
|
4
|
+
when :error, :aborted, :missing, :dead
|
|
5
|
+
:red
|
|
6
|
+
when :streaming, :started
|
|
7
|
+
:cyan
|
|
8
|
+
when :done
|
|
9
|
+
:green
|
|
10
|
+
when :noinfo
|
|
11
|
+
:blue
|
|
12
|
+
when :dependencies, :waiting, :setyp
|
|
13
|
+
:yellow
|
|
14
|
+
else
|
|
15
|
+
if status.to_s.index ">"
|
|
16
|
+
:cyan
|
|
17
|
+
else
|
|
18
|
+
:cyan
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
Log.color(color, status.to_s)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.prov_report_msg(status, name, path, info = nil)
|
|
25
|
+
parts = path.sub(/\{.*/,'').sub(/#{Regexp.quote(name)}$/,'').split "/"
|
|
26
|
+
|
|
27
|
+
task = Log.color(:yellow, parts.pop)
|
|
28
|
+
workflow = Log.color(:magenta, parts.pop)
|
|
29
|
+
if status.to_s == 'noinfo' and parts.last != 'jobs'
|
|
30
|
+
task, status, workflow = Log.color(:yellow, info[:task_name]), Log.color(:blue, "file"), Log.color(:magenta, "-")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
path_mtime = begin
|
|
34
|
+
Open.mtime(path)
|
|
35
|
+
rescue
|
|
36
|
+
nil
|
|
37
|
+
end
|
|
38
|
+
str = if not Open.remote?(path) and (Open.exists?(path) and $main_mtime and path_mtime and ($main_mtime - path_mtime) < -2)
|
|
39
|
+
iii [path, path_mtime, $main_mtime, $main_mtime - path_mtime]
|
|
40
|
+
prov_status_msg(status.to_s) << " " << [workflow, task, path].compact * " " << " (#{Log.color(:red, "Mtime out of sync") })"
|
|
41
|
+
else
|
|
42
|
+
prov_status_msg(status.to_s) << " " << [workflow, task, path].compact * " "
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if $inputs and $inputs.any?
|
|
46
|
+
job_inputs = Workflow.load_step(path).recursive_inputs.to_hash
|
|
47
|
+
IndiferentHash.setup(job_inputs)
|
|
48
|
+
|
|
49
|
+
$inputs.each do |input|
|
|
50
|
+
value = job_inputs[input]
|
|
51
|
+
next if value.nil?
|
|
52
|
+
value_str = Misc.fingerprint(value)
|
|
53
|
+
str << "\t#{Log.color :magenta, input}=#{value_str}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
if $info_fields and $info_fields.any?
|
|
58
|
+
$info_fields.each do |field|
|
|
59
|
+
IndiferentHash.setup(info)
|
|
60
|
+
value = info[field]
|
|
61
|
+
next if value.nil?
|
|
62
|
+
value_str = Misc.fingerprint(value)
|
|
63
|
+
str << "\t#{Log.color :magenta, field}=#{value_str}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
str << "\n"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.prov_report(step, offset = 0, task = nil)
|
|
71
|
+
info = step.info || {}
|
|
72
|
+
info[:task_name] = task
|
|
73
|
+
path = step.path
|
|
74
|
+
status = info[:status] || :missing
|
|
75
|
+
status = "remote" if Open.remote?(path)
|
|
76
|
+
name = info[:name] || File.basename(path)
|
|
77
|
+
status = :unsync if status == :done and not Open.exist? path
|
|
78
|
+
str = " " * offset
|
|
79
|
+
str << prov_report_msg(status, name, path, info)
|
|
80
|
+
seen = []
|
|
81
|
+
step.dependencies.each do |dep|
|
|
82
|
+
path = dep.path
|
|
83
|
+
new = ! seen.include?(path)
|
|
84
|
+
if new
|
|
85
|
+
seen << path
|
|
86
|
+
str << prov_report(dep, offset + 1, task)
|
|
87
|
+
else
|
|
88
|
+
str << Log.color(:blue, Log.uncolor(prov_report(dep, offset+1, task)))
|
|
89
|
+
end
|
|
90
|
+
end if step.dependencies
|
|
91
|
+
str
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -385,7 +385,14 @@ class Step
|
|
|
385
385
|
required_dep_paths << path if list.length > 1
|
|
386
386
|
end
|
|
387
387
|
|
|
388
|
-
required_dep_paths.concat dependencies.collect{|dep| dep.path
|
|
388
|
+
required_dep_paths.concat dependencies.collect{|dep| dep.path}
|
|
389
|
+
required_dep_paths.concat(rec_dependencies.collect do |dep|
|
|
390
|
+
dep.inputs.flatten.select{|i| Step === i}.collect{|d| d.path}
|
|
391
|
+
end.flatten)
|
|
392
|
+
|
|
393
|
+
required_dep_paths.concat(dependencies.collect do |dep|
|
|
394
|
+
[dep.path] + dep.inputs.flatten.select{|i| Step === i}.collect{|d| d.path}
|
|
395
|
+
end.flatten)
|
|
389
396
|
|
|
390
397
|
log :dependencies, "Dependencies for step #{Log.color :yellow, task.name.to_s || ""}"
|
|
391
398
|
|
|
@@ -398,7 +405,7 @@ class Step
|
|
|
398
405
|
next if seen_paths.include? step.path
|
|
399
406
|
seen_paths << step.path
|
|
400
407
|
next unless required_dep_paths.include? step.path
|
|
401
|
-
if
|
|
408
|
+
if step.inputs.flatten.select{|i| Step === i}.any?
|
|
402
409
|
if ComputeDependency === step
|
|
403
410
|
next if produced.include? step.path
|
|
404
411
|
compute_last_deps[step.compute] ||= []
|
|
@@ -417,6 +424,11 @@ class Step
|
|
|
417
424
|
end
|
|
418
425
|
end
|
|
419
426
|
|
|
427
|
+
Log.medium "Computing pre dependencies: #{Misc.fingerprint(compute_pre_deps)} - #{Log.color :blue, self.path}" if compute_pre_deps.any?
|
|
428
|
+
compute_pre_deps.each do |type,list|
|
|
429
|
+
run_compute_dependencies(type, list, dep_step)
|
|
430
|
+
end
|
|
431
|
+
|
|
420
432
|
Log.medium "Processing pre dependencies: #{Misc.fingerprint(pre_deps)} - #{Log.color :blue, self.path}" if pre_deps.any?
|
|
421
433
|
pre_deps.each do |step|
|
|
422
434
|
next if compute_deps.include? step
|
|
@@ -427,11 +439,6 @@ class Step
|
|
|
427
439
|
end
|
|
428
440
|
end
|
|
429
441
|
|
|
430
|
-
Log.medium "Computing pre dependencies: #{Misc.fingerprint(compute_pre_deps)} - #{Log.color :blue, self.path}" if compute_pre_deps.any?
|
|
431
|
-
compute_pre_deps.each do |type,list|
|
|
432
|
-
run_compute_dependencies(type, list, dep_step)
|
|
433
|
-
end
|
|
434
|
-
|
|
435
442
|
Log.medium "Processing last dependencies: #{Misc.fingerprint(last_deps)} - #{Log.color :blue, self.path}" if last_deps.any?
|
|
436
443
|
last_deps.each do |step|
|
|
437
444
|
next if compute_deps.include? step
|
|
@@ -219,6 +219,8 @@ class Step
|
|
|
219
219
|
|
|
220
220
|
Open.write(pid_file, Process.pid.to_s) unless Open.exists? pid_file
|
|
221
221
|
|
|
222
|
+
config_keys_pre = Rbbt::Config::GOT_KEYS.dup
|
|
223
|
+
|
|
222
224
|
@exec = false
|
|
223
225
|
init_info(true)
|
|
224
226
|
|
|
@@ -405,6 +407,8 @@ class Step
|
|
|
405
407
|
|
|
406
408
|
set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]}
|
|
407
409
|
|
|
410
|
+
set_info :config_keys, (Rbbt::Config::GOT_KEYS - config_keys_pre).uniq
|
|
411
|
+
|
|
408
412
|
if result.nil? && File.exists?(self.tmp_path) && ! File.exists?(self.path)
|
|
409
413
|
Open.mv self.tmp_path, self.path
|
|
410
414
|
end
|
|
@@ -6,6 +6,7 @@ require 'rbbt-util'
|
|
|
6
6
|
require 'fileutils'
|
|
7
7
|
require 'rbbt/util/simpleopt'
|
|
8
8
|
require 'rbbt/workflow/step'
|
|
9
|
+
require 'rbbt/workflow/provenance'
|
|
9
10
|
require 'rbbt/util/misc'
|
|
10
11
|
|
|
11
12
|
require 'rbbt-util'
|
|
@@ -40,74 +41,6 @@ def get_step(file)
|
|
|
40
41
|
Workflow.load_step file
|
|
41
42
|
end
|
|
42
43
|
|
|
43
|
-
def status_msg(status)
|
|
44
|
-
color = case status.to_sym
|
|
45
|
-
when :error, :aborted, :missing, :dead
|
|
46
|
-
:red
|
|
47
|
-
when :streaming, :started
|
|
48
|
-
:cyan
|
|
49
|
-
when :done
|
|
50
|
-
:green
|
|
51
|
-
when :noinfo
|
|
52
|
-
:blue
|
|
53
|
-
when :dependencies, :waiting, :setyp
|
|
54
|
-
:yellow
|
|
55
|
-
else
|
|
56
|
-
if status.to_s.index ">"
|
|
57
|
-
:cyan
|
|
58
|
-
else
|
|
59
|
-
:cyan
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
Log.color(color, status.to_s)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def report_msg(status, name, path, info = nil)
|
|
66
|
-
parts = path.sub(/\{.*/,'').sub(/#{Regexp.quote(name)}$/,'').split "/"
|
|
67
|
-
|
|
68
|
-
task = Log.color(:yellow, parts.pop)
|
|
69
|
-
workflow = Log.color(:magenta, parts.pop)
|
|
70
|
-
if status.to_s == 'noinfo' and parts.last != 'jobs'
|
|
71
|
-
task, status, workflow = Log.color(:yellow, info[:task_name]), Log.color(:blue, "file"), Log.color(:magenta, "-")
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
path_mtime = begin
|
|
75
|
-
Open.mtime(path)
|
|
76
|
-
rescue
|
|
77
|
-
nil
|
|
78
|
-
end
|
|
79
|
-
str = if not Open.remote?(path) and (Open.exists?(path) and $main_mtime and path_mtime and ($main_mtime - path_mtime) < -2)
|
|
80
|
-
iii [path, path_mtime, $main_mtime, $main_mtime - path_mtime]
|
|
81
|
-
status_msg(status.to_s) << " " << [workflow, task, path].compact * " " << " (#{Log.color(:red, "Mtime out of sync") })"
|
|
82
|
-
else
|
|
83
|
-
status_msg(status.to_s) << " " << [workflow, task, path].compact * " "
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
if $inputs and $inputs.any?
|
|
87
|
-
job_inputs = Workflow.load_step(path).recursive_inputs.to_hash
|
|
88
|
-
IndiferentHash.setup(job_inputs)
|
|
89
|
-
|
|
90
|
-
$inputs.each do |input|
|
|
91
|
-
value = job_inputs[input]
|
|
92
|
-
next if value.nil?
|
|
93
|
-
value_str = Misc.fingerprint(value)
|
|
94
|
-
str << "\t#{Log.color :magenta, input}=#{value_str}"
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
if $info_fields and $info_fields.any?
|
|
99
|
-
$info_fields.each do |field|
|
|
100
|
-
IndiferentHash.setup(info)
|
|
101
|
-
value = info[field]
|
|
102
|
-
next if value.nil?
|
|
103
|
-
value_str = Misc.fingerprint(value)
|
|
104
|
-
str << "\t#{Log.color :magenta, field}=#{value_str}"
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
str << "\n"
|
|
109
|
-
end
|
|
110
|
-
|
|
111
44
|
def touch(step)
|
|
112
45
|
return unless File.exists?(step.path)
|
|
113
46
|
step.dependencies.each do |dep|
|
|
@@ -120,29 +53,6 @@ def touch(step)
|
|
|
120
53
|
end if step.dependencies
|
|
121
54
|
end
|
|
122
55
|
|
|
123
|
-
def report(step, offset = 0, task = nil)
|
|
124
|
-
info = step.info || {}
|
|
125
|
-
info[:task_name] = task
|
|
126
|
-
path = step.path
|
|
127
|
-
status = info[:status] || :missing
|
|
128
|
-
status = "remote" if Open.remote?(path)
|
|
129
|
-
name = info[:name] || File.basename(path)
|
|
130
|
-
status = :unsync if status == :done and not Open.exist? path
|
|
131
|
-
str = " " * offset
|
|
132
|
-
str << report_msg(status, name, path, info)
|
|
133
|
-
step.dependencies.each do |dep|
|
|
134
|
-
path = dep.path
|
|
135
|
-
new = ! $seen.include?(path)
|
|
136
|
-
if new
|
|
137
|
-
$seen << path
|
|
138
|
-
str << report(dep, offset + 1, task)
|
|
139
|
-
else
|
|
140
|
-
str << Log.color(:blue, Log.uncolor(report(dep, offset+1, task)))
|
|
141
|
-
end
|
|
142
|
-
end if step.dependencies
|
|
143
|
-
str
|
|
144
|
-
end
|
|
145
|
-
|
|
146
56
|
step = get_step file
|
|
147
57
|
$main_mtime = Open.exist?(step.path) ? Open.mtime(step.path) : nil
|
|
148
58
|
|
|
@@ -220,6 +130,6 @@ if options[:plot]
|
|
|
220
130
|
end
|
|
221
131
|
|
|
222
132
|
else
|
|
223
|
-
puts
|
|
133
|
+
puts Step.prov_report(step).strip
|
|
224
134
|
end
|
|
225
135
|
|
|
@@ -364,6 +364,12 @@ begin
|
|
|
364
364
|
exit 0
|
|
365
365
|
end
|
|
366
366
|
|
|
367
|
+
if options.delete(:provenance)
|
|
368
|
+
require 'rbbt/workflow/provenance'
|
|
369
|
+
puts Step.prov_report(job)
|
|
370
|
+
exit 0
|
|
371
|
+
end
|
|
372
|
+
|
|
367
373
|
if do_fork
|
|
368
374
|
ENV["RBBT_NO_PROGRESS"] = "true"
|
|
369
375
|
if detach
|
|
@@ -380,12 +386,6 @@ begin
|
|
|
380
386
|
end
|
|
381
387
|
|
|
382
388
|
|
|
383
|
-
if options.delete(:provenance)
|
|
384
|
-
job.join
|
|
385
|
-
pp job.provenance_paths
|
|
386
|
-
exit 0
|
|
387
|
-
end
|
|
388
|
-
|
|
389
389
|
if options.delete(:printname)
|
|
390
390
|
job.join if IO === job.result
|
|
391
391
|
puts job.name
|
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.25.
|
|
4
|
+
version: 5.25.39
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Miguel Vazquez
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-
|
|
11
|
+
date: 2019-04-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -323,6 +323,7 @@ files:
|
|
|
323
323
|
- lib/rbbt/workflow/definition.rb
|
|
324
324
|
- lib/rbbt/workflow/doc.rb
|
|
325
325
|
- lib/rbbt/workflow/examples.rb
|
|
326
|
+
- lib/rbbt/workflow/provenance.rb
|
|
326
327
|
- lib/rbbt/workflow/soap.rb
|
|
327
328
|
- lib/rbbt/workflow/step.rb
|
|
328
329
|
- lib/rbbt/workflow/step/dependencies.rb
|