rbbt-util 3.0.2 → 3.0.3
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.
- data/lib/rbbt/util/log.rb +8 -2
- data/lib/rbbt/util/misc.rb +31 -3
- data/lib/rbbt/util/open.rb +16 -3
- data/lib/rbbt/util/persistence.rb +52 -37
- data/lib/rbbt/util/resource.rb +8 -0
- data/lib/rbbt/util/task.rb +41 -281
- data/lib/rbbt/util/task/job.rb +276 -0
- data/lib/rbbt/util/tsv/attach.rb +86 -19
- data/lib/rbbt/util/workflow.rb +18 -24
- data/test/rbbt/util/test_misc.rb +42 -10
- data/test/rbbt/util/test_task.rb +7 -6
- data/test/rbbt/util/test_tc_hash.rb +20 -2
- data/test/rbbt/util/test_workflow.rb +38 -8
- data/test/rbbt/util/tsv/test_attach.rb +17 -0
- metadata +19 -4
data/lib/rbbt/util/log.rb
CHANGED
@@ -16,13 +16,15 @@ module Log
|
|
16
16
|
@@severity
|
17
17
|
end
|
18
18
|
|
19
|
-
SEVERITY_COLOR = ["0;37m", "32m", "33m", "31m", "1;0m" ].collect{|e| "\033[#{e}"}
|
19
|
+
SEVERITY_COLOR = ["0;37m", "0;32m", "0;33m", "0;31m", "1;0m" ].collect{|e| "\033[#{e}"}
|
20
20
|
|
21
21
|
def self.log(message, severity = MEDIUM)
|
22
22
|
severity_color = SEVERITY_COLOR[severity]
|
23
|
+
font_color = {false => "\033[0;37m", true => "\033[0m"}[severity >= INFO]
|
24
|
+
|
23
25
|
STDERR.puts caller.select{|l| l =~ /rbbt/} * "\n" if @@severity == -1 and not message.empty?
|
24
26
|
#STDERR.puts "#{Time.now.strftime("[%m/%d/%y-%H:%M:%S]")}[#{severity.to_s}]: " + message if severity >= @@severity
|
25
|
-
STDERR.puts "\033[0;37m#{Time.now.strftime("[%m/%d/%y-%H:%M:%S]")}#{severity_color}[#{severity.to_s}]\033[0m
|
27
|
+
STDERR.puts "\033[0;37m#{Time.now.strftime("[%m/%d/%y-%H:%M:%S]")}#{severity_color}[#{severity.to_s}]\033[0m:#{font_color} " << message.strip << "\033[0m" if severity >= @@severity
|
26
28
|
end
|
27
29
|
|
28
30
|
def self.debug(message)
|
@@ -41,6 +43,10 @@ module Log
|
|
41
43
|
log(message, HIGH)
|
42
44
|
end
|
43
45
|
|
46
|
+
def self.info(message)
|
47
|
+
log(message, INFO)
|
48
|
+
end
|
49
|
+
|
44
50
|
def self.warn(message)
|
45
51
|
log(message, WARN)
|
46
52
|
end
|
data/lib/rbbt/util/misc.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'iconv'
|
2
|
+
require 'lockfile'
|
2
3
|
require 'digest/md5'
|
3
4
|
|
4
5
|
class RBBTError < StandardError
|
@@ -14,9 +15,32 @@ class RBBTError < StandardError
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
module IndiferentHash
|
19
|
+
def indiferent_get(key)
|
20
|
+
old_get(key) ||
|
21
|
+
old_get(key.to_s) ||
|
22
|
+
old_get(key.to_sym)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.extended(base)
|
26
|
+
class << base
|
27
|
+
alias_method :old_get, :[]
|
28
|
+
alias_method :[], :indiferent_get
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
17
33
|
module Misc
|
18
34
|
class FieldNotFoundError < StandardError;end
|
19
35
|
|
36
|
+
def self.lock(file, *args)
|
37
|
+
FileUtils.mkdir_p File.dirname(File.expand_path(file)) unless File.exists? File.dirname(File.expand_path(file))
|
38
|
+
lockfile = Lockfile.new file + '.lock'
|
39
|
+
lockfile.lock do
|
40
|
+
yield file, *args
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
20
44
|
def self.string2const(string)
|
21
45
|
return nil if string.nil?
|
22
46
|
mod = Kernel
|
@@ -137,15 +161,19 @@ module Misc
|
|
137
161
|
|
138
162
|
def self.hash2md5(hash)
|
139
163
|
o = {}
|
140
|
-
hash.each do |k
|
141
|
-
|
164
|
+
hash.keys.sort_by{|k| k.to_s}.each do |k|
|
165
|
+
v = hash[k]
|
166
|
+
case
|
167
|
+
when v.inspect =~ /:0x0/
|
142
168
|
o[k] = v.inspect.sub(/:0x[a-f0-9]+@/,'')
|
169
|
+
when Resource::Path === v
|
170
|
+
"" << String.new(v.to_s)
|
143
171
|
else
|
144
172
|
o[k] = v
|
145
173
|
end
|
146
174
|
end
|
147
175
|
|
148
|
-
Digest::MD5.hexdigest(o.inspect)
|
176
|
+
Digest::MD5.hexdigest(o.sort_by{|k| k.to_s}.inspect)
|
149
177
|
end
|
150
178
|
|
151
179
|
def self.string2hash(string)
|
data/lib/rbbt/util/open.rb
CHANGED
@@ -200,9 +200,21 @@ module Open
|
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
203
|
-
def self.write(file, content)
|
203
|
+
def self.write(file, content = nil)
|
204
204
|
FileUtils.mkdir_p File.dirname(file)
|
205
|
-
|
205
|
+
case
|
206
|
+
when content.nil?
|
207
|
+
begin
|
208
|
+
File.open(file, 'w') do |f|
|
209
|
+
f.flock(File::LOCK_EX)
|
210
|
+
yield f
|
211
|
+
f.flock(File::LOCK_UN)
|
212
|
+
end
|
213
|
+
rescue Exception
|
214
|
+
FileUtils.rm file if File.exists? file
|
215
|
+
raise $!
|
216
|
+
end
|
217
|
+
when String === content
|
206
218
|
File.open(file, 'w') do |f|
|
207
219
|
f.flock(File::LOCK_EX)
|
208
220
|
f.write content
|
@@ -217,8 +229,9 @@ module Open
|
|
217
229
|
end
|
218
230
|
f.flock(File::LOCK_UN)
|
219
231
|
end
|
220
|
-
rescue
|
232
|
+
rescue Exception
|
221
233
|
FileUtils.rm file if File.exists? file
|
234
|
+
raise $!
|
222
235
|
end
|
223
236
|
content.close
|
224
237
|
end
|
@@ -181,6 +181,7 @@ module Persistence
|
|
181
181
|
FileUtils.rm persistence_file
|
182
182
|
end
|
183
183
|
|
184
|
+
Log.debug "Dump data into '#{persistence_file}'"
|
184
185
|
per = Persistence::TSV.get persistence_file, true, serializer
|
185
186
|
|
186
187
|
per.write
|
@@ -227,30 +228,41 @@ module Persistence
|
|
227
228
|
|
228
229
|
serializer = tsv_serializer res, extra
|
229
230
|
|
230
|
-
|
231
|
+
begin
|
232
|
+
per = Persistence::TSV.get persistence_file, true, serializer
|
231
233
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
234
|
+
per.write
|
235
|
+
per.merge! res
|
236
|
+
Persistence::TSV::FIELD_INFO_ENTRIES.keys.each do |key|
|
237
|
+
if extra.include?(key.to_sym) and per.respond_to?(key.to_sym)
|
238
|
+
per.send "#{key}=".to_sym, extra[key.to_sym]
|
239
|
+
end
|
237
240
|
end
|
241
|
+
rescue Exception
|
242
|
+
per.close
|
243
|
+
raise $!
|
238
244
|
end
|
245
|
+
|
239
246
|
per.read
|
240
247
|
|
241
248
|
[ per, extra ]
|
242
249
|
else
|
243
250
|
Log.debug "Loading #{ persistence_file }. Prefix = #{prefix}"
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
251
|
+
begin
|
252
|
+
per = Persistence::TSV.get persistence_file, true, serializer
|
253
|
+
|
254
|
+
extra = {}
|
255
|
+
Persistence::TSV::FIELD_INFO_ENTRIES.keys.each do |key|
|
256
|
+
if per.respond_to?(key.to_sym)
|
257
|
+
extra[key] = per.send(key.to_sym)
|
258
|
+
end
|
250
259
|
end
|
251
|
-
end
|
252
260
|
|
253
|
-
|
261
|
+
rescue Exception
|
262
|
+
per.close
|
263
|
+
raise $!
|
264
|
+
end
|
265
|
+
[ per, extra ]
|
254
266
|
end
|
255
267
|
end
|
256
268
|
|
@@ -314,16 +326,16 @@ module Persistence
|
|
314
326
|
|
315
327
|
filename = get_filename(file)
|
316
328
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
persistence_update, persistence_dir, persistence_file, filename
|
322
|
-
Misc.process_options options, :persistence_update, :persistence_dir, :persistence_file, :filename
|
329
|
+
o = options.dup
|
330
|
+
o =
|
331
|
+
Misc.add_defaults o, :persistence_update => false, :persistence_file => nil, :filename => nil
|
332
|
+
persistence_update, persistence_dir, persistence_file, filename =
|
333
|
+
Misc.process_options o, :persistence_update, :persistence_dir, :persistence_file, :filename
|
323
334
|
|
324
|
-
|
325
|
-
|
335
|
+
filename ||= get_filename(file)
|
336
|
+
persistence_file ||= get_persistence_file(filename, prefix, o.merge(:persistence_dir => persistence_dir))
|
326
337
|
|
338
|
+
if persistence == :no_create
|
327
339
|
persistence = false if not File.exists? persistence_file
|
328
340
|
end
|
329
341
|
|
@@ -333,21 +345,24 @@ module Persistence
|
|
333
345
|
else
|
334
346
|
Log.low "Persistent Loading for #{filename}. Prefix: #{prefix}. Type #{persistence_type.to_s}"
|
335
347
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
348
|
+
Misc.lock(persistence_file, file, prefix, options, block) do |persistence_file,file,prefix,options,block|
|
349
|
+
|
350
|
+
case persistence_type.to_sym
|
351
|
+
when :string
|
352
|
+
persist_string(file, prefix, options, &block)
|
353
|
+
when :marshal
|
354
|
+
persist_marshal(file, prefix, options, &block)
|
355
|
+
when :yaml
|
356
|
+
persist_yaml(file, prefix, options, &block)
|
357
|
+
when :tsv
|
358
|
+
persist_tsv(file, prefix, options, &block)
|
359
|
+
when :tsv_string
|
360
|
+
persist_tsv_string(file, prefix, options, &block)
|
361
|
+
when :tsv_extra
|
362
|
+
persist_tsv_extra(file, prefix, options, &block)
|
363
|
+
when :fwt
|
364
|
+
persist_fwt(file, prefix, options, &block)
|
365
|
+
end
|
351
366
|
end
|
352
367
|
end
|
353
368
|
end
|
data/lib/rbbt/util/resource.rb
CHANGED
@@ -240,6 +240,14 @@ source "$INSTALL_HELPER_FILE"
|
|
240
240
|
Open.read self.find, *args
|
241
241
|
end
|
242
242
|
|
243
|
+
def yaml(*args)
|
244
|
+
YAML.load(open)
|
245
|
+
end
|
246
|
+
|
247
|
+
def marshal(*args)
|
248
|
+
Marshal.load(open)
|
249
|
+
end
|
250
|
+
|
243
251
|
def write(content, *args)
|
244
252
|
FileUtils.mkdir_p File.dirname(self.find) unless File.exists? self.find
|
245
253
|
Open.write(self.find, content, *args)
|
data/lib/rbbt/util/task.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rbbt/util/open'
|
2
|
+
require 'rbbt/util/task/job'
|
2
3
|
|
3
4
|
class Task
|
4
5
|
class << self
|
@@ -7,246 +8,12 @@ class Task
|
|
7
8
|
|
8
9
|
@basedir = "."
|
9
10
|
|
10
|
-
class Job
|
11
|
-
attr_accessor :task, :id, :name, :options, :dependencies, :pid, :path, :previous_jobs
|
12
|
-
|
13
|
-
IDSEP = "_"
|
14
|
-
|
15
|
-
def self.id2name(job_id)
|
16
|
-
job_id.split(IDSEP)
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.load(task, id)
|
20
|
-
name, hash = id2name(id)
|
21
|
-
self.new task, id, name, nil, nil
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(task, id, name, options, dependencies)
|
25
|
-
@task = task
|
26
|
-
@id =id
|
27
|
-
@name = name
|
28
|
-
@options = options
|
29
|
-
@dependencies = dependencies
|
30
|
-
|
31
|
-
if @dependencies
|
32
|
-
@previous_jobs = Hash[*dependencies.first.collect{|job| job.task.name}.zip(dependencies.first).flatten]
|
33
|
-
dependencies.first.collect{|job| @previous_jobs.merge! job.previous_jobs }
|
34
|
-
else
|
35
|
-
@previous_jobs = []
|
36
|
-
end
|
37
|
-
|
38
|
-
basedir = task.workflow.jobdir unless task.workflow.nil?
|
39
|
-
@path = File.join(basedir || Task.basedir, task.name, id)
|
40
|
-
end
|
41
|
-
|
42
|
-
def info_file
|
43
|
-
path + '.info'
|
44
|
-
end
|
45
|
-
|
46
|
-
def info
|
47
|
-
return {} if not File.exists?(info_file)
|
48
|
-
YAML.load(File.open(info_file))
|
49
|
-
end
|
50
|
-
|
51
|
-
def set_info(key, value)
|
52
|
-
i = self.info
|
53
|
-
new_info = i.merge(key => value)
|
54
|
-
Open.write(info_file, new_info.to_yaml)
|
55
|
-
end
|
56
|
-
|
57
|
-
def step(name = nil, message = nil)
|
58
|
-
if name.nil?
|
59
|
-
info[:step]
|
60
|
-
else
|
61
|
-
set_info(:step, name)
|
62
|
-
set_info(:messages, info[:messages] || [] << message) if not message.nil?
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def messages
|
67
|
-
info[:messages] || []
|
68
|
-
end
|
69
|
-
|
70
|
-
def done?
|
71
|
-
[:done, :error, :aborted].include? info[:step]
|
72
|
-
end
|
73
|
-
|
74
|
-
def error?
|
75
|
-
step == :error or step == :aborted
|
76
|
-
end
|
77
|
-
|
78
|
-
def arguments
|
79
|
-
options.values_at *task.options
|
80
|
-
end
|
81
|
-
|
82
|
-
def block
|
83
|
-
task.block
|
84
|
-
end
|
85
|
-
|
86
|
-
def run_dependencies
|
87
|
-
jobs, files = dependencies
|
88
|
-
jobs.each do |job| job.start unless File.exists? job.path; job.step(:done) end
|
89
|
-
files.each do |file| file.produce end
|
90
|
-
end
|
91
|
-
|
92
|
-
def input
|
93
|
-
dep = dependencies.flatten.first
|
94
|
-
if Job === dep
|
95
|
-
dep.load
|
96
|
-
else
|
97
|
-
dep.read
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def start
|
102
|
-
Log.medium("Starting Job '#{ name }'. Path: '#{ path }'")
|
103
|
-
set_info(:start_time, Time.now)
|
104
|
-
save_options(options)
|
105
|
-
|
106
|
-
extend task.scope unless task.scope.nil? or Object == task.scope.class
|
107
|
-
|
108
|
-
begin
|
109
|
-
|
110
|
-
if dependencies.flatten.any?
|
111
|
-
run_dependencies
|
112
|
-
end
|
113
|
-
|
114
|
-
result = instance_exec *arguments, &block
|
115
|
-
|
116
|
-
|
117
|
-
if not result.nil?
|
118
|
-
case task.persistence
|
119
|
-
when nil, :string, :tsv, :integer
|
120
|
-
Open.write(path, result.to_s)
|
121
|
-
when :marshal
|
122
|
-
Open.write(path, Marshal.dump(result))
|
123
|
-
when :yaml
|
124
|
-
Open.write(path, YAML.dump(result))
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
set_info(:end_time, Time.now)
|
129
|
-
Log.medium("Finished Job '#{ name }'. Path: '#{ path }'")
|
130
|
-
rescue Exception
|
131
|
-
step(:error, "#{$!.class}: #{$!.message}")
|
132
|
-
raise $!
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def save_options(options)
|
137
|
-
new_options = {}
|
138
|
-
options.each do |key, value|
|
139
|
-
case
|
140
|
-
when TSV === value
|
141
|
-
new_options[key] = value.to_s
|
142
|
-
else
|
143
|
-
new_options[key] = value
|
144
|
-
end
|
145
|
-
end
|
146
|
-
set_info(:options, new_options)
|
147
|
-
end
|
148
|
-
|
149
|
-
def recursive_done?
|
150
|
-
previous_jobs.values.inject(true){|acc,j| acc and j.recursive_done?} and done?
|
151
|
-
end
|
152
|
-
|
153
|
-
def run
|
154
|
-
return self if recursive_done?
|
155
|
-
begin
|
156
|
-
step(:started)
|
157
|
-
start
|
158
|
-
step(:done)
|
159
|
-
rescue Exception
|
160
|
-
Log.debug $!.message
|
161
|
-
Log.debug $!.backtrace * "\n"
|
162
|
-
step(:error, "#{$!.class}: #{$!.message}")
|
163
|
-
end
|
164
|
-
self
|
165
|
-
end
|
166
|
-
|
167
|
-
def fork
|
168
|
-
return self if recursive_done?
|
169
|
-
@pid = Process.fork do
|
170
|
-
begin
|
171
|
-
step(:started)
|
172
|
-
start
|
173
|
-
step(:done)
|
174
|
-
rescue Exception
|
175
|
-
Log.debug $!.message
|
176
|
-
Log.debug $!.backtrace * "\n"
|
177
|
-
step(:error, "#{$!.class}: #{$!.message}")
|
178
|
-
end
|
179
|
-
exit
|
180
|
-
end
|
181
|
-
|
182
|
-
self
|
183
|
-
end
|
184
|
-
|
185
|
-
def join
|
186
|
-
if @pid.nil?
|
187
|
-
while not done? do
|
188
|
-
Log.debug "Waiting: #{info[:step]}"
|
189
|
-
sleep 5
|
190
|
-
end
|
191
|
-
else
|
192
|
-
Process.waitpid @pid
|
193
|
-
end
|
194
|
-
|
195
|
-
self
|
196
|
-
end
|
197
|
-
|
198
|
-
def open
|
199
|
-
File.open(path)
|
200
|
-
end
|
201
|
-
|
202
|
-
def read
|
203
|
-
File.open(path) do |f| f.read end
|
204
|
-
end
|
205
|
-
|
206
|
-
def load
|
207
|
-
case task.persistence
|
208
|
-
when :float
|
209
|
-
Open.read(path).to_f
|
210
|
-
when :integer
|
211
|
-
Open.read(path).to_i
|
212
|
-
when :string
|
213
|
-
Open.read(path)
|
214
|
-
when :tsv
|
215
|
-
TSV.new(path)
|
216
|
-
when :marshal
|
217
|
-
Marshal.load(Open.read(path))
|
218
|
-
when :yaml
|
219
|
-
YAML.load(Open.read(path))
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def clean
|
224
|
-
FileUtils.rm path if File.exists? path
|
225
|
-
FileUtils.rm info_file if File.exists? info_file
|
226
|
-
end
|
227
|
-
|
228
|
-
def recursive_clean
|
229
|
-
dependencies.first.each do |job| job.recursive_clean end
|
230
|
-
clean
|
231
|
-
end
|
232
|
-
end # END Job
|
233
|
-
|
234
11
|
def load(job_id)
|
235
12
|
Job.load(self, job_id)
|
236
13
|
end
|
237
14
|
|
238
|
-
def
|
239
|
-
|
240
|
-
|
241
|
-
job_options = {}
|
242
|
-
options.each do |option|
|
243
|
-
job_options[option] = Misc.process_options run_options, option
|
244
|
-
end
|
245
|
-
|
246
|
-
job_options
|
247
|
-
end
|
248
|
-
|
249
|
-
def job_id(name, job_options)
|
15
|
+
def job_id(name, job_options, previous_jobs)
|
16
|
+
job_options = job_options.merge :previous_jobs => previous_jobs.collect{|job| job.id} if previous_jobs.any?
|
250
17
|
if job_options.any?
|
251
18
|
name.to_s + "_" + Misc.hash2md5(job_options)
|
252
19
|
else
|
@@ -254,8 +21,8 @@ class Task
|
|
254
21
|
end
|
255
22
|
end
|
256
23
|
|
257
|
-
attr_accessor :name, :persistence, :options, :option_descriptions, :option_types, :option_defaults, :workflow, :dependencies, :scope, :block
|
258
|
-
def initialize(name, persistence = nil, options = nil, option_descriptions = nil, option_types = nil, option_defaults = nil, workflow = nil, dependencies = nil, scope = nil, &block)
|
24
|
+
attr_accessor :name, :persistence, :options, :option_descriptions, :option_types, :option_defaults, :workflow, :dependencies, :scope, :description, :block
|
25
|
+
def initialize(name, persistence = nil, options = nil, option_descriptions = nil, option_types = nil, option_defaults = nil, workflow = nil, dependencies = nil, scope = nil, description = nil, &block)
|
259
26
|
dependencies = [dependencies] unless dependencies.nil? or Array === dependencies
|
260
27
|
@name = name.to_s
|
261
28
|
|
@@ -269,68 +36,61 @@ class Task
|
|
269
36
|
@workflow = workflow
|
270
37
|
@dependencies = dependencies || []
|
271
38
|
@scope = scope
|
39
|
+
@description = description
|
272
40
|
|
273
41
|
@block = block unless not block_given?
|
274
42
|
end
|
275
43
|
|
276
|
-
def
|
277
|
-
|
278
|
-
option_descriptions = {}
|
279
|
-
option_types = {}
|
280
|
-
option_defaults = {}
|
281
|
-
|
282
|
-
all_options.concat self.options if self.options
|
283
|
-
option_descriptions.merge! self.option_descriptions if self.option_descriptions
|
284
|
-
option_types.merge! self.option_types if self.option_types
|
285
|
-
option_defaults.merge! self.option_defaults if self.option_defaults
|
44
|
+
def process_options(args, optional_args)
|
45
|
+
run_options = {}
|
286
46
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
n_all_options, n_option_descriptions, n_option_types, n_option_defaults = task.recursive_options
|
298
|
-
|
299
|
-
all_options.concat n_all_options if n_all_options
|
300
|
-
option_descriptions.merge! n_option_descriptions if n_option_descriptions
|
301
|
-
option_types.merge! n_option_types if n_option_types
|
302
|
-
option_defaults.merge! n_option_defaults if n_option_defaults
|
303
|
-
end
|
304
|
-
|
305
|
-
[all_options, option_descriptions, option_types, option_defaults]
|
47
|
+
options.each do |option|
|
48
|
+
if option_defaults and option_defaults.include? option
|
49
|
+
run_options[option] = Misc.process_options(optional_args, option) || option_defaults[option]
|
50
|
+
else
|
51
|
+
run_options[option] = args.shift
|
52
|
+
end
|
53
|
+
end unless options.nil?
|
54
|
+
|
55
|
+
[run_options, args, optional_args]
|
306
56
|
end
|
307
57
|
|
308
|
-
def
|
309
|
-
|
310
|
-
|
58
|
+
def setup(jobname, args, optional_args, dependencies)
|
59
|
+
previous_jobs = []
|
60
|
+
required_files = []
|
61
|
+
|
62
|
+
run_options, args, optional_args = process_options args, optional_args
|
63
|
+
|
311
64
|
dependencies.each do |dependency|
|
312
65
|
case
|
66
|
+
when Proc === dependency
|
67
|
+
previous_jobs << dependency.call(jobname, run_options)
|
313
68
|
when Task === dependency
|
314
|
-
|
69
|
+
previous_jobs << dependency.job(jobname, *(args + [optional_args]))
|
70
|
+
when Task::Job === dependency
|
71
|
+
previous_jobs << dependency
|
315
72
|
when Symbol === dependency
|
316
|
-
|
317
|
-
jobs << workflow.tasks[dependency].job(jobname, run_options)
|
73
|
+
previous_jobs << workflow.tasks[dependency].job(jobname, *(args + [optional_args]))
|
318
74
|
else
|
319
|
-
|
75
|
+
required_files << dependency
|
320
76
|
end
|
321
77
|
end
|
322
|
-
[jobs, files]
|
323
|
-
end
|
324
78
|
|
325
|
-
|
79
|
+
[previous_jobs, required_files, run_options]
|
80
|
+
end
|
326
81
|
|
327
|
-
|
82
|
+
def job(jobname, *args)
|
83
|
+
if Hash === args.last
|
84
|
+
optional_args = args.pop
|
85
|
+
else
|
86
|
+
optional_args = {}
|
87
|
+
end
|
328
88
|
|
329
|
-
|
89
|
+
previous_jobs, required_files, run_options = setup(jobname, args, optional_args, dependencies)
|
330
90
|
|
331
|
-
|
91
|
+
job_id = self.job_id jobname, run_options, previous_jobs
|
332
92
|
|
333
|
-
Job.new(self, job_id, jobname,
|
93
|
+
Job.new(self, job_id, jobname, run_options, previous_jobs, required_files, previous_jobs.first)
|
334
94
|
end
|
335
95
|
|
336
96
|
def run(*args)
|