scout-gear 5.1.1 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +10 -4
  3. data/Rakefile +2 -0
  4. data/VERSION +1 -1
  5. data/bin/scout +2 -0
  6. data/lib/scout/meta_extension.rb +4 -2
  7. data/lib/scout/misc/format.rb +16 -4
  8. data/lib/scout/misc/monitor.rb +23 -0
  9. data/lib/scout/misc.rb +1 -0
  10. data/lib/scout/open/stream.rb +1 -0
  11. data/lib/scout/path/find.rb +2 -1
  12. data/lib/scout/path.rb +1 -1
  13. data/lib/scout/persist/serialize.rb +15 -4
  14. data/lib/scout/resource/path.rb +5 -0
  15. data/lib/scout/resource/util.rb +48 -0
  16. data/lib/scout/resource.rb +2 -0
  17. data/lib/scout/simple_opt/doc.rb +26 -2
  18. data/lib/scout/workflow/definition.rb +8 -2
  19. data/lib/scout/workflow/documentation.rb +32 -26
  20. data/lib/scout/workflow/step/info.rb +11 -11
  21. data/lib/scout/workflow/step/load.rb +18 -0
  22. data/lib/scout/workflow/step.rb +40 -4
  23. data/lib/scout/workflow/task/inputs.rb +4 -2
  24. data/lib/scout/workflow/task.rb +15 -1
  25. data/lib/scout/workflow/usage.rb +96 -76
  26. data/lib/scout/workflow.rb +1 -0
  27. data/scout-gear.gemspec +14 -3
  28. data/scout_commands/workflow/info +29 -0
  29. data/scout_commands/workflow/list +27 -0
  30. data/scout_commands/workflow/task +32 -681
  31. data/scout_commands/workflow/task_old +706 -0
  32. data/test/scout/resource/test_util.rb +27 -0
  33. data/test/scout/simple_opt/test_doc.rb +16 -0
  34. data/test/scout/test_meta_extension.rb +9 -0
  35. data/test/scout/workflow/step/test_info.rb +17 -15
  36. data/test/scout/workflow/step/test_load.rb +65 -0
  37. data/test/scout/workflow/test_definition.rb +0 -0
  38. data/test/scout/workflow/test_documentation.rb +30 -0
  39. data/test/scout/workflow/test_task.rb +1 -0
  40. data/test/scout/workflow/test_usage.rb +12 -3
  41. metadata +13 -2
@@ -1,707 +1,58 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'scout-gear'
4
- require 'workflow-scout'
3
+ require 'scout'
5
4
 
6
- def report_options(options)
7
- if options.nil? or options.empty?
8
- puts "No options"
9
- else
10
- options.each do |key, value|
11
- puts [Log.color(:cyan, key), Misc.fingerprint(value)] * ": "
12
- end
13
- end
14
- end
15
-
16
- def usage(workflow = nil, task = nil, exception=nil, abridge = false)
17
- puts SOPT.doc
18
- puts
19
- if workflow.nil?
20
- puts "No workflow specified. Use `scout workflow list` to list available workflows."
21
- exit! -1
22
- end
23
-
24
- if task.nil?
25
- workflow.load_tasks if workflow.respond_to? :load_tasks
26
- workflow.doc nil, abridge
27
- puts
28
- puts "E.g. scout workflow task #{workflow.to_s} #{workflow.tasks.keys.first.to_s} -h"
29
- else
30
- puts Log.color :magenta, workflow.to_s
31
- puts Log.color :magenta, "=" * workflow.to_s.length
32
- if workflow.documentation[:title] and not workflow.documentation[:title].empty?
33
- puts
34
- puts Misc.format_paragraph workflow.documentation[:title]
35
- end
36
- if workflow.documentation[:description] and not workflow.documentation[:description].empty?
37
- puts
38
- puts Misc.format_paragraph workflow.documentation[:description]
39
- end
40
- puts
41
- workflow.doc(task, abridge)
42
- end
43
-
44
- print_error(exception.message, exception.backtrace) if exception
45
-
46
- true
47
- end
48
-
49
- def get_value_stream(value)
50
- if value == "-"
51
- io = Misc.open_pipe do |sin|
52
- while not STDIN.eof?
53
- sin.write STDIN.read(2048)
54
- end
55
- sin.close
56
- end
57
- else
58
- io = Open.open(value)
59
- end
60
- class << io
61
- attr_accessor :filename
62
- end
63
- io.filename = value
64
- io
65
- end
66
-
67
- def fix_options(workflow, task, job_options)
68
- input_types = IndiferentHash.setup workflow.rec_input_types(task.name)
69
- input_options = IndiferentHash.setup workflow.rec_input_options(task.name)
70
-
71
- job_options_cleaned = {}
72
-
73
- job_options.each do |name, value|
74
- type = input_types[name]
75
- type = type.to_sym if type
76
-
77
- if Step === value
78
- job_options_cleaned[name] = value
79
- next
80
- end
81
-
82
- if Path === value && Step === value.resource
83
- job_options_cleaned[name] = value
84
- next
85
- end
86
-
87
- value = case type
88
- when nil
89
- value
90
- when :boolean
91
- TrueClass === value or %w(true TRUE T yes).include? value
92
- when :float
93
- value.to_f
94
- when :path
95
- Path.setup(value)
96
- when :integer
97
- value.to_i
98
- when :text
99
- if input_options[name] and input_options[name][:stream] and String === value
100
- get_value_stream(value)
101
- else
102
- case
103
- when value == '-'
104
- STDIN.read
105
- when (String === value and File.exist?(value) and not File.directory?(value))
106
- Open.read(value)
107
- else
108
- value
109
- end
110
- end
111
- when :array
112
- if input_options[name] && input_options[name][:stream] && String === value && Misc.is_filename?(value) && !! input_options[name][:nofile]
113
- get_value_stream(value)
114
- elsif input_options[name] and input_options[name][:stream] and value == "-"
115
- STDIN
116
- else
117
- if Array === value || IO === value
118
- value
119
- else
120
- array_separator = $array_separator
121
- str = case
122
- when value == '-'
123
- array_separator ||= "\n"
124
- STDIN.read
125
- when (String === value and File.exist?(value) and not (input_options[name] && input_options[name][:nofile]))
126
- array_separator ||= "\n"
127
- Open.read(value)
128
- else
129
- value
130
- end
131
-
132
- if array_separator
133
- str.split(/#{array_separator}/)
134
- else
135
- str.split(/[,|\s]/)
136
- end
137
- end
138
- end
139
- when :tsv
140
- if input_options[name] and input_options[name][:stream] and String === value
141
- TSV::Parser.new(value == '-' ? STDIN : Open.open(value), :filename => value )
142
- else
143
- case value
144
- when TSV
145
- value
146
- when '-'
147
- TSV.open(STDIN, :unnamed => true, :sep => $field_separator, :sep2 => ($array_separator || "|"))
148
- when (Misc.is_filename?(value) and String)
149
- TSV.open(value, :unnamed => true, :sep => $field_separator, :sep2 => ($array_separator || "|"))
150
- when IO
151
- TSV.open(value, :unnamed => true, :sep => $field_separator, :sep2 => ($array_separator || "|"))
152
- else
153
- TSV.open(StringIO.new(value), :unnamed => true, :sep => $field_separator, :sep2 => ($array_separator || "|"))
154
- end
155
- end
156
- when :directory
157
- Path.setup(File.expand_path(value))
158
- else
159
- value
160
- end
161
-
162
- job_options_cleaned[name] = value
163
- end
164
-
165
- job_options_cleaned
166
- end
5
+ $0 = "scout #{$previous_commands.any? ? $previous_commands*" " + " " : "" }#{ File.basename(__FILE__) }" if $previous_commands
167
6
 
168
7
  options = SOPT.setup <<EOF
169
- Enact workflow tasks
170
-
171
- $ scout workflow task <workflow> [<task>] [<options>]
172
8
 
173
- Examine workflows and enact tasks from them. If no `task` is specified, a list
174
- of available tasks is shown. If a `task` is given it will be enacted with the
175
- parameters specified in `options`. Use *-h* option to display the description
176
- of a task, including the parameters it accepts; and some examples, if
177
- available. Examples can be enacted using `scout workflow example <workflow>
178
- [<task>] [<example>]`.
9
+ Run a workflow job
179
10
 
180
- When a task is enacted a job is instantiated. This job is identified by the
181
- `jobname` (which is *#{Task::DEFAULT_NAME}* unless specified otherwise) and the values of the
182
- parameters; these two things determine the filename under which the job result
183
- will be saved. If the taks is enacted using the same `jobname` and parameters
184
- it will result in the same job, pointing to the same result file.
11
+ $ #{$0} [<options>] <workflow> <task>
185
12
 
186
- The first time a job is executed it will save the result. The saved result will
187
- be returned directly if the same task is re-enacted. Once the job is done you
188
- can redo it using the `clean` parameter, this cleans the last step of the task.
189
- The `recursive_clean` cleans all the job dependency steps recursively.
190
-
191
- -h--help Show this help
192
- -ha--abridge Abridge help
193
- -wd--workdir* Change the working directory of the workflow
194
- -wda--workdir_all* Change the working directory of ALL workflow
195
- -as--array_separator* Change the character that separates elements of Arrays, ',', '|', or '\\n' by default
196
- -fs--field_separator* Change the character that separates fields of TSV files '\\t' by default
197
- -jn--jobname* Job name to use. The name '#{Task::DEFAULT_NAME}' is used by default
198
- -pn--printname Print the name of the job and exit without starting it
199
- -pf--printpath Print the path of the job result
200
- -cl--clean Clean the last step of the job so that it gets recomputed
201
- -ct--clean_task* Clean a particular dependency task
202
- -rcl--recursive_clean Clean the last step and its dependencies to recompute the job completely
203
- -uaj--update_all_jobs Consider all dependencies when checking for updates, even when they have no info files
204
- --fork Run job asyncronously and monitor progress. It monitors detached processes as well
205
- --orchestrate* Run the job through the orchestrator
206
- --detach Run job asyncronously and detach process
207
- --exec Run job with no persistence
208
- -O--output* Save job result into file
209
- -jf--job_file* Output one of the job produced files
210
- -ljf--list_job_files List all the files produced in that step
211
- --load_inputs* Load inputs from a directory
212
- --info Show the job info
213
- -prov--provenance Report the jobs provenance
214
- -W--workflows* Load a list of workflows
215
- -R--requires* Require a list of files
216
- -pro--produce* Prepare dependencies
217
- -proc--produce_cpus* Number of dependencies prepared in parallel
218
- -rwt--remote_workflow_tasks* Load a yaml file describing remote workflow tasks
219
- -od--override_deps* Override deps using 'Workflow#task=<path>' array_separated
220
- -PERF--procpath_performance* Measure performance using procpath
221
- -r--relay* Relay job to SSH server
222
- -sr--slurm_relay* Relay job to SSH SLURM server
223
- -rdep--relay_dependencies* Relay dependencies instead of main job
224
- -pdr--produce_dependencies_for_relay Prepare dependencies previous to relay jobs
13
+ -h--help Print this help
14
+ -jn--job_name* Name to use as job identifier
15
+ -pf--print_filepath Print the file path
16
+ -cl--clean Clean the last step
17
+ -rcl--recursive_clean Clean all steps
225
18
  EOF
226
19
 
227
- workflow = ARGV.shift
228
- usage and exit! -1 if workflow.nil?
229
-
230
- task = ARGV.shift
20
+ workflow_name, task_name = ARGV
231
21
 
232
- # Set log, fork, clean, recursive_clean and help
233
- help = !!options.delete(:help)
234
- do_fork = !!options.delete(:fork)
235
- detach = !!options.delete(:detach)
236
- do_exec = !!options.delete(:exec)
237
- clean_task = options.delete(:clean_task)
238
- clean = !!options.delete(:clean) || clean_task
239
- override_deps = options.delete(:override_deps)
240
- recursive_clean = !!options.delete(:recursive_clean)
241
- out = options.include?(:output) ? File.open(options[:output], 'wb') : STDOUT
242
-
243
- $array_separator = options.delete(:array_separator)
244
- $field_separator = options.delete(:field_separator) || "\t"
245
-
246
- # Get workflow
247
-
248
- if Scout.etc.remote_workflows.exists?
249
- remote_workflows = Scout.etc.remote_workflows.yaml
250
- else
251
- remote_workflows = {}
252
- end
253
-
254
- #Workflow.workdir = Path.setup(File.expand_path(options.delete(:workdir_all))) if options[:workdir_all]
255
- Workflow.workdir.search_paths.merge!({:workdir => File.expand_path(options.delete(:workdir_all)), :default => :workdir }) if options[:workdir_all]
256
-
257
- workflow = Workflow.require_workflow workflow
258
-
259
- if clean_task
260
- ENV["RBBT_UPDATE"] = 'true'
261
- end
262
-
263
- if options[:update_all_jobs]
264
- ENV["RBBT_UPDATE_ALL_JOBS"] = 'true'
265
- ENV["RBBT_UPDATE"] = 'true'
266
- end
267
-
268
- if options[:workflows]
269
- require 'scout/workflow'
270
- workflows = options[:workflows].split(',')
271
- workflows.each do |workflow|
272
- workflow.strip!
273
- Workflow.require_workflow workflow
274
- end
275
- end
276
-
277
- if options[:requires]
278
- requires = options[:requires].split(',')
279
- requires.each do |req|
280
- req.strip!
281
- require req
282
- end
283
- end
284
-
285
- if options[:remote_workflow_tasks]
286
- Workflow.load_remote_tasks(options[:remote_workflow_tasks])
287
- end
288
-
289
- # Set task
290
- namespace = nil, nil
291
-
292
- case
293
- when task.nil?
294
- usage workflow, nil, nil, options[:abridge] and exit 0
295
- else
296
- task_name = task.to_sym
297
- begin
298
- task = workflow.tasks[task_name]
299
- raise Workflow::TaskNotFoundException.new workflow, task_name if task.nil?
300
- rescue Workflow::TaskNotFoundException
301
- usage workflow, nil, nil, options[:abridge]
302
-
303
- puts
304
- puts Log.color :magenta, "## Error"
305
- puts
306
- puts $!.message
307
- puts
308
-
309
- exit -1
310
- end
311
- end
312
-
313
- usage workflow, task, nil, options[:abridge] and exit 0 if help
314
-
315
- name = options.delete(:jobname)
316
-
317
- # get job args
318
- job_options = workflow.get_SOPT(task)
319
-
320
- if options[:load_inputs]
321
- task_info = workflow.task_info(task_name)
322
- job_options = Workflow.load_inputs(options[:load_inputs], task_info[:inputs], task_info[:input_types]).merge(job_options)
323
- end
324
-
325
- job_options = fix_options(workflow, task, job_options)
326
- saved_job_options = job_options
327
-
328
- workflow.workdir = Path.setup(File.expand_path(options.delete(:workdir))) if options[:workdir]
329
-
330
- if override_deps
331
- override_deps.split($array_separator || ",").each do |part|
332
- t_, value = part.split("=")
333
- job_options.merge!( t_ => value)
334
- end
335
- end
22
+ raise MissingParameterException.new :workflow if workflow_name.nil?
336
23
 
337
- #- get job
24
+ workflow = Workflow.require_workflow workflow_name
25
+ task = workflow.tasks[task_name.to_sym] if task_name
338
26
 
339
- job = workflow.job(task.name, name, job_options)
340
- $job = job
27
+ options[:help] = true if task.nil?
341
28
 
342
- # clean job
343
- if clean
344
- job.clean
345
- sleep 1
346
- end
347
-
348
- if clean_task
349
- clean_task.split(",").each do |clean_task|
350
- if clean_task.include? "#"
351
- clean_workflow, clean_task = clean_task.split("#")
352
- end
353
-
354
- job.rec_dependencies.each do |dep|
355
- next unless dep.task_name.to_s == clean_task.to_s
356
- next unless clean_workflow.nil? || clean_workflow == dep.workflow.to_s
357
- dep.clean
358
- dep.set_info :status, :cleaned
359
- end
360
-
361
- job.clean if job.task_name.to_s == clean_task.to_s
29
+ if options[:help]
30
+ if defined? scout_usage
31
+ scout_usage
32
+ else
33
+ puts SOPT.doc
362
34
  end
363
- end
364
35
 
365
- if recursive_clean
366
- job.recursive_clean
36
+ puts workflow.usage(task) if workflow
37
+ exit 0
367
38
  end
368
39
 
369
- require 'pp'
370
-
371
- # run
372
- begin
373
- if options[:info]
374
- pp job.info
375
- exit 0
376
- end
377
-
378
- if options.delete(:printname)
379
- puts job.name
380
- exit 0
381
- end
382
-
383
- if do_exec or (job.respond_to?(:is_exec) and job.is_exec)
384
- res = job.exec(:stream)
385
-
386
- result_type = job.result_type
387
-
388
- res = JSON.parse(res.read) if (defined?(RemoteStep) and RemoteStep === job) && %w(array float integer boolean).include?(result_type.to_s)
389
-
390
- case
391
- when res.respond_to?(:gets)
392
- begin
393
- Misc.consume_stream(res, false, out)
394
- rescue EOFError, IOError
395
- end
396
- res.join if res.respond_to? :join
397
- when Array === res
398
- out.puts res * "\n"
399
- when TSV === res
400
- out.puts res
401
- when Hash === res
402
- out.puts res.to_yaml
403
- when IO === res
404
- while block = res.read(2048)
405
- out.write block
406
- end
407
- else
408
- out.puts res
409
- end
410
- exit 0
411
- end
412
-
413
- if options.delete(:provenance)
414
- if options.delete(:printpath)
415
- puts job.path
416
- else
417
- puts Step.prov_report(job)
418
- end
419
- exit 0
420
- end
421
-
422
- def match_dependencies(queries, dependencies)
423
- queries = queries.collect{|q| q.include?("#") ? q.split("#") : q }
424
-
425
- matched = []
426
- queries.each do |q|
427
- matched += dependencies.select do |dep|
428
- if Array === q
429
- q.first == dep.workflow.to_s && q.last == dep.task_name.to_s
430
- else
431
- q.to_s == dep.task_name.to_s
432
- end
433
- end
434
- end
435
-
436
- matched
437
- end
438
-
439
- def replace_relayed_jobs(jobs_to_relay, server, produce_dependencies_for_relay = false, run_type = :run)
440
- jobs_to_relay.each do |job|
441
- ComputeDependency.setup(job, :bootstrap)
442
- next if job.done?
443
- Log.low "Relaying #{Misc.fingerprint job} to #{server}"
444
- jmeta = class << job; self; end
445
-
446
- job.instance_variable_set(:@job, job)
447
- job.instance_variable_set(:@host, server)
448
- job.instance_variable_set(:@produce_dependencies, produce_dependencies_for_relay)
449
-
450
- jmeta.define_method :run do |*args|
451
- if done?
452
- load
453
- else
454
- RemoteWorkflow::SSH.relay_job_list([@job], @host, :run_type => run_type, :migrate => true, :produce_dependencies => @produce_dependencies)
455
- Step.migrate(@job, 'user', :source => @host)
456
- load
457
- end
458
- end
459
- #job.dependencies = []
460
-
461
- #([job] + job.rec_dependencies).each do |j|
462
- # next if job.done?
463
- # jmeta = class << j; self; end
464
-
465
- # j.instance_variable_set(:@job, job)
466
- # j.instance_variable_set(:@host, server)
467
- # j.instance_variable_set(:@produce_dependencies, produce_dependencies_for_relay)
468
-
469
- # jmeta.define_method :run do |*args|
470
- # if done?
471
- # load
472
- # else
473
- # RemoteWorkflow::SSH.relay_job_list([@job], @host, :run_type => run_type, :migrate => true, :produce_dependencies => @produce_dependencies)
474
- # Step.migrate(@job, 'user', :source => @host)
475
- # load
476
- # end
477
- # end
478
- #end
479
- end
480
- end
481
-
482
-
483
- if server = options.delete(:relay)
484
- require 'scout/workflow/remote_workflow'
485
- relay_dependencies = options.delete(:relay_dependencies).split(",")
486
- produce_dependencies_for_relay = options.delete(:produce_dependencies_for_relay)
487
-
488
- jobs_to_relay = relay_dependencies ? match_dependencies(relay_dependencies, job.rec_dependencies) : [job]
489
- jobs_to_relay.reject!{|d| d.done? }
490
-
491
- replace_relayed_jobs(jobs_to_relay, server, produce_dependencies_for_relay, :run)
492
- end
493
-
494
- if server = options.delete(:slurm_relay)
495
- require 'scout/workflow/remote_workflow'
496
- relay_dependencies = options.delete(:relay_dependencies).split(",")
497
- produce_dependencies_for_relay = options.delete(:produce_dependencies_for_relay)
498
- jobs_to_relay = relay_dependencies ? match_dependencies(relay_dependencies, job.rec_dependencies) : [job]
499
- jobs_to_relay.reject!{|d| d.done? }
40
+ job_options = task.get_SOPT(task)
41
+ job = task.job(options[:job_name], job_options)
500
42
 
501
- replace_relayed_jobs(jobs_to_relay, server, produce_dependencies_for_relay, :orchestrate)
502
- end
503
-
504
-
505
- if options[:procpath_performance]
506
- require 'scout/util/procpath'
507
- current_pid = job.info[:pid]
508
- job.fork
509
- job.soft_grace
510
- sleep 2 if job.info[:pid] == current_pid
511
- if job.info[:pid] != current_pid
512
- pid = job.info[:pid]
513
- begin
514
- ProcPath.monitor(pid, options[:procpath_performance])
515
- rescue Errno::ECHILD
516
- Log.warn "Procpath didn't find process #{pid} to monitor. Maybe it finished already"
517
- rescue
518
- Log.warn "Procpath failed: #{$!.message}"
519
- end
520
- end
521
- end
522
-
523
- if tasks = options.delete(:produce)
524
- tasks = tasks.split(",")
525
- produce_cpus = (options[:produce_cpus] || 1)
526
- puts Step.produce_dependencies(job, tasks, produce_cpus)
527
- exit 0
528
- end
529
-
530
-
531
- if do_fork
532
- ENV["RBBT_NO_PROGRESS"] = "true"
533
- if detach
534
- job.fork
535
- Process.detach job.pid if job.pid
536
- puts Log.color(:magenta, "Issued: ") + Log.color(:magenta, job.pid ? job.pid.to_s : 'no pid') + ' -- ' + job.path
537
- exit 0
538
- end
539
-
540
- job.fork
541
- elsif options[:orchestrate]
542
- require 'scout/workflow/util/orchestrator'
543
- rules = case options[:orchestrate]
544
- when 'none', 'open', 'default'
545
- nil
546
- else
547
- YAML.parse(Open.read(options[:orchestrate]))
548
- end
549
- if rules
550
- Workflow::Orchestrator.process rules, job
551
- else
552
- Workflow::Orchestrator.process job
553
- end unless job.done?
554
- else
555
- job.run(:stream)
556
- res = job
557
- end
43
+ job.recursive_clean if options[:recursive_clean]
44
+ job.clean if options[:clean]
558
45
 
559
- if options.delete(:printpath)
560
- job.join if job.running?
561
- raise job.messages.last if (job.error? || job.aborted?) && job.messages
562
- if Open.remote? job.path
563
- puts job.url + Log.color(:blue, "?_format=raw")
564
- else
565
- puts job.path
566
- end
567
- exit 0
568
- end
46
+ job.run
569
47
 
570
- if do_fork
48
+ if options[:print_filepath]
49
+ path = job.path
50
+ path = path.find if Path === path
51
+ puts path
52
+ else
53
+ if ! Open.consume_stream(job.stream, false, STDOUT, false).end_with? "\n"
571
54
  puts
572
- space = 1
573
- Log.tty_size ||= 100
574
-
575
- while not job.done?
576
- message = (job.messages and job.messages.any?) ? job.messages.last.strip : "no message"
577
- status = job.status || "no status"
578
- if job.info and job.info.include? :issued
579
- issued = job.info[:issued]
580
- issued = Time.parse(issued) unless Time === issued
581
- time = Time.now - issued
582
- end
583
-
584
- space.times do
585
- Log.clear_line
586
- end
587
-
588
- puts "#{Log.color :blue, job.path}"
589
- str = "Waiting on #{Log.color :blue, job.info[:pid] || job.pid} (#{time ? time.to_i : '?'} sec. ago) " << [Log.color(:cyan, status.to_s),message.strip].compact*" "
590
- puts Misc.format_paragraph str, Log.tty_size
591
-
592
- space = 2 + Log.uncolor(str).length / Log.tty_size
593
- sleep 2
594
- end
595
- raise job.messages.last if job.error?
596
-
597
- if job.info and job.info.include? :issued
598
- issued = job.info[:issued]
599
- issued = Time.parse(issued) unless Time === issued
600
- time = Time.now - issued
601
- end
602
-
603
- space.times do
604
- Log.clear_line
605
- end
606
-
607
- if Open.remote?(job.path)
608
- out.puts job.path + Log.color(:blue, "?_format=raw")
609
- else
610
- out.puts job.path
611
- end
612
-
613
- exit 0
614
55
  end
615
- rescue ParameterException
616
- SOPT.delete_inputs(workflow.rec_inputs(task.name))
617
- usage(workflow, task, $!)
618
- puts Log.color :magenta, "Options:"
619
- puts
620
- report_options saved_job_options
621
- puts
622
- exit! -1
623
- end
624
-
625
- if options.delete(:list_job_files)
626
- out.puts job.files * "\n"
627
- exit 0
628
- end
629
-
630
- if job_file = options.delete(:job_file)
631
- job.join
632
- file = job.file(job_file)
633
- out.puts Path === file ? file.read : file
634
- exit 0
635
56
  end
636
57
 
637
- case res
638
- #when (defined?(WorkflowRemoteClient) and WorkflowRemoteClient::RemoteStep)
639
- when (defined?(RemoteStep) and RemoteStep)
640
- res = job.result
641
- if res.respond_to? :gets
642
- begin
643
- Misc.consume_stream(res, false, out)
644
- rescue EOFError, IOError
645
- end
646
- res.join if res.respond_to? :join
647
- elsif res.nil?
648
- job.join
649
- raise job.get_exception if job.error? || job.aborted?
650
- puts Open.read(job.path, :nocache => true, :nofail => true)
651
- else
652
- if Array === res
653
- out.puts res * "\n"
654
- else
655
- out.puts res.to_s
656
- end
657
- end
658
- when Step
659
- if res.streaming?
660
- io = TSV.get_stream res
661
- Misc.consume_stream(io, false, out)
662
- io.join if io.respond_to? :join
663
- elsif IO === res.result
664
- begin
665
- io = res.get_stream
666
- Misc.consume_stream(io, false, out)
667
- io.join if io.respond_to? :join
668
- rescue Aborted, Interrupt
669
- Log.error "Process interrupted. Aborting step"
670
- res.abort
671
- begin
672
- io.abort if io.respond_to? :abort
673
- io.join if io.respond_to? :join
674
- ensure
675
- exit! -1
676
- end
677
- rescue Exception
678
- Log.exception $!
679
- res.abort
680
- begin
681
- io.abort if io.respond_to? :abort
682
- io.join if io.respond_to? :join
683
- ensure
684
- exit! -1
685
- end
686
- end
687
- elsif detach
688
- exit! 0
689
- else
690
- res.join if res.running?
691
- if %w(float integer string boolean).include?(res.result_type.to_s)
692
- out.puts res.load
693
- else
694
- Open.open(res.path, :mode => 'rb') do |io|
695
- Misc.consume_stream(io, false, out)
696
- end if Open.exist?(res.path) || Open.remote?(res.path) || Open.ssh?(res.path)
697
- end if res.done?
698
- end
699
- else
700
- if Array === res
701
- out.puts res * "\n"
702
- else
703
- out.puts res.to_s
704
- end
705
- end
706
58
 
707
- exit 0