rbbt-util 5.32.16 → 5.32.21
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/lib/rbbt/hpc/slurm.rb +1 -0
- data/lib/rbbt/resource/path.rb +6 -6
- data/lib/rbbt/tsv/parallel/traverse.rb +1 -1
- data/lib/rbbt/util/log.rb +15 -4
- data/lib/rbbt/util/misc/inspect.rb +3 -1
- data/lib/rbbt/util/open.rb +1 -0
- data/lib/rbbt/workflow.rb +43 -1
- data/lib/rbbt/workflow/accessor.rb +15 -242
- data/lib/rbbt/workflow/definition.rb +7 -4
- data/lib/rbbt/workflow/dependencies.rb +196 -0
- data/lib/rbbt/workflow/step.rb +4 -184
- data/lib/rbbt/workflow/step/accessor.rb +1 -311
- data/lib/rbbt/workflow/step/dependencies.rb +75 -3
- data/lib/rbbt/workflow/step/info.rb +294 -0
- data/lib/rbbt/workflow/step/status.rb +146 -0
- data/lib/rbbt/workflow/usage.rb +4 -2
- data/lib/rbbt/workflow/util/orchestrator.rb +1 -1
- data/lib/rbbt/workflow/util/provenance.rb +16 -4
- data/share/rbbt_commands/system/clean +1 -0
- data/share/rbbt_commands/workflow/prov +1 -1
- metadata +5 -2
|
@@ -77,14 +77,15 @@ module Workflow
|
|
|
77
77
|
returns workflow.tasks[oname].result_description if workflow.tasks.include?(oname) unless @result_description
|
|
78
78
|
task name do
|
|
79
79
|
raise RbbtException, "dependency not found in dep_task" if dependencies.empty?
|
|
80
|
+
Step.wait_for_jobs dependencies.select{|d| d.streaming? }
|
|
80
81
|
dep = dependencies.last
|
|
81
82
|
dep.join
|
|
82
83
|
raise dep.get_exception if dep.error?
|
|
83
84
|
raise Aborted, "Aborted dependency #{dep.path}" if dep.aborted?
|
|
84
85
|
set_info :result_type, dep.info[:result_type]
|
|
85
|
-
forget = config :forget_dep_tasks, "forget_dep_tasks",
|
|
86
|
+
forget = config :forget_dep_tasks, "forget_dep_tasks", :default => FORGET_DEP_TASKS
|
|
86
87
|
if forget
|
|
87
|
-
remove = config :remove_dep_tasks, "remove_dep_tasks",
|
|
88
|
+
remove = config :remove_dep_tasks, "remove_dep_tasks", :default => REMOVE_DEP_TASKS
|
|
88
89
|
|
|
89
90
|
self.archive_deps
|
|
90
91
|
self.copy_files_dir
|
|
@@ -92,15 +93,17 @@ module Workflow
|
|
|
92
93
|
Open.rm_rf self.files_dir if Open.exist? self.files_dir
|
|
93
94
|
FileUtils.cp_r dep.files_dir, self.files_dir if Open.exist?(dep.files_dir)
|
|
94
95
|
Open.ln_h dep.path, self.tmp_path
|
|
96
|
+
|
|
95
97
|
case remove.to_s
|
|
96
98
|
when 'true'
|
|
97
99
|
dep.clean
|
|
98
100
|
when 'recursive'
|
|
99
|
-
dep.rec_dependencies.each do |d|
|
|
101
|
+
(dep.dependencies + dep.rec_dependencies).uniq.each do |d|
|
|
102
|
+
next if d.overriden
|
|
100
103
|
d.clean unless config(:remove_dep, d.task_signature, d.task_name, d.workflow.to_s, :default => true).to_s == 'false'
|
|
101
104
|
end
|
|
102
105
|
dep.clean unless config(:remove_dep, dep.task_signature, dep.task_name, dep.workflow.to_s, :default => true).to_s == 'false'
|
|
103
|
-
end
|
|
106
|
+
end unless dep.overriden
|
|
104
107
|
else
|
|
105
108
|
if Open.exists?(dep.files_dir)
|
|
106
109
|
Open.rm_rf self.files_dir
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
module Workflow
|
|
2
|
+
def rec_dependencies(taskname, seen = [])
|
|
3
|
+
@rec_dependencies ||= {}
|
|
4
|
+
@rec_dependencies[taskname] ||= [] unless task_dependencies.include?(taskname)
|
|
5
|
+
@rec_dependencies[taskname] ||= begin
|
|
6
|
+
|
|
7
|
+
deps = task_dependencies[taskname]
|
|
8
|
+
|
|
9
|
+
all_deps = []
|
|
10
|
+
deps.each do |dep|
|
|
11
|
+
next if seen.include?(dep)
|
|
12
|
+
if DependencyBlock === dep
|
|
13
|
+
all_deps << dep.dependency if dep.dependency
|
|
14
|
+
else
|
|
15
|
+
all_deps << dep unless Proc === dep
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
begin
|
|
19
|
+
case dep
|
|
20
|
+
when Array
|
|
21
|
+
wf, t, o = dep
|
|
22
|
+
|
|
23
|
+
wf.rec_dependencies(t.to_sym, seen + [dep]).each do |d|
|
|
24
|
+
if Array === d
|
|
25
|
+
new = d.dup
|
|
26
|
+
else
|
|
27
|
+
new = [dep.first, d]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
if Hash === o and not o.empty?
|
|
31
|
+
if Hash === new.last
|
|
32
|
+
hash = new.last.dup
|
|
33
|
+
o.each{|k,v| hash[k] ||= v}
|
|
34
|
+
new[new.length-1] = hash
|
|
35
|
+
else
|
|
36
|
+
new.push o.dup
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
all_deps << new
|
|
41
|
+
end if wf && t
|
|
42
|
+
|
|
43
|
+
when String, Symbol
|
|
44
|
+
rec_deps = rec_dependencies(dep.to_sym, seen + [dep])
|
|
45
|
+
all_deps.concat rec_deps
|
|
46
|
+
when DependencyBlock
|
|
47
|
+
dep = dep.dependency
|
|
48
|
+
raise TryAgain
|
|
49
|
+
end
|
|
50
|
+
rescue TryAgain
|
|
51
|
+
retry
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
all_deps.uniq
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def override_dependencies(inputs)
|
|
59
|
+
override_dependencies = IndiferentHash.setup({})
|
|
60
|
+
return override_dependencies if inputs.nil?
|
|
61
|
+
inputs.each do |key,value|
|
|
62
|
+
if String === key && m = key.match(/(.*)#(.*)/)
|
|
63
|
+
workflow, task = m.values_at 1, 2
|
|
64
|
+
workflow = self.to_s if workflow.empty?
|
|
65
|
+
override_dependencies[workflow] ||= IndiferentHash.setup({})
|
|
66
|
+
override_dependencies[workflow][task] = value
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
override_dependencies
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def setup_override_dependency(dep, workflow, task_name)
|
|
73
|
+
return [] if dep == :skip || dep == 'skip'
|
|
74
|
+
dep = Step === dep ? dep.dup : Workflow.load_step(dep)
|
|
75
|
+
dep.workflow = workflow
|
|
76
|
+
dep.info[:name] = dep.name
|
|
77
|
+
dep.original_task_name ||= dep.task_name if dep.workflow
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
begin
|
|
81
|
+
workflow = Kernel.const_get workflow if String === workflow
|
|
82
|
+
dep.task = workflow.tasks[task_name] if dep.task.nil? && workflow.tasks.include?(task_name)
|
|
83
|
+
rescue
|
|
84
|
+
Log.exception $!
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
dep.task_name = task_name
|
|
88
|
+
dep.overriden = dep.original_task_name.to_sym if dep.original_task_name
|
|
89
|
+
|
|
90
|
+
dep.extend step_module
|
|
91
|
+
|
|
92
|
+
dep
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def real_dependencies(task, orig_jobname, inputs, dependencies)
|
|
96
|
+
real_dependencies = []
|
|
97
|
+
path_deps = {}
|
|
98
|
+
|
|
99
|
+
override_dependencies = override_dependencies(inputs)
|
|
100
|
+
|
|
101
|
+
dependencies.each do |dependency|
|
|
102
|
+
_inputs = IndiferentHash.setup(inputs.dup)
|
|
103
|
+
jobname = orig_jobname
|
|
104
|
+
jobname = _inputs[:jobname] if _inputs.include? :jobname
|
|
105
|
+
|
|
106
|
+
real_dep = case dependency
|
|
107
|
+
when Array
|
|
108
|
+
workflow, dep_task, options = dependency
|
|
109
|
+
|
|
110
|
+
if override_dependencies[workflow.to_s] && value = override_dependencies[workflow.to_s][dep_task]
|
|
111
|
+
setup_override_dependency(value, workflow, dep_task)
|
|
112
|
+
else
|
|
113
|
+
|
|
114
|
+
compute = options[:compute] if options
|
|
115
|
+
|
|
116
|
+
all_d = (real_dependencies + real_dependencies.flatten.collect{|d| d.rec_dependencies} ).flatten.compact.uniq
|
|
117
|
+
|
|
118
|
+
_inputs = assign_dep_inputs(_inputs, options, all_d, workflow.task_info(dep_task))
|
|
119
|
+
jobname = _inputs.delete :jobname if _inputs.include? :jobname
|
|
120
|
+
|
|
121
|
+
job = workflow._job(dep_task, jobname, _inputs)
|
|
122
|
+
ComputeDependency.setup(job, compute) if compute
|
|
123
|
+
job
|
|
124
|
+
end
|
|
125
|
+
when Step
|
|
126
|
+
dependency
|
|
127
|
+
when Symbol
|
|
128
|
+
if override_dependencies[self.to_s] && value = override_dependencies[self.to_s][dependency]
|
|
129
|
+
setup_override_dependency(value, self, dependency)
|
|
130
|
+
else
|
|
131
|
+
_job(dependency, jobname, _inputs)
|
|
132
|
+
end
|
|
133
|
+
when Proc
|
|
134
|
+
if DependencyBlock === dependency
|
|
135
|
+
orig_dep = dependency.dependency
|
|
136
|
+
wf, task_name, options = orig_dep
|
|
137
|
+
|
|
138
|
+
if override_dependencies[wf.to_s] && value = override_dependencies[wf.to_s][task_name]
|
|
139
|
+
dep = setup_override_dependency(value, wf, task_name)
|
|
140
|
+
else
|
|
141
|
+
|
|
142
|
+
options = {} if options.nil?
|
|
143
|
+
compute = options[:compute]
|
|
144
|
+
|
|
145
|
+
options = IndiferentHash.setup(options.dup)
|
|
146
|
+
dep = dependency.call jobname, _inputs.merge(options), real_dependencies
|
|
147
|
+
|
|
148
|
+
dep = [dep] unless Array === dep
|
|
149
|
+
|
|
150
|
+
new_=[]
|
|
151
|
+
dep.each{|d|
|
|
152
|
+
next if d.nil?
|
|
153
|
+
if Hash === d
|
|
154
|
+
d[:workflow] ||= wf
|
|
155
|
+
d[:task] ||= task_name
|
|
156
|
+
_override_dependencies = override_dependencies.merge(override_dependencies(d[:inputs] || {}))
|
|
157
|
+
d = if _override_dependencies[d[:workflow].to_s] && value = _override_dependencies[d[:workflow].to_s][d[:task]]
|
|
158
|
+
setup_override_dependency(value, d[:workflow], d[:task])
|
|
159
|
+
else
|
|
160
|
+
task_info = d[:workflow].task_info(d[:task])
|
|
161
|
+
|
|
162
|
+
_inputs = assign_dep_inputs({}, options.merge(d[:inputs] || {}), real_dependencies, task_info)
|
|
163
|
+
d[:workflow]._job(d[:task], d[:jobname], _inputs)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
ComputeDependency.setup(d, compute) if compute
|
|
167
|
+
new_ << d
|
|
168
|
+
}
|
|
169
|
+
dep = new_
|
|
170
|
+
end
|
|
171
|
+
else
|
|
172
|
+
_inputs = IndiferentHash.setup(_inputs.dup)
|
|
173
|
+
dep = dependency.call jobname, _inputs, real_dependencies
|
|
174
|
+
if Hash === dep
|
|
175
|
+
dep[:workflow] ||= wf || self
|
|
176
|
+
_override_dependencies = override_dependencies.merge(override_dependencies(dep[:inputs] || {}))
|
|
177
|
+
if _override_dependencies[dep[:workflow].to_s] && value = _override_dependencies[dep[:workflow].to_s][dep[:task]]
|
|
178
|
+
setup_override_dependency(value, dep[:workflow], dep[:task])
|
|
179
|
+
else
|
|
180
|
+
task_info = (dep[:task] && dep[:workflow]) ? dep[:workflow].task_info(dep[:task]) : nil
|
|
181
|
+
_inputs = assign_dep_inputs({}, dep[:inputs], real_dependencies, task_info)
|
|
182
|
+
dep = dep[:workflow]._job(dep[:task], dep[:jobname], _inputs)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
dep
|
|
188
|
+
else
|
|
189
|
+
raise "Dependency for #{task.name} not understood: #{Misc.fingerprint dependency}"
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
real_dependencies << real_dep
|
|
193
|
+
end
|
|
194
|
+
real_dependencies.flatten.compact
|
|
195
|
+
end
|
|
196
|
+
end
|
data/lib/rbbt/workflow/step.rb
CHANGED
|
@@ -4,6 +4,8 @@ require 'rbbt/util/log'
|
|
|
4
4
|
require 'rbbt/util/semaphore'
|
|
5
5
|
require 'rbbt/workflow/step/accessor'
|
|
6
6
|
require 'rbbt/workflow/step/prepare'
|
|
7
|
+
require 'rbbt/workflow/step/status'
|
|
8
|
+
require 'rbbt/workflow/step/info'
|
|
7
9
|
|
|
8
10
|
class Step
|
|
9
11
|
attr_accessor :clean_name, :path, :task, :workflow, :inputs, :dependencies, :bindings
|
|
@@ -35,41 +37,6 @@ class Step
|
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
|
|
38
|
-
def overriden?
|
|
39
|
-
return true if @overriden
|
|
40
|
-
return true if dependencies.select{|dep| dep.overriden? }.any?
|
|
41
|
-
info[:archived_info].each do |f,i|
|
|
42
|
-
return true if i[:overriden] || i["overriden"]
|
|
43
|
-
end if info[:archived_info]
|
|
44
|
-
return false
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def overriden
|
|
48
|
-
@overriden
|
|
49
|
-
#if @overriden.nil?
|
|
50
|
-
# return false if dependencies.nil?
|
|
51
|
-
# dependencies.select{|dep| dep.overriden? }.any?
|
|
52
|
-
#else
|
|
53
|
-
# @overriden
|
|
54
|
-
#end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def overriden_deps
|
|
58
|
-
ord = []
|
|
59
|
-
deps = dependencies.dup
|
|
60
|
-
while dep = deps.shift
|
|
61
|
-
case dep.overriden
|
|
62
|
-
when FalseClass
|
|
63
|
-
next
|
|
64
|
-
when Symbol
|
|
65
|
-
ord << dep
|
|
66
|
-
else
|
|
67
|
-
deps += dep.dependencies
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
ord
|
|
71
|
-
end
|
|
72
|
-
|
|
73
40
|
def initialize(path, task = nil, inputs = nil, dependencies = nil, bindings = nil, clean_name = nil)
|
|
74
41
|
path = Path.setup(Misc.sanitize_filename(path)) if String === path
|
|
75
42
|
path = path.call if Proc === path
|
|
@@ -99,35 +66,6 @@ class Step
|
|
|
99
66
|
end
|
|
100
67
|
|
|
101
68
|
|
|
102
|
-
def load_inputs_from_info
|
|
103
|
-
if info[:inputs]
|
|
104
|
-
info_inputs = info[:inputs]
|
|
105
|
-
if task && task.respond_to?(:inputs) && task.inputs
|
|
106
|
-
IndiferentHash.setup info_inputs
|
|
107
|
-
@inputs = NamedArray.setup info_inputs.values_at(*task.inputs.collect{|name| name.to_s}), task.inputs
|
|
108
|
-
else
|
|
109
|
-
@inputs = NamedArray.setup info_inputs.values, info_inputs.keys
|
|
110
|
-
end
|
|
111
|
-
else
|
|
112
|
-
nil
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def load_dependencies_from_info
|
|
117
|
-
relocated = nil
|
|
118
|
-
@dependencies = (self.info[:dependencies] || []).collect do |task,name,dep_path|
|
|
119
|
-
if Open.exists?(dep_path) || Open.exists?(dep_path + '.info')
|
|
120
|
-
Workflow._load_step dep_path
|
|
121
|
-
else
|
|
122
|
-
next if FalseClass === relocated
|
|
123
|
-
new_path = Workflow.relocate(path, dep_path)
|
|
124
|
-
relocated = true if Open.exists?(new_path) || Open.exists?(new_path + '.info')
|
|
125
|
-
Workflow._load_step new_path
|
|
126
|
-
end
|
|
127
|
-
end.compact
|
|
128
|
-
@relocated = relocated
|
|
129
|
-
end
|
|
130
|
-
|
|
131
69
|
|
|
132
70
|
def inputs
|
|
133
71
|
return @inputs if NamedArray === @inputs
|
|
@@ -151,54 +89,6 @@ class Step
|
|
|
151
89
|
end
|
|
152
90
|
end
|
|
153
91
|
|
|
154
|
-
def archive_deps
|
|
155
|
-
self.set_info :archived_info, archived_info
|
|
156
|
-
self.set_info :archived_dependencies, info[:dependencies]
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def archived_info
|
|
160
|
-
return info[:archived_info] if info[:archived_info]
|
|
161
|
-
|
|
162
|
-
archived_info = {}
|
|
163
|
-
dependencies.each do |dep|
|
|
164
|
-
if Symbol === dep.overriden && ! Open.exists?(dep.info_file)
|
|
165
|
-
archived_info[dep.path] = dep.overriden
|
|
166
|
-
else
|
|
167
|
-
archived_info[dep.path] = dep.info
|
|
168
|
-
end
|
|
169
|
-
archived_info.merge!(dep.archived_info)
|
|
170
|
-
end if dependencies
|
|
171
|
-
|
|
172
|
-
archived_info
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def archived_inputs
|
|
176
|
-
return {} unless info[:archived_dependencies]
|
|
177
|
-
archived_info = self.archived_info
|
|
178
|
-
|
|
179
|
-
all_inputs = IndiferentHash.setup({})
|
|
180
|
-
deps = info[:archived_dependencies].collect{|p| p.last}
|
|
181
|
-
seen = []
|
|
182
|
-
while path = deps.pop
|
|
183
|
-
dep_info = archived_info[path]
|
|
184
|
-
if dep_info
|
|
185
|
-
dep_info[:inputs].each do |k,v|
|
|
186
|
-
all_inputs[k] = v unless all_inputs.include?(k)
|
|
187
|
-
end if dep_info[:inputs]
|
|
188
|
-
deps.concat(dep_info[:dependencies].collect{|p| p.last } - seen) if dep_info[:dependencies]
|
|
189
|
-
deps.concat(dep_info[:archived_dependencies].collect{|p| p.last } - seen) if dep_info[:archived_dependencies]
|
|
190
|
-
end
|
|
191
|
-
seen << path
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
all_inputs
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def dependencies=(dependencies)
|
|
198
|
-
@dependencies = dependencies
|
|
199
|
-
set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]} if dependencies
|
|
200
|
-
end
|
|
201
|
-
|
|
202
92
|
def recursive_inputs
|
|
203
93
|
if NamedArray === inputs
|
|
204
94
|
i = {}
|
|
@@ -213,7 +103,8 @@ class Step
|
|
|
213
103
|
|
|
214
104
|
dep.inputs.zip(dep.inputs.fields).each do |v,f|
|
|
215
105
|
if i.include?(f) && i[f] != v
|
|
216
|
-
|
|
106
|
+
next
|
|
107
|
+
#Log.debug "Variable '#{f}' reused with different values: #{[Misc.fingerprint(i[f]), Misc.fingerprint(v)] * " <-> "}"
|
|
217
108
|
else
|
|
218
109
|
i[f] = v
|
|
219
110
|
end
|
|
@@ -453,34 +344,6 @@ class Step
|
|
|
453
344
|
res
|
|
454
345
|
end
|
|
455
346
|
|
|
456
|
-
def self.clean(path)
|
|
457
|
-
info_file = Step.info_file path
|
|
458
|
-
pid_file = Step.pid_file path
|
|
459
|
-
md5_file = Step.md5_file path
|
|
460
|
-
files_dir = Step.files_dir path
|
|
461
|
-
tmp_path = Step.tmp_path path
|
|
462
|
-
|
|
463
|
-
if ! (Open.writable?(path) && Open.writable?(info_file))
|
|
464
|
-
Log.warn "Could not clean #{path}: not writable"
|
|
465
|
-
return
|
|
466
|
-
end
|
|
467
|
-
|
|
468
|
-
if (Open.exists?(path) or Open.broken_link?(path)) or Open.exists?(pid_file) or Open.exists?(info_file) or Open.exists?(files_dir) or Open.broken_link?(files_dir)
|
|
469
|
-
|
|
470
|
-
@result = nil
|
|
471
|
-
@pid = nil
|
|
472
|
-
|
|
473
|
-
Misc.insist do
|
|
474
|
-
Open.rm info_file if Open.exists?(info_file)
|
|
475
|
-
Open.rm md5_file if Open.exists?(md5_file)
|
|
476
|
-
Open.rm path if (Open.exists?(path) || Open.broken_link?(path))
|
|
477
|
-
Open.rm_rf files_dir if Open.exists?(files_dir) || Open.broken_link?(files_dir)
|
|
478
|
-
Open.rm pid_file if Open.exists?(pid_file)
|
|
479
|
-
Open.rm tmp_path if Open.exists?(tmp_path)
|
|
480
|
-
end
|
|
481
|
-
end
|
|
482
|
-
end
|
|
483
|
-
|
|
484
347
|
def update
|
|
485
348
|
if dirty?
|
|
486
349
|
dependencies.collect{|d| d.update } if dependencies
|
|
@@ -488,49 +351,6 @@ class Step
|
|
|
488
351
|
end
|
|
489
352
|
end
|
|
490
353
|
|
|
491
|
-
def clean
|
|
492
|
-
if ! Open.exists?(info_file)
|
|
493
|
-
Log.high "Refusing to clean step with no .info file: #{path}"
|
|
494
|
-
return self
|
|
495
|
-
end
|
|
496
|
-
status = []
|
|
497
|
-
status << "dirty" if done? && dirty?
|
|
498
|
-
status << "not running" if ! done? && ! running?
|
|
499
|
-
status.unshift " " if status.any?
|
|
500
|
-
Log.high "Cleaning step: #{path}#{status * " "}"
|
|
501
|
-
Log.stack caller if RBBT_DEBUG_CLEAN
|
|
502
|
-
abort if ! done? && running?
|
|
503
|
-
Step.clean(path)
|
|
504
|
-
self
|
|
505
|
-
end
|
|
506
|
-
|
|
507
|
-
#connected = true means that dependency searching ends when a result is done
|
|
508
|
-
#but dependencies are absent, meanining that the file could have been dropped
|
|
509
|
-
#in
|
|
510
|
-
def rec_dependencies(connected = false, seen = [])
|
|
511
|
-
|
|
512
|
-
# A step result with no info_file means that it was manually
|
|
513
|
-
# placed. In that case, do not consider its dependencies
|
|
514
|
-
return [] if ! (defined? WorkflowRemoteClient && WorkflowRemoteClient::RemoteStep === self) && ! Open.exists?(self.info_file) && Open.exists?(self.path.to_s)
|
|
515
|
-
|
|
516
|
-
return [] if dependencies.nil? or dependencies.empty?
|
|
517
|
-
|
|
518
|
-
new_dependencies = []
|
|
519
|
-
archived_deps = self.info[:archived_info] ? self.info[:archived_info].keys : []
|
|
520
|
-
|
|
521
|
-
dependencies.each{|step|
|
|
522
|
-
#next if self.done? && Open.exists?(info_file) && info[:dependencies] && info[:dependencies].select{|task,name,path| path == step.path }.empty?
|
|
523
|
-
next if archived_deps.include? step.path
|
|
524
|
-
next if seen.include? step.path
|
|
525
|
-
next if self.done? && connected && ! updatable?
|
|
526
|
-
|
|
527
|
-
r = step.rec_dependencies(connected, new_dependencies.collect{|d| d.path})
|
|
528
|
-
new_dependencies.concat r
|
|
529
|
-
new_dependencies << step
|
|
530
|
-
}
|
|
531
|
-
new_dependencies.uniq
|
|
532
|
-
end
|
|
533
|
-
|
|
534
354
|
def writable?
|
|
535
355
|
Open.writable?(self.path) && Open.writable?(self.info_file)
|
|
536
356
|
end
|