xpflow 0.1b
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/bin/xpflow +96 -0
- data/lib/colorado.rb +198 -0
- data/lib/json/add/core.rb +243 -0
- data/lib/json/add/rails.rb +8 -0
- data/lib/json/common.rb +423 -0
- data/lib/json/editor.rb +1369 -0
- data/lib/json/ext.rb +28 -0
- data/lib/json/pure/generator.rb +442 -0
- data/lib/json/pure/parser.rb +320 -0
- data/lib/json/pure.rb +15 -0
- data/lib/json/version.rb +8 -0
- data/lib/json.rb +62 -0
- data/lib/mime/types.rb +881 -0
- data/lib/mime-types.rb +3 -0
- data/lib/restclient/abstract_response.rb +106 -0
- data/lib/restclient/exceptions.rb +193 -0
- data/lib/restclient/net_http_ext.rb +55 -0
- data/lib/restclient/payload.rb +235 -0
- data/lib/restclient/raw_response.rb +34 -0
- data/lib/restclient/request.rb +316 -0
- data/lib/restclient/resource.rb +169 -0
- data/lib/restclient/response.rb +24 -0
- data/lib/restclient.rb +174 -0
- data/lib/xpflow/bash.rb +341 -0
- data/lib/xpflow/bundle.rb +113 -0
- data/lib/xpflow/cmdline.rb +249 -0
- data/lib/xpflow/collection.rb +122 -0
- data/lib/xpflow/concurrency.rb +79 -0
- data/lib/xpflow/data.rb +393 -0
- data/lib/xpflow/dsl.rb +816 -0
- data/lib/xpflow/engine.rb +574 -0
- data/lib/xpflow/ensemble.rb +135 -0
- data/lib/xpflow/events.rb +56 -0
- data/lib/xpflow/experiment.rb +65 -0
- data/lib/xpflow/exts/facter.rb +30 -0
- data/lib/xpflow/exts/g5k.rb +931 -0
- data/lib/xpflow/exts/g5k_use.rb +50 -0
- data/lib/xpflow/exts/gui.rb +140 -0
- data/lib/xpflow/exts/model.rb +155 -0
- data/lib/xpflow/graph.rb +1603 -0
- data/lib/xpflow/graph_xpflow.rb +251 -0
- data/lib/xpflow/import.rb +196 -0
- data/lib/xpflow/library.rb +349 -0
- data/lib/xpflow/logging.rb +153 -0
- data/lib/xpflow/manager.rb +147 -0
- data/lib/xpflow/nodes.rb +1250 -0
- data/lib/xpflow/runs.rb +773 -0
- data/lib/xpflow/runtime.rb +125 -0
- data/lib/xpflow/scope.rb +168 -0
- data/lib/xpflow/ssh.rb +186 -0
- data/lib/xpflow/stat.rb +50 -0
- data/lib/xpflow/stdlib.rb +381 -0
- data/lib/xpflow/structs.rb +369 -0
- data/lib/xpflow/taktuk.rb +193 -0
- data/lib/xpflow/templates/ssh-config.basic +14 -0
- data/lib/xpflow/templates/ssh-config.inria +18 -0
- data/lib/xpflow/templates/ssh-config.proxy +13 -0
- data/lib/xpflow/templates/taktuk +6590 -0
- data/lib/xpflow/templates/utils/batch +4 -0
- data/lib/xpflow/templates/utils/bootstrap +12 -0
- data/lib/xpflow/templates/utils/hostname +3 -0
- data/lib/xpflow/templates/utils/ping +3 -0
- data/lib/xpflow/templates/utils/rsync +12 -0
- data/lib/xpflow/templates/utils/scp +17 -0
- data/lib/xpflow/templates/utils/scp_many +8 -0
- data/lib/xpflow/templates/utils/ssh +3 -0
- data/lib/xpflow/templates/utils/ssh-interactive +4 -0
- data/lib/xpflow/templates/utils/taktuk +19 -0
- data/lib/xpflow/threads.rb +187 -0
- data/lib/xpflow/utils.rb +569 -0
- data/lib/xpflow/visual.rb +230 -0
- data/lib/xpflow/with_g5k.rb +7 -0
- data/lib/xpflow.rb +349 -0
- metadata +135 -0
data/lib/xpflow/dsl.rb
ADDED
@@ -0,0 +1,816 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# DSL implementation.
|
5
|
+
#
|
6
|
+
|
7
|
+
module XPFlow
|
8
|
+
|
9
|
+
class LibraryLink
|
10
|
+
|
11
|
+
constructor :process, :key, :parts
|
12
|
+
|
13
|
+
def method_missing(method, *args, &block)
|
14
|
+
new_parts = @parts + [ method.to_s ]
|
15
|
+
full_name = new_parts.join(".")
|
16
|
+
obj = @process.library.resolve_name(full_name)
|
17
|
+
if obj.nil?
|
18
|
+
raise "No such object '#{full_name}'"
|
19
|
+
end
|
20
|
+
if obj.is_a?(Library)
|
21
|
+
raise NoMethodError, "Library referencing requires no args" if args.length > 0
|
22
|
+
else
|
23
|
+
# activity/process
|
24
|
+
args = XPValue.flatten(args)
|
25
|
+
full_name = XPValue.flatten(full_name)
|
26
|
+
run = RunDSL.new(@process, @key, full_name, args, {}, block)
|
27
|
+
return @process.push(run)
|
28
|
+
end
|
29
|
+
return LibraryLink.new(@process, @key, new_parts)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Key
|
34
|
+
|
35
|
+
def initialize(array)
|
36
|
+
@array = array
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
class DSL
|
42
|
+
|
43
|
+
def initialize(process, key)
|
44
|
+
@process = process
|
45
|
+
if key.nil?
|
46
|
+
@_key = []
|
47
|
+
elsif key.is_a?(Array)
|
48
|
+
@_key = key
|
49
|
+
elsif key.is_a?(String)
|
50
|
+
@_key = from_string(key)
|
51
|
+
else
|
52
|
+
raise "Unsupported key type"
|
53
|
+
end
|
54
|
+
@current_key = -1
|
55
|
+
@keys = []
|
56
|
+
end
|
57
|
+
|
58
|
+
def from_string(s) # string => Array
|
59
|
+
raise "error" unless s.start_with?("/")
|
60
|
+
arr = s.split("/"); arr.shift
|
61
|
+
return arr
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_string(arr)
|
65
|
+
return "/" + arr.join("/")
|
66
|
+
end
|
67
|
+
|
68
|
+
def key
|
69
|
+
return to_string(@_key)
|
70
|
+
end
|
71
|
+
|
72
|
+
def new_key
|
73
|
+
@current_key += 1
|
74
|
+
key = @_key + [ @current_key ]
|
75
|
+
@keys.push(key)
|
76
|
+
return to_string(key)
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse(*args, &block)
|
80
|
+
begin
|
81
|
+
$current_dsl.push(self)
|
82
|
+
self.instance_exec(*args, &block)
|
83
|
+
ensure
|
84
|
+
$current_dsl.pop
|
85
|
+
end
|
86
|
+
return self
|
87
|
+
end
|
88
|
+
|
89
|
+
def repr
|
90
|
+
{
|
91
|
+
:key => key()
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
$current_dsl = []
|
98
|
+
|
99
|
+
class DSLVariable
|
100
|
+
|
101
|
+
include Operations
|
102
|
+
|
103
|
+
attr_reader :key
|
104
|
+
constructor :key
|
105
|
+
|
106
|
+
def to_s
|
107
|
+
"Var[-@@@@-#{key}-@@@@-]"
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.replace(s, scope)
|
111
|
+
out = s.gsub(/Var\[-@@@@-([\/\d]+)-@@@@-\]/) do |m|
|
112
|
+
key = $1
|
113
|
+
scope.get(key).to_s
|
114
|
+
end
|
115
|
+
return out
|
116
|
+
end
|
117
|
+
|
118
|
+
def to_ary
|
119
|
+
return 10.times.map do |i|
|
120
|
+
u = XPValue.flatten(self)
|
121
|
+
u.index(XPConst.new(i))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def as_s
|
126
|
+
return method_missing(:to_s)
|
127
|
+
end
|
128
|
+
|
129
|
+
def as_i
|
130
|
+
return method_missing(:to_i)
|
131
|
+
end
|
132
|
+
|
133
|
+
def method_missing(method, *args)
|
134
|
+
dsl = $current_dsl.last
|
135
|
+
raise "Fatal error" if dsl.nil?
|
136
|
+
raise "Arguments are unsupported" if args.length > 0
|
137
|
+
return dsl.get_of(self, method)
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
class RunDSL < DSL
|
143
|
+
|
144
|
+
constructor [ :process, :key ], :name, :args, :opts, :block
|
145
|
+
|
146
|
+
def repr
|
147
|
+
super.merge({
|
148
|
+
:type => :run,
|
149
|
+
:name => @name,
|
150
|
+
:args => @args,
|
151
|
+
:opts => @opts
|
152
|
+
})
|
153
|
+
end
|
154
|
+
|
155
|
+
def collect_meta(xxxx)
|
156
|
+
{
|
157
|
+
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
def as_run
|
162
|
+
return ActivityRun.new(key, @name, @args, @opts, @block)
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
class ReturnLoopDSL < DSL
|
168
|
+
|
169
|
+
constructor [ :process, :key ], :flag, :cond, :value
|
170
|
+
|
171
|
+
def as_run
|
172
|
+
return ReturnLoopRun.new(key, @flag, @cond, @value)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
class CheckpointDSL < DSL
|
177
|
+
|
178
|
+
constructor [ :process, :key ], :name, :opts, :parent
|
179
|
+
|
180
|
+
def as_run
|
181
|
+
return CheckpointRun.new(new_key, @name, @opts, @parent)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class OtherwiseDSL < DSL
|
186
|
+
|
187
|
+
constructor [ :process, :key ]
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
class ListDSL < DSL
|
192
|
+
|
193
|
+
constructor [ :process, :key ], :list
|
194
|
+
|
195
|
+
def __list__
|
196
|
+
return @list
|
197
|
+
end
|
198
|
+
|
199
|
+
def __as_run__
|
200
|
+
return @list.map(&:as_run)
|
201
|
+
end
|
202
|
+
|
203
|
+
def push(x, inc = 0)
|
204
|
+
@list.push(x)
|
205
|
+
return DSLVariable.new(x.key)
|
206
|
+
end
|
207
|
+
|
208
|
+
def parse_and_push(dsl, *args, &block)
|
209
|
+
return push(dsl.parse(*args, &block))
|
210
|
+
end
|
211
|
+
|
212
|
+
def as_run
|
213
|
+
runs = __as_run__
|
214
|
+
return SequenceRun.new(key, runs)
|
215
|
+
end
|
216
|
+
|
217
|
+
def __workflow__(*args)
|
218
|
+
block, _ = @process.current_workflow
|
219
|
+
seq = SequenceDSL.new(@process, new_key)
|
220
|
+
return parse_and_push(seq, *args, &block)
|
221
|
+
end
|
222
|
+
|
223
|
+
### DSL PART ###
|
224
|
+
|
225
|
+
def parallel(opts = {}, &block)
|
226
|
+
retries = opts[:retry]
|
227
|
+
if retries.nil?
|
228
|
+
dsl = ParallelDSL.new(@process, new_key)
|
229
|
+
return parse_and_push(dsl, &block)
|
230
|
+
else
|
231
|
+
try :retry => retries do
|
232
|
+
parallel(&block)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def any(&block)
|
238
|
+
one = XPValue.flatten(-1)
|
239
|
+
dsl = ManyDSL.new(@process, new_key, one)
|
240
|
+
return parse_and_push(dsl, &block)
|
241
|
+
end
|
242
|
+
|
243
|
+
def many(arg, &block)
|
244
|
+
n = XPValue.flatten(arg)
|
245
|
+
dsl = ManyDSL.new(@process, new_key, n)
|
246
|
+
return parse_and_push(dsl, &block)
|
247
|
+
end
|
248
|
+
|
249
|
+
def formany(arg, array, &block)
|
250
|
+
n = XPValue.flatten(arg)
|
251
|
+
array = XPValue.flatten(array)
|
252
|
+
dsl = ForManyDSL.new(@process, new_key, n, array)
|
253
|
+
return parse_and_push(dsl, &block)
|
254
|
+
end
|
255
|
+
|
256
|
+
def sequence(&block)
|
257
|
+
dsl = SequenceDSL.new(@process, new_key)
|
258
|
+
return parse_and_push(dsl, &block)
|
259
|
+
end
|
260
|
+
|
261
|
+
def seq(&block)
|
262
|
+
return sequence(&block)
|
263
|
+
end
|
264
|
+
|
265
|
+
def seqtry(&block)
|
266
|
+
dsl = SeqtryDSL.new(@process, new_key)
|
267
|
+
return parse_and_push(dsl, &block)
|
268
|
+
end
|
269
|
+
|
270
|
+
def foreach(array, opts = {}, &block)
|
271
|
+
array = XPValue.flatten(array)
|
272
|
+
opts = XPValue.flatten(opts)
|
273
|
+
dsl = ForEachDSL.new(@process, new_key, array, opts)
|
274
|
+
return parse_and_push(dsl, &block)
|
275
|
+
end
|
276
|
+
|
277
|
+
def forall(array, opts = {}, &block)
|
278
|
+
array = XPValue.flatten(array)
|
279
|
+
opts = XPValue.flatten(opts)
|
280
|
+
dsl = ForAllDSL.new(@process, new_key, array, opts)
|
281
|
+
return parse_and_push(dsl, &block)
|
282
|
+
end
|
283
|
+
|
284
|
+
def times(loops, &block)
|
285
|
+
loops = XPValue.flatten(loops)
|
286
|
+
dsl = TimesDSL.new(@process, new_key, loops)
|
287
|
+
return parse_and_push(dsl, &block)
|
288
|
+
end
|
289
|
+
|
290
|
+
def forany(array, &block)
|
291
|
+
one = XPValue.flatten(-1)
|
292
|
+
array = XPValue.flatten(array)
|
293
|
+
dsl = ForManyDSL.new(@process, new_key, one, array)
|
294
|
+
return parse_and_push(dsl, &block)
|
295
|
+
end
|
296
|
+
|
297
|
+
def on(condition, &block)
|
298
|
+
condition = XPValue.flatten(condition)
|
299
|
+
dsl = IfDSL.new(@process, new_key, condition)
|
300
|
+
return parse_and_push(dsl, &block)
|
301
|
+
end
|
302
|
+
|
303
|
+
def switch(*args, &block)
|
304
|
+
if args.length == 0
|
305
|
+
s = SwitchDSL.new(@process, new_key)
|
306
|
+
parse_and_push(s, &block)
|
307
|
+
elsif args.length == 1
|
308
|
+
s = BoundSwitchDSL.new(@process, new_key, XPValue.flatten(args.first))
|
309
|
+
parse_and_push(s, &block)
|
310
|
+
else
|
311
|
+
raise
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def multi(&block)
|
316
|
+
dsl = MultiDSL.new(@process, new_key)
|
317
|
+
return parse_and_push(dsl, &block)
|
318
|
+
end
|
319
|
+
|
320
|
+
def try(opts = {}, &block)
|
321
|
+
opts = XPValue.flatten(opts)
|
322
|
+
dsl = TryDSL.new(@process, new_key, opts)
|
323
|
+
return parse_and_push(dsl, &block)
|
324
|
+
end
|
325
|
+
|
326
|
+
def result(path, opts = {}, &block)
|
327
|
+
# TODO: reimplement with macros!
|
328
|
+
opts = XPValue.flatten(opts)
|
329
|
+
path = XPValue.flatten(path)
|
330
|
+
dsl = ResultDSL.new(@process, new_key, path, opts)
|
331
|
+
return parse_and_push(dsl, &block)
|
332
|
+
end
|
333
|
+
|
334
|
+
def loop(opts = {}, &block)
|
335
|
+
opts = XPValue.flatten(opts)
|
336
|
+
dsl = LoopDSL.new(@process, new_key, opts)
|
337
|
+
return parse_and_push(dsl, &block)
|
338
|
+
end
|
339
|
+
|
340
|
+
def cache(opts = {}, &block)
|
341
|
+
dsl = CacheDSL.new(@process, new_key, opts)
|
342
|
+
return parse_and_push(dsl, &block)
|
343
|
+
end
|
344
|
+
|
345
|
+
|
346
|
+
def info(opts = {}, &block)
|
347
|
+
opts = XPValue.flatten(opts)
|
348
|
+
dsl = InfoDSL.new(@process, opts)
|
349
|
+
return parse_and_push(dsl, &block)
|
350
|
+
end
|
351
|
+
|
352
|
+
def run(arg, *args, &block)
|
353
|
+
# Kernel.puts "run: #{args} #{args.inspect}"
|
354
|
+
opts = XPFlow::parse_comment_opts(__FILE__)
|
355
|
+
name = nil
|
356
|
+
if arg.is_a?(Hash)
|
357
|
+
opts = opts.merge(arg)
|
358
|
+
name, args = args.first, args.tail
|
359
|
+
else
|
360
|
+
name = arg
|
361
|
+
end
|
362
|
+
raise 'No name given' if name.nil?
|
363
|
+
args = XPValue.flatten(args)
|
364
|
+
name = XPValue.flatten(name)
|
365
|
+
return push(RunDSL.new(@process, new_key, name, args, opts, block))
|
366
|
+
end
|
367
|
+
|
368
|
+
def rerun(name, *args, &block)
|
369
|
+
# TODO
|
370
|
+
try :retry => 100000 do # as many times as needed
|
371
|
+
run(name, *args, &block)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
def sleep(t)
|
376
|
+
# this has to be present in DSL for some rather obscure reasons :)
|
377
|
+
return method_missing(:sleep, t)
|
378
|
+
end
|
379
|
+
|
380
|
+
def puts(*args)
|
381
|
+
# overloads the standard 'puts'
|
382
|
+
return method_missing(:log, *args)
|
383
|
+
end
|
384
|
+
|
385
|
+
def fail(*args)
|
386
|
+
# same here
|
387
|
+
return method_missing(:fail, *args)
|
388
|
+
end
|
389
|
+
|
390
|
+
def system(cmd)
|
391
|
+
# same here
|
392
|
+
return method_missing(:system, cmd)
|
393
|
+
end
|
394
|
+
|
395
|
+
def send(o, method, *args)
|
396
|
+
# same reason as sleep
|
397
|
+
return method_missing(:send, o, method, *args)
|
398
|
+
end
|
399
|
+
|
400
|
+
def method_missing(method, *args, &block)
|
401
|
+
# this is rather tricky:
|
402
|
+
# 1. DSL has predefined commands.
|
403
|
+
# 2. When no command matches we try to find "injected" activity, or activity
|
404
|
+
# the was injected into the DSL. That way we can move many DSL commands to activities.
|
405
|
+
# 3. When injected activities do not match, we try to match with a namespace. If there
|
406
|
+
# is a library with such a name we return a special variable. The only use for that
|
407
|
+
# is to be able to run activities like that: run g5k.reserve_nodes
|
408
|
+
# 4. If nothing matches, we raise an error.
|
409
|
+
|
410
|
+
# pp @process.library.traversal_graph
|
411
|
+
|
412
|
+
name = method.to_s
|
413
|
+
activity = @process.library.get_activity_or_nil(name)
|
414
|
+
|
415
|
+
if activity.is_a?(MacroDSL)
|
416
|
+
m = activity
|
417
|
+
seq = nil
|
418
|
+
raise "Macro must be provided with a workflow" if block.nil?
|
419
|
+
@process.with_workflow(block, args) do
|
420
|
+
seq = SequenceDSL.new(@process, new_key)
|
421
|
+
seq.parse(*args, &m.block)
|
422
|
+
push(seq)
|
423
|
+
end
|
424
|
+
return seq
|
425
|
+
end
|
426
|
+
|
427
|
+
if activity.nil? == false
|
428
|
+
args = XPValue.flatten(args)
|
429
|
+
name = XPValue.flatten(name)
|
430
|
+
opts = XPFlow::parse_comment_opts(__FILE__)
|
431
|
+
run = RunDSL.new(@process, new_key, name, args, opts, block)
|
432
|
+
return push(run)
|
433
|
+
end
|
434
|
+
|
435
|
+
library = @process.library.get_library_or_nil(name)
|
436
|
+
|
437
|
+
if library.nil? == false
|
438
|
+
raise NoMethodError, "Library referencing requires no args" if args.length > 0
|
439
|
+
return LibraryLink.new(@process, new_key, [ method.to_s ])
|
440
|
+
end
|
441
|
+
|
442
|
+
if name.end_with?('_of') and [ 1, 2 ].include?(args.length)
|
443
|
+
name = name.chomp('_of')
|
444
|
+
return self.get_of(args.first, name.to_sym, args[1])
|
445
|
+
end
|
446
|
+
|
447
|
+
raise NoMethodError, "Unknown or malformed DSL command or no such activity (:#{method})"
|
448
|
+
end
|
449
|
+
|
450
|
+
def _visit(*args)
|
451
|
+
pp caller
|
452
|
+
raise "Somebody did something stupid (see #{self.class})."
|
453
|
+
end
|
454
|
+
|
455
|
+
def experiment_scope(name = nil, &block)
|
456
|
+
# creates a new experiment scope
|
457
|
+
dsl = ExperimentDSL.new(@process, name)
|
458
|
+
return parse_and_push(dsl, &block)
|
459
|
+
end
|
460
|
+
|
461
|
+
### END OF DSL ###
|
462
|
+
|
463
|
+
end
|
464
|
+
|
465
|
+
class SequenceDSL < ListDSL
|
466
|
+
|
467
|
+
def initialize(process, key)
|
468
|
+
super(process, key, [])
|
469
|
+
end
|
470
|
+
|
471
|
+
def self.repr(o)
|
472
|
+
return {
|
473
|
+
:key => o.key,
|
474
|
+
:type => :seq,
|
475
|
+
:body => o.__list__.map(&:repr)
|
476
|
+
}
|
477
|
+
end
|
478
|
+
|
479
|
+
def repr
|
480
|
+
return SequenceDSL.repr(self)
|
481
|
+
end
|
482
|
+
|
483
|
+
end
|
484
|
+
|
485
|
+
class ProcessDSL < SequenceDSL
|
486
|
+
|
487
|
+
attr_reader :args
|
488
|
+
attr_reader :name
|
489
|
+
attr_reader :library
|
490
|
+
|
491
|
+
def initialize(name, library, &block)
|
492
|
+
super(self, [])
|
493
|
+
@name = name
|
494
|
+
@library = library
|
495
|
+
@workflows = [] # a stack of current workflows used in macros
|
496
|
+
if block.nil?
|
497
|
+
raise "Block is nil?"
|
498
|
+
end
|
499
|
+
count = block.arity
|
500
|
+
if count >= 0
|
501
|
+
@args = count.times.map { |i| DSLVariable.new(new_key()) }
|
502
|
+
else
|
503
|
+
@args = 10.times.map { |i| DSLVariable.new(new_key()) }
|
504
|
+
end
|
505
|
+
self.parse(*@args, &block)
|
506
|
+
end
|
507
|
+
|
508
|
+
def checkpoint(*args)
|
509
|
+
name = nil
|
510
|
+
opts = {}
|
511
|
+
opts = args.pop if args.last.is_a?(Hash)
|
512
|
+
raise 'Wrong arguments' if args.length > 1
|
513
|
+
name = args.first if args.length == 1
|
514
|
+
push(CheckpointDSL.new(@process, new_key, name, opts, self))
|
515
|
+
end
|
516
|
+
|
517
|
+
def get_injection(name)
|
518
|
+
return @library.get_injection(name)
|
519
|
+
end
|
520
|
+
|
521
|
+
def as_process
|
522
|
+
keys = @args.map(&:key)
|
523
|
+
seq = self.as_run
|
524
|
+
return ProcessActivity.new(@name, keys, seq)
|
525
|
+
end
|
526
|
+
|
527
|
+
def repr
|
528
|
+
return {
|
529
|
+
:type => :process,
|
530
|
+
:name => @name,
|
531
|
+
:body => SequenceDSL.repr(self)
|
532
|
+
}
|
533
|
+
end
|
534
|
+
|
535
|
+
def with_workflow(m, args)
|
536
|
+
begin
|
537
|
+
@workflows.push([ m, args ])
|
538
|
+
yield
|
539
|
+
ensure
|
540
|
+
@workflows.pop
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
def current_workflow
|
545
|
+
raise "No current workflow" if @workflows.length == 0
|
546
|
+
return @workflows.last
|
547
|
+
end
|
548
|
+
|
549
|
+
end
|
550
|
+
|
551
|
+
|
552
|
+
class InnerDSL < SequenceDSL
|
553
|
+
|
554
|
+
alias :sequence_run :as_run
|
555
|
+
|
556
|
+
end
|
557
|
+
|
558
|
+
class WithParamsDSL < InnerDSL
|
559
|
+
|
560
|
+
def parse(&block)
|
561
|
+
args = @args.map { |x| DSLVariable.new(x) }
|
562
|
+
return super(*args, &block)
|
563
|
+
end
|
564
|
+
|
565
|
+
def repr
|
566
|
+
super.merge({
|
567
|
+
:args => @args
|
568
|
+
})
|
569
|
+
end
|
570
|
+
|
571
|
+
end
|
572
|
+
|
573
|
+
|
574
|
+
class SeqtryDSL < InnerDSL
|
575
|
+
|
576
|
+
constructor [ :process, :key ]
|
577
|
+
|
578
|
+
def as_run
|
579
|
+
return SeqtryRun.new(key, sequence_run.body)
|
580
|
+
end
|
581
|
+
|
582
|
+
end
|
583
|
+
|
584
|
+
class ExperimentDSL < InnerDSL
|
585
|
+
|
586
|
+
constructor [ :process ], :name
|
587
|
+
|
588
|
+
def as_run
|
589
|
+
return ExperimentRun.new(@process.get_key, @name, sequence_run)
|
590
|
+
end
|
591
|
+
|
592
|
+
end
|
593
|
+
|
594
|
+
class ForEachDSL < WithParamsDSL
|
595
|
+
|
596
|
+
constructor [ :process, :key ], :array, :opts
|
597
|
+
|
598
|
+
def init
|
599
|
+
@args = [ new_key() ] # iterator
|
600
|
+
end
|
601
|
+
|
602
|
+
def as_run
|
603
|
+
return ForEachRun.new(key, @array, @args.first, @opts, sequence_run)
|
604
|
+
end
|
605
|
+
|
606
|
+
def repr
|
607
|
+
super.merge({
|
608
|
+
:type => :foreach,
|
609
|
+
:array => @array
|
610
|
+
})
|
611
|
+
end
|
612
|
+
|
613
|
+
end
|
614
|
+
|
615
|
+
class ParallelDSL < InnerDSL
|
616
|
+
|
617
|
+
def as_run
|
618
|
+
return ParallelRun.new(key, __as_run__)
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
class TimesDSL < WithParamsDSL
|
623
|
+
|
624
|
+
constructor [ :process, :key ], :loops
|
625
|
+
|
626
|
+
def init
|
627
|
+
@args = [ new_key() ] # iterator
|
628
|
+
end
|
629
|
+
|
630
|
+
def as_run
|
631
|
+
return TimesRun.new(key, @loops, @args.first, sequence_run)
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
class ForAllDSL < WithParamsDSL
|
636
|
+
|
637
|
+
constructor [ :process, :key ], :array, :opts
|
638
|
+
|
639
|
+
def init
|
640
|
+
@args = [ new_key() ] # iterator
|
641
|
+
end
|
642
|
+
|
643
|
+
def as_run
|
644
|
+
return ForAllRun.new(key, @array, @args.first, @opts, sequence_run)
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
class ForManyDSL < WithParamsDSL
|
649
|
+
|
650
|
+
constructor [ :process, :key ], :number, :array
|
651
|
+
|
652
|
+
def init
|
653
|
+
@args = [ new_key() ] # iterator
|
654
|
+
end
|
655
|
+
|
656
|
+
def as_run
|
657
|
+
return ForManyRun.new(key, @number, @array, @args.first, sequence_run)
|
658
|
+
end
|
659
|
+
|
660
|
+
end
|
661
|
+
|
662
|
+
class ManyDSL < InnerDSL
|
663
|
+
|
664
|
+
constructor [ :process, :key ], :number
|
665
|
+
|
666
|
+
def as_run
|
667
|
+
return ManyRun.new(key, @number, __as_run__)
|
668
|
+
end
|
669
|
+
|
670
|
+
end
|
671
|
+
|
672
|
+
class TryDSL < InnerDSL
|
673
|
+
|
674
|
+
constructor [ :process, :key ], :opts
|
675
|
+
|
676
|
+
def as_run
|
677
|
+
return TryRun.new(key, @opts, sequence_run)
|
678
|
+
end
|
679
|
+
|
680
|
+
end
|
681
|
+
|
682
|
+
class ResultDSL < InnerDSL
|
683
|
+
|
684
|
+
constructor [ :process, :key ], :path, :opts
|
685
|
+
|
686
|
+
def as_run
|
687
|
+
return ResultRun.new(key, @path, @opts, sequence_run)
|
688
|
+
end
|
689
|
+
|
690
|
+
end
|
691
|
+
|
692
|
+
class CacheDSL < InnerDSL
|
693
|
+
|
694
|
+
constructor [ :process, :key ], :opts
|
695
|
+
|
696
|
+
def as_run
|
697
|
+
return CacheRun.new(key, @opts, sequence_run)
|
698
|
+
end
|
699
|
+
|
700
|
+
end
|
701
|
+
|
702
|
+
class InfoDSL < InnerDSL
|
703
|
+
|
704
|
+
constructor [ :process, :key ], :opts
|
705
|
+
|
706
|
+
def as_run
|
707
|
+
return InfoRun.new(key, @opts, sequence_run)
|
708
|
+
end
|
709
|
+
end
|
710
|
+
|
711
|
+
|
712
|
+
class IfDSL < SequenceDSL
|
713
|
+
|
714
|
+
constructor [ :process, :key ], :cond
|
715
|
+
|
716
|
+
def otherwise
|
717
|
+
push(OtherwiseDSL.new(@process, new_key))
|
718
|
+
end
|
719
|
+
|
720
|
+
def as_run
|
721
|
+
i = nil
|
722
|
+
@list.length.times do |j|
|
723
|
+
i = j if (@list[j].is_a?(OtherwiseDSL))
|
724
|
+
end
|
725
|
+
on_true = []
|
726
|
+
on_false = []
|
727
|
+
if i.nil?
|
728
|
+
on_true = @list
|
729
|
+
else
|
730
|
+
on_true = @list[0..(i-1)]
|
731
|
+
on_false = @list[(i+1)..-1]
|
732
|
+
raise if (on_true.length + on_false.length + 1) != @list.length
|
733
|
+
end
|
734
|
+
on_true = ListDSL.new(@process, new_key, on_true).as_run
|
735
|
+
on_false = ListDSL.new(@process, new_key, on_false).as_run
|
736
|
+
return IfRun.new(key, @cond, on_true, on_false)
|
737
|
+
end
|
738
|
+
|
739
|
+
end
|
740
|
+
|
741
|
+
class LoopDSL < WithParamsDSL
|
742
|
+
|
743
|
+
constructor [ :process, :key ], :opts
|
744
|
+
|
745
|
+
def init
|
746
|
+
@flag = new_key()
|
747
|
+
@iter = new_key()
|
748
|
+
@array = new_key()
|
749
|
+
@args = [ @iter, @array ]
|
750
|
+
end
|
751
|
+
|
752
|
+
def return_on(cond, value = nil)
|
753
|
+
cond = XPValue.flatten(cond)
|
754
|
+
value = XPValue.flatten(value)
|
755
|
+
push(ReturnLoopDSL.new(@process, key, @flag, cond, value))
|
756
|
+
end
|
757
|
+
|
758
|
+
def as_run
|
759
|
+
return LoopRun.new(key, @flag, @iter, @array, __as_run__, @opts)
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
class SwitchDSL < DSL
|
764
|
+
|
765
|
+
constructor [ :process, :key ], :cases => [], :default => nil
|
766
|
+
|
767
|
+
def on(cond, &block)
|
768
|
+
body = SequenceDSL.new(@process, new_key).parse(&block)
|
769
|
+
@cases.push([ XPValue.flatten(cond), body ])
|
770
|
+
end
|
771
|
+
|
772
|
+
def default(&block)
|
773
|
+
@default = SequenceDSL.new(@process, new_key).parse(&block)
|
774
|
+
end
|
775
|
+
|
776
|
+
def _cases_as_runs
|
777
|
+
return @cases.map { |c, b| [ c, b.as_run ] }
|
778
|
+
end
|
779
|
+
|
780
|
+
def _default_as_run
|
781
|
+
return nil if @default.nil?
|
782
|
+
return @default.as_run
|
783
|
+
end
|
784
|
+
|
785
|
+
def as_run
|
786
|
+
return SwitchRun.new(key, _cases_as_runs, _default_as_run)
|
787
|
+
end
|
788
|
+
end
|
789
|
+
|
790
|
+
class MultiDSL < SwitchDSL
|
791
|
+
|
792
|
+
def as_run
|
793
|
+
return MultiRun.new(key, _cases_as_runs, _default_as_run)
|
794
|
+
end
|
795
|
+
end
|
796
|
+
|
797
|
+
class BoundSwitchDSL < SwitchDSL
|
798
|
+
|
799
|
+
constructor [ :process, :key ], :cond
|
800
|
+
|
801
|
+
def as_run
|
802
|
+
return BoundSwitchRun.new(key, _cases_as_runs, _default_as_run, @cond)
|
803
|
+
end
|
804
|
+
end
|
805
|
+
|
806
|
+
class MacroDSL
|
807
|
+
|
808
|
+
# stores a block for workflow construction later
|
809
|
+
|
810
|
+
attr_reader :block
|
811
|
+
|
812
|
+
constructor :name, :engine, :block
|
813
|
+
|
814
|
+
end
|
815
|
+
|
816
|
+
end
|