etna 0.1.27 → 0.1.32
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/etna.completion +137 -55
- data/lib/etna.rb +1 -0
- data/lib/etna/application.rb +4 -0
- data/lib/etna/client.rb +30 -2
- data/lib/etna/clients/magma/formatting.rb +2 -1
- data/lib/etna/clients/magma/formatting/models_odm_xml.rb +293 -0
- data/lib/etna/clients/magma/models.rb +13 -1
- data/lib/etna/clients/magma/workflows/create_project_workflow.rb +1 -1
- data/lib/etna/clients/magma/workflows/crud_workflow.rb +19 -2
- data/lib/etna/clients/magma/workflows/materialize_magma_record_files_workflow.rb +46 -30
- data/lib/etna/clients/magma/workflows/model_synchronization_workflow.rb +1 -1
- data/lib/etna/clients/magma/workflows/update_attributes_from_csv_workflow.rb +19 -6
- data/lib/etna/clients/magma/workflows/walk_model_tree_workflow.rb +33 -6
- data/lib/etna/clients/metis/client.rb +6 -1
- data/lib/etna/clients/metis/models.rb +15 -0
- data/lib/etna/clients/metis/workflows/metis_download_workflow.rb +15 -11
- data/lib/etna/clients/metis/workflows/metis_upload_workflow.rb +83 -13
- data/lib/etna/clients/metis/workflows/sync_metis_data_workflow.rb +43 -79
- data/lib/etna/command.rb +10 -0
- data/lib/etna/cwl.rb +701 -0
- data/lib/etna/directed_graph.rb +50 -0
- data/lib/etna/filesystem.rb +145 -15
- data/lib/etna/generate_autocompletion_script.rb +11 -6
- data/lib/etna/hmac.rb +2 -2
- data/lib/etna/route.rb +44 -4
- data/lib/etna/spec/auth.rb +6 -6
- data/lib/etna/user.rb +15 -11
- metadata +33 -3
data/lib/etna/command.rb
CHANGED
@@ -39,6 +39,10 @@ module Etna
|
|
39
39
|
def string_flags
|
40
40
|
@string_flags ||= []
|
41
41
|
end
|
42
|
+
|
43
|
+
def multi_flags
|
44
|
+
@multi_flags ||= []
|
45
|
+
end
|
42
46
|
end
|
43
47
|
|
44
48
|
def flag_as_parameter(flag)
|
@@ -69,6 +73,12 @@ module Etna
|
|
69
73
|
else
|
70
74
|
flags[arg_name] = args.shift
|
71
75
|
end
|
76
|
+
elsif self.class.multi_flags.include?(next_arg)
|
77
|
+
if args.empty?
|
78
|
+
raise "flag #{next_arg} requires an argument"
|
79
|
+
else
|
80
|
+
(flags[arg_name] ||= []) << args.shift
|
81
|
+
end
|
72
82
|
elsif !found_non_flag
|
73
83
|
raise "#{program_name} does not recognize flag #{next_arg}"
|
74
84
|
else
|
data/lib/etna/cwl.rb
ADDED
@@ -0,0 +1,701 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Etna
|
4
|
+
class Cwl
|
5
|
+
FIELD_LOADERS = {}
|
6
|
+
|
7
|
+
def initialize(attributes)
|
8
|
+
@attributes = attributes
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.loader
|
12
|
+
Etna::Cwl::RecordLoader.new(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.as_json(obj)
|
16
|
+
if obj.is_a?(Cwl)
|
17
|
+
as_json(obj.instance_variable_get(:@attributes))
|
18
|
+
elsif obj.is_a?(Hash)
|
19
|
+
{}.tap do |result|
|
20
|
+
obj.each do |k, v|
|
21
|
+
result[k] = as_json(v)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
elsif obj.is_a?(Array)
|
25
|
+
obj.map { |v| as_json(v) }
|
26
|
+
else
|
27
|
+
obj
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def as_json
|
32
|
+
self.class.as_json(@attributes)
|
33
|
+
end
|
34
|
+
|
35
|
+
class Loader
|
36
|
+
def load(val)
|
37
|
+
raise "Unimplemented"
|
38
|
+
end
|
39
|
+
|
40
|
+
def optional
|
41
|
+
OptionalLoader.new(self)
|
42
|
+
end
|
43
|
+
|
44
|
+
def map(&block)
|
45
|
+
FunctorMapLoader.new(self, &block)
|
46
|
+
end
|
47
|
+
|
48
|
+
def as_mapped_array(id_key = nil, value_key = nil)
|
49
|
+
MapLoader.new(self.as_array, id_key, value_key)
|
50
|
+
end
|
51
|
+
|
52
|
+
def or(*alternatives)
|
53
|
+
UnionLoader.new(self, *alternatives)
|
54
|
+
end
|
55
|
+
|
56
|
+
def as_array
|
57
|
+
ArrayLoader.new(self)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class AnyLoader < Loader
|
62
|
+
def load(val)
|
63
|
+
val
|
64
|
+
end
|
65
|
+
|
66
|
+
ANY = AnyLoader.new
|
67
|
+
end
|
68
|
+
|
69
|
+
class PrimitiveLoader < Loader
|
70
|
+
def initialize(name, type)
|
71
|
+
@name = name
|
72
|
+
@type = type
|
73
|
+
end
|
74
|
+
|
75
|
+
def load(val)
|
76
|
+
unless val.is_a?(@type)
|
77
|
+
raise "Unexpected val #{val.inspect} for #{@name} type"
|
78
|
+
end
|
79
|
+
|
80
|
+
val
|
81
|
+
end
|
82
|
+
|
83
|
+
def name
|
84
|
+
@name
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.find_primitive_type_loader(type_name)
|
88
|
+
constants.each do |c|
|
89
|
+
c = const_get(c)
|
90
|
+
if c.is_a?(Loader)
|
91
|
+
return c if c.name == type_name
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
STRING = PrimitiveLoader.new('string', String)
|
97
|
+
INT = PrimitiveLoader.new('int', Integer)
|
98
|
+
LONG = PrimitiveLoader.new('long', Integer)
|
99
|
+
FLOAT = PrimitiveLoader.new('float', Float)
|
100
|
+
DOUBLE = PrimitiveLoader.new('double', Float)
|
101
|
+
NULL = PrimitiveLoader.new('null', NilClass)
|
102
|
+
|
103
|
+
class BooleanLoader < Loader
|
104
|
+
def name
|
105
|
+
'boolean'
|
106
|
+
end
|
107
|
+
|
108
|
+
def load(val)
|
109
|
+
raise "Invalid value #{val.inspect} for boolean" unless val.instance_of?(TrueClass) || val.instance_of?(FalseClass)
|
110
|
+
val
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
BOOLEAN = BooleanLoader.new
|
115
|
+
end
|
116
|
+
|
117
|
+
class SourceLoader < Loader
|
118
|
+
# Resolves a string of the forms "a-primary-identifier" or "step_name/output" into
|
119
|
+
# [:primary_inputs, "a-primary-identifier"] or
|
120
|
+
# ["step_name", "output"] respectively
|
121
|
+
def load(val)
|
122
|
+
parts = []
|
123
|
+
|
124
|
+
if val.is_a?(Symbol)
|
125
|
+
val = val.to_s
|
126
|
+
end
|
127
|
+
|
128
|
+
if val.is_a?(Array)
|
129
|
+
parts = PrimitiveLoader::STRING.as_array.load(val)
|
130
|
+
elsif val.is_a?(String)
|
131
|
+
parts = val.split('/', max = 2)
|
132
|
+
end
|
133
|
+
|
134
|
+
if parts.length == 1
|
135
|
+
return [:primary_inputs, parts[0]]
|
136
|
+
elsif parts.length == 2
|
137
|
+
return parts
|
138
|
+
end
|
139
|
+
|
140
|
+
raise "Unexpected value for source #{val.inspect}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class StrictMapLoader < Loader
|
145
|
+
def initialize(items, keys)
|
146
|
+
@items = items
|
147
|
+
@keys = keys
|
148
|
+
end
|
149
|
+
|
150
|
+
def load(val)
|
151
|
+
if val.is_a?(Hash)
|
152
|
+
val.map do |k, v|
|
153
|
+
[@keys.load(k), @items.load(v)]
|
154
|
+
end.to_h
|
155
|
+
else
|
156
|
+
raise "Unexpected val #{val.inspect} for hash"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class MapLoader < Loader
|
162
|
+
def initialize(items, idKey = nil, valueKey = nil)
|
163
|
+
@items = items
|
164
|
+
@idKey = idKey
|
165
|
+
@valueKey = valueKey
|
166
|
+
end
|
167
|
+
|
168
|
+
def load(val)
|
169
|
+
if val.is_a?(Hash)
|
170
|
+
val = [].tap do |result|
|
171
|
+
errors = {}
|
172
|
+
val.keys.sort.each do |k|
|
173
|
+
begin
|
174
|
+
v = val[k]
|
175
|
+
if v.is_a?(Hash)
|
176
|
+
v[@idKey] = k
|
177
|
+
else
|
178
|
+
v = {@idKey => k, @valueKey => v}
|
179
|
+
end
|
180
|
+
|
181
|
+
result << v
|
182
|
+
rescue => e
|
183
|
+
errors[k] = e.to_s
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
unless errors.empty?
|
188
|
+
raise errors.map { |k, v| "#{k}: #{v}" }.join("\n")
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
@items.load(val)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
class ArrayLoader < Loader
|
198
|
+
def initialize(items)
|
199
|
+
@items = items
|
200
|
+
end
|
201
|
+
|
202
|
+
def load(val)
|
203
|
+
unless val.is_a?(Array)
|
204
|
+
raise "Unexpected val #{val.inspect} for array"
|
205
|
+
end
|
206
|
+
|
207
|
+
[].tap do |result|
|
208
|
+
errors = []
|
209
|
+
val.each do |item|
|
210
|
+
begin
|
211
|
+
loaded = Cwl.load_item(item, UnionLoader.new(self, @items))
|
212
|
+
if loaded.is_a?(Array)
|
213
|
+
result.push(*loaded)
|
214
|
+
else
|
215
|
+
result << loaded
|
216
|
+
end
|
217
|
+
rescue => e
|
218
|
+
errors << e.to_s
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
unless errors.empty?
|
223
|
+
raise errors.join("\n")
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
class EnumLoader < Loader
|
230
|
+
def initialize(*options)
|
231
|
+
@options = options
|
232
|
+
end
|
233
|
+
|
234
|
+
def load(val)
|
235
|
+
if @options.include?(val)
|
236
|
+
return val
|
237
|
+
end
|
238
|
+
|
239
|
+
raise "Value #{val.inspect} does not belong to one of (#{@options.join(', ')})"
|
240
|
+
end
|
241
|
+
|
242
|
+
PRIMITIVE_TYPE = EnumLoader.new("null", "boolean", "int", "long", "float", "double", "string")
|
243
|
+
NOMINAL_TYPE = EnumLoader.new("File")
|
244
|
+
end
|
245
|
+
|
246
|
+
class OptionalLoader < Loader
|
247
|
+
def initialize(inner_loader)
|
248
|
+
@inner_loader = inner_loader
|
249
|
+
end
|
250
|
+
|
251
|
+
def load(val)
|
252
|
+
if val.nil?
|
253
|
+
return nil
|
254
|
+
end
|
255
|
+
|
256
|
+
@inner_loader.load(val)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
class RecordLoader < Loader
|
261
|
+
def initialize(klass, field_loaders = nil)
|
262
|
+
@klass = klass
|
263
|
+
@field_loaders = field_loaders
|
264
|
+
end
|
265
|
+
|
266
|
+
def field_loaders
|
267
|
+
@field_loaders || @klass::FIELD_LOADERS
|
268
|
+
end
|
269
|
+
|
270
|
+
def load(val)
|
271
|
+
unless val.is_a?(Hash)
|
272
|
+
raise "Unexpected value #{val.inspect} for type #{@klass.name}"
|
273
|
+
end
|
274
|
+
|
275
|
+
errors = {}
|
276
|
+
@klass.new({}.tap do |result|
|
277
|
+
field_loaders.each do |field_sym, loader|
|
278
|
+
field_str = field_sym.to_s
|
279
|
+
begin
|
280
|
+
result[field_str] = loader.load(val[field_str])
|
281
|
+
rescue => e
|
282
|
+
errors[field_str] = e.to_s
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
unless errors.empty?
|
287
|
+
raise errors.map { |k, e| "#{k}: #{e}" }.join(',')
|
288
|
+
end
|
289
|
+
end)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
class NeverLoader < Loader
|
294
|
+
def load(val)
|
295
|
+
raise "This feature is not supported"
|
296
|
+
end
|
297
|
+
|
298
|
+
UNSUPPORTED = NeverLoader.new.optional
|
299
|
+
end
|
300
|
+
|
301
|
+
class UnionLoader < Loader
|
302
|
+
def initialize(*alternatives)
|
303
|
+
@alternatives = alternatives
|
304
|
+
end
|
305
|
+
|
306
|
+
def load(val)
|
307
|
+
errors = []
|
308
|
+
@alternatives.each do |loader|
|
309
|
+
begin
|
310
|
+
return loader.load(val)
|
311
|
+
rescue => e
|
312
|
+
errors << e.to_s
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
raise errors.join(", ")
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
class ArrayType < Cwl
|
321
|
+
class InnerLoader < Loader
|
322
|
+
def load(val)
|
323
|
+
RecordLoader.new(ArrayType, {
|
324
|
+
type: EnumLoader.new("array"),
|
325
|
+
items: TypedDSLLoader::WITH_UNIONS_TYPE_LOADER,
|
326
|
+
}).load(val)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def type_loader
|
331
|
+
loader = RecordType::Field.type_loader(@attributes['items'])
|
332
|
+
return nil if loader.nil?
|
333
|
+
@type_loader ||= ArrayLoader.new(loader)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
class EnumType < Cwl
|
338
|
+
class InnerLoader < Loader
|
339
|
+
def load(val)
|
340
|
+
RecordLoader.new(EnumType, {
|
341
|
+
type: EnumLoader.new("enum"),
|
342
|
+
symbols: PrimitiveLoader::STRING.as_array,
|
343
|
+
}).load(val)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
def type_loader
|
348
|
+
@type_loader ||= EnumLoader.new(*@attributes['symbols'])
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
class RecordType < Cwl
|
353
|
+
class RecordTypeLoader
|
354
|
+
def load(val)
|
355
|
+
RecordLoader.new(RecordType, {
|
356
|
+
type: EnumLoader.new("record"),
|
357
|
+
fields: Field::FieldLoader.new.as_mapped_array('name', 'type')
|
358
|
+
}).load(val)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
class Record
|
363
|
+
def self.new(h)
|
364
|
+
h
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
def type_loader
|
369
|
+
@type_loader ||= begin
|
370
|
+
record_class = Class.new(Record)
|
371
|
+
RecordLoader.new(record_class, @attributes['fields'].map do |field|
|
372
|
+
loader = Field.type_loader(field.type)
|
373
|
+
return nil if loader.nil?
|
374
|
+
[field.name.to_sym, loader]
|
375
|
+
end.to_h)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
class Field < Cwl
|
380
|
+
class FieldLoader < Loader
|
381
|
+
def load(val)
|
382
|
+
RecordLoader.new(Field, {
|
383
|
+
name: PrimitiveLoader::STRING,
|
384
|
+
type: TypedDSLLoader::WITH_UNIONS_TYPE_LOADER,
|
385
|
+
doc: PrimitiveLoader::STRING.optional,
|
386
|
+
}).load(val)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
def name
|
391
|
+
@attributes['name']
|
392
|
+
end
|
393
|
+
|
394
|
+
def type
|
395
|
+
@attributes['type']
|
396
|
+
end
|
397
|
+
|
398
|
+
def type_loader
|
399
|
+
self.class.type_loader(self.type)
|
400
|
+
end
|
401
|
+
|
402
|
+
def self.type_loader(type)
|
403
|
+
case type
|
404
|
+
when Array
|
405
|
+
type_loaders = type.map { |t| Field.type_loader(t) }
|
406
|
+
return nil if type_loaders.any?(&:nil?)
|
407
|
+
UnionLoader.new(*type_loaders)
|
408
|
+
when EnumType
|
409
|
+
type.type_loader
|
410
|
+
when RecordType
|
411
|
+
type.type_loader
|
412
|
+
when ArrayType
|
413
|
+
type.type_loader
|
414
|
+
when String
|
415
|
+
PrimitiveLoader.find_primitive_type_loader(type)
|
416
|
+
else
|
417
|
+
raise "Could not determine loader for type #{type.inspect}"
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
class FunctorMapLoader < Loader
|
424
|
+
def initialize(inner, &block)
|
425
|
+
@block = block
|
426
|
+
@inner = inner
|
427
|
+
end
|
428
|
+
|
429
|
+
def load(val)
|
430
|
+
@block.call(@inner.load(val))
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
# Prepares a unique set of structured nominal types for an inner
|
435
|
+
# loading of types
|
436
|
+
class TypedDSLLoader < Loader
|
437
|
+
def initialize(inner)
|
438
|
+
@inner = inner
|
439
|
+
end
|
440
|
+
|
441
|
+
REGEX = /^([^\[?]+)(\[\])?(\?)?$/
|
442
|
+
|
443
|
+
def resolve(val)
|
444
|
+
m = REGEX.match(val)
|
445
|
+
|
446
|
+
unless m.nil?
|
447
|
+
type = m[1]
|
448
|
+
unless m[2].nil?
|
449
|
+
type = {'type' => 'array', 'items' => type}
|
450
|
+
end
|
451
|
+
unless m[3].nil?
|
452
|
+
type = ["null", type]
|
453
|
+
end
|
454
|
+
|
455
|
+
return type
|
456
|
+
end
|
457
|
+
|
458
|
+
val
|
459
|
+
end
|
460
|
+
|
461
|
+
def load(val)
|
462
|
+
if val.is_a?(Array)
|
463
|
+
@inner.load(val.map do |item|
|
464
|
+
item.is_a?(String) ? resolve(item) : item
|
465
|
+
end)
|
466
|
+
elsif val.is_a?(String)
|
467
|
+
@inner.load(resolve(val))
|
468
|
+
else
|
469
|
+
@inner.load(val)
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
OUTER_TYPE_LOADER = TypedDSLLoader.new(
|
474
|
+
UnionLoader.new(
|
475
|
+
RecordType::RecordTypeLoader.new,
|
476
|
+
ArrayType::InnerLoader.new,
|
477
|
+
EnumType::InnerLoader.new,
|
478
|
+
EnumLoader::PRIMITIVE_TYPE,
|
479
|
+
EnumLoader::NOMINAL_TYPE,
|
480
|
+
)
|
481
|
+
)
|
482
|
+
|
483
|
+
WITH_UNIONS_TYPE_LOADER = TypedDSLLoader.new(
|
484
|
+
UnionLoader.new(
|
485
|
+
OUTER_TYPE_LOADER,
|
486
|
+
ArrayLoader.new(OUTER_TYPE_LOADER),
|
487
|
+
)
|
488
|
+
)
|
489
|
+
end
|
490
|
+
|
491
|
+
def self.load_item(val, field_type)
|
492
|
+
if val.is_a?(Hash)
|
493
|
+
if val.include?("$import")
|
494
|
+
raise "$import expressions are not yet supported"
|
495
|
+
elsif val.include?("$include")
|
496
|
+
raise "$include expressions are not yet supported"
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
return field_type.load(val)
|
501
|
+
end
|
502
|
+
|
503
|
+
class InputParameter < Cwl
|
504
|
+
FIELD_LOADERS = {
|
505
|
+
id: PrimitiveLoader::STRING.optional,
|
506
|
+
label: PrimitiveLoader::STRING.optional,
|
507
|
+
secondaryFiles: NeverLoader::UNSUPPORTED,
|
508
|
+
streamable: NeverLoader::UNSUPPORTED,
|
509
|
+
loadContents: NeverLoader::UNSUPPORTED,
|
510
|
+
loadListing: NeverLoader::UNSUPPORTED,
|
511
|
+
valueFrom: NeverLoader::UNSUPPORTED,
|
512
|
+
doc: PrimitiveLoader::STRING.optional,
|
513
|
+
|
514
|
+
type: TypedDSLLoader::WITH_UNIONS_TYPE_LOADER,
|
515
|
+
default: AnyLoader::ANY.optional,
|
516
|
+
format: PrimitiveLoader::STRING.optional,
|
517
|
+
}
|
518
|
+
|
519
|
+
def default
|
520
|
+
default = @attributes['default']
|
521
|
+
return nil unless default
|
522
|
+
RecordType::Field.type_loader(@attributes['type'])&.load(default)
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
class OutputParameter < Cwl
|
527
|
+
FIELD_LOADERS = {
|
528
|
+
id: PrimitiveLoader::STRING.optional,
|
529
|
+
label: PrimitiveLoader::STRING.optional,
|
530
|
+
secondaryFiles: NeverLoader::UNSUPPORTED,
|
531
|
+
streamable: NeverLoader::UNSUPPORTED,
|
532
|
+
doc: PrimitiveLoader::STRING.optional,
|
533
|
+
|
534
|
+
outputBinding: NeverLoader::UNSUPPORTED,
|
535
|
+
type: TypedDSLLoader::WITH_UNIONS_TYPE_LOADER,
|
536
|
+
format: PrimitiveLoader::STRING.optional,
|
537
|
+
}
|
538
|
+
end
|
539
|
+
|
540
|
+
class WorkflowOutputParameter < Cwl
|
541
|
+
FIELD_LOADERS = {
|
542
|
+
id: PrimitiveLoader::STRING,
|
543
|
+
label: PrimitiveLoader::STRING.optional,
|
544
|
+
secondaryFiles: NeverLoader::UNSUPPORTED,
|
545
|
+
streamable: NeverLoader::UNSUPPORTED,
|
546
|
+
linkMerge: NeverLoader::UNSUPPORTED,
|
547
|
+
pickValue: NeverLoader::UNSUPPORTED,
|
548
|
+
doc: PrimitiveLoader::STRING.optional,
|
549
|
+
|
550
|
+
outputSource: SourceLoader.new,
|
551
|
+
type: TypedDSLLoader::WITH_UNIONS_TYPE_LOADER,
|
552
|
+
format: PrimitiveLoader::STRING.optional,
|
553
|
+
}
|
554
|
+
|
555
|
+
def outputSource
|
556
|
+
@attributes['outputSource']
|
557
|
+
end
|
558
|
+
|
559
|
+
def id
|
560
|
+
@attributes['id']
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
class WorkflowInputParameter < Cwl
|
565
|
+
FIELD_LOADERS = {
|
566
|
+
id: PrimitiveLoader::STRING,
|
567
|
+
label: PrimitiveLoader::STRING.optional,
|
568
|
+
secondaryFiles: NeverLoader::UNSUPPORTED,
|
569
|
+
streamable: NeverLoader::UNSUPPORTED,
|
570
|
+
loadContents: NeverLoader::UNSUPPORTED,
|
571
|
+
loadListing: NeverLoader::UNSUPPORTED,
|
572
|
+
doc: PrimitiveLoader::STRING.optional,
|
573
|
+
inputBinding: NeverLoader::UNSUPPORTED,
|
574
|
+
|
575
|
+
default: AnyLoader::ANY,
|
576
|
+
type: TypedDSLLoader::WITH_UNIONS_TYPE_LOADER,
|
577
|
+
format: PrimitiveLoader::STRING.optional,
|
578
|
+
}
|
579
|
+
|
580
|
+
def id
|
581
|
+
@attributes['id']
|
582
|
+
end
|
583
|
+
|
584
|
+
def default
|
585
|
+
@attributes['default']
|
586
|
+
end
|
587
|
+
|
588
|
+
def type
|
589
|
+
@attributes['type']
|
590
|
+
end
|
591
|
+
end
|
592
|
+
|
593
|
+
class StepOutput < Cwl
|
594
|
+
FIELD_LOADERS = {
|
595
|
+
id: PrimitiveLoader::STRING,
|
596
|
+
}
|
597
|
+
|
598
|
+
def id
|
599
|
+
@attributes['id']
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
|
604
|
+
class StepInput < Cwl
|
605
|
+
FIELD_LOADERS = {
|
606
|
+
id: PrimitiveLoader::STRING.optional,
|
607
|
+
source: SourceLoader.new.optional,
|
608
|
+
label: PrimitiveLoader::STRING.optional,
|
609
|
+
linkMerge: NeverLoader::UNSUPPORTED,
|
610
|
+
pickValue: NeverLoader::UNSUPPORTED,
|
611
|
+
loadContents: NeverLoader::UNSUPPORTED,
|
612
|
+
loadListing: NeverLoader::UNSUPPORTED,
|
613
|
+
valueFrom: NeverLoader::UNSUPPORTED,
|
614
|
+
default: AnyLoader::ANY.optional,
|
615
|
+
}
|
616
|
+
|
617
|
+
def id
|
618
|
+
@attributes['id']
|
619
|
+
end
|
620
|
+
|
621
|
+
def source
|
622
|
+
@attributes['source']
|
623
|
+
end
|
624
|
+
end
|
625
|
+
|
626
|
+
class Operation < Cwl
|
627
|
+
FIELD_LOADERS = {
|
628
|
+
id: PrimitiveLoader::STRING.optional,
|
629
|
+
label: PrimitiveLoader::STRING.optional,
|
630
|
+
doc: PrimitiveLoader::STRING.optional,
|
631
|
+
requirements: NeverLoader::UNSUPPORTED,
|
632
|
+
hints: NeverLoader::UNSUPPORTED,
|
633
|
+
cwlVersion: EnumLoader.new("v1.0", "v1.1", "v1.2").optional,
|
634
|
+
intent: NeverLoader::UNSUPPORTED,
|
635
|
+
class: EnumLoader.new("Operation"),
|
636
|
+
inputs: InputParameter.loader.as_mapped_array('id', 'type'),
|
637
|
+
outputs: OutputParameter.loader.as_mapped_array('id', 'type'),
|
638
|
+
}
|
639
|
+
|
640
|
+
def id
|
641
|
+
@attributes['id']
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
class Step < Cwl
|
646
|
+
FIELD_LOADERS = {
|
647
|
+
id: PrimitiveLoader::STRING.optional,
|
648
|
+
label: PrimitiveLoader::STRING.optional,
|
649
|
+
doc: PrimitiveLoader::STRING.optional,
|
650
|
+
in: StepInput.loader.as_mapped_array('id', 'source'),
|
651
|
+
out: StepOutput.loader.or(PrimitiveLoader::STRING.map { |id| StepOutput.loader.load({'id' => id}) }).as_array,
|
652
|
+
requirements: NeverLoader::UNSUPPORTED,
|
653
|
+
hints: NeverLoader::UNSUPPORTED,
|
654
|
+
run: PrimitiveLoader::STRING.map { |id| Operation.loader.load({'id' => id, 'class' => 'Operation', 'inputs' => [], 'outputs' => []}) }.or(Operation.loader),
|
655
|
+
when: NeverLoader::UNSUPPORTED,
|
656
|
+
scatter: NeverLoader::UNSUPPORTED,
|
657
|
+
scatterMethod: NeverLoader::UNSUPPORTED,
|
658
|
+
}
|
659
|
+
|
660
|
+
def id
|
661
|
+
@attributes['id']
|
662
|
+
end
|
663
|
+
|
664
|
+
def in
|
665
|
+
@attributes['in']
|
666
|
+
end
|
667
|
+
|
668
|
+
def out
|
669
|
+
@attributes['out']
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
class Workflow < Cwl
|
674
|
+
FIELD_LOADERS = {
|
675
|
+
id: PrimitiveLoader::STRING.optional,
|
676
|
+
label: PrimitiveLoader::STRING.optional,
|
677
|
+
doc: PrimitiveLoader::STRING.optional,
|
678
|
+
requirements: NeverLoader::UNSUPPORTED,
|
679
|
+
hints: NeverLoader::UNSUPPORTED,
|
680
|
+
intent: NeverLoader::UNSUPPORTED,
|
681
|
+
class: EnumLoader.new("Workflow"),
|
682
|
+
cwlVersion: EnumLoader.new("v1.0", "v1.1", "v1.2"),
|
683
|
+
inputs: WorkflowInputParameter.loader.as_mapped_array('id', 'type'),
|
684
|
+
outputs: WorkflowOutputParameter.loader.as_mapped_array('id', 'type'),
|
685
|
+
steps: Step.loader.as_mapped_array('id', 'source')
|
686
|
+
}
|
687
|
+
|
688
|
+
def inputs
|
689
|
+
@attributes['inputs']
|
690
|
+
end
|
691
|
+
|
692
|
+
def outputs
|
693
|
+
@attributes['outputs']
|
694
|
+
end
|
695
|
+
|
696
|
+
def steps
|
697
|
+
@attributes['steps']
|
698
|
+
end
|
699
|
+
end
|
700
|
+
end
|
701
|
+
end
|