rbbt-util 5.35.4 → 5.37.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/lib/rbbt/persist.rb +2 -0
- data/lib/rbbt/resource/path.rb +12 -2
- data/lib/rbbt/util/concurrency/processes/socket.rb +1 -0
- data/lib/rbbt/util/concurrency/processes/worker.rb +1 -5
- data/lib/rbbt/util/concurrency/processes.rb +29 -24
- data/lib/rbbt/util/misc/inspect.rb +2 -2
- data/lib/rbbt/util/python.rb +2 -2
- data/lib/rbbt/workflow/definition.rb +2 -0
- data/lib/rbbt/workflow/dependencies.rb +26 -4
- data/lib/rbbt/workflow/doc.rb +1 -0
- data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +62 -20
- data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +31 -3
- data/lib/rbbt/workflow/remote_workflow/remote_step.rb +1 -0
- data/lib/rbbt/workflow/step/accessor.rb +42 -5
- data/lib/rbbt/workflow/step/dependencies.rb +37 -28
- data/lib/rbbt/workflow/step/{prepare.rb → produce.rb} +1 -1
- data/lib/rbbt/workflow/step/run.rb +39 -28
- data/lib/rbbt/workflow/step/status.rb +1 -1
- data/lib/rbbt/workflow/step.rb +55 -83
- data/lib/rbbt/workflow/task.rb +4 -2
- data/lib/rbbt/workflow/util/archive.rb +29 -23
- data/lib/rbbt/workflow.rb +13 -3
- data/python/rbbt.py +87 -1
- data/share/rbbt_commands/tsv/write_excel +3 -2
- data/share/rbbt_commands/workflow/task +53 -5
- data/test/rbbt/test_workflow.rb +88 -0
- data/test/rbbt/workflow/step/test_dependencies.rb +1 -0
- metadata +88 -144
@@ -3,7 +3,7 @@ class Step
|
|
3
3
|
STREAM_CACHE = {}
|
4
4
|
STREAM_CACHE_MUTEX = Mutex.new
|
5
5
|
def self.purge_stream_cache
|
6
|
-
Log.debug "Purging dup. stream cache"
|
6
|
+
# Log.debug "Purging dup. stream cache"
|
7
7
|
STREAM_CACHE_MUTEX.synchronize do
|
8
8
|
STREAM_CACHE.clear
|
9
9
|
end
|
@@ -145,11 +145,12 @@ class Step
|
|
145
145
|
end
|
146
146
|
|
147
147
|
def input_dependencies
|
148
|
-
@input_dependencies ||=
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
148
|
+
@input_dependencies ||= recursive_inputs.flatten.
|
149
|
+
select{|i| Step === i || (defined?(RemoteStep) && RemoteStep === i) } +
|
150
|
+
recursive_inputs.flatten.
|
151
|
+
select{|dep| Path === dep && Step === dep.resource }.
|
152
|
+
select{|dep| ! dep.resource.started? }. # Ignore input_deps already started
|
153
|
+
collect{|dep| dep.resource }
|
153
154
|
end
|
154
155
|
|
155
156
|
def execute_dependency(dependency, log = true)
|
@@ -209,7 +210,7 @@ class Step
|
|
209
210
|
end
|
210
211
|
|
211
212
|
rescue TryAgain
|
212
|
-
Log.low "Retrying dep. #{Log.color :yellow, dependency.task_name.to_s} -- [#{dependency.status}] #{(dependency.messages || ["No message"]).last}"
|
213
|
+
#Log.low "Retrying dep. #{Log.color :yellow, dependency.task_name.to_s} -- [#{dependency.status}] #{(dependency.messages || ["No message"]).last}"
|
213
214
|
retry
|
214
215
|
rescue Aborted, Interrupt
|
215
216
|
Log.error "Aborted dep. #{Log.color :red, dependency.task_name.to_s}"
|
@@ -260,6 +261,9 @@ class Step
|
|
260
261
|
dep.produce
|
261
262
|
rescue RbbtException
|
262
263
|
Log.warn "Allowing failing of #{dep.path}: #{dep.messages.last if dep.messages}"
|
264
|
+
rescue Exception
|
265
|
+
Log.warn "Not Allowing failing of #{dep.path} because #{$!.class} not RbbtException"
|
266
|
+
raise $!
|
263
267
|
end
|
264
268
|
nil
|
265
269
|
end
|
@@ -430,7 +434,6 @@ class Step
|
|
430
434
|
|
431
435
|
required_dep_paths = []
|
432
436
|
dep_step.each do |path,list|
|
433
|
-
#required_dep_paths << path if list.length > 1
|
434
437
|
required_dep_paths << path if (list & dependencies).any?
|
435
438
|
end
|
436
439
|
|
@@ -442,42 +445,48 @@ class Step
|
|
442
445
|
[dep.path] + dep.input_dependencies
|
443
446
|
end.flatten)
|
444
447
|
|
445
|
-
log :dependencies, "Dependencies for step #{Log.color :yellow, task.name.to_s || ""}"
|
446
448
|
|
447
449
|
pre_deps = []
|
448
|
-
|
449
|
-
|
450
|
+
simple_dependencies = []
|
451
|
+
compute_simple_dependencies = {}
|
450
452
|
compute_last_deps = {}
|
451
453
|
seen_paths = Set.new
|
452
|
-
rec_dependencies.uniq.each do |step|
|
454
|
+
rec_dependencies.uniq.reverse.each do |step|
|
453
455
|
next if seen_paths.include? step.path
|
454
456
|
seen_paths << step.path
|
455
457
|
next unless required_dep_paths.include? step.path
|
456
|
-
|
457
|
-
|
458
|
-
|
458
|
+
required_seen_paths = seen_paths & required_dep_paths
|
459
|
+
|
460
|
+
inputs = step.inputs
|
461
|
+
inputs = inputs.values if Hash === inputs
|
462
|
+
internal = inputs.select{|i| i.respond_to?(:path) && required_seen_paths.include?(i.path) }.any?
|
463
|
+
|
464
|
+
if ComputeDependency === step
|
465
|
+
next if produced.include? step.path
|
466
|
+
if internal
|
459
467
|
compute_last_deps[step.compute] ||= []
|
460
468
|
compute_last_deps[step.compute] << step
|
461
469
|
else
|
462
|
-
|
470
|
+
compute_simple_dependencies[step.compute] ||= []
|
471
|
+
compute_simple_dependencies[step.compute] << step
|
463
472
|
end
|
464
473
|
else
|
465
|
-
if
|
466
|
-
|
467
|
-
compute_pre_deps[step.compute] ||= []
|
468
|
-
compute_pre_deps[step.compute] << step
|
474
|
+
if internal
|
475
|
+
simple_dependencies << step
|
469
476
|
else
|
470
|
-
|
477
|
+
simple_dependencies.prepend(step)
|
471
478
|
end
|
472
479
|
end
|
473
480
|
end
|
474
481
|
|
475
|
-
|
476
|
-
|
482
|
+
log :dependencies, "Processing dependencies for #{Log.color :yellow, task_name.to_s || ""}" if compute_simple_dependencies.any? || simple_dependencies.any? || compute_last_deps.any?
|
483
|
+
|
484
|
+
Log.debug "compute_simple_dependencies: #{Misc.fingerprint(compute_simple_dependencies)} - #{Log.color :blue, self.path}" if compute_simple_dependencies.any?
|
485
|
+
compute_simple_dependencies.each do |type,list|
|
477
486
|
run_compute_dependencies(type, list, dep_step)
|
478
487
|
end
|
479
488
|
|
480
|
-
Log.
|
489
|
+
Log.low "pre_deps: #{Misc.fingerprint(pre_deps)} - #{Log.color :blue, self.path}" if pre_deps.any?
|
481
490
|
pre_deps.each do |step|
|
482
491
|
next if compute_deps.include? step
|
483
492
|
begin
|
@@ -487,8 +496,8 @@ class Step
|
|
487
496
|
end
|
488
497
|
end
|
489
498
|
|
490
|
-
Log.
|
491
|
-
|
499
|
+
Log.debug "simple_dependencies: #{Misc.fingerprint(simple_dependencies)} - #{Log.color :blue, self.path}" if simple_dependencies.any?
|
500
|
+
simple_dependencies.each do |step|
|
492
501
|
next if compute_deps.include? step
|
493
502
|
begin Exception
|
494
503
|
execute_and_dup(step, dep_step)
|
@@ -497,8 +506,8 @@ class Step
|
|
497
506
|
end
|
498
507
|
end
|
499
508
|
|
500
|
-
Log.
|
501
|
-
|
509
|
+
Log.low "compute_last_deps: #{Misc.fingerprint(compute_simple_dependencies)} - #{Log.color :blue, self.path}" if compute_simple_dependencies.any?
|
510
|
+
compute_simple_dependencies.each do |type,list|
|
502
511
|
run_compute_dependencies(type, list, dep_step)
|
503
512
|
end
|
504
513
|
|
@@ -96,7 +96,13 @@ class Step
|
|
96
96
|
@exec = true if @exec.nil?
|
97
97
|
begin
|
98
98
|
old = Signal.trap("INT"){ Thread.current.raise Aborted }
|
99
|
-
@task.
|
99
|
+
if @task.respond_to?(:exec_in)
|
100
|
+
@task.exec_in((bindings || self), *@inputs)
|
101
|
+
elsif @task
|
102
|
+
(bindings || self).instance_exec *@inputs, &@task
|
103
|
+
else
|
104
|
+
raise DependencyError, "Dependency #{self.path} cannot be produced"
|
105
|
+
end
|
100
106
|
ensure
|
101
107
|
Signal.trap("INT", old)
|
102
108
|
end
|
@@ -223,14 +229,15 @@ class Step
|
|
223
229
|
end
|
224
230
|
|
225
231
|
begin
|
226
|
-
|
227
|
-
|
228
|
-
no_load = :stream if no_load
|
232
|
+
no_load = :stream if no_load
|
233
|
+
result_type = self.result_type || info[:result_type]
|
229
234
|
|
235
|
+
res = @mutex.synchronize do
|
236
|
+
time_elapsed = total_time_elapsed = nil
|
230
237
|
Open.write(pid_file, Process.pid.to_s) unless Open.exists?(path) or Open.exists?(pid_file)
|
231
|
-
|
232
|
-
result_type = info[:result_type] if result_type.nil?
|
238
|
+
|
233
239
|
result = Persist.persist "Job", result_type, :file => path, :check => persist_checks, :no_load => no_load do
|
240
|
+
|
234
241
|
if Step === Step.log_relay_step and not self == Step.log_relay_step
|
235
242
|
relay_log(Step.log_relay_step) unless self.respond_to? :relay_step and self.relay_step
|
236
243
|
end
|
@@ -240,26 +247,30 @@ class Step
|
|
240
247
|
@exec = false
|
241
248
|
init_info(true)
|
242
249
|
|
243
|
-
|
250
|
+
workflow = @workflow || @task.respond_to?(:workflow) ? @task.workflow : nil
|
251
|
+
result_type = @task.respond_to?(:result_type) ? @task.result_type : nil
|
252
|
+
result_description = @task.respond_to?(:result_description) ? @task.result_description : nil
|
253
|
+
|
254
|
+
log :setup, "#{Log.color :green, "Setup"} step #{Log.color :yellow, task_name}"
|
244
255
|
|
245
256
|
merge_info({
|
246
|
-
:issued
|
247
|
-
:name
|
248
|
-
:pid
|
249
|
-
:pid_hostname
|
250
|
-
:clean_name
|
251
|
-
:workflow
|
252
|
-
:task_name
|
253
|
-
:result_type
|
254
|
-
:result_description =>
|
255
|
-
:dependencies
|
256
|
-
:versions
|
257
|
+
:issued => (issue_time = Time.now),
|
258
|
+
:name => name,
|
259
|
+
:pid => Process.pid.to_s,
|
260
|
+
:pid_hostname => Socket.gethostname,
|
261
|
+
:clean_name => clean_name,
|
262
|
+
:workflow => workflow.to_s,
|
263
|
+
:task_name => task_name,
|
264
|
+
:result_type => result_type,
|
265
|
+
:result_description => result_description,
|
266
|
+
:dependencies => dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]},
|
267
|
+
:versions => Rbbt.versions
|
257
268
|
})
|
258
269
|
|
259
270
|
new_inputs = []
|
260
271
|
@inputs.each_with_index do |input,i|
|
261
|
-
name = @task.inputs[i]
|
262
|
-
type = @task.input_types[
|
272
|
+
name = @task.respond_to?(:inputs) ? @task.inputs[i] : nil
|
273
|
+
type = @task.respond_to?(:input_types) ? @task.input_types[i] : nil
|
263
274
|
|
264
275
|
if type == :directory
|
265
276
|
directory_inputs = file('directory_inputs')
|
@@ -303,7 +314,7 @@ class Step
|
|
303
314
|
|
304
315
|
@inputs = new_inputs if @inputs
|
305
316
|
|
306
|
-
if @inputs && ! task.inputs.nil?
|
317
|
+
if @inputs && task.respond_to?(:inputs) && ! task.inputs.nil?
|
307
318
|
info_inputs = @inputs.collect do |i|
|
308
319
|
if Path === i
|
309
320
|
i.to_s
|
@@ -323,7 +334,7 @@ class Step
|
|
323
334
|
end
|
324
335
|
|
325
336
|
set_info :started, (start_time = Time.now)
|
326
|
-
log :started, "Starting step #{Log.color :yellow,
|
337
|
+
log :started, "Starting step #{Log.color :yellow, task_name}"
|
327
338
|
|
328
339
|
config_keys_pre = Rbbt::Config::GOT_KEYS.dup
|
329
340
|
begin
|
@@ -357,7 +368,7 @@ class Step
|
|
357
368
|
end
|
358
369
|
|
359
370
|
if stream
|
360
|
-
log :streaming, "Streaming step #{Log.color :yellow,
|
371
|
+
log :streaming, "Streaming step #{Log.color :yellow, task_name.to_s || ""}"
|
361
372
|
|
362
373
|
callback = Proc.new do
|
363
374
|
if AbortedStream === stream
|
@@ -377,7 +388,7 @@ class Step
|
|
377
388
|
:time_elapsed => (time_elapsed = done_time - start_time),
|
378
389
|
:versions => Rbbt.versions
|
379
390
|
})
|
380
|
-
log :done, "Completed step #{Log.color :yellow,
|
391
|
+
log :done, "Completed step #{Log.color :yellow, task_name.to_s || ""} in #{time_elapsed.to_i}+#{(total_time_elapsed - time_elapsed).to_i} sec."
|
381
392
|
end
|
382
393
|
end
|
383
394
|
rescue
|
@@ -393,7 +404,7 @@ class Step
|
|
393
404
|
if exception
|
394
405
|
self.exception exception
|
395
406
|
else
|
396
|
-
log :aborted, "#{Log.color :red, "Aborted"} step #{Log.color :yellow,
|
407
|
+
log :aborted, "#{Log.color :red, "Aborted"} step #{Log.color :yellow, task_name.to_s || ""}" if status == :streaming
|
397
408
|
end
|
398
409
|
_clean_finished
|
399
410
|
rescue
|
@@ -419,7 +430,6 @@ class Step
|
|
419
430
|
})
|
420
431
|
log :ending
|
421
432
|
Step.purge_stream_cache
|
422
|
-
Open.rm pid_file if Open.exist?(pid_file)
|
423
433
|
end
|
424
434
|
|
425
435
|
set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]}
|
@@ -430,16 +440,17 @@ class Step
|
|
430
440
|
if result.nil? && File.exist?(self.tmp_path) && ! File.exist?(self.path)
|
431
441
|
Open.mv self.tmp_path, self.path
|
432
442
|
end
|
443
|
+
Open.rm pid_file if Open.exist?(pid_file) unless stream
|
433
444
|
result
|
434
445
|
end # END PERSIST
|
435
|
-
log :done, "Completed step #{Log.color :yellow,
|
446
|
+
log :done, "Completed step #{Log.color :yellow, task_name.to_s || ""} in #{time_elapsed.to_i}+#{(total_time_elapsed - time_elapsed).to_i} sec." unless stream or time_elapsed.nil?
|
436
447
|
|
437
448
|
if no_load
|
438
449
|
@result ||= result
|
439
450
|
self
|
440
451
|
else
|
441
452
|
Step.purge_stream_cache
|
442
|
-
@result = prepare_result result,
|
453
|
+
@result = prepare_result result, result_description
|
443
454
|
end
|
444
455
|
end # END SYNC
|
445
456
|
res
|
data/lib/rbbt/workflow/step.rb
CHANGED
@@ -3,20 +3,12 @@ require 'rbbt/persist/tsv'
|
|
3
3
|
require 'rbbt/util/log'
|
4
4
|
require 'rbbt/util/semaphore'
|
5
5
|
require 'rbbt/workflow/step/accessor'
|
6
|
-
require 'rbbt/workflow/step/
|
6
|
+
require 'rbbt/workflow/step/produce'
|
7
7
|
require 'rbbt/workflow/step/status'
|
8
8
|
require 'rbbt/workflow/step/info'
|
9
9
|
require 'rbbt/workflow/step/save_load_inputs'
|
10
10
|
|
11
11
|
class Step
|
12
|
-
attr_accessor :clean_name, :path, :task, :workflow, :inputs, :dependencies, :bindings
|
13
|
-
attr_accessor :task_name, :overriden
|
14
|
-
attr_accessor :pid
|
15
|
-
attr_accessor :exec
|
16
|
-
attr_accessor :relocated
|
17
|
-
attr_accessor :result, :mutex, :seen
|
18
|
-
attr_accessor :real_inputs, :original_task_name, :original_workflow
|
19
|
-
|
20
12
|
RBBT_DEBUG_CLEAN = ENV["RBBT_DEBUG_CLEAN"] == 'true'
|
21
13
|
|
22
14
|
class << self
|
@@ -38,10 +30,12 @@ class Step
|
|
38
30
|
end
|
39
31
|
|
40
32
|
|
41
|
-
def initialize(path, task = nil, inputs = nil, dependencies = nil, bindings = nil, clean_name = nil)
|
33
|
+
def initialize(path, task = nil, inputs = nil, dependencies = nil, bindings = nil, clean_name = nil, &block)
|
42
34
|
path = Path.setup(Misc.sanitize_filename(path)) if String === path
|
43
35
|
path = path.call if Proc === path
|
44
36
|
|
37
|
+
task = block if block_given?
|
38
|
+
|
45
39
|
@path = path
|
46
40
|
@task = task
|
47
41
|
@bindings = bindings
|
@@ -73,7 +67,8 @@ class Step
|
|
73
67
|
|
74
68
|
load_inputs_from_info if @inputs.nil?
|
75
69
|
|
76
|
-
|
70
|
+
task_inputs = task.respond_to?(:inputs) ? task.inputs : nil
|
71
|
+
NamedArray.setup(@inputs, task_inputs) unless NamedArray === @inputs
|
77
72
|
|
78
73
|
@inputs || []
|
79
74
|
end
|
@@ -133,15 +128,6 @@ class Step
|
|
133
128
|
v
|
134
129
|
end
|
135
130
|
|
136
|
-
def task_name
|
137
|
-
@task_name ||= begin
|
138
|
-
if @task.nil?
|
139
|
-
@path.split("/")[-2]
|
140
|
-
else
|
141
|
-
@task.name
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
131
|
|
146
132
|
def path
|
147
133
|
if Proc === @path
|
@@ -155,8 +141,11 @@ class Step
|
|
155
141
|
attr_accessor :log_relay_step
|
156
142
|
end
|
157
143
|
|
144
|
+
|
145
|
+
# May be deprecated: This is no loger used
|
158
146
|
def relay_log(step)
|
159
|
-
return self
|
147
|
+
return self if self.task_name.nil?
|
148
|
+
|
160
149
|
if not self.respond_to? :original_log
|
161
150
|
class << self
|
162
151
|
attr_accessor :relay_step
|
@@ -164,77 +153,58 @@ class Step
|
|
164
153
|
def log(status, message = nil)
|
165
154
|
self.status = status
|
166
155
|
message Log.uncolor message
|
167
|
-
relay_step.log([
|
156
|
+
relay_step.log([self.task_name.to_s, status.to_s] * ">", message.nil? ? nil : message ) unless (relay_step.done? or relay_step.error? or relay_step.aborted?)
|
168
157
|
end
|
169
158
|
end
|
170
159
|
end
|
171
160
|
@relay_step = step
|
172
|
-
self
|
173
|
-
end
|
174
161
|
|
175
|
-
|
176
|
-
@result_type ||= if @task.nil?
|
177
|
-
info[:result_type] || :binary
|
178
|
-
else
|
179
|
-
@task.result_type || info[:result_type] || :string
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def result_type=(type)
|
184
|
-
@result_type = type
|
185
|
-
end
|
186
|
-
|
187
|
-
def result_description
|
188
|
-
@result_description ||= if @task.nil?
|
189
|
-
info[:result_description]
|
190
|
-
else
|
191
|
-
@task.result_description
|
192
|
-
end
|
162
|
+
self
|
193
163
|
end
|
194
164
|
|
195
165
|
def prepare_result(value, description = nil, entity_info = nil)
|
196
166
|
res = case
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
end
|
205
|
-
array
|
206
|
-
when :tsv
|
207
|
-
begin
|
208
|
-
TSV.open(value)
|
209
|
-
rescue IOError
|
210
|
-
TSV.setup({})
|
211
|
-
end
|
212
|
-
else
|
213
|
-
value.read
|
214
|
-
end
|
215
|
-
value.join if value.respond_to? :join
|
216
|
-
res
|
217
|
-
rescue Exception
|
218
|
-
value.abort if value.respond_to? :abort
|
219
|
-
self.abort
|
220
|
-
raise $!
|
221
|
-
end
|
222
|
-
when (not defined? Entity or description.nil? or not Entity.formats.include? description)
|
223
|
-
value
|
224
|
-
when (Annotated === value and info.empty?)
|
225
|
-
value
|
226
|
-
when Annotated === value
|
227
|
-
annotations = value.annotations
|
228
|
-
entity_info ||= begin
|
229
|
-
entity_info = info.dup
|
230
|
-
entity_info.merge! info[:inputs] if info[:inputs]
|
231
|
-
entity_info
|
167
|
+
when IO === value
|
168
|
+
begin
|
169
|
+
res = case result_type
|
170
|
+
when :array
|
171
|
+
array = []
|
172
|
+
while line = value.gets
|
173
|
+
array << line.chomp
|
232
174
|
end
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
175
|
+
array
|
176
|
+
when :tsv
|
177
|
+
begin
|
178
|
+
TSV.open(value)
|
179
|
+
rescue IOError
|
180
|
+
TSV.setup({})
|
181
|
+
end
|
182
|
+
else
|
183
|
+
value.read
|
184
|
+
end
|
185
|
+
value.join if value.respond_to? :join
|
186
|
+
res
|
187
|
+
rescue Exception
|
188
|
+
value.abort if value.respond_to? :abort
|
189
|
+
self.abort
|
190
|
+
raise $!
|
191
|
+
end
|
192
|
+
when (not defined? Entity or description.nil? or not Entity.formats.include? description)
|
193
|
+
value
|
194
|
+
when (Annotated === value and info.empty?)
|
195
|
+
value
|
196
|
+
when Annotated === value
|
197
|
+
annotations = value.annotations
|
198
|
+
entity_info ||= begin
|
199
|
+
entity_info = info.dup
|
200
|
+
entity_info.merge! info[:inputs] if info[:inputs]
|
201
|
+
entity_info
|
202
|
+
end
|
203
|
+
entity_info.each do |k,v|
|
204
|
+
value.send("#{h}=", v) if annotations.include? k
|
205
|
+
end
|
206
|
+
|
207
|
+
value
|
238
208
|
else
|
239
209
|
entity_info ||= begin
|
240
210
|
entity_info = info.dup
|
@@ -371,8 +341,9 @@ class Step
|
|
371
341
|
def step(name)
|
372
342
|
@steps ||= {}
|
373
343
|
@steps[name] ||= begin
|
344
|
+
name = name.to_sym
|
374
345
|
deps = rec_dependencies.select{|step|
|
375
|
-
step.task_name.to_sym == name
|
346
|
+
step.task_name && step.task_name.to_sym == name
|
376
347
|
}
|
377
348
|
raise "Dependency step not found: #{ name }" if deps.empty?
|
378
349
|
if (deps & self.dependencies).any?
|
@@ -385,3 +356,4 @@ class Step
|
|
385
356
|
end
|
386
357
|
|
387
358
|
require 'rbbt/workflow/step/run'
|
359
|
+
require 'rbbt/workflow/step/accessor'
|
data/lib/rbbt/workflow/task.rb
CHANGED
@@ -88,13 +88,15 @@ module Task
|
|
88
88
|
next
|
89
89
|
end
|
90
90
|
|
91
|
+
task_name ||= task.name
|
92
|
+
|
91
93
|
maps = (Array === dep and Hash === dep.last) ? dep.last.keys : []
|
92
94
|
raise "Dependency task not found: #{dep}" if task.nil?
|
93
|
-
next if seen.include? [wf,
|
95
|
+
next if seen.include? [wf, task_name, maps]
|
94
96
|
|
95
97
|
task.workflow = wf if wf
|
96
98
|
|
97
|
-
seen << [wf,
|
99
|
+
seen << [wf, task_name, maps]
|
98
100
|
new_inputs = task.inputs - maps
|
99
101
|
next unless new_inputs.any?
|
100
102
|
if task_inputs[task].nil?
|
@@ -160,44 +160,50 @@ puts files * "\n"
|
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
163
|
-
def self.migrate(
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
163
|
+
def self.migrate(paths, search_path, options = {})
|
164
|
+
subpath_files = {}
|
165
|
+
target_paths = []
|
166
|
+
resource = options[:resource] || Rbbt
|
167
|
+
|
168
|
+
target = Rbbt.migrate_target_path('var/jobs', search_path, resource, options[:target])
|
169
|
+
|
170
|
+
(Array === paths ? paths : [paths]).each do |path|
|
171
|
+
if Step === path
|
172
|
+
if options[:source]
|
173
|
+
path = Rbbt.identify(path.path)
|
174
|
+
else
|
175
|
+
path = path.path
|
176
|
+
end
|
169
177
|
end
|
170
|
-
|
171
|
-
search_path = 'user' if search_path.nil?
|
178
|
+
search_path = 'user' if search_path.nil?
|
172
179
|
|
173
|
-
resource = Rbbt
|
174
180
|
|
175
|
-
|
181
|
+
path, real_paths, lpath = self.migrate_source_paths(path, resource, options[:source], options[:recursive])
|
176
182
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
183
|
+
real_paths.sort.each do |path|
|
184
|
+
parts = path.split("/")
|
185
|
+
subpath = parts[0..-4] * "/" + "/"
|
186
|
+
|
187
|
+
if subpath_files.keys.any? && subpath.start_with?(subpath_files.keys.last)
|
188
|
+
subpath = subpath_files.keys.last
|
189
|
+
end
|
181
190
|
|
182
|
-
|
183
|
-
|
191
|
+
source = path.chars[subpath.length..-1] * ""
|
192
|
+
|
193
|
+
subpath_files[subpath] ||= []
|
194
|
+
subpath_files[subpath] << source
|
184
195
|
end
|
185
196
|
|
186
|
-
source = path.chars[subpath.length..-1] * ""
|
187
197
|
|
188
|
-
|
189
|
-
subpath_files[subpath] << source
|
198
|
+
target_paths << File.join(target, *path.split("/")[-3..-1])
|
190
199
|
end
|
191
200
|
|
192
|
-
target = Rbbt.migrate_target_path('var/jobs', search_path, resource, options[:target])
|
193
|
-
|
194
|
-
target_path = File.join(target, *path.split("/")[-3..-1])
|
195
201
|
|
196
202
|
subpath_files.each do |subpath, files|
|
197
203
|
Rbbt.migrate_files([subpath], target, options.merge(:files => files))
|
198
204
|
end
|
199
205
|
|
200
|
-
|
206
|
+
target_paths
|
201
207
|
end
|
202
208
|
|
203
209
|
def self.purge(path, recursive = false, skip_overriden = true)
|
data/lib/rbbt/workflow.rb
CHANGED
@@ -212,11 +212,13 @@ module Workflow
|
|
212
212
|
end
|
213
213
|
workflow.load_documentation
|
214
214
|
|
215
|
+
|
215
216
|
first ||= workflow
|
216
217
|
end
|
217
|
-
return first
|
218
218
|
|
219
|
-
|
219
|
+
first.complete_name = wf_name
|
220
|
+
|
221
|
+
return first
|
220
222
|
end
|
221
223
|
|
222
224
|
attr_accessor :description
|
@@ -230,6 +232,12 @@ module Workflow
|
|
230
232
|
attr_accessor :relay_tasks
|
231
233
|
|
232
234
|
#{{{ ATTR DEFAULTS
|
235
|
+
#
|
236
|
+
attr_accessor :complete_name
|
237
|
+
|
238
|
+
def self.complete_name
|
239
|
+
@complete_name ||= self.to_s
|
240
|
+
end
|
233
241
|
|
234
242
|
def self.workdir=(path)
|
235
243
|
path = Path.setup path.dup unless Path === path
|
@@ -482,8 +490,10 @@ module Workflow
|
|
482
490
|
end
|
483
491
|
end
|
484
492
|
|
493
|
+
overriden = true if dependencies.select{|d| d.overriden && d.clean_name != d.name }.any?
|
494
|
+
|
485
495
|
input_values = task.take_input_values(inputs)
|
486
|
-
if real_inputs.empty? && Workflow::TAG != :inputs && ! overriden
|
496
|
+
if real_inputs.empty? && Workflow::TAG != :inputs && ! overriden #&& ! dependencies.select{|d| d.overriden && d.clean_name != d.name }.any?
|
487
497
|
step_path = step_path taskname, jobname, [], [], extension
|
488
498
|
else
|
489
499
|
step_path = step_path taskname, jobname, input_values, dependencies, extension
|