@platforma-sdk/workflow-tengo 1.2.6
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/README.md +6 -0
- package/dist/tengo/lib/assets.lib.tengo +64 -0
- package/dist/tengo/lib/constants.lib.tengo +75 -0
- package/dist/tengo/lib/exec.internal.lib.tengo +211 -0
- package/dist/tengo/lib/exec.lib.tengo +516 -0
- package/dist/tengo/lib/exec.package.lib.tengo +296 -0
- package/dist/tengo/lib/exec.runcmd.lib.tengo +275 -0
- package/dist/tengo/lib/exec.runenv.lib.tengo +221 -0
- package/dist/tengo/lib/exec.stream.lib.tengo +64 -0
- package/dist/tengo/lib/file.lib.tengo +112 -0
- package/dist/tengo/lib/ll.lib.tengo +233 -0
- package/dist/tengo/lib/maps.lib.tengo +102 -0
- package/dist/tengo/lib/objects.lib.tengo +22 -0
- package/dist/tengo/lib/oop.lib.tengo +29 -0
- package/dist/tengo/lib/path.lib.tengo +165 -0
- package/dist/tengo/lib/pframes.constants.lib.tengo +53 -0
- package/dist/tengo/lib/pframes.export-pcolumn.lib.tengo +47 -0
- package/dist/tengo/lib/pframes.lib.tengo +84 -0
- package/dist/tengo/lib/pframes.ll.lib.tengo +86 -0
- package/dist/tengo/lib/pframes.util.lib.tengo +244 -0
- package/dist/tengo/lib/pframes.xsv.lib.tengo +178 -0
- package/dist/tengo/lib/render.lib.tengo +100 -0
- package/dist/tengo/lib/sets.lib.tengo +93 -0
- package/dist/tengo/lib/slices.lib.tengo +202 -0
- package/dist/tengo/lib/smart.lib.tengo +1005 -0
- package/dist/tengo/lib/tpl.lib.tengo +535 -0
- package/dist/tengo/lib/tpl.state-await.lib.tengo +255 -0
- package/dist/tengo/lib/tpl.util.lib.tengo +19 -0
- package/dist/tengo/lib/validation.lib.tengo +428 -0
- package/dist/tengo/lib/workdir.lib.tengo +300 -0
- package/dist/tengo/lib/workdir.proc.lib.tengo +158 -0
- package/dist/tengo/lib/workdir.save.lib.tengo +158 -0
- package/dist/tengo/lib/workflow.bobject.lib.tengo +51 -0
- package/dist/tengo/lib/workflow.bquery.lib.tengo +208 -0
- package/dist/tengo/lib/workflow.constants.lib.tengo +8 -0
- package/dist/tengo/lib/workflow.context.lib.tengo +56 -0
- package/dist/tengo/lib/workflow.lib.tengo +298 -0
- package/dist/tengo/tpl/exec.create-python-venv.plj.gz +0 -0
- package/dist/tengo/tpl/exec.exec.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.import-xsv-map.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.map-pframe.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/index.d.ts +4 -0
- package/index.js +13 -0
- package/package.json +25 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
2
|
+
smart := import("@platforma-sdk/workflow-tengo:smart")
|
|
3
|
+
workdir := import("@platforma-sdk/workflow-tengo:workdir")
|
|
4
|
+
oop := import("@platforma-sdk/workflow-tengo:oop")
|
|
5
|
+
sets := import("@platforma-sdk/workflow-tengo:sets")
|
|
6
|
+
validation := import("@platforma-sdk/workflow-tengo:validation")
|
|
7
|
+
json := import("json")
|
|
8
|
+
|
|
9
|
+
runEnvDescriptorScheme := {
|
|
10
|
+
registry: "string",
|
|
11
|
+
package: "string",
|
|
12
|
+
type: "string",
|
|
13
|
+
binDir: "string"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
binaryDescriptorScheme := {
|
|
17
|
+
registry: "string",
|
|
18
|
+
package: "string",
|
|
19
|
+
cmd: ["string"],
|
|
20
|
+
runEnv: runEnvDescriptorScheme
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
localDescriptorScheme := {
|
|
24
|
+
hash: "string",
|
|
25
|
+
path: "string",
|
|
26
|
+
cmd: ["string"],
|
|
27
|
+
runEnv: runEnvDescriptorScheme
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
descriptorScheme := {
|
|
31
|
+
"isDev,omitempty": "bool",
|
|
32
|
+
"binary,omitempty": binaryDescriptorScheme,
|
|
33
|
+
"local,omitempty": localDescriptorScheme
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
softwareInfoScheme := {
|
|
37
|
+
"name": "string",
|
|
38
|
+
"version": "string",
|
|
39
|
+
"descriptor": descriptorScheme
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
META_KEY_DESCRIPTOR := "ctl/runner/package/descriptor"
|
|
43
|
+
|
|
44
|
+
_RTYPE_PACKAGE_GET := { Name: "PackageGet", Version: "1" }
|
|
45
|
+
_INPUT_PACKAGE_NAME := "packageName"
|
|
46
|
+
_INPUT_REGISTRY := "registry"
|
|
47
|
+
_OUTPUT_ARCHIVE := "archive"
|
|
48
|
+
|
|
49
|
+
get := func(registryName, pkgName) {
|
|
50
|
+
res := smart.structBuilder(_RTYPE_PACKAGE_GET)
|
|
51
|
+
|
|
52
|
+
res.getField(_INPUT_REGISTRY).setRefOrJson(registryName)
|
|
53
|
+
res.getField(_INPUT_PACKAGE_NAME).setRefOrJson(pkgName)
|
|
54
|
+
|
|
55
|
+
self := undefined
|
|
56
|
+
self = oop.inherit(res, {
|
|
57
|
+
/**
|
|
58
|
+
* Reference to the software package archive downloaded by 'get'
|
|
59
|
+
*
|
|
60
|
+
* @return archive: field - output field, where info on downloaded archive will appear
|
|
61
|
+
*/
|
|
62
|
+
archive: func() {
|
|
63
|
+
return res.outputs()[_OUTPUT_ARCHIVE]
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
return self
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
_RTYPE_PACKAGE_INSTALL := { Name: "PackageInstall", Version: "1" }
|
|
71
|
+
_INPUT_ARCHIVE := "archive"
|
|
72
|
+
_OUTPUT_PACKAGE := "package"
|
|
73
|
+
|
|
74
|
+
install := func(archive) {
|
|
75
|
+
ll.assert(smart.isReference(archive),
|
|
76
|
+
"package.install: <archive> must be reference to package archive. It is usually obtained from package.get().archive")
|
|
77
|
+
|
|
78
|
+
res := smart.structBuilder(_RTYPE_PACKAGE_INSTALL)
|
|
79
|
+
|
|
80
|
+
res.getField(_INPUT_ARCHIVE).set(archive)
|
|
81
|
+
|
|
82
|
+
self := undefined
|
|
83
|
+
self = oop.inherit(res, {
|
|
84
|
+
/**
|
|
85
|
+
* Reference to installed package
|
|
86
|
+
*
|
|
87
|
+
* @return package: smart.field - output field, where installed package will appear
|
|
88
|
+
*/
|
|
89
|
+
package: func() {
|
|
90
|
+
return res.getField(_OUTPUT_PACKAGE)
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
return self
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_RTYPE_PACKAGE_USE := { Name: "PackageUse", Version: "1" }
|
|
98
|
+
_INPUT_PACKAGE_USE_SETTINGS := "settings"
|
|
99
|
+
|
|
100
|
+
_useSettingsSchema := {
|
|
101
|
+
hash: ["or", "bytes", "string"],
|
|
102
|
+
path: "string",
|
|
103
|
+
descriptor: "any",
|
|
104
|
+
origin: {
|
|
105
|
+
registry: "string",
|
|
106
|
+
url: "string",
|
|
107
|
+
packageName: "string"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
use := func(settings) {
|
|
112
|
+
res := smart.structBuilder(_RTYPE_PACKAGE_USE)
|
|
113
|
+
|
|
114
|
+
validation.assertJsonSchema(settings, _useSettingsSchema, "package.use(<settings>): settings have invalid format")
|
|
115
|
+
settingsRes := smart.createJsonResource(settings)
|
|
116
|
+
|
|
117
|
+
res.getField(_INPUT_PACKAGE_USE_SETTINGS).set(settingsRes)
|
|
118
|
+
|
|
119
|
+
self := undefined
|
|
120
|
+
self = oop.inherit(res, {
|
|
121
|
+
/**
|
|
122
|
+
* Reference to installed package
|
|
123
|
+
*
|
|
124
|
+
* @return package: field - output field, where installed package will appear
|
|
125
|
+
*/
|
|
126
|
+
package: func() {
|
|
127
|
+
return res.outputs()[_OUTPUT_PACKAGE]
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
return self
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
_RTYPE_PACKAGE_PUT_ASSET := { Name: "PackagePutAssetsToWD", Version: "1" }
|
|
136
|
+
_INPUT_PACKAGE := "package"
|
|
137
|
+
_INPUT_WD_IN := "workdirIn"
|
|
138
|
+
_OUTPUT_WD_OUT := "workdirOut"
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Load assets and provide them as files or raw content.
|
|
142
|
+
*
|
|
143
|
+
* @param pkg: package - installed package (usually from package.install(<archive>))
|
|
144
|
+
*
|
|
145
|
+
* @return loader: assetsLoader - builder that provides requested files and content after load() call
|
|
146
|
+
*/
|
|
147
|
+
assetsLoader := func(pkg) {
|
|
148
|
+
ll.assert(smart.isReference(pkg),
|
|
149
|
+
"package.loadAssets: <pkg> must be reference to installed package. It is usually obtained from package.install().package")
|
|
150
|
+
|
|
151
|
+
filePaths := []
|
|
152
|
+
fileContentPaths := []
|
|
153
|
+
|
|
154
|
+
self := undefined
|
|
155
|
+
|
|
156
|
+
self = {
|
|
157
|
+
saveFile: func(path) {
|
|
158
|
+
validation.assertJsonSchema(path, "string", "package.assetsLoader.saveFile: <path> must be string")
|
|
159
|
+
filePaths = append(filePaths, path)
|
|
160
|
+
|
|
161
|
+
return self
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
saveFiles: func(paths) {
|
|
165
|
+
validation.assertJsonSchema(paths, ["string"], "package.assetsLoader.saveFiles: <paths> must be array of strings")
|
|
166
|
+
for p in paths {
|
|
167
|
+
self.saveFile(p)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return self
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
saveFileContent: func(path) {
|
|
174
|
+
validation.assertJsonSchema(path, "string", "package.assetsLoader.saveFileContent: <path> must be string")
|
|
175
|
+
fileContentPaths = append(fileContentPaths, path)
|
|
176
|
+
return self
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
saveFilesContent: func(paths) {
|
|
180
|
+
validation.assertJsonSchema(paths, ["string"], "package.assetsLoader.saveFilesContent: <paths> must be array of strings")
|
|
181
|
+
for p in paths {
|
|
182
|
+
self.saveFileContent(p)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return self
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
load: func() {
|
|
189
|
+
wd := workdir.create()
|
|
190
|
+
|
|
191
|
+
allPaths := sets.fromSlice(filePaths)
|
|
192
|
+
allPaths = sets.add(allPaths, fileContentPaths...)
|
|
193
|
+
|
|
194
|
+
res := smart.ephemeralBuilder(_RTYPE_PACKAGE_PUT_ASSET, json.encode({
|
|
195
|
+
paths: sets.toSlice(allPaths)
|
|
196
|
+
}))
|
|
197
|
+
|
|
198
|
+
res.getField(_INPUT_PACKAGE).set(pkg)
|
|
199
|
+
res.getField(_INPUT_WD_IN).set(wd)
|
|
200
|
+
|
|
201
|
+
wdAfter := res.getField(_OUTPUT_WD_OUT)
|
|
202
|
+
|
|
203
|
+
wdSaveBuilder := workdir.save(wdAfter)
|
|
204
|
+
for p in filePaths {
|
|
205
|
+
wdSaveBuilder.saveFile(p)
|
|
206
|
+
}
|
|
207
|
+
for p in fileContentPaths {
|
|
208
|
+
wdSaveBuilder.saveFileContent(p)
|
|
209
|
+
}
|
|
210
|
+
wdSave := wdSaveBuilder.build()
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
files: wdSave.files,
|
|
214
|
+
filesContent: wdSave.filesContent,
|
|
215
|
+
progress: wdSave.progress,
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Retrieves selected asset file by its path (use saveFile() to provide asset as file)
|
|
219
|
+
*
|
|
220
|
+
* @param fileName: string
|
|
221
|
+
* @return file: smart.field - a reference to the file resource.
|
|
222
|
+
*/
|
|
223
|
+
getFile: func(fileName) {
|
|
224
|
+
return wdSave.files.getFutureInputField(fileName)
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Retrieves selected asset data by its path (use saveFileContent() to provide asset's data)
|
|
229
|
+
*
|
|
230
|
+
* @param fileName: string
|
|
231
|
+
* @return file: smart.field - a reference to the file resource.
|
|
232
|
+
*/
|
|
233
|
+
getFileContent: func(fileName) {
|
|
234
|
+
return wdSave.filesContent.getFutureInputField(fileName)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return ll.toStrict(self)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Load single asset by its path inside package, providing it as file.
|
|
245
|
+
*
|
|
246
|
+
* @param pkg: package - installed package (usually from package.install(<archive>))
|
|
247
|
+
* @param assetPath: string - path to asset inside package <pkg>
|
|
248
|
+
*
|
|
249
|
+
* @return file: singleAsset - object with reference to the file resource and progress report
|
|
250
|
+
*/
|
|
251
|
+
loadAssetFile := func(pkg, assetPath) {
|
|
252
|
+
assets := assetsLoader(pkg).
|
|
253
|
+
saveFile(assetPath).
|
|
254
|
+
load()
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
file: assets.getFile(assetPath),
|
|
258
|
+
progress: assets.progress
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Load single asset by its path inside package, providing its raw content.
|
|
264
|
+
*
|
|
265
|
+
* @param pkg: package - installed package (usually from package.install(<archive>))
|
|
266
|
+
* @param assetPath: string - path to asset inside package <pkg>
|
|
267
|
+
*
|
|
268
|
+
* @return content: singleAsset - object with reference to the asset content resource and progress report
|
|
269
|
+
*/
|
|
270
|
+
loadAssetContent := func(pkg, assetPath) {
|
|
271
|
+
assets := assetsLoader(pkg).
|
|
272
|
+
saveFileContent(assetPath).
|
|
273
|
+
load()
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
content: assets.getFileContent(assetPath),
|
|
277
|
+
progress: assets.progress
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
export ll.toStrict({
|
|
283
|
+
softwareInfoScheme : softwareInfoScheme,
|
|
284
|
+
binaryDescriptorScheme : binaryDescriptorScheme,
|
|
285
|
+
localDescriptorScheme : localDescriptorScheme,
|
|
286
|
+
runEnvDescriptorScheme : runEnvDescriptorScheme,
|
|
287
|
+
|
|
288
|
+
META_KEY_DESCRIPTOR : META_KEY_DESCRIPTOR,
|
|
289
|
+
|
|
290
|
+
get : get,
|
|
291
|
+
install : install,
|
|
292
|
+
use : use,
|
|
293
|
+
assetsLoader : assetsLoader,
|
|
294
|
+
loadAssetFile : loadAssetFile,
|
|
295
|
+
loadAssetContent : loadAssetContent
|
|
296
|
+
})
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/** A library that creates RunCommand resource. */
|
|
2
|
+
|
|
3
|
+
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
4
|
+
maps := import("@platforma-sdk/workflow-tengo:maps")
|
|
5
|
+
oop := import("@platforma-sdk/workflow-tengo:oop")
|
|
6
|
+
smart := import("@platforma-sdk/workflow-tengo:smart")
|
|
7
|
+
json := import("json")
|
|
8
|
+
|
|
9
|
+
_RTYPE_RUN_COMMAND := { Name: "RunCommand/executor", Version: "1" }
|
|
10
|
+
_RTYPE_RUN_COMMAND_CMD := { Name: "RunCommandCmd", Version: "1" }
|
|
11
|
+
_RTYPE_RUN_COMMAND_ARGS := { Name: "RunCommandArgs", Version: "1" }
|
|
12
|
+
_RTYPE_RUN_COMMAND_OPTIONS := { Name: "run-command/options", Version: "1" }
|
|
13
|
+
_RTYPE_RUN_COMMAND_REFS := { Name: "RunCommandRefs", Version: "1" }
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a simple argument for the command.
|
|
17
|
+
*
|
|
18
|
+
* @param argument: string - the argument to create.
|
|
19
|
+
*/
|
|
20
|
+
_createSimpleArg := func(argument) {
|
|
21
|
+
return {
|
|
22
|
+
type: "string",
|
|
23
|
+
value: argument
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Creates 'variableRef' argument.
|
|
29
|
+
* @param argTpl: string - argument value in any form with variables inside (e.g. "file://{pkg}/some-file" or "o-{java}-o")
|
|
30
|
+
*/
|
|
31
|
+
_createVariableArg := func(argTpl) {
|
|
32
|
+
return {
|
|
33
|
+
type: "variableRef",
|
|
34
|
+
value: argTpl
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Builder function for creating a RunCommand resource.
|
|
40
|
+
*
|
|
41
|
+
* @param workdir: string - the working directory for the command.
|
|
42
|
+
* @return builder - the builder object with methods for configuring and building the RunCommand resource.
|
|
43
|
+
*/
|
|
44
|
+
builder := func(workdir) {
|
|
45
|
+
res := smart.ephemeralBuilder(_RTYPE_RUN_COMMAND)
|
|
46
|
+
res.getField("workdirIn").set(workdir)
|
|
47
|
+
|
|
48
|
+
self := undefined
|
|
49
|
+
|
|
50
|
+
cmd := undefined
|
|
51
|
+
args := []
|
|
52
|
+
envs := {}
|
|
53
|
+
queue := ""
|
|
54
|
+
refs := {}
|
|
55
|
+
|
|
56
|
+
substRules := {}
|
|
57
|
+
hasPatternArgs := false
|
|
58
|
+
customPaths := []
|
|
59
|
+
|
|
60
|
+
stdout := "stdout.txt"
|
|
61
|
+
stderr := "stderr.txt"
|
|
62
|
+
nErrorLines := 200
|
|
63
|
+
|
|
64
|
+
self = ll.toStrict(oop.inherit(res, {
|
|
65
|
+
/**
|
|
66
|
+
* Sets the command, e.g. /usr/bin/env or sh.
|
|
67
|
+
*
|
|
68
|
+
* @param commandName: string - the name of the command.
|
|
69
|
+
*/
|
|
70
|
+
cmd: func(commandName) {
|
|
71
|
+
cmd = _createSimpleArg(commandName)
|
|
72
|
+
return self
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Sets the command with variables inside to be rendered using rules
|
|
77
|
+
* from .substitutionRules().
|
|
78
|
+
*
|
|
79
|
+
* @param commandTpl: string - string with '{varName}' substitutions to be replaced with
|
|
80
|
+
* software paths. Replace rules are defined by .substitutionRule()
|
|
81
|
+
* and .substitutionRules(),
|
|
82
|
+
*/
|
|
83
|
+
cmdVar: func(commandTpl) {
|
|
84
|
+
cmd = _createVariableArg(commandTpl)
|
|
85
|
+
hasPatternArgs = true
|
|
86
|
+
return self
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Adds an argument to the command.
|
|
91
|
+
*
|
|
92
|
+
* @param arg: string - the argument to add.
|
|
93
|
+
*/
|
|
94
|
+
arg: func(arg) {
|
|
95
|
+
args = append(args, _createSimpleArg(arg))
|
|
96
|
+
return self
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Adds an argument with variables inside to be rendered using rules
|
|
101
|
+
* from .substitutionRules().
|
|
102
|
+
*
|
|
103
|
+
* @param argTpl: string - string with '{varName}' substitutions to be replaced with
|
|
104
|
+
* software paths. Replace rules are defined by .substitutionRule()
|
|
105
|
+
* and .substitutionRules(),
|
|
106
|
+
*/
|
|
107
|
+
argVar: func(argTpl) {
|
|
108
|
+
args = append(args, _createVariableArg(argTpl))
|
|
109
|
+
hasPatternArgs = true
|
|
110
|
+
return self
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
ref: func(refKey, ref) {
|
|
114
|
+
ll.assert(smart.isReference(ref),
|
|
115
|
+
"runcmd.builder().ref() must be a reference (valid field or resource)")
|
|
116
|
+
|
|
117
|
+
ll.assert(!maps.containsKey(refs, refKey),
|
|
118
|
+
"attempt to override existing reference %q", refKey)
|
|
119
|
+
|
|
120
|
+
refs[refKey] = ref
|
|
121
|
+
return self
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Sets an environment variable for the command.
|
|
126
|
+
*
|
|
127
|
+
* @param name: string - the name of the environment variable.
|
|
128
|
+
* @param value: string - the value of the environment variable.
|
|
129
|
+
*/
|
|
130
|
+
env: func(name, value) {
|
|
131
|
+
envs[name] = value
|
|
132
|
+
return self
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Sets environment variable with substitution inside value, to be rendered
|
|
137
|
+
* using rules from .substitutionRules().
|
|
138
|
+
*
|
|
139
|
+
* @param name: string - the name of the environment variable.
|
|
140
|
+
* @param valueTpl: string - the value of the environment variable.
|
|
141
|
+
*/
|
|
142
|
+
envVar: func(name, valueTpl) {
|
|
143
|
+
envs[name] = _createVariableArg(valueTpl)
|
|
144
|
+
hasPatternArgs = true
|
|
145
|
+
return self
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
/*
|
|
149
|
+
* Patch 'PATH' environment variable, adding software path to it.
|
|
150
|
+
*
|
|
151
|
+
* @param value: string - the value of the environment variable with variables to be replaced to software path.
|
|
152
|
+
* @param hasVars: boolean - wether Platforma Backend should try to substitute variables inside <value> on server side
|
|
153
|
+
*/
|
|
154
|
+
addToPath: func(value, hasVars) {
|
|
155
|
+
if hasVars {
|
|
156
|
+
customPaths = append(customPaths, _createVariableArg(value))
|
|
157
|
+
hasPatternArgs = true
|
|
158
|
+
} else {
|
|
159
|
+
customPaths = append(customPaths, _createSimpleArg(value))
|
|
160
|
+
}
|
|
161
|
+
return self
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Define substitution variable for software args.
|
|
166
|
+
*
|
|
167
|
+
* @param varName: string - variable to be substituted in arg value ("var1" would be
|
|
168
|
+
* substituted in place of {var1} of arg value)
|
|
169
|
+
* @param refKey: string - key of ref (added with .ref()) that points to installed software.
|
|
170
|
+
*/
|
|
171
|
+
substitutionRule: func(varName, refKey) {
|
|
172
|
+
substRules[varName] = refKey
|
|
173
|
+
return self
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Batched .substitutionRule() call (add several rules in single call)
|
|
178
|
+
*
|
|
179
|
+
* @param rules: map[string]string - <var name> -> <ref key> pairs to be added to substitution rules.
|
|
180
|
+
*/
|
|
181
|
+
substitutionRules: func(rules) {
|
|
182
|
+
for k, v in rules {
|
|
183
|
+
substRules[k] = v
|
|
184
|
+
}
|
|
185
|
+
return self
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Sets the queue name for the command.
|
|
190
|
+
*
|
|
191
|
+
* @param queueName: string - the name of the queue.
|
|
192
|
+
*/
|
|
193
|
+
inQueue: func(queueName) {
|
|
194
|
+
queue = queueName
|
|
195
|
+
return self
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Sets the stdout file name for the command.
|
|
200
|
+
*
|
|
201
|
+
* @param fileName: string - the name of the stdout file.
|
|
202
|
+
*/
|
|
203
|
+
stdout: func(fileName) {
|
|
204
|
+
stdout = fileName
|
|
205
|
+
return self
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Sets the stderr file name for the command.
|
|
210
|
+
*
|
|
211
|
+
* @param fileName: string - the name of the stderr file.
|
|
212
|
+
*/
|
|
213
|
+
stderr: func(fileName) {
|
|
214
|
+
stderr = fileName
|
|
215
|
+
return self
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Sets the number of error lines for the command.
|
|
220
|
+
*
|
|
221
|
+
* @param number: int - the number of error lines.
|
|
222
|
+
*/
|
|
223
|
+
nErrorLines: func(number) {
|
|
224
|
+
nErrorLines = number
|
|
225
|
+
return self
|
|
226
|
+
},
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Builds the RunCommand resource.
|
|
230
|
+
*
|
|
231
|
+
* @return object - the built RunCommand resource.
|
|
232
|
+
*/
|
|
233
|
+
build: func() {
|
|
234
|
+
// TODO: add assertions about the state
|
|
235
|
+
|
|
236
|
+
ll.assert(!hasPatternArgs || len(substRules) != 0,
|
|
237
|
+
"found pattern argument, but no substitution rules were set")
|
|
238
|
+
|
|
239
|
+
refsRes := smart.createMapResourceWithType(_RTYPE_RUN_COMMAND_REFS, refs)
|
|
240
|
+
self.getField("refs").set(refsRes)
|
|
241
|
+
|
|
242
|
+
cmdRes := smart.createValueResource(_RTYPE_RUN_COMMAND_CMD, json.encode(cmd))
|
|
243
|
+
self.getField("cmd").set(cmdRes)
|
|
244
|
+
|
|
245
|
+
options := {
|
|
246
|
+
queueName: queue,
|
|
247
|
+
errorLines: nErrorLines,
|
|
248
|
+
redirectStdout: stdout,
|
|
249
|
+
redirectStderr: stderr,
|
|
250
|
+
env: envs,
|
|
251
|
+
additionalPaths: customPaths,
|
|
252
|
+
substitutions: substRules
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
optionsRes := smart.createValueResource(_RTYPE_RUN_COMMAND_OPTIONS, json.encode(options))
|
|
256
|
+
self.getField("options").set(optionsRes)
|
|
257
|
+
|
|
258
|
+
argsRes := smart.createValueResource(_RTYPE_RUN_COMMAND_ARGS, json.encode(args))
|
|
259
|
+
self.getField("args").set(argsRes)
|
|
260
|
+
|
|
261
|
+
res := ll.toStrict(oop.inherit(self.lockAndBuild(), {
|
|
262
|
+
"workdir": self.outputs().workdirOut,
|
|
263
|
+
"options": options
|
|
264
|
+
}))
|
|
265
|
+
|
|
266
|
+
return res
|
|
267
|
+
}
|
|
268
|
+
}))
|
|
269
|
+
|
|
270
|
+
return self
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export ll.toStrict({
|
|
274
|
+
builder: builder
|
|
275
|
+
})
|