@platforma-sdk/workflow-tengo 2.9.6 → 2.9.7
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.
- package/dist/tengo/lib/assets.lib.tengo +52 -52
- package/dist/tengo/lib/assets.swinfo.lib.tengo +45 -45
- package/dist/tengo/lib/constants.lib.tengo +32 -32
- package/dist/tengo/lib/exec.R.internal.lib.tengo +29 -29
- package/dist/tengo/lib/exec.R.lib.tengo +166 -166
- package/dist/tengo/lib/exec.constants.lib.tengo +4 -4
- package/dist/tengo/lib/exec.descriptor.lib.tengo +31 -31
- package/dist/tengo/lib/exec.internal.lib.tengo +297 -297
- package/dist/tengo/lib/exec.lib.tengo +815 -815
- package/dist/tengo/lib/exec.monetization.lib.tengo +130 -130
- package/dist/tengo/lib/exec.package.lib.tengo +212 -212
- package/dist/tengo/lib/exec.python.internal.lib.tengo +6 -6
- package/dist/tengo/lib/exec.python.lib.tengo +146 -146
- package/dist/tengo/lib/exec.runcmd.lib.tengo +371 -371
- package/dist/tengo/lib/exec.runenv.lib.tengo +92 -92
- package/dist/tengo/lib/exec.stream.lib.tengo +40 -40
- package/dist/tengo/lib/file.internal.lib.tengo +77 -77
- package/dist/tengo/lib/file.lib.tengo +57 -57
- package/dist/tengo/lib/ll.lib.tengo +244 -244
- package/dist/tengo/lib/maps.lib.tengo +152 -152
- package/dist/tengo/lib/objects.lib.tengo +13 -13
- package/dist/tengo/lib/oop.lib.tengo +19 -19
- package/dist/tengo/lib/path.lib.tengo +125 -125
- package/dist/tengo/lib/pframes.constants.lib.tengo +28 -28
- package/dist/tengo/lib/pframes.export-pcolumn.lib.tengo +33 -33
- package/dist/tengo/lib/pframes.lib.tengo +43 -43
- package/dist/tengo/lib/pframes.ll.lib.tengo +72 -72
- package/dist/tengo/lib/pframes.pcolumn.lib.tengo +49 -49
- package/dist/tengo/lib/pframes.spec.lib.tengo +96 -96
- package/dist/tengo/lib/pframes.util.lib.tengo +288 -288
- package/dist/tengo/lib/pframes.xsv.lib.tengo +272 -272
- package/dist/tengo/lib/render.lib.tengo +75 -75
- package/dist/tengo/lib/sets.lib.tengo +68 -68
- package/dist/tengo/lib/slices.lib.tengo +258 -155
- package/dist/tengo/lib/smart.lib.tengo +1069 -1069
- package/dist/tengo/lib/test.lib.tengo +161 -161
- package/dist/tengo/lib/tpl.lib.tengo +515 -515
- package/dist/tengo/lib/tpl.state-await.lib.tengo +240 -240
- package/dist/tengo/lib/tpl.util.lib.tengo +9 -9
- package/dist/tengo/lib/validation.lib.tengo +378 -378
- package/dist/tengo/lib/workdir.lib.tengo +331 -331
- package/dist/tengo/lib/workdir.proc.lib.tengo +144 -144
- package/dist/tengo/lib/workdir.save.lib.tengo +130 -130
- package/dist/tengo/lib/workflow.bobject.lib.tengo +26 -26
- package/dist/tengo/lib/workflow.bquery.lib.tengo +165 -165
- package/dist/tengo/lib/workflow.constants.lib.tengo +2 -2
- package/dist/tengo/lib/workflow.context.lib.tengo +32 -32
- package/dist/tengo/lib/workflow.lib.tengo +206 -206
- package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
- package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
- package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.aggregate.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.map-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
- package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
- package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* A builder for executing commands.
|
|
3
|
+
*/
|
|
4
4
|
|
|
5
5
|
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
6
6
|
assets := import("@platforma-sdk/workflow-tengo:assets")
|
|
@@ -24,820 +24,820 @@ _MEDIUM_QUEUE := "medium"
|
|
|
24
24
|
_LIGHT_QUEUE := "light"
|
|
25
25
|
_UI_TASKS_QUEUE := "ui-tasks"
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new builder for constructing and executing commands.
|
|
29
|
+
*
|
|
30
|
+
* @return builder - a new builder instance.
|
|
31
|
+
*/
|
|
32
32
|
builder := func() {
|
|
33
|
-
self := undefined
|
|
34
|
-
|
|
35
|
-
soft := undefined
|
|
36
|
-
cmd := undefined
|
|
37
|
-
args := [] // list of strings
|
|
38
|
-
argsTyped := [] // list of {type: expression|string, value: string}
|
|
39
|
-
typedArgSet := false
|
|
40
|
-
typedEnvSet := false
|
|
41
|
-
envs := {} // map of names to values-strings
|
|
42
|
-
envsTyped := {} // map of names to {type: expression|string, value: string}
|
|
43
|
-
secrets := {} // { "env_name": "{secrets.secret_name}", ... }
|
|
44
|
-
|
|
45
|
-
entrypointSet := false
|
|
46
|
-
|
|
47
|
-
assertEntrypointNotSet := func() {
|
|
48
|
-
ll.assert(!entrypointSet,
|
|
49
|
-
"either a command with arguments or a software were already set.")
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
queue := _HEAVY_QUEUE
|
|
53
|
-
cache := 0
|
|
54
|
-
nErrorLines := 200
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
filesToAdd := {}
|
|
58
|
-
|
|
59
|
-
filesToWrite := {}
|
|
60
|
-
|
|
61
|
-
dirsToCreate := {}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
filesToSave := {}
|
|
65
|
-
|
|
66
|
-
filesContentToSave := {}
|
|
67
|
-
|
|
68
|
-
fileSetsToSave := {}
|
|
69
|
-
|
|
70
|
-
fileSetsContentToSave := {}
|
|
71
|
-
|
|
72
|
-
filesToStream := {}
|
|
73
|
-
|
|
74
|
-
wdProcessors := {}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
assetInfos := {}
|
|
78
|
-
assetDescriptors := {}
|
|
79
|
-
assetRules := {}
|
|
80
|
-
assetCache := {}
|
|
81
|
-
|
|
82
|
-
mnz := monetization.init()
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
_getMnzOption := func(...opts) {
|
|
86
|
-
if slices.length(opts) < 1 {
|
|
87
|
-
return undefined
|
|
88
|
-
}
|
|
89
|
-
opt := opts[0]["mnz"]
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return is_undefined(opt) ? undefined : opt
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
_addMnzOption := func(fileName, ...opts) {
|
|
97
|
-
opt := _getMnzOption(opts...)
|
|
98
|
-
if !is_undefined(opt) {
|
|
99
|
-
monetization.addFileParams(mnz, fileName, opt)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
stdout := "stdout.txt"
|
|
104
|
-
stderr := "stderr.txt"
|
|
105
|
-
|
|
106
|
-
stdoutToValue := false
|
|
107
|
-
stderrToValue := false
|
|
108
|
-
stderrToStdout := false
|
|
109
|
-
|
|
110
|
-
self = ll.toStrict({
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
cmd: func(commandName) {
|
|
117
|
-
assertEntrypointNotSet()
|
|
118
|
-
|
|
119
|
-
cmd = commandName
|
|
120
|
-
entrypointSet = true
|
|
121
|
-
return self
|
|
122
|
-
},
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
software: func(sw) {
|
|
130
|
-
assertEntrypointNotSet()
|
|
131
|
-
ll.assert(assets.isSoftwareInfo(sw),
|
|
132
|
-
"exec.builder.software: <software> parameter is not a software info. Provide the value obtained from assets.importSoftware() here"
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
soft = sw
|
|
136
|
-
entrypointSet = true
|
|
137
|
-
return self
|
|
138
|
-
},
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
arg: func(arg) {
|
|
146
|
-
ll.assert(is_string(arg), "exec.arg(): argument must be a string, got: %v", arg)
|
|
147
|
-
args = append(args, arg)
|
|
148
|
-
argsTyped = append(argsTyped, {
|
|
149
|
-
type: execConstants.ARG_TYPE_STRING,
|
|
150
|
-
value: arg
|
|
151
|
-
})
|
|
152
|
-
return self
|
|
153
|
-
},
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
argWithVar: func(arg) {
|
|
161
|
-
ll.assert(is_string(arg), "exec.argWithVar(): argument with var must be a string, got: %v", arg)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
t := desc.canBackendUseExpressions() ? execConstants.ARG_TYPE_EXPRESSION : execConstants.ARG_TYPE_VAR
|
|
165
|
-
argsTyped = append(argsTyped, {
|
|
166
|
-
type: t,
|
|
167
|
-
value: arg
|
|
168
|
-
})
|
|
169
|
-
typedArgSet = true
|
|
170
|
-
|
|
171
|
-
return self
|
|
172
|
-
},
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
env: func(name, value) {
|
|
181
|
-
validation.assertJsonSchema([name, value], ["string"])
|
|
182
|
-
envs[name] = value
|
|
183
|
-
envsTyped[name] = {
|
|
184
|
-
type: execConstants.ARG_TYPE_STRING,
|
|
185
|
-
value: value
|
|
186
|
-
}
|
|
187
|
-
return self
|
|
188
|
-
},
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
envWithVar: func(name, value) {
|
|
197
|
-
validation.assertJsonSchema([name, value], ["string"])
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
t := desc.canBackendUseExpressions() ? execConstants.ARG_TYPE_EXPRESSION : execConstants.ARG_TYPE_VAR
|
|
201
|
-
envsTyped[name] = {
|
|
202
|
-
type: t,
|
|
203
|
-
value: value
|
|
204
|
-
}
|
|
205
|
-
typedEnvSet = true
|
|
206
|
-
|
|
207
|
-
return self
|
|
208
|
-
},
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
envMap: func(envMap) {
|
|
216
|
-
enum.each(envMap, self.env)
|
|
217
|
-
return self
|
|
218
|
-
},
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
secret: func(secretName, envName) {
|
|
227
|
-
validation.assertJsonSchema([secretName, envName], ["string"])
|
|
228
|
-
secrets[envName] = "{secrets."+secretName+"}"
|
|
229
|
-
return self
|
|
230
|
-
},
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
inHeavyQueue: func() {
|
|
236
|
-
queue = _HEAVY_QUEUE
|
|
237
|
-
return self
|
|
238
|
-
},
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
inMediumQueue: func() {
|
|
244
|
-
queue = _MEDIUM_QUEUE
|
|
245
|
-
return self
|
|
246
|
-
},
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
inLightQueue: func() {
|
|
252
|
-
queue = _LIGHT_QUEUE
|
|
253
|
-
return self
|
|
254
|
-
},
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
inUiQueue: func() {
|
|
260
|
-
queue = _UI_TASKS_QUEUE
|
|
261
|
-
return self
|
|
262
|
-
},
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
cache: func(time) {
|
|
271
|
-
ll.assert(
|
|
272
|
-
is_int(time),
|
|
273
|
-
"cache time must be an integer. " +
|
|
274
|
-
"Did you forget to import a standard tengo library 'times'?")
|
|
275
|
-
cache = time
|
|
276
|
-
return self
|
|
277
|
-
},
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
cacheMillis: func(millis) {
|
|
285
|
-
ll.assert(is_int(millis) && millis > 0, "cache time must be a number of milliseconds")
|
|
286
|
-
cache = millis * times.millisecond
|
|
287
|
-
return self
|
|
288
|
-
},
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
cacheSeconds: func(seconds) {
|
|
296
|
-
ll.assert(is_int(seconds) && seconds > 0, "cache time must be a number of seconds")
|
|
297
|
-
cache = seconds * times.second
|
|
298
|
-
return self
|
|
299
|
-
},
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
cacheMinutes: func(minutes) {
|
|
307
|
-
ll.assert(is_int(minutes) && minutes > 0, "cache time must be a number of minutes")
|
|
308
|
-
cache = minutes * times.minute
|
|
309
|
-
return self
|
|
310
|
-
},
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
cacheHours: func(hours) {
|
|
318
|
-
ll.assert(is_int(hours) && hours > 0, "cache time must be a number of hours")
|
|
319
|
-
cache = hours * times.hour
|
|
320
|
-
return self
|
|
321
|
-
},
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
cacheDays: func(days) {
|
|
329
|
-
ll.assert(is_int(days) && days > 0, "cache time must be a number of days")
|
|
330
|
-
cache = days * times.hour * 24
|
|
331
|
-
return self
|
|
332
|
-
},
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
nErrorLines: func(lines) {
|
|
340
|
-
ll.assert(
|
|
341
|
-
is_int(lines) && lines >= 0,
|
|
342
|
-
"lines must be integer")
|
|
343
|
-
|
|
344
|
-
nErrorLines = lines
|
|
345
|
-
return self
|
|
346
|
-
},
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
addAsset: func(asset, destinationDir, ...pathsInArchive) {
|
|
357
|
-
if (len(pathsInArchive) == 1 && is_array(pathsInArchive[0])) {
|
|
358
|
-
|
|
359
|
-
pathsInArchive = pathsInArchive[0]
|
|
360
|
-
}
|
|
361
|
-
if len(pathsInArchive) == 0 {
|
|
362
|
-
|
|
363
|
-
pathsInArchive = []
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
ll.assert(assets.isAssetInfo(asset),
|
|
367
|
-
"exec.builder.addAsset: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
368
|
-
validation.assertJsonSchema(destinationDir, "string", "exec.builder.addAsset: <destinationDir> is not a string. It must be a path inside working directory")
|
|
369
|
-
validation.assertJsonSchema(pathsInArchive, ["string"], "exec.builder.addAsset: <pathsInArchive> must contain list of strings with paths inside archive")
|
|
370
|
-
|
|
371
|
-
assetIdKey := ll.idToString(asset._id)
|
|
372
|
-
if is_undefined(assetRules[assetIdKey]) {
|
|
373
|
-
assetInfos[assetIdKey] = asset.resource
|
|
374
|
-
assetDescriptors[assetIdKey] = ll.fromStrict(asset.descriptor)
|
|
375
|
-
assetRules[assetIdKey] = {}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if len(pathsInArchive) == 0 || is_undefined(assetRules[assetIdKey][destinationDir]) {
|
|
379
|
-
assetRules[assetIdKey][destinationDir] = []
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
if (len(pathsInArchive) > 0) {
|
|
383
|
-
assetRules[assetIdKey][destinationDir] = append(assetRules[assetIdKey][destinationDir], pathsInArchive...)
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
return self
|
|
387
|
-
},
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
cacheAssetMillis: func (asset, millis) {
|
|
394
|
-
ll.assert(assets.isAssetInfo(asset),
|
|
395
|
-
"exec.builder.cacheAssetMillis: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
396
|
-
ll.assert(is_int(millis),
|
|
397
|
-
"exec.builder.cacheAssetMillis: asset cache time must be a number of milliseconds.")
|
|
398
|
-
|
|
399
|
-
assetIdKey := ll.idToString(asset._id)
|
|
400
|
-
assetCache[assetIdKey] = millis * times.millisecond
|
|
401
|
-
|
|
402
|
-
return self
|
|
403
|
-
},
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
cacheAssetSeconds: func (asset, seconds) {
|
|
410
|
-
ll.assert(assets.isAssetInfo(asset),
|
|
411
|
-
"exec.builder.cacheAssetSeconds: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
412
|
-
ll.assert(is_int(seconds),
|
|
413
|
-
"exec.builder.cacheAssetSeconds: asset cache time must be a number of seconds.")
|
|
414
|
-
|
|
415
|
-
assetIdKey := ll.idToString(asset._id)
|
|
416
|
-
assetCache[assetIdKey] = seconds * times.second
|
|
417
|
-
|
|
418
|
-
return self
|
|
419
|
-
},
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
cacheAssetMinutes: func (asset, minutes) {
|
|
426
|
-
ll.assert(assets.isAssetInfo(asset),
|
|
427
|
-
"exec.builder.cacheAssetMinutes: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
428
|
-
ll.assert(is_int(minutes),
|
|
429
|
-
"exec.builder.cacheAssetMinutes: asset cache time must be a number of minutes.")
|
|
430
|
-
|
|
431
|
-
assetIdKey := ll.idToString(asset._id)
|
|
432
|
-
assetCache[assetIdKey] = minutes * times.minute
|
|
433
|
-
|
|
434
|
-
return self
|
|
435
|
-
},
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
cacheAssetHours: func (asset, hours) {
|
|
442
|
-
ll.assert(assets.isAssetInfo(asset),
|
|
443
|
-
"exec.builder.cacheAssetHours: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
444
|
-
ll.assert(is_int(hours),
|
|
445
|
-
"exec.builder.cacheAssetHours: asset cache time must be a number of hours.")
|
|
446
|
-
|
|
447
|
-
assetIdKey := ll.idToString(asset._id)
|
|
448
|
-
assetCache[assetIdKey] = hours * times.hour
|
|
449
|
-
|
|
450
|
-
return self
|
|
451
|
-
},
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
cacheAssetDays: func (asset, days) {
|
|
458
|
-
ll.assert(assets.isAssetInfo(asset),
|
|
459
|
-
"exec.builder.cacheAssetHours: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
460
|
-
ll.assert(is_int(days),
|
|
461
|
-
"exec.builder.cacheAssetHours: asset cache time must be a number of days.")
|
|
462
|
-
|
|
463
|
-
assetIdKey := ll.idToString(asset._id)
|
|
464
|
-
assetCache[assetIdKey] = days * 24 * times.hour
|
|
465
|
-
|
|
466
|
-
return self
|
|
467
|
-
},
|
|
468
|
-
|
|
469
|
-
enableMnz: func(productName) {
|
|
470
|
-
monetization.enable(mnz, productName)
|
|
471
|
-
return self
|
|
472
|
-
},
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
addFile: func(fileName, file, ...opts) {
|
|
481
|
-
ll.assert(is_string(fileName), "exec.builder().addFile: fileName must be a string")
|
|
482
|
-
ll.assert(smart.isReference(file), "exec.builder().addFile: file must be a reference")
|
|
483
|
-
|
|
484
|
-
fileName = path.canonize(fileName)
|
|
485
|
-
filesToAdd[fileName] = file
|
|
486
|
-
_addMnzOption(fileName, opts...)
|
|
487
|
-
return self
|
|
488
|
-
},
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
addFiles: func(filesMap, ...opts) {
|
|
496
|
-
ll.assert(ll.isMap(filesMap), "exec.builder().addFiles: filesMap must be map of file names to file resources")
|
|
497
|
-
for fileName, file in filesMap {
|
|
498
|
-
self.addFile(fileName, file, opts...)
|
|
499
|
-
}
|
|
500
|
-
return self
|
|
501
|
-
},
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
writeFile: func(fileName, data, ...opts) {
|
|
511
|
-
validation.assertJsonSchema(data, ["or",
|
|
512
|
-
"string",
|
|
513
|
-
"bytes",
|
|
514
|
-
validation.reference])
|
|
515
|
-
|
|
516
|
-
fileName = path.canonize(fileName)
|
|
517
|
-
|
|
518
|
-
filesToWrite[fileName] = data
|
|
519
|
-
_addMnzOption(fileName, opts...)
|
|
520
|
-
|
|
521
|
-
return self
|
|
522
|
-
},
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
mkDir: func(dir) {
|
|
530
|
-
dir = path.canonize(dir)
|
|
531
|
-
dirsToCreate = sets.add(dirsToCreate, dir)
|
|
532
|
-
return self
|
|
533
|
-
},
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
saveFile: func(fileName) {
|
|
541
|
-
fileName = path.canonize(fileName)
|
|
542
|
-
sets.add(filesToSave, fileName)
|
|
543
|
-
return self
|
|
544
|
-
},
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
saveFileContent: func(fileName) {
|
|
552
|
-
fileName = path.canonize(fileName)
|
|
553
|
-
sets.add(filesContentToSave, fileName)
|
|
554
|
-
return self
|
|
555
|
-
},
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
saveFileSet: func(name, regex) {
|
|
564
|
-
fileSetsToSave[name] = regex
|
|
565
|
-
return self
|
|
566
|
-
},
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
processWorkdir: func(name, tpl, tplArgs) {
|
|
572
|
-
wdProcessors[name] = {
|
|
573
|
-
tpl: tpl,
|
|
574
|
-
tplArgs: tplArgs
|
|
575
|
-
}
|
|
576
|
-
return self
|
|
577
|
-
},
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
saveFileSetContent: func(name, regex) {
|
|
586
|
-
fileSetsContentToSave[name] = regex
|
|
587
|
-
return self
|
|
588
|
-
},
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
streamFile: func(fileName) {
|
|
596
|
-
fileName = path.canonize(fileName)
|
|
597
|
-
sets.add(filesToStream, fileName)
|
|
598
|
-
|
|
599
|
-
return self
|
|
600
|
-
},
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
stdoutFileName: func(fileName) {
|
|
606
|
-
fileName = path.canonize(fileName)
|
|
607
|
-
stdout = fileName
|
|
608
|
-
return self
|
|
609
|
-
},
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
stderrFileName: func(fileName) {
|
|
615
|
-
fileName = path.canonize(fileName)
|
|
616
|
-
stderr = fileName
|
|
617
|
-
return self
|
|
618
|
-
},
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
saveStdoutContent: func() {
|
|
624
|
-
stdoutToValue = true
|
|
625
|
-
return self
|
|
626
|
-
},
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
saveStderrContent: func() {
|
|
632
|
-
stderrToValue = true
|
|
633
|
-
return self
|
|
634
|
-
},
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
printErrStreamToStdout: func() {
|
|
640
|
-
stderrToStdout = true
|
|
641
|
-
return self
|
|
642
|
-
},
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
run: func() {
|
|
650
|
-
if stderrToStdout {
|
|
651
|
-
stderr = stdout
|
|
652
|
-
}
|
|
653
|
-
sets.add(filesToStream, stdout)
|
|
654
|
-
sets.add(filesToStream, stderr)
|
|
655
|
-
sets.add(filesToSave, stdout)
|
|
656
|
-
sets.add(filesToSave, stderr)
|
|
657
|
-
if stdoutToValue {
|
|
658
|
-
sets.add(filesContentToSave, stdout)
|
|
659
|
-
}
|
|
660
|
-
if stderrToValue {
|
|
661
|
-
sets.add(filesContentToSave, stderr)
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
filesToWriteRefs := maps.mapValues(filesToWrite, func(v) {
|
|
668
|
-
if smart.isReference(v) { return v }
|
|
669
|
-
return smart.createValueResource(constants.RTYPE_BINARY_VALUE, v)
|
|
670
|
-
})
|
|
671
|
-
|
|
672
|
-
ll.assert(entrypointSet,
|
|
673
|
-
"incomplete command: cmd() or software() must be provided to exec.builder")
|
|
674
|
-
|
|
675
|
-
runOptions := {
|
|
676
|
-
cmd: cmd,
|
|
677
|
-
args: args,
|
|
678
|
-
envs: envs,
|
|
679
|
-
secrets: secrets,
|
|
680
|
-
queue: queue,
|
|
681
|
-
stdout: stdout,
|
|
682
|
-
stderr: stderr,
|
|
683
|
-
nErrorLines: nErrorLines
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
execInputs := {
|
|
687
|
-
filesToAdd: smart.createMapResource(filesToAdd),
|
|
688
|
-
filesToWrite: smart.createMapResource(filesToWriteRefs),
|
|
689
|
-
dirsToCreate: slices.fromSet(dirsToCreate),
|
|
690
|
-
runOptions: runOptions,
|
|
691
|
-
filesToSave: slices.fromSet(filesToSave),
|
|
692
|
-
filesContentToSave: slices.fromSet(filesContentToSave),
|
|
693
|
-
fileSetsToSave: fileSetsToSave,
|
|
694
|
-
fileSetsContentToSave: fileSetsContentToSave,
|
|
695
|
-
filesToStream: slices.fromSet(filesToStream),
|
|
696
|
-
wdProcessors: wdProcessors,
|
|
697
|
-
assets: smart.createMapResource(assetInfos),
|
|
698
|
-
assetDescriptors: assetDescriptors,
|
|
699
|
-
assetRules: assetRules,
|
|
700
|
-
assetCache: assetCache
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
if monetization.shouldRun(mnz) {
|
|
707
|
-
execInputs.runOptions.monetization = monetization.toJson(mnz)
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
if typedArgSet || typedEnvSet {
|
|
713
|
-
execInputs.runOptions.argsTyped = argsTyped
|
|
714
|
-
execInputs.runOptions.envsTyped = envsTyped
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
if !is_undefined(soft) {
|
|
718
|
-
execInputs.softwareInfo = soft.resource
|
|
719
|
-
execInputs.runOptions.software = {
|
|
720
|
-
name: soft.name,
|
|
721
|
-
version: soft.version,
|
|
722
|
-
descriptor: ll.fromStrict(soft.descriptor)
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
tpl := render.create(assets.importTemplate("@platforma-sdk/workflow-tengo:exec.exec"), execInputs)
|
|
727
|
-
|
|
728
|
-
self := undefined
|
|
729
|
-
self = ll.toStrict(oop.inherit(tpl, {
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
getFile: func(fileName) {
|
|
737
|
-
return tpl.output("files", cache).getFutureInputField(fileName)
|
|
738
|
-
},
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
getFileContent: func(fileName) {
|
|
747
|
-
return tpl.output("filesContent", cache).getFutureInputField(fileName)
|
|
748
|
-
},
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
getFileStream: func(fileName) {
|
|
757
|
-
return tpl.output("fileStreams", cache).getFutureInputField(fileName, true)
|
|
758
|
-
},
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
getFileSet: func(fileSetName) {
|
|
767
|
-
return tpl.output("fileSets", cache).getFutureInputField(fileSetName)
|
|
768
|
-
},
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
getFileSetContent: func(fileSetName) {
|
|
777
|
-
return tpl.output("fileSetsContent", cache).getFutureInputField(fileSetName)
|
|
778
|
-
},
|
|
779
|
-
|
|
780
|
-
getProcessorResult: func(procName) {
|
|
781
|
-
return tpl.output("wdProcessors", cache).getFutureInputField(procName)
|
|
782
|
-
},
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
getStdoutStream: func() {
|
|
788
|
-
return self.getFileStream(stdout)
|
|
789
|
-
},
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
getStderrStream: func() {
|
|
795
|
-
return self.getFileStream(stderr)
|
|
796
|
-
},
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
getStdoutFile: func() {
|
|
802
|
-
return self.getFile(stdout)
|
|
803
|
-
},
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
getStderrFile: func() {
|
|
809
|
-
return self.getFile(stderr)
|
|
810
|
-
},
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
getStdoutFileContent: func() {
|
|
816
|
-
if stdoutToValue {
|
|
817
|
-
return self.getFileContent(stdout)
|
|
818
|
-
}
|
|
819
|
-
ll.panic("stdout was not saved as a content")
|
|
820
|
-
},
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
getStderrFileContent: func() {
|
|
826
|
-
if stderrToValue {
|
|
827
|
-
return self.getFileContent(stderr)
|
|
828
|
-
}
|
|
829
|
-
ll.panic("stderr was not saved as a content")
|
|
830
|
-
}
|
|
831
|
-
}))
|
|
832
|
-
|
|
833
|
-
return self
|
|
834
|
-
}
|
|
835
|
-
})
|
|
836
|
-
|
|
837
|
-
return self
|
|
33
|
+
self := undefined
|
|
34
|
+
|
|
35
|
+
soft := undefined
|
|
36
|
+
cmd := undefined
|
|
37
|
+
args := [] // list of strings
|
|
38
|
+
argsTyped := [] // list of {type: expression|string, value: string}
|
|
39
|
+
typedArgSet := false
|
|
40
|
+
typedEnvSet := false
|
|
41
|
+
envs := {} // map of names to values-strings
|
|
42
|
+
envsTyped := {} // map of names to {type: expression|string, value: string}
|
|
43
|
+
secrets := {} // { "env_name": "{secrets.secret_name}", ... }
|
|
44
|
+
|
|
45
|
+
entrypointSet := false
|
|
46
|
+
|
|
47
|
+
assertEntrypointNotSet := func() {
|
|
48
|
+
ll.assert(!entrypointSet,
|
|
49
|
+
"either a command with arguments or a software were already set.")
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
queue := _HEAVY_QUEUE
|
|
53
|
+
cache := 0
|
|
54
|
+
nErrorLines := 200
|
|
55
|
+
|
|
56
|
+
// files to be added in workdir
|
|
57
|
+
filesToAdd := {}
|
|
58
|
+
// files to be created in the workdir with the content from resources
|
|
59
|
+
filesToWrite := {}
|
|
60
|
+
// directories to create in the workdir
|
|
61
|
+
dirsToCreate := {}
|
|
62
|
+
|
|
63
|
+
// files to save from the workdir
|
|
64
|
+
filesToSave := {}
|
|
65
|
+
// files which content to save from the workdir
|
|
66
|
+
filesContentToSave := {}
|
|
67
|
+
// file sets to save by regex
|
|
68
|
+
fileSetsToSave := {}
|
|
69
|
+
// file sets to save by regex (save file content)
|
|
70
|
+
fileSetsContentToSave := {}
|
|
71
|
+
// files to stream from the workdir
|
|
72
|
+
filesToStream := {}
|
|
73
|
+
// workdir processors
|
|
74
|
+
wdProcessors := {}
|
|
75
|
+
|
|
76
|
+
// assets to be extracted into workdir before execution
|
|
77
|
+
assetInfos := {}
|
|
78
|
+
assetDescriptors := {}
|
|
79
|
+
assetRules := {}
|
|
80
|
+
assetCache := {}
|
|
81
|
+
|
|
82
|
+
mnz := monetization.init()
|
|
83
|
+
|
|
84
|
+
/** Gets mnz key from opts or undefined. */
|
|
85
|
+
_getMnzOption := func(...opts) {
|
|
86
|
+
if slices.length(opts) < 1 {
|
|
87
|
+
return undefined
|
|
88
|
+
}
|
|
89
|
+
opt := opts[0]["mnz"]
|
|
90
|
+
|
|
91
|
+
// readability if: we can return undefined here
|
|
92
|
+
return is_undefined(opt) ? undefined : opt
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Adds a monetization option if it's defined into mnzFileParams. */
|
|
96
|
+
_addMnzOption := func(fileName, ...opts) {
|
|
97
|
+
opt := _getMnzOption(opts...)
|
|
98
|
+
if !is_undefined(opt) {
|
|
99
|
+
monetization.addFileParams(mnz, fileName, opt)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
stdout := "stdout.txt"
|
|
104
|
+
stderr := "stderr.txt"
|
|
105
|
+
|
|
106
|
+
stdoutToValue := false
|
|
107
|
+
stderrToValue := false
|
|
108
|
+
stderrToStdout := false
|
|
109
|
+
|
|
110
|
+
self = ll.toStrict({
|
|
111
|
+
/**
|
|
112
|
+
* Sets the command to be executed, e.g. /usr/bin/env or sh.
|
|
113
|
+
*
|
|
114
|
+
* @param commandName: string - the name of the command.
|
|
115
|
+
*/
|
|
116
|
+
cmd: func(commandName) {
|
|
117
|
+
assertEntrypointNotSet()
|
|
118
|
+
|
|
119
|
+
cmd = commandName
|
|
120
|
+
entrypointSet = true
|
|
121
|
+
return self
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Sets the software to be executed.
|
|
126
|
+
*
|
|
127
|
+
* @param software: softwareInfo - the software to execute.
|
|
128
|
+
*/
|
|
129
|
+
software: func(sw) {
|
|
130
|
+
assertEntrypointNotSet()
|
|
131
|
+
ll.assert(assets.isSoftwareInfo(sw),
|
|
132
|
+
"exec.builder.software: <software> parameter is not a software info. Provide the value obtained from assets.importSoftware() here"
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
soft = sw
|
|
136
|
+
entrypointSet = true
|
|
137
|
+
return self
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Adds an argument to the command.
|
|
142
|
+
*
|
|
143
|
+
* @param arg: string - the argument to add.
|
|
144
|
+
*/
|
|
145
|
+
arg: func(arg) {
|
|
146
|
+
ll.assert(is_string(arg), "exec.arg(): argument must be a string, got: %v", arg)
|
|
147
|
+
args = append(args, arg)
|
|
148
|
+
argsTyped = append(argsTyped, {
|
|
149
|
+
type: execConstants.ARG_TYPE_STRING,
|
|
150
|
+
value: arg
|
|
151
|
+
})
|
|
152
|
+
return self
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Adds an argument that will be evaluated as expression in the command.
|
|
157
|
+
*
|
|
158
|
+
* @param arg: string - e.g. -Xms{system.memory_mb * 80 / 100}m
|
|
159
|
+
*/
|
|
160
|
+
argWithVar: func(arg) {
|
|
161
|
+
ll.assert(is_string(arg), "exec.argWithVar(): argument with var must be a string, got: %v", arg)
|
|
162
|
+
|
|
163
|
+
// deprecated: remove ARG_TYPE_VAR and this check after 15 Mar 2025
|
|
164
|
+
t := desc.canBackendUseExpressions() ? execConstants.ARG_TYPE_EXPRESSION : execConstants.ARG_TYPE_VAR
|
|
165
|
+
argsTyped = append(argsTyped, {
|
|
166
|
+
type: t,
|
|
167
|
+
value: arg
|
|
168
|
+
})
|
|
169
|
+
typedArgSet = true
|
|
170
|
+
|
|
171
|
+
return self
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Sets an environment variable.
|
|
176
|
+
*
|
|
177
|
+
* @param name: string - the name of the environment variable.
|
|
178
|
+
* @param value: string - the value of the environment variable.
|
|
179
|
+
*/
|
|
180
|
+
env: func(name, value) {
|
|
181
|
+
validation.assertJsonSchema([name, value], ["string"])
|
|
182
|
+
envs[name] = value
|
|
183
|
+
envsTyped[name] = {
|
|
184
|
+
type: execConstants.ARG_TYPE_STRING,
|
|
185
|
+
value: value
|
|
186
|
+
}
|
|
187
|
+
return self
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Sets an environment variable.
|
|
192
|
+
*
|
|
193
|
+
* @param name: string - the name of the environment variable.
|
|
194
|
+
* @param value: string - the value of the environment variable.
|
|
195
|
+
*/
|
|
196
|
+
envWithVar: func(name, value) {
|
|
197
|
+
validation.assertJsonSchema([name, value], ["string"])
|
|
198
|
+
|
|
199
|
+
// deprecated: remove ARG_TYPE_VAR and this check after 15 Mar 2025
|
|
200
|
+
t := desc.canBackendUseExpressions() ? execConstants.ARG_TYPE_EXPRESSION : execConstants.ARG_TYPE_VAR
|
|
201
|
+
envsTyped[name] = {
|
|
202
|
+
type: t,
|
|
203
|
+
value: value
|
|
204
|
+
}
|
|
205
|
+
typedEnvSet = true
|
|
206
|
+
|
|
207
|
+
return self
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Sets multiple environment variables.
|
|
212
|
+
*
|
|
213
|
+
* @param envMap: map[string]string - a map of environment variables.
|
|
214
|
+
*/
|
|
215
|
+
envMap: func(envMap) {
|
|
216
|
+
enum.each(envMap, self.env)
|
|
217
|
+
return self
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Set environment variable to value of given secret.
|
|
222
|
+
*
|
|
223
|
+
* @param secretName: string - name of secret to pass as environment variable.
|
|
224
|
+
* @param envName: string - name of environment variable to set with value of secret.
|
|
225
|
+
*/
|
|
226
|
+
secret: func(secretName, envName) {
|
|
227
|
+
validation.assertJsonSchema([secretName, envName], ["string"])
|
|
228
|
+
secrets[envName] = "{secrets."+secretName+"}"
|
|
229
|
+
return self
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Execute command in the 'heavy' queue.
|
|
234
|
+
*/
|
|
235
|
+
inHeavyQueue: func() {
|
|
236
|
+
queue = _HEAVY_QUEUE
|
|
237
|
+
return self
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Execute command in the 'medium' queue.
|
|
242
|
+
*/
|
|
243
|
+
inMediumQueue: func() {
|
|
244
|
+
queue = _MEDIUM_QUEUE
|
|
245
|
+
return self
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Execute command in the 'light' queue.
|
|
250
|
+
*/
|
|
251
|
+
inLightQueue: func() {
|
|
252
|
+
queue = _LIGHT_QUEUE
|
|
253
|
+
return self
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Execute command in the 'ui-tasks' queue.
|
|
258
|
+
*/
|
|
259
|
+
inUiQueue: func() {
|
|
260
|
+
queue = _UI_TASKS_QUEUE
|
|
261
|
+
return self
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Use cacheMillis, cacheSeconds, cacheMinutes, cacheHours and cacheDays to not make hidden mistakes in cache time ranges.
|
|
266
|
+
* Sets the cache time.
|
|
267
|
+
*
|
|
268
|
+
* @param time: duration - the cache time from 'times' library.
|
|
269
|
+
*/
|
|
270
|
+
cache: func(time) {
|
|
271
|
+
ll.assert(
|
|
272
|
+
is_int(time),
|
|
273
|
+
"cache time must be an integer. " +
|
|
274
|
+
"Did you forget to import a standard tengo library 'times'?")
|
|
275
|
+
cache = time
|
|
276
|
+
return self
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Sets the cache time in milliseconds.
|
|
281
|
+
*
|
|
282
|
+
* @param millis: number
|
|
283
|
+
*/
|
|
284
|
+
cacheMillis: func(millis) {
|
|
285
|
+
ll.assert(is_int(millis) && millis > 0, "cache time must be a number of milliseconds")
|
|
286
|
+
cache = millis * times.millisecond
|
|
287
|
+
return self
|
|
288
|
+
},
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Sets the cache time in seconds.
|
|
292
|
+
*
|
|
293
|
+
* @param seconds: number
|
|
294
|
+
*/
|
|
295
|
+
cacheSeconds: func(seconds) {
|
|
296
|
+
ll.assert(is_int(seconds) && seconds > 0, "cache time must be a number of seconds")
|
|
297
|
+
cache = seconds * times.second
|
|
298
|
+
return self
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Sets the cache time in minutes.
|
|
303
|
+
*
|
|
304
|
+
* @param minutes: number
|
|
305
|
+
*/
|
|
306
|
+
cacheMinutes: func(minutes) {
|
|
307
|
+
ll.assert(is_int(minutes) && minutes > 0, "cache time must be a number of minutes")
|
|
308
|
+
cache = minutes * times.minute
|
|
309
|
+
return self
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Sets the cache time in hours.
|
|
314
|
+
*
|
|
315
|
+
* @param hours: number
|
|
316
|
+
*/
|
|
317
|
+
cacheHours: func(hours) {
|
|
318
|
+
ll.assert(is_int(hours) && hours > 0, "cache time must be a number of hours")
|
|
319
|
+
cache = hours * times.hour
|
|
320
|
+
return self
|
|
321
|
+
},
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Sets the cache time in days
|
|
325
|
+
*
|
|
326
|
+
* @param days: number
|
|
327
|
+
*/
|
|
328
|
+
cacheDays: func(days) {
|
|
329
|
+
ll.assert(is_int(days) && days > 0, "cache time must be a number of days")
|
|
330
|
+
cache = days * times.hour * 24
|
|
331
|
+
return self
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Sets the number of error lines to be captured.
|
|
336
|
+
*
|
|
337
|
+
* @param lines: number - the number of error lines.
|
|
338
|
+
*/
|
|
339
|
+
nErrorLines: func(lines) {
|
|
340
|
+
ll.assert(
|
|
341
|
+
is_int(lines) && lines >= 0,
|
|
342
|
+
"lines must be integer")
|
|
343
|
+
|
|
344
|
+
nErrorLines = lines
|
|
345
|
+
return self
|
|
346
|
+
},
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Adds files from given asset into working directory.
|
|
350
|
+
*
|
|
351
|
+
* @param asset: assetInfo - asset info loaded from assets.importAsset()
|
|
352
|
+
* @param destinationDir: string - path inside working directory for files to be extracted from archive. Use "." for root of the workdir.
|
|
353
|
+
* @param pathsInArchive: string[] - paths inside the archive to be extracted into destinationDir.
|
|
354
|
+
* Empty array means 'unpack full archive'.
|
|
355
|
+
*/
|
|
356
|
+
addAsset: func(asset, destinationDir, ...pathsInArchive) {
|
|
357
|
+
if (len(pathsInArchive) == 1 && is_array(pathsInArchive[0])) {
|
|
358
|
+
// support [<paths>] single argument
|
|
359
|
+
pathsInArchive = pathsInArchive[0]
|
|
360
|
+
}
|
|
361
|
+
if len(pathsInArchive) == 0 {
|
|
362
|
+
// default for 'no paths' is to extract all
|
|
363
|
+
pathsInArchive = []
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
ll.assert(assets.isAssetInfo(asset),
|
|
367
|
+
"exec.builder.addAsset: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
368
|
+
validation.assertJsonSchema(destinationDir, "string", "exec.builder.addAsset: <destinationDir> is not a string. It must be a path inside working directory")
|
|
369
|
+
validation.assertJsonSchema(pathsInArchive, ["string"], "exec.builder.addAsset: <pathsInArchive> must contain list of strings with paths inside archive")
|
|
370
|
+
|
|
371
|
+
assetIdKey := ll.idToString(asset._id)
|
|
372
|
+
if is_undefined(assetRules[assetIdKey]) {
|
|
373
|
+
assetInfos[assetIdKey] = asset.resource
|
|
374
|
+
assetDescriptors[assetIdKey] = ll.fromStrict(asset.descriptor)
|
|
375
|
+
assetRules[assetIdKey] = {}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if len(pathsInArchive) == 0 || is_undefined(assetRules[assetIdKey][destinationDir]) {
|
|
379
|
+
assetRules[assetIdKey][destinationDir] = []
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (len(pathsInArchive) > 0) {
|
|
383
|
+
assetRules[assetIdKey][destinationDir] = append(assetRules[assetIdKey][destinationDir], pathsInArchive...)
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return self
|
|
387
|
+
},
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Set custom cache time for given asset. By default, cache time of 1 day is applied to all assets.
|
|
391
|
+
* This allows to customize cache time on per-asset basis
|
|
392
|
+
*/
|
|
393
|
+
cacheAssetMillis: func (asset, millis) {
|
|
394
|
+
ll.assert(assets.isAssetInfo(asset),
|
|
395
|
+
"exec.builder.cacheAssetMillis: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
396
|
+
ll.assert(is_int(millis),
|
|
397
|
+
"exec.builder.cacheAssetMillis: asset cache time must be a number of milliseconds.")
|
|
398
|
+
|
|
399
|
+
assetIdKey := ll.idToString(asset._id)
|
|
400
|
+
assetCache[assetIdKey] = millis * times.millisecond
|
|
401
|
+
|
|
402
|
+
return self
|
|
403
|
+
},
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Set custom cache time for given asset. By default, cache time of 1 day is applied to all assets.
|
|
407
|
+
* This allows to customize cache time on per-asset basis
|
|
408
|
+
*/
|
|
409
|
+
cacheAssetSeconds: func (asset, seconds) {
|
|
410
|
+
ll.assert(assets.isAssetInfo(asset),
|
|
411
|
+
"exec.builder.cacheAssetSeconds: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
412
|
+
ll.assert(is_int(seconds),
|
|
413
|
+
"exec.builder.cacheAssetSeconds: asset cache time must be a number of seconds.")
|
|
414
|
+
|
|
415
|
+
assetIdKey := ll.idToString(asset._id)
|
|
416
|
+
assetCache[assetIdKey] = seconds * times.second
|
|
417
|
+
|
|
418
|
+
return self
|
|
419
|
+
},
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Set custom cache time for given asset. By default, cache time of 1 day is applied to all assets.
|
|
423
|
+
* This allows to customize cache time on per-asset basis
|
|
424
|
+
*/
|
|
425
|
+
cacheAssetMinutes: func (asset, minutes) {
|
|
426
|
+
ll.assert(assets.isAssetInfo(asset),
|
|
427
|
+
"exec.builder.cacheAssetMinutes: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
428
|
+
ll.assert(is_int(minutes),
|
|
429
|
+
"exec.builder.cacheAssetMinutes: asset cache time must be a number of minutes.")
|
|
430
|
+
|
|
431
|
+
assetIdKey := ll.idToString(asset._id)
|
|
432
|
+
assetCache[assetIdKey] = minutes * times.minute
|
|
433
|
+
|
|
434
|
+
return self
|
|
435
|
+
},
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Set custom cache time for given asset. By default, cache time of 1 day is applied to all assets.
|
|
439
|
+
* This allows to customize cache time on per-asset basis
|
|
440
|
+
*/
|
|
441
|
+
cacheAssetHours: func (asset, hours) {
|
|
442
|
+
ll.assert(assets.isAssetInfo(asset),
|
|
443
|
+
"exec.builder.cacheAssetHours: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
444
|
+
ll.assert(is_int(hours),
|
|
445
|
+
"exec.builder.cacheAssetHours: asset cache time must be a number of hours.")
|
|
446
|
+
|
|
447
|
+
assetIdKey := ll.idToString(asset._id)
|
|
448
|
+
assetCache[assetIdKey] = hours * times.hour
|
|
449
|
+
|
|
450
|
+
return self
|
|
451
|
+
},
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Set custom cache time for given asset. By default, cache time of 1 day is applied to all assets.
|
|
455
|
+
* This allows to customize cache time on per-asset basis
|
|
456
|
+
*/
|
|
457
|
+
cacheAssetDays: func (asset, days) {
|
|
458
|
+
ll.assert(assets.isAssetInfo(asset),
|
|
459
|
+
"exec.builder.cacheAssetHours: <asset> parameter is not an asset info. Provide the value obtained from assets.importAsset() here")
|
|
460
|
+
ll.assert(is_int(days),
|
|
461
|
+
"exec.builder.cacheAssetHours: asset cache time must be a number of days.")
|
|
462
|
+
|
|
463
|
+
assetIdKey := ll.idToString(asset._id)
|
|
464
|
+
assetCache[assetIdKey] = days * 24 * times.hour
|
|
465
|
+
|
|
466
|
+
return self
|
|
467
|
+
},
|
|
468
|
+
|
|
469
|
+
enableMnz: func(productName) {
|
|
470
|
+
monetization.enable(mnz, productName)
|
|
471
|
+
return self
|
|
472
|
+
},
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Adds a file to the working directory
|
|
476
|
+
*
|
|
477
|
+
* @param fileName: string - the name of the input file.
|
|
478
|
+
* @param file: reference - a resource id of the file or a field that points to it.
|
|
479
|
+
*/
|
|
480
|
+
addFile: func(fileName, file, ...opts) {
|
|
481
|
+
ll.assert(is_string(fileName), "exec.builder().addFile: fileName must be a string")
|
|
482
|
+
ll.assert(smart.isReference(file), "exec.builder().addFile: file must be a reference")
|
|
483
|
+
|
|
484
|
+
fileName = path.canonize(fileName)
|
|
485
|
+
filesToAdd[fileName] = file
|
|
486
|
+
_addMnzOption(fileName, opts...)
|
|
487
|
+
return self
|
|
488
|
+
},
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Adds multiple files to the working directory.
|
|
492
|
+
*
|
|
493
|
+
* @param filesMap: map[string]reference - a map of file names to files' references.
|
|
494
|
+
*/
|
|
495
|
+
addFiles: func(filesMap, ...opts) {
|
|
496
|
+
ll.assert(ll.isMap(filesMap), "exec.builder().addFiles: filesMap must be map of file names to file resources")
|
|
497
|
+
for fileName, file in filesMap {
|
|
498
|
+
self.addFile(fileName, file, opts...)
|
|
499
|
+
}
|
|
500
|
+
return self
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Writes a file with a given content.
|
|
505
|
+
*
|
|
506
|
+
* @param fileName: string - the name of the content.
|
|
507
|
+
* @param data: bytes|reference - a primitive tengo value (map or array) or a reference to
|
|
508
|
+
* a resource from which data we create a file.
|
|
509
|
+
*/
|
|
510
|
+
writeFile: func(fileName, data, ...opts) {
|
|
511
|
+
validation.assertJsonSchema(data, ["or",
|
|
512
|
+
"string",
|
|
513
|
+
"bytes",
|
|
514
|
+
validation.reference])
|
|
515
|
+
|
|
516
|
+
fileName = path.canonize(fileName)
|
|
517
|
+
|
|
518
|
+
filesToWrite[fileName] = data
|
|
519
|
+
_addMnzOption(fileName, opts...)
|
|
520
|
+
|
|
521
|
+
return self
|
|
522
|
+
},
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Creates a directory.
|
|
526
|
+
*
|
|
527
|
+
* @param dir: string - the directory to create.
|
|
528
|
+
*/
|
|
529
|
+
mkDir: func(dir) {
|
|
530
|
+
dir = path.canonize(dir)
|
|
531
|
+
dirsToCreate = sets.add(dirsToCreate, dir)
|
|
532
|
+
return self
|
|
533
|
+
},
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Saves a file.
|
|
537
|
+
*
|
|
538
|
+
* @param fileName: string - the name of the output file.
|
|
539
|
+
*/
|
|
540
|
+
saveFile: func(fileName) {
|
|
541
|
+
fileName = path.canonize(fileName)
|
|
542
|
+
sets.add(filesToSave, fileName)
|
|
543
|
+
return self
|
|
544
|
+
},
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Saves a file's content to a value resource.
|
|
548
|
+
*
|
|
549
|
+
* @param fileName: string - the name of the output value.
|
|
550
|
+
*/
|
|
551
|
+
saveFileContent: func(fileName) {
|
|
552
|
+
fileName = path.canonize(fileName)
|
|
553
|
+
sets.add(filesContentToSave, fileName)
|
|
554
|
+
return self
|
|
555
|
+
},
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Saves files from the exec workdir using regex.
|
|
559
|
+
*
|
|
560
|
+
* @param name: string - a name to refer this file set in the outputs
|
|
561
|
+
* @param regex: string - regex pattern
|
|
562
|
+
*/
|
|
563
|
+
saveFileSet: func(name, regex) {
|
|
564
|
+
fileSetsToSave[name] = regex
|
|
565
|
+
return self
|
|
566
|
+
},
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Run specified
|
|
570
|
+
*/
|
|
571
|
+
processWorkdir: func(name, tpl, tplArgs) {
|
|
572
|
+
wdProcessors[name] = {
|
|
573
|
+
tpl: tpl,
|
|
574
|
+
tplArgs: tplArgs
|
|
575
|
+
}
|
|
576
|
+
return self
|
|
577
|
+
},
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Saves files content from the exec workdir using regex.
|
|
581
|
+
*
|
|
582
|
+
* @param name: string - a name to refer this file set in the outputs
|
|
583
|
+
* @param regex: string - regex pattern
|
|
584
|
+
*/
|
|
585
|
+
saveFileSetContent: func(name, regex) {
|
|
586
|
+
fileSetsContentToSave[name] = regex
|
|
587
|
+
return self
|
|
588
|
+
},
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* A command to stream a file by a given file name.
|
|
592
|
+
*
|
|
593
|
+
* @param fileName: string - the name of the file to stream.
|
|
594
|
+
*/
|
|
595
|
+
streamFile: func(fileName) {
|
|
596
|
+
fileName = path.canonize(fileName)
|
|
597
|
+
sets.add(filesToStream, fileName)
|
|
598
|
+
|
|
599
|
+
return self
|
|
600
|
+
},
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Set stdout file name
|
|
604
|
+
*/
|
|
605
|
+
stdoutFileName: func(fileName) {
|
|
606
|
+
fileName = path.canonize(fileName)
|
|
607
|
+
stdout = fileName
|
|
608
|
+
return self
|
|
609
|
+
},
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Set stderr file name
|
|
613
|
+
*/
|
|
614
|
+
stderrFileName: func(fileName) {
|
|
615
|
+
fileName = path.canonize(fileName)
|
|
616
|
+
stderr = fileName
|
|
617
|
+
return self
|
|
618
|
+
},
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Sets stdout to be captured as a value resource.
|
|
622
|
+
*/
|
|
623
|
+
saveStdoutContent: func() {
|
|
624
|
+
stdoutToValue = true
|
|
625
|
+
return self
|
|
626
|
+
},
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Sets stderr to be captured as a value resource.
|
|
630
|
+
*/
|
|
631
|
+
saveStderrContent: func() {
|
|
632
|
+
stderrToValue = true
|
|
633
|
+
return self
|
|
634
|
+
},
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Redirects stderr output to stdout.
|
|
638
|
+
*/
|
|
639
|
+
printErrStreamToStdout: func() {
|
|
640
|
+
stderrToStdout = true
|
|
641
|
+
return self
|
|
642
|
+
},
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Executes the command.
|
|
646
|
+
*
|
|
647
|
+
* @return A map containing the execution results.
|
|
648
|
+
*/
|
|
649
|
+
run: func() {
|
|
650
|
+
if stderrToStdout {
|
|
651
|
+
stderr = stdout
|
|
652
|
+
}
|
|
653
|
+
sets.add(filesToStream, stdout)
|
|
654
|
+
sets.add(filesToStream, stderr)
|
|
655
|
+
sets.add(filesToSave, stdout)
|
|
656
|
+
sets.add(filesToSave, stderr)
|
|
657
|
+
if stdoutToValue {
|
|
658
|
+
sets.add(filesContentToSave, stdout)
|
|
659
|
+
}
|
|
660
|
+
if stderrToValue {
|
|
661
|
+
sets.add(filesContentToSave, stderr)
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// We don't want these values to be encoded as JSON's since
|
|
665
|
+
// values are pure bytes.
|
|
666
|
+
// Thus, we create a resource with a custom type here manually.
|
|
667
|
+
filesToWriteRefs := maps.mapValues(filesToWrite, func(v) {
|
|
668
|
+
if smart.isReference(v) { return v }
|
|
669
|
+
return smart.createValueResource(constants.RTYPE_BINARY_VALUE, v)
|
|
670
|
+
})
|
|
671
|
+
|
|
672
|
+
ll.assert(entrypointSet,
|
|
673
|
+
"incomplete command: cmd() or software() must be provided to exec.builder")
|
|
674
|
+
|
|
675
|
+
runOptions := {
|
|
676
|
+
cmd: cmd,
|
|
677
|
+
args: args,
|
|
678
|
+
envs: envs,
|
|
679
|
+
secrets: secrets,
|
|
680
|
+
queue: queue,
|
|
681
|
+
stdout: stdout,
|
|
682
|
+
stderr: stderr,
|
|
683
|
+
nErrorLines: nErrorLines
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
execInputs := {
|
|
687
|
+
filesToAdd: smart.createMapResource(filesToAdd),
|
|
688
|
+
filesToWrite: smart.createMapResource(filesToWriteRefs),
|
|
689
|
+
dirsToCreate: slices.fromSet(dirsToCreate),
|
|
690
|
+
runOptions: runOptions,
|
|
691
|
+
filesToSave: slices.fromSet(filesToSave),
|
|
692
|
+
filesContentToSave: slices.fromSet(filesContentToSave),
|
|
693
|
+
fileSetsToSave: fileSetsToSave,
|
|
694
|
+
fileSetsContentToSave: fileSetsContentToSave,
|
|
695
|
+
filesToStream: slices.fromSet(filesToStream),
|
|
696
|
+
wdProcessors: wdProcessors,
|
|
697
|
+
assets: smart.createMapResource(assetInfos),
|
|
698
|
+
assetDescriptors: assetDescriptors,
|
|
699
|
+
assetRules: assetRules,
|
|
700
|
+
assetCache: assetCache
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// We add monetization only if it's enabled
|
|
704
|
+
// to not break a deduplication of exec's
|
|
705
|
+
// that were created before this feature existed.
|
|
706
|
+
if monetization.shouldRun(mnz) {
|
|
707
|
+
execInputs.runOptions.monetization = monetization.toJson(mnz)
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// We add new argsTyped and envsTyped only when they were added
|
|
711
|
+
// to not break a deduplication on old pl backend.
|
|
712
|
+
if typedArgSet || typedEnvSet {
|
|
713
|
+
execInputs.runOptions.argsTyped = argsTyped
|
|
714
|
+
execInputs.runOptions.envsTyped = envsTyped
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
if !is_undefined(soft) {
|
|
718
|
+
execInputs.softwareInfo = soft.resource
|
|
719
|
+
execInputs.runOptions.software = {
|
|
720
|
+
name: soft.name,
|
|
721
|
+
version: soft.version,
|
|
722
|
+
descriptor: ll.fromStrict(soft.descriptor)
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
tpl := render.create(assets.importTemplate("@platforma-sdk/workflow-tengo:exec.exec"), execInputs)
|
|
727
|
+
|
|
728
|
+
self := undefined
|
|
729
|
+
self = ll.toStrict(oop.inherit(tpl, {
|
|
730
|
+
/**
|
|
731
|
+
* Retrieves a file.
|
|
732
|
+
*
|
|
733
|
+
* @param fileName: string
|
|
734
|
+
* @return field - a reference to the file resource.
|
|
735
|
+
*/
|
|
736
|
+
getFile: func(fileName) {
|
|
737
|
+
return tpl.output("files", cache).getFutureInputField(fileName)
|
|
738
|
+
},
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Retrieves the content of a file.
|
|
742
|
+
*
|
|
743
|
+
* @param fileName: string
|
|
744
|
+
* @return field - a reference to the file content resource.
|
|
745
|
+
*/
|
|
746
|
+
getFileContent: func(fileName) {
|
|
747
|
+
return tpl.output("filesContent", cache).getFutureInputField(fileName)
|
|
748
|
+
},
|
|
749
|
+
|
|
750
|
+
/**
|
|
751
|
+
* Retrieves a file stream.
|
|
752
|
+
*
|
|
753
|
+
* @param fileName: string
|
|
754
|
+
* @return field - a reference to the file stream resource.
|
|
755
|
+
*/
|
|
756
|
+
getFileStream: func(fileName) {
|
|
757
|
+
return tpl.output("fileStreams", cache).getFutureInputField(fileName, true)
|
|
758
|
+
},
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Retrieves a file set resource.
|
|
762
|
+
*
|
|
763
|
+
* @param fileSetName: string - name of a file set
|
|
764
|
+
* @return field - a reference to the map resource with files
|
|
765
|
+
*/
|
|
766
|
+
getFileSet: func(fileSetName) {
|
|
767
|
+
return tpl.output("fileSets", cache).getFutureInputField(fileSetName)
|
|
768
|
+
},
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Retrieves a file set content resource.
|
|
772
|
+
*
|
|
773
|
+
* @param fileSetName: string - name of a file set
|
|
774
|
+
* @return field - a reference to the map resource with files
|
|
775
|
+
*/
|
|
776
|
+
getFileSetContent: func(fileSetName) {
|
|
777
|
+
return tpl.output("fileSetsContent", cache).getFutureInputField(fileSetName)
|
|
778
|
+
},
|
|
779
|
+
|
|
780
|
+
getProcessorResult: func(procName) {
|
|
781
|
+
return tpl.output("wdProcessors", cache).getFutureInputField(procName)
|
|
782
|
+
},
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Retrieves the stdout stream.
|
|
786
|
+
*/
|
|
787
|
+
getStdoutStream: func() {
|
|
788
|
+
return self.getFileStream(stdout)
|
|
789
|
+
},
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* Retrieves the stderr stream.
|
|
793
|
+
*/
|
|
794
|
+
getStderrStream: func() {
|
|
795
|
+
return self.getFileStream(stderr)
|
|
796
|
+
},
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* Retrieves the stdout file.
|
|
800
|
+
*/
|
|
801
|
+
getStdoutFile: func() {
|
|
802
|
+
return self.getFile(stdout)
|
|
803
|
+
},
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Retrieves the stderr file.
|
|
807
|
+
*/
|
|
808
|
+
getStderrFile: func() {
|
|
809
|
+
return self.getFile(stderr)
|
|
810
|
+
},
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* Retrieves the content of the stdout file.
|
|
814
|
+
*/
|
|
815
|
+
getStdoutFileContent: func() {
|
|
816
|
+
if stdoutToValue {
|
|
817
|
+
return self.getFileContent(stdout)
|
|
818
|
+
}
|
|
819
|
+
ll.panic("stdout was not saved as a content")
|
|
820
|
+
},
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Retrieves the content of the stderr file.
|
|
824
|
+
*/
|
|
825
|
+
getStderrFileContent: func() {
|
|
826
|
+
if stderrToValue {
|
|
827
|
+
return self.getFileContent(stderr)
|
|
828
|
+
}
|
|
829
|
+
ll.panic("stderr was not saved as a content")
|
|
830
|
+
}
|
|
831
|
+
}))
|
|
832
|
+
|
|
833
|
+
return self
|
|
834
|
+
}
|
|
835
|
+
})
|
|
836
|
+
|
|
837
|
+
return self
|
|
838
838
|
}
|
|
839
839
|
|
|
840
840
|
export ll.toStrict({
|
|
841
|
-
builder: builder,
|
|
842
|
-
canBackendUseExpressions: desc.canBackendUseExpressions
|
|
841
|
+
builder: builder,
|
|
842
|
+
canBackendUseExpressions: desc.canBackendUseExpressions
|
|
843
843
|
})
|