@platforma-sdk/workflow-tengo 6.8.3 → 6.10.0

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.
Files changed (53) hide show
  1. package/dist/tengo/lib/exec.constants.lib.tengo +2 -0
  2. package/dist/tengo/lib/exec.delayed-compute-allocation.lib.tengo +5 -1
  3. package/dist/tengo/lib/exec.formula.lib.tengo +13 -1
  4. package/dist/tengo/lib/exec.lib.tengo +152 -5
  5. package/dist/tengo/lib/exec.limits.lib.tengo +31 -0
  6. package/dist/tengo/lib/exec.tmpdir-compat.lib.tengo +270 -0
  7. package/dist/tengo/lib/feats.lib.tengo +12 -0
  8. package/dist/tengo/tpl/annotations.compute.plj.gz +0 -0
  9. package/dist/tengo/tpl/anonymize.deanonymize.plj.gz +0 -0
  10. package/dist/tengo/tpl/anonymize.impl.plj.gz +0 -0
  11. package/dist/tengo/tpl/check_network.create_workdir_from_storage.plj.gz +0 -0
  12. package/dist/tengo/tpl/check_network.download_blob.plj.gz +0 -0
  13. package/dist/tengo/tpl/check_network.run_hello_world.plj.gz +0 -0
  14. package/dist/tengo/tpl/check_network.run_hello_world_py.plj.gz +0 -0
  15. package/dist/tengo/tpl/check_network.upload_blob.plj.gz +0 -0
  16. package/dist/tengo/tpl/check_network.upload_template.plj.gz +0 -0
  17. package/dist/tengo/tpl/check_network.workdir_type_name_extractor.plj.gz +0 -0
  18. package/dist/tengo/tpl/exec.conda.create-env.plj.gz +0 -0
  19. package/dist/tengo/tpl/exec.delayed-compute-allocation.impl.plj.gz +0 -0
  20. package/dist/tengo/tpl/exec.exec-impl.plj.gz +0 -0
  21. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  22. package/dist/tengo/tpl/exec.load-software.impl.plj.gz +0 -0
  23. package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
  24. package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
  25. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  26. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  27. package/dist/tengo/tpl/exec.python.venv-bin-path.plj.gz +0 -0
  28. package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
  29. package/dist/tengo/tpl/pframes.build-table.plj.gz +0 -0
  30. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  31. package/dist/tengo/tpl/pframes.export-parquet-pcolumn-chunk.plj.gz +0 -0
  32. package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
  33. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  34. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  35. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  36. package/dist/tengo/tpl/pframes.merge-resource-maps.plj.gz +0 -0
  37. package/dist/tengo/tpl/pframes.parse-to-json.plj.gz +0 -0
  38. package/dist/tengo/tpl/pframes.process-pcolumn-batch-split.plj.gz +0 -0
  39. package/dist/tengo/tpl/pframes.process-pcolumn-batch.plj.gz +0 -0
  40. package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
  41. package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
  42. package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
  43. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  44. package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
  45. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  46. package/dist/tengo/tpl/pt.import-dir.plj.gz +0 -0
  47. package/dist/tengo/tpl/pt.workflow-run.plj.gz +0 -0
  48. package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
  49. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  50. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  51. package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
  52. package/dist/tengo/tpl/workflow.query-context-filter.plj.gz +0 -0
  53. package/package.json +2 -2
@@ -28,6 +28,7 @@ RUNNER_EXECUTOR := "executor" // local binary execution
28
28
  META_INPUT_MEM_FORMULA := "__memFormula__"
29
29
  META_INPUT_CPU_FORMULA := "__cpuFormula__"
30
30
  META_INPUT_GPU_FORMULA := "__gpuFormula__"
31
+ META_INPUT_SCRATCH_FORMULA := "__scratchFormula__"
31
32
  REGULAR_INPUT_LINE_COUNT := "__metric_lineCount__"
32
33
 
33
34
  export ll.toStrict({
@@ -49,5 +50,6 @@ export ll.toStrict({
49
50
  META_INPUT_MEM_FORMULA: META_INPUT_MEM_FORMULA,
50
51
  META_INPUT_CPU_FORMULA: META_INPUT_CPU_FORMULA,
51
52
  META_INPUT_GPU_FORMULA: META_INPUT_GPU_FORMULA,
53
+ META_INPUT_SCRATCH_FORMULA: META_INPUT_SCRATCH_FORMULA,
52
54
  REGULAR_INPUT_LINE_COUNT: REGULAR_INPUT_LINE_COUNT
53
55
  })
@@ -22,7 +22,8 @@ create := func(workdir, req) {
22
22
  "queue": "string",
23
23
  "cpu,?": "number",
24
24
  "ram,?": ["or", "number", "string"],
25
- "gpuMemory,?": "string"
25
+ "gpuMemory,?": "string",
26
+ "scratchFreeSpace,?": ["or", "number", "string"]
26
27
  }, "request must be a valid request")
27
28
 
28
29
  reqMap := { queue: req.queue }
@@ -35,6 +36,9 @@ create := func(workdir, req) {
35
36
  if !is_undefined(req.gpuMemory) {
36
37
  reqMap.gpuMemory = req.gpuMemory
37
38
  }
39
+ if !is_undefined(req.scratchFreeSpace) {
40
+ reqMap.scratchFreeSpace = req.scratchFreeSpace
41
+ }
38
42
 
39
43
  delayedComputeAllocation := render.createEphemeral(tpl, {
40
44
  request: smart.createJsonResource(reqMap),
@@ -298,12 +298,21 @@ referencedMetricFiles := func(resolvedNode) {
298
298
 
299
299
 
300
300
 
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
301
309
 
302
310
 
303
311
 
304
312
  applyFormulaFallback := func(dims) {
305
313
  gpu := is_undefined(dims.gpu) ? {} : dims.gpu
306
- res := { ram: dims.ram.static, cpu: dims.cpu.static, gpu: gpu.static, err: undefined }
314
+ scratch := is_undefined(dims.scratch) ? {} : dims.scratch
315
+ res := { ram: dims.ram.static, cpu: dims.cpu.static, gpu: gpu.static, scratch: scratch.static, err: undefined }
307
316
  if !is_undefined(_unwrap(dims.ram.ast)) && is_undefined(res.ram) {
308
317
  if is_undefined(dims.ram.fallback) {
309
318
  res.err = "exec.builder: the RAM formula needs a static fallback on backends that can't evaluate resource formulas at run time. Provide .staticFallback(...) on the RAM formula, set a static ram, or upgrade the backend."
@@ -325,6 +334,9 @@ applyFormulaFallback := func(dims) {
325
334
  }
326
335
  res.gpu = gpu.fallback
327
336
  }
337
+ if !is_undefined(_unwrap(scratch.ast)) && is_undefined(res.scratch) {
338
+ res.scratch = scratch.fallback
339
+ }
328
340
  return res
329
341
  }
330
342
 
@@ -19,6 +19,7 @@ constants := import("@platforma-sdk/workflow-tengo:constants")
19
19
  canonical := import("@platforma-sdk/workflow-tengo:canonical")
20
20
  monetization := import("@platforma-sdk/workflow-tengo:exec.monetization_internal")
21
21
  execConstants := import("@platforma-sdk/workflow-tengo:exec.constants")
22
+ tmpdirCompat := import("@platforma-sdk/workflow-tengo:exec.tmpdir-compat")
22
23
  execFormula := import("@platforma-sdk/workflow-tengo:exec.formula")
23
24
  units := import("@platforma-sdk/workflow-tengo:units")
24
25
  feats := import("@platforma-sdk/workflow-tengo:feats")
@@ -65,6 +66,16 @@ _assertValidGpuRequest := func(amount, ctx) {
65
66
 
66
67
 
67
68
 
69
+ _assertValidScratchRequest := func(amount, ctx) {
70
+ validation.assertType(amount, ["or", "number", "string"], ctx + ": scratch space amount must be a number of bytes or a size string like '500GiB'")
71
+ ll.assert(is_string(amount) || amount == 0 || amount >= 16 * units.MiB, ctx + ": scratch space in bytes should be at least 16MiB, or exactly 0 to ask only for a temporary directory (did you pass bytes instead of GiB?)")
72
+ }
73
+
74
+
75
+
76
+
77
+
78
+
68
79
  builder := func() {
69
80
  self := undefined
70
81
 
@@ -92,6 +103,7 @@ builder := func() {
92
103
  cpuRequest := undefined
93
104
  ramRequest := undefined
94
105
  gpuMemory := undefined
106
+ scratchFreeSpace := undefined
95
107
 
96
108
 
97
109
 
@@ -103,6 +115,8 @@ builder := func() {
103
115
  cpuFormulaFallback := undefined
104
116
  gpuFormulaAst := undefined
105
117
  gpuFormulaFallback := undefined
118
+ scratchFormulaAst := undefined
119
+ scratchFormulaFallback := undefined
106
120
  fileTags := {} // fileName -> tag (for f.size("tag") / f.lineCount("tag") aggregation)
107
121
 
108
122
  commandName := ""
@@ -520,6 +534,27 @@ builder := func() {
520
534
 
521
535
 
522
536
 
537
+
538
+
539
+
540
+
541
+
542
+
543
+
544
+
545
+
546
+
547
+
548
+
549
+
550
+
551
+
552
+
553
+
554
+
555
+
556
+
557
+
523
558
 
524
559
 
525
560
 
@@ -592,6 +627,20 @@ builder := func() {
592
627
  memFormulaFallback = undefined
593
628
  }
594
629
  }
630
+ setScratch := func(v, ctx) {
631
+ if execFormula.isFormula(v) {
632
+ scratchFormulaAst = execFormula.astOf(v)
633
+ scratchFormulaFallback = undefined
634
+ fb := execFormula.fallbackOf(v)
635
+ if !is_undefined(fb) { _assertValidScratchRequest(fb, ctx + " scratchFreeSpace fallback"); scratchFormulaFallback = fb }
636
+ scratchFreeSpace = undefined
637
+ } else {
638
+ _assertValidScratchRequest(v, ctx + " scratchFreeSpace")
639
+ scratchFreeSpace = v
640
+ scratchFormulaAst = undefined
641
+ scratchFormulaFallback = undefined
642
+ }
643
+ }
595
644
  setVram := func(v, ctx) {
596
645
  if execFormula.isFormula(v) {
597
646
  gpuFormulaAst = execFormula.astOf(v)
@@ -610,8 +659,8 @@ builder := func() {
610
659
  assertKeys := func(block, name, allowVram) {
611
660
  ll.assert(ll.isMap(block), "exec.builder.resources.%s: expected a map", name)
612
661
  for k, _ in block {
613
- ok := k == "cpu" || k == "ram" || (allowVram && k == "vram")
614
- ll.assert(ok, "exec.builder.resources.%s: unknown key %q (allowed: %s)", name, k, allowVram ? "cpu, ram, vram" : "cpu, ram")
662
+ ok := k == "cpu" || k == "ram" || k == "scratchFreeSpace" || (allowVram && k == "vram")
663
+ ll.assert(ok, "exec.builder.resources.%s: unknown key %q (allowed: %s)", name, k, allowVram ? "cpu, ram, vram, scratchFreeSpace" : "cpu, ram, scratchFreeSpace")
615
664
  }
616
665
  ll.assert(!is_undefined(block.cpu) && !is_undefined(block.ram),
617
666
  "exec.builder.resources.%s: cpu and ram are required", name)
@@ -636,15 +685,30 @@ builder := func() {
636
685
  "exec.builder.resources: onGPU was set without onCPU (GPU required), but this backend has no GPU support (exec.hasGpu is false). Add an onCPU block for an adaptive CPU fallback, or run on a GPU-enabled backend.")
637
686
  }
638
687
 
688
+
689
+
690
+
691
+ setScratchFrom := func(block, ctx) {
692
+ if is_undefined(block.scratchFreeSpace) {
693
+ scratchFreeSpace = undefined
694
+ scratchFormulaAst = undefined
695
+ scratchFormulaFallback = undefined
696
+ return
697
+ }
698
+ setScratch(block.scratchFreeSpace, ctx)
699
+ }
700
+
639
701
  if useGPU {
640
702
  g := spec.onGPU
641
703
  setCpu(g.cpu, "resources.onGPU")
642
704
  setRam(g.ram, "resources.onGPU")
643
705
  setVram(g.vram, "resources.onGPU")
706
+ setScratchFrom(g, "resources.onGPU")
644
707
  } else {
645
708
  c := spec.onCPU
646
709
  setCpu(c.cpu, "resources.onCPU")
647
710
  setRam(c.ram, "resources.onCPU")
711
+ setScratchFrom(c, "resources.onCPU")
648
712
 
649
713
 
650
714
  gpuMemory = undefined
@@ -1277,6 +1341,53 @@ builder := func() {
1277
1341
 
1278
1342
 
1279
1343
 
1344
+
1345
+
1346
+
1347
+ tmpdirCompatNeeded := tmpdirCompat.isNeeded(
1348
+ feats,
1349
+ tmpdirCompat.isSizedRequest(scratchFreeSpace, scratchFormulaAst)
1350
+ )
1351
+ if tmpdirCompatNeeded {
1352
+ filesToWrite[tmpdirCompat.SCRIPT_FILE_NAME] = tmpdirCompat.script()
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1359
+ args = slices.map(args, tmpdirCompat.rewriteScratchExpressions)
1360
+ argsTyped = slices.map(argsTyped, func(a) {
1361
+ a.value = tmpdirCompat.rewriteScratchExpressions(a.value)
1362
+ return a
1363
+ })
1364
+ envs = maps.mapValues(envs, tmpdirCompat.rewriteScratchExpressions)
1365
+ envsTyped = maps.mapValues(envsTyped, func(e) {
1366
+ e.value = tmpdirCompat.rewriteScratchExpressions(e.value)
1367
+ return e
1368
+ })
1369
+
1370
+
1371
+
1372
+ if is_undefined(soft) {
1373
+ wrapped := tmpdirCompat.wrapCommand(cmd)
1374
+ cmd = wrapped.cmd
1375
+
1376
+
1377
+
1378
+
1379
+ args = tmpdirCompat.concat(wrapped.prependArgs, args)
1380
+ argsTyped = tmpdirCompat.concat(
1381
+ slices.map(wrapped.prependArgs, func(a) {
1382
+ return { type: execConstants.ARG_TYPE_STRING, value: a }
1383
+ }),
1384
+ argsTyped)
1385
+ }
1386
+ }
1387
+
1388
+
1389
+
1390
+
1280
1391
  filesToWriteRefs := maps.mapValues(filesToWrite, func(v) {
1281
1392
  if smart.isReference(v) { return v }
1282
1393
  return smart.createValueResource(constants.RTYPE_BINARY_VALUE, v)
@@ -1333,10 +1444,12 @@ builder := func() {
1333
1444
 
1334
1445
 
1335
1446
 
1336
- hasFormula := !is_undefined(memFormulaAst) || !is_undefined(cpuFormulaAst) || !is_undefined(gpuFormulaAst)
1447
+ hasFormula := !is_undefined(memFormulaAst) || !is_undefined(cpuFormulaAst) ||
1448
+ !is_undefined(gpuFormulaAst) || !is_undefined(scratchFormulaAst)
1337
1449
  resolvedMem := undefined
1338
1450
  resolvedCpu := undefined
1339
1451
  resolvedGpu := undefined
1452
+ resolvedScratch := undefined
1340
1453
  lineCountMapResource := undefined
1341
1454
 
1342
1455
  if hasFormula {
@@ -1358,14 +1471,20 @@ builder := func() {
1358
1471
  fb := execFormula.applyFormulaFallback({
1359
1472
  ram: { ast: memFormulaAst, fallback: memFormulaFallback, static: ramRequest },
1360
1473
  cpu: { ast: cpuFormulaAst, fallback: cpuFormulaFallback, static: cpuRequest },
1361
- gpu: { ast: gpuFormulaAst, fallback: gpuFormulaFallback, static: gpuMemory }
1474
+ gpu: { ast: gpuFormulaAst, fallback: gpuFormulaFallback, static: gpuMemory },
1475
+ scratch: { ast: scratchFormulaAst, fallback: scratchFormulaFallback, static: scratchFreeSpace }
1362
1476
  })
1363
1477
  ll.assert(is_undefined(fb.err), fb.err)
1364
1478
  ramRequest = fb.ram
1365
1479
  cpuRequest = fb.cpu
1366
1480
  gpuMemory = fb.gpu
1481
+
1482
+
1483
+
1484
+ scratchFreeSpace = fb.scratch
1367
1485
  if is_int(ramRequest) { ramRequest = string(ramRequest) + "b" }
1368
1486
  if is_int(gpuMemory) { gpuMemory = string(gpuMemory) + "b" }
1487
+ if is_int(scratchFreeSpace) { scratchFreeSpace = string(scratchFreeSpace) + "b" }
1369
1488
  } else {
1370
1489
  tagMap := {}
1371
1490
  for fileName, tag in fileTags {
@@ -1390,6 +1509,11 @@ builder := func() {
1390
1509
  refs := execFormula.referencedMetricFiles(resolvedGpu)
1391
1510
  if !is_undefined(refs.lineCount) { sets.add(neededLineCount, refs.lineCount...) }
1392
1511
  }
1512
+ if !is_undefined(scratchFormulaAst) {
1513
+ resolvedScratch = execFormula.resolveAst(scratchFormulaAst, tagMap, allFiles)
1514
+ refs := execFormula.referencedMetricFiles(resolvedScratch)
1515
+ if !is_undefined(refs.lineCount) { sets.add(neededLineCount, refs.lineCount...) }
1516
+ }
1393
1517
 
1394
1518
  if len(neededLineCount) > 0 {
1395
1519
  perFile := {}
@@ -1419,6 +1543,24 @@ builder := func() {
1419
1543
 
1420
1544
  if !is_undefined(gpuMemory) { quotaData.gpuMemory = gpuMemory }
1421
1545
  }
1546
+
1547
+
1548
+
1549
+
1550
+
1551
+
1552
+
1553
+
1554
+
1555
+
1556
+
1557
+
1558
+
1559
+
1560
+
1561
+ scratchRequest := is_undefined(scratchFreeSpace) ? 0 : scratchFreeSpace
1562
+ if is_int(scratchRequest) { scratchRequest = string(scratchRequest) + "b" }
1563
+ quotaData.scratchFreeSpace = scratchRequest
1422
1564
  metaExecInputs := {
1423
1565
  quota: smart.createJsonResource(quotaData)
1424
1566
  }
@@ -1442,6 +1584,7 @@ builder := func() {
1442
1584
  if !is_undefined(resolvedMem) { metaExecInputs[execConstants.META_INPUT_MEM_FORMULA] = smart.createJsonResource(resolvedMem) }
1443
1585
  if !is_undefined(resolvedCpu) { metaExecInputs[execConstants.META_INPUT_CPU_FORMULA] = smart.createJsonResource(resolvedCpu) }
1444
1586
  if !is_undefined(resolvedGpu) { metaExecInputs[execConstants.META_INPUT_GPU_FORMULA] = smart.createJsonResource(resolvedGpu) }
1587
+ if !is_undefined(resolvedScratch) { metaExecInputs[execConstants.META_INPUT_SCRATCH_FORMULA] = smart.createJsonResource(resolvedScratch) }
1445
1588
  if !is_undefined(lineCountMapResource) { pureExecInputs[execConstants.REGULAR_INPUT_LINE_COUNT] = lineCountMapResource }
1446
1589
 
1447
1590
 
@@ -1466,10 +1609,14 @@ builder := func() {
1466
1609
 
1467
1610
  if !is_undefined(soft) {
1468
1611
  pureExecInputs.softwareInfo = soft.resource
1612
+ descriptor := ll.fromStrict(soft.descriptor)
1613
+ if tmpdirCompatNeeded {
1614
+ descriptor = tmpdirCompat.patchSoftwareDescriptor(descriptor, feats.isDockerAvailable)
1615
+ }
1469
1616
  pureExecInputs.runOptions.software = {
1470
1617
  name: soft.name,
1471
1618
  version: soft.version,
1472
- descriptor: ll.fromStrict(soft.descriptor)
1619
+ descriptor: descriptor
1473
1620
  }
1474
1621
  }
1475
1622
 
@@ -56,6 +56,7 @@ quotaBuilder := func() {
56
56
  cpu_request := undefined
57
57
  ram_request := undefined
58
58
  gpu_request := undefined
59
+ scratch_request := undefined
59
60
 
60
61
  self = ll.toStrict({
61
62
 
@@ -127,6 +128,33 @@ quotaBuilder := func() {
127
128
 
128
129
 
129
130
 
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+ scratchFreeSpace: func(amount) {
139
+ validation.assertType(
140
+ amount,
141
+ ["or", "number", "string", "null"],
142
+ "exec.quota.builder.scratchFreeSpace: scratch space amount should be a number or string")
143
+
144
+
145
+
146
+ ll.assert(is_undefined(amount) || is_string(amount) || amount >= 0,
147
+ "exec.quota.builder.scratchFreeSpace: amount in bytes cannot be negative")
148
+ scratch_request = amount
149
+
150
+ return self
151
+ },
152
+
153
+
154
+
155
+
156
+
157
+
130
158
  build: func() {
131
159
  ll.assert(queue_name != "", "exec.quota.builder: queue name is mandatory and could not be empty string")
132
160
 
@@ -142,6 +170,9 @@ quotaBuilder := func() {
142
170
  if !is_undefined(gpu_request) {
143
171
  data.gpuMemory = gpu_request
144
172
  }
173
+ if !is_undefined(scratch_request) {
174
+ data.scratchFreeSpace = scratch_request
175
+ }
145
176
 
146
177
  return smart.ephemeralBuilder(_RTYPE_QUOTA, json.encode(data)).lockAndBuild()
147
178
  }
@@ -0,0 +1,270 @@
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+ ll := import("@platforma-sdk/workflow-tengo:ll")
31
+ text := import("text")
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+ SCRIPT_FILE_NAME := ".pl-run-compat-f9b7eca1b8.sh"
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+ SCRATCH_PATH_VARIABLE := "system.scratch.path"
50
+ SCRATCH_SIZE_VARIABLES := ["system.scratch.bytes", "system.scratch.gib", "system.scratch.kib",
51
+ "system.scratch.mib", "system.scratch.gb", "system.scratch.kb", "system.scratch.mb",
52
+ "system.scratch.b"]
53
+
54
+
55
+
56
+
57
+ WORKDIR_TMP_REL_PATH := ".pl/tmp"
58
+
59
+
60
+
61
+
62
+
63
+
64
+ script := func() {
65
+ return `#!/bin/sh
66
+
67
+ # Compatibility layer between a current workflow-tengo SDK and a Platforma Backend from before
68
+ # the temporary-directory contract. Update the backend and this file stops appearing here.
69
+ #
70
+ # Written by exec.tmpdirCompat in @platforma-sdk/workflow-tengo.
71
+
72
+ wd="${PL_JOB_WORKDIR:-$PWD}"
73
+ tmp="$wd/` + WORKDIR_TMP_REL_PATH + `"
74
+ mkdir -p "$tmp"
75
+
76
+ TMPDIR="$tmp"
77
+ TMP="$tmp"
78
+ export TMPDIR TMP
79
+
80
+ exec "$@"
81
+ `
82
+ }
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+ isNeeded := func(feats, scratchSized) {
93
+ if feats.supportsScratchSpaceRequests {
94
+
95
+ return false
96
+ }
97
+
98
+ if feats.hasScratchSpace {
99
+
100
+ return !scratchSized
101
+ }
102
+
103
+
104
+ return true
105
+ }
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+ isSizedRequest := func(scratchFreeSpace, scratchFormulaAst) {
117
+ if !is_undefined(scratchFormulaAst) {
118
+ return true
119
+ }
120
+
121
+ if is_undefined(scratchFreeSpace) {
122
+ return false
123
+ }
124
+
125
+ return scratchFreeSpace != 0
126
+ }
127
+
128
+
129
+
130
+
131
+ isWindows := func() {
132
+ return ll.pathSeparator == "\\"
133
+ }
134
+
135
+
136
+
137
+
138
+
139
+ concat := func(prefix, tail) {
140
+ result := copy(prefix)
141
+ for item in tail {
142
+ result = append(result, item)
143
+ }
144
+
145
+ return result
146
+ }
147
+
148
+
149
+
150
+
151
+ _assertNotWindows := func() {
152
+ ll.assert(!isWindows(),
153
+ "exec.builder: this Platforma Backend is too old to provide a temporary directory (TMPDIR),"+
154
+ " and the workaround for it is POSIX-shell only, so it cannot run on Windows."+
155
+ " Update Platforma Backend to a version >=4.4.5")
156
+ }
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+
166
+
167
+
168
+
169
+ patchSoftwareDescriptor := func(descriptor, isDockerAvailable) {
170
+ if isDockerAvailable && !is_undefined(descriptor.docker) {
171
+ docker := ll.fromStrict(descriptor.docker)
172
+
173
+ entrypoint := docker.entrypoint
174
+ if is_undefined(entrypoint) { entrypoint = [] }
175
+ docker.entrypoint = concat(["sh", "./" + SCRIPT_FILE_NAME], entrypoint)
176
+
177
+ descriptor.docker = docker
178
+ return descriptor
179
+ }
180
+
181
+
182
+
183
+ _assertNotWindows()
184
+
185
+ for kind in ["local", "binary"] {
186
+ if is_undefined(descriptor[kind]) { continue }
187
+
188
+ pkg := ll.fromStrict(descriptor[kind])
189
+ ll.assert(is_array(pkg.cmd) && len(pkg.cmd) != 0,
190
+ "exec.tmpdirCompat: software descriptor %q has no 'cmd' to wrap", kind)
191
+
192
+ pkg.cmd = concat(["sh", "./" + SCRIPT_FILE_NAME], pkg.cmd)
193
+ descriptor[kind] = pkg
194
+ }
195
+
196
+ return descriptor
197
+ }
198
+
199
+
200
+
201
+
202
+
203
+
204
+ wrapCommand := func(cmd) {
205
+ _assertNotWindows()
206
+
207
+ return {
208
+ cmd: "sh",
209
+ prependArgs: ["./" + SCRIPT_FILE_NAME, cmd]
210
+ }
211
+ }
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+
232
+ rewriteScratchExpressions := func(value) {
233
+ if !is_string(value) {
234
+ return value
235
+ }
236
+
237
+
238
+ value = text.replace(value, "{" + SCRATCH_PATH_VARIABLE + "}", WORKDIR_TMP_REL_PATH, -1)
239
+ for variable in SCRATCH_SIZE_VARIABLES {
240
+ value = text.replace(value, "{" + variable + "}", "0", -1)
241
+ }
242
+
243
+ if !text.contains(value, "system.scratch.") {
244
+ return value
245
+ }
246
+
247
+
248
+ value = text.replace(value, SCRATCH_PATH_VARIABLE, "'" + WORKDIR_TMP_REL_PATH + "'", -1)
249
+ for variable in SCRATCH_SIZE_VARIABLES {
250
+ value = text.replace(value, variable, "0", -1)
251
+ }
252
+
253
+ return value
254
+ }
255
+
256
+ export ll.toStrict({
257
+ SCRIPT_FILE_NAME: SCRIPT_FILE_NAME,
258
+ WORKDIR_TMP_REL_PATH: WORKDIR_TMP_REL_PATH,
259
+ SCRATCH_PATH_VARIABLE: SCRATCH_PATH_VARIABLE,
260
+ SCRATCH_SIZE_VARIABLES: SCRATCH_SIZE_VARIABLES,
261
+
262
+ script: script,
263
+ isNeeded: isNeeded,
264
+ isSizedRequest: isSizedRequest,
265
+ isWindows: isWindows,
266
+ patchSoftwareDescriptor: patchSoftwareDescriptor,
267
+ wrapCommand: wrapCommand,
268
+ rewriteScratchExpressions: rewriteScratchExpressions,
269
+ concat: concat
270
+ })
@@ -82,5 +82,17 @@ export ll.toStrict({
82
82
 
83
83
 
84
84
 
85
+
86
+
87
+ supportsScratchSpaceRequests: _isEnabled("supportsScratchSpaceRequests"),
88
+
89
+
90
+
91
+
92
+ hasScratchSpace: _isEnabled("scratchSpace"),
93
+
94
+
95
+
96
+
85
97
  multiStepProgress: _isEnabled("multiStepProgress")
86
98
  })
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/workflow-tengo",
3
- "version": "6.8.3",
3
+ "version": "6.10.0",
4
4
  "description": "Tengo SDK library",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -23,7 +23,7 @@
23
23
  "@platforma-open/milaboratories.software-ptexter": "1.2.4"
24
24
  },
25
25
  "devDependencies": {
26
- "@platforma-sdk/tengo-builder": "4.0.23"
26
+ "@platforma-sdk/tengo-builder": "4.0.26"
27
27
  },
28
28
  "scripts": {
29
29
  "type-check": "pl-tengo check",