@platforma-sdk/workflow-tengo 2.14.0 → 2.15.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 (80) hide show
  1. package/README.md +17 -1
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +3 -1
  4. package/dist/index.mjs +3 -1
  5. package/dist/tengo/lib/assets.lib.tengo +28 -28
  6. package/dist/tengo/lib/assets.swinfo.lib.tengo +24 -24
  7. package/dist/tengo/lib/constants.lib.tengo +6 -3
  8. package/dist/tengo/lib/exec.R.internal.lib.tengo +2 -2
  9. package/dist/tengo/lib/exec.R.lib.tengo +41 -41
  10. package/dist/tengo/lib/exec.descriptor.lib.tengo +3 -3
  11. package/dist/tengo/lib/exec.internal.lib.tengo +41 -41
  12. package/dist/tengo/lib/exec.lib.tengo +289 -289
  13. package/dist/tengo/lib/exec.limits.lib.tengo +49 -49
  14. package/dist/tengo/lib/exec.monetization.lib.tengo +1 -1
  15. package/dist/tengo/lib/exec.monetization_internal.lib.tengo +38 -38
  16. package/dist/tengo/lib/exec.package.lib.tengo +53 -53
  17. package/dist/tengo/lib/exec.python.internal.lib.tengo +1 -1
  18. package/dist/tengo/lib/exec.python.lib.tengo +37 -37
  19. package/dist/tengo/lib/exec.runcmd.lib.tengo +138 -138
  20. package/dist/tengo/lib/exec.runenv.lib.tengo +18 -18
  21. package/dist/tengo/lib/exec.stream.lib.tengo +25 -25
  22. package/dist/tengo/lib/feats.lib.tengo +3 -3
  23. package/dist/tengo/lib/file.internal.lib.tengo +31 -31
  24. package/dist/tengo/lib/file.lib.tengo +29 -29
  25. package/dist/tengo/lib/ll.get-future-field-default.lib.tengo +137 -0
  26. package/dist/tengo/lib/ll.lib.tengo +129 -129
  27. package/dist/tengo/lib/maps.lib.tengo +38 -38
  28. package/dist/tengo/lib/objects.lib.tengo +6 -6
  29. package/dist/tengo/lib/oop.lib.tengo +11 -11
  30. package/dist/tengo/lib/path.lib.tengo +60 -60
  31. package/dist/tengo/lib/pframes.builder.lib.tengo +3 -3
  32. package/dist/tengo/lib/pframes.constants.lib.tengo +20 -20
  33. package/dist/tengo/lib/pframes.export-pcolumn.lib.tengo +5 -5
  34. package/dist/tengo/lib/pframes.lib.tengo +206 -198
  35. package/dist/tengo/lib/pframes.ll.lib.tengo +59 -59
  36. package/dist/tengo/lib/pframes.pcolumn.lib.tengo +18 -18
  37. package/dist/tengo/lib/pframes.remove-nulls.lib.tengo +36 -0
  38. package/dist/tengo/lib/pframes.spec.lib.tengo +83 -83
  39. package/dist/tengo/lib/pframes.util.lib.tengo +176 -176
  40. package/dist/tengo/lib/pframes.xsv-import-file.lib.tengo +160 -0
  41. package/dist/tengo/lib/pframes.xsv.lib.tengo +84 -167
  42. package/dist/tengo/lib/render.lib.tengo +100 -45
  43. package/dist/tengo/lib/sets.lib.tengo +44 -44
  44. package/dist/tengo/lib/slices.lib.tengo +126 -126
  45. package/dist/tengo/lib/smart.lib.tengo +654 -507
  46. package/dist/tengo/lib/test.lib.tengo +120 -120
  47. package/dist/tengo/lib/tpl.lib.tengo +206 -170
  48. package/dist/tengo/lib/tpl.state-await.lib.tengo +17 -17
  49. package/dist/tengo/lib/tpl.util.lib.tengo +5 -5
  50. package/dist/tengo/lib/units.lib.tengo +2 -2
  51. package/dist/tengo/lib/validation.lib.tengo +130 -130
  52. package/dist/tengo/lib/waiter.lib.tengo +13 -13
  53. package/dist/tengo/lib/workdir.lib.tengo +126 -126
  54. package/dist/tengo/lib/workdir.proc.lib.tengo +47 -47
  55. package/dist/tengo/lib/workdir.save.lib.tengo +53 -53
  56. package/dist/tengo/lib/workflow.bobject.lib.tengo +11 -11
  57. package/dist/tengo/lib/workflow.bquery.lib.tengo +40 -40
  58. package/dist/tengo/lib/workflow.constants.lib.tengo +1 -1
  59. package/dist/tengo/lib/workflow.context.lib.tengo +16 -16
  60. package/dist/tengo/lib/workflow.lib.tengo +76 -76
  61. package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
  62. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  63. package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
  64. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  65. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  66. package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
  67. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  68. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  69. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  70. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  71. package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
  72. package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
  73. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  74. package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
  75. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  76. package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
  77. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  78. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  79. package/package.json +2 -2
  80. package/dist/tengo/tpl/pframes.map-pframe.plj.gz +0 -0
package/README.md CHANGED
@@ -1,6 +1,22 @@
1
+ # Platforma Template Engine: Intelligent Workflows Made Simple
2
+
3
+ *Transform static workflows into intelligent pipelines that make decisions as they process your data.*
4
+
5
+ The Platforma Template Engine (powered by Tengo) enables bioinformaticians and scientists to:
6
+
7
+ - Create workflows that automatically adapt to different data characteristics without manual intervention
8
+ - Build reusable analysis components that can be combined into sophisticated processing pipelines
9
+ - Define smart decision points where your workflow can take different paths based on results
10
+ - Handle varying data inputs and quality issues with built-in adaptive logic
11
+ - Focus on scientific questions instead of complex workflow orchestration
12
+ - Scale from simple analyses to complex multi-stage pipelines with minimal code
13
+ - Respond dynamically to unexpected data patterns or computational outcomes
14
+
15
+ Perfect for researchers who need flexible data processing that can intelligently respond to experimental results, sequence quality, or computational findings - all without requiring extensive programming expertise.
16
+
1
17
  # Resources
2
18
 
3
19
  - [Tengo syntax](https://github.com/d5/tengo/blob/master/docs/tutorial.md)
4
20
  - [Tengo builtin functions](https://github.com/d5/tengo/blob/master/docs/builtins.md)
5
- - [Modules provided by the pl (`tx` and `plapi`)](https://github.com/milaboratory/pl/blob/main/controllers/templates/pkg/lang/interpreter_api_v1.go)
21
+
6
22
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  declare type TemplateFromFile = { readonly type: "from-file"; readonly path: string; };
2
- declare type TplName = "pframes.export-single-pcolumn" | "pframes.import-dir" | "pframes.map-pframe" | "waiter.waiter" | "workdir.save" | "workflow.build-ctx" | "exec.R.create-renv" | "exec.python.install-deps" | "pframes.export-multiple-pcolumns" | "exec.python.create-venv" | "exec.monetization_to_json" | "exec.exec" | "pframes.xsv-export-pframe" | "pframes.xsv-import-map" | "pframes.process-pcolumn-data" | "pframes.export-pframe";
2
+ declare type TplName = "ll.get-field" | "pframes.export-single-pcolumn" | "pframes.import-dir" | "pframes.remove-nulls" | "waiter.waiter" | "workdir.save" | "workflow.build-ctx" | "exec.R.create-renv" | "exec.python.install-deps" | "pframes.export-multiple-pcolumns" | "exec.python.create-venv" | "exec.monetization_to_json" | "exec.exec" | "pframes.xsv-export-pframe" | "pframes.xsv-import-if-not-null" | "pframes.xsv-import-map" | "pframes.process-pcolumn-data" | "pframes.export-pframe";
3
3
  declare const Templates: Record<TplName, TemplateFromFile>;
4
4
  export { Templates };
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  module.exports = { Templates: {
2
+ 'll.get-field': { type: 'from-file', path: require.resolve('./tengo/tpl/ll.get-field.plj.gz') },
2
3
  'pframes.export-single-pcolumn': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.export-single-pcolumn.plj.gz') },
3
4
  'pframes.import-dir': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.import-dir.plj.gz') },
4
- 'pframes.map-pframe': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.map-pframe.plj.gz') },
5
+ 'pframes.remove-nulls': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.remove-nulls.plj.gz') },
5
6
  'waiter.waiter': { type: 'from-file', path: require.resolve('./tengo/tpl/waiter.waiter.plj.gz') },
6
7
  'workdir.save': { type: 'from-file', path: require.resolve('./tengo/tpl/workdir.save.plj.gz') },
7
8
  'workflow.build-ctx': { type: 'from-file', path: require.resolve('./tengo/tpl/workflow.build-ctx.plj.gz') },
@@ -12,6 +13,7 @@ module.exports = { Templates: {
12
13
  'exec.monetization_to_json': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.monetization_to_json.plj.gz') },
13
14
  'exec.exec': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.exec.plj.gz') },
14
15
  'pframes.xsv-export-pframe': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.xsv-export-pframe.plj.gz') },
16
+ 'pframes.xsv-import-if-not-null': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.xsv-import-if-not-null.plj.gz') },
15
17
  'pframes.xsv-import-map': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.xsv-import-map.plj.gz') },
16
18
  'pframes.process-pcolumn-data': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.process-pcolumn-data.plj.gz') },
17
19
  'pframes.export-pframe': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.export-pframe.plj.gz') }
package/dist/index.mjs CHANGED
@@ -1,8 +1,9 @@
1
1
  import { resolve } from 'node:path';
2
2
  export const Templates = {
3
+ 'll.get-field': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/ll.get-field.plj.gz') },
3
4
  'pframes.export-single-pcolumn': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.export-single-pcolumn.plj.gz') },
4
5
  'pframes.import-dir': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.import-dir.plj.gz') },
5
- 'pframes.map-pframe': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.map-pframe.plj.gz') },
6
+ 'pframes.remove-nulls': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.remove-nulls.plj.gz') },
6
7
  'waiter.waiter': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/waiter.waiter.plj.gz') },
7
8
  'workdir.save': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/workdir.save.plj.gz') },
8
9
  'workflow.build-ctx': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/workflow.build-ctx.plj.gz') },
@@ -13,6 +14,7 @@ export const Templates = {
13
14
  'exec.monetization_to_json': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.monetization_to_json.plj.gz') },
14
15
  'exec.exec': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.exec.plj.gz') },
15
16
  'pframes.xsv-export-pframe': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.xsv-export-pframe.plj.gz') },
17
+ 'pframes.xsv-import-if-not-null': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.xsv-import-if-not-null.plj.gz') },
16
18
  'pframes.xsv-import-map': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.xsv-import-map.plj.gz') },
17
19
  'pframes.process-pcolumn-data': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.process-pcolumn-data.plj.gz') },
18
20
  'pframes.export-pframe': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.export-pframe.plj.gz') }
@@ -1,4 +1,4 @@
1
- /** API to retrieve assets packed with template code (like other templates). */
1
+
2
2
 
3
3
  plapi := import("plapi")
4
4
  json := import("json")
@@ -7,30 +7,30 @@ smart := import("@platforma-sdk/workflow-tengo:smart")
7
7
  swinfo := import("@platforma-sdk/workflow-tengo:assets.swinfo")
8
8
  maps := import("@platforma-sdk/workflow-tengo:maps")
9
9
 
10
- /**
11
- * Returns resource of template available in current execution context.
12
- *
13
- * @param tplName: string - full name of a template, including namespace (package name).
14
- * Local templates (within the same package) can omit namespace part and start the name with colon:
15
- * - "@company/package:someTemplateName"
16
- * - ":myLocalTemplate"
17
- *
18
- * @return template: smart.resource - resource of tengo template with given name.
19
- */
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
20
  importTemplate := func(tplName) {
21
21
  return smart.resource(plapi.getTemplateId(tplName))
22
22
  }
23
23
 
24
- /**
25
- * Returns asset description suitable for 'exec' operations.
26
- * Asset is the way to put static files into working directory before execution of the command.
27
- *
28
- * @param assetName: string - full name of asset entrypoint, including namespace (NPM package name).
29
- * Local software entrypoints (within the same package) can omit namespace
30
- * part and start the name with colon:
31
- * - "@company/package:some-software"
32
- * - ":my-local-software"
33
- */
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
34
  importAsset := func(assetName) {
35
35
  asset := plapi.getSoftwareInfo(assetName)
36
36
  return ll.toStrict({
@@ -45,13 +45,13 @@ importAsset := func(assetName) {
45
45
  })
46
46
  }
47
47
 
48
- /**
49
- * Checks if given item is an asset info
50
- *
51
- * @param toCheck: any - item to check
52
- *
53
- * @return isAsset: boolean - true for asset info, loaded with importAsset()
54
- */
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
55
  isAssetInfo := func(toCheck) {
56
56
  if !ll.isMap(toCheck) {
57
57
  return false
@@ -1,6 +1,6 @@
1
- /**
2
- * A file that contains software info constructors and related functions.
3
- */
1
+
2
+
3
+
4
4
 
5
5
  plapi := import("plapi")
6
6
  ll := import("@platforma-sdk/workflow-tengo:ll")
@@ -8,9 +8,9 @@ maps := import("@platforma-sdk/workflow-tengo:maps")
8
8
  smart := import("@platforma-sdk/workflow-tengo:smart")
9
9
  json := import("json")
10
10
 
11
- /**
12
- * Creates a software info by sw that is got from backend.
13
- */
11
+
12
+
13
+
14
14
  newSoftwareInfo := func(sw) {
15
15
  return ll.toStrict({
16
16
  _type: "softwareDescriptor",
@@ -24,28 +24,28 @@ newSoftwareInfo := func(sw) {
24
24
  })
25
25
  }
26
26
 
27
- /**
28
- * Returns software description suitable for 'exec' operations.
29
- *
30
- * @param swName: string - full name of the software entrypoint, including namespace (NPM package name).
31
- * Local software entrypoints (within the same package) can omit namespace part
32
- * and start the name with colon:
33
- * - "@company/package:some-oftware"
34
- * - ":my-local-software"
35
- *
36
- * @return softwareInfo: softwareInfo - structure with software info.
37
- */
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
38
  importSoftware := func(swName) {
39
39
  return newSoftwareInfo(plapi.getSoftwareInfo(swName))
40
40
  }
41
41
 
42
- /**
43
- * Checks if given item is a software info
44
- *
45
- * @param toCheck: any - item to check
46
- *
47
- * @return isSoftware: boolean - true for software info, loaded with importSoftware()
48
- */
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
49
  isSoftwareInfo := func(toCheck) {
50
50
  if !ll.isMap(toCheck) {
51
51
  return false
@@ -1,11 +1,13 @@
1
- // constants
1
+
2
2
 
3
3
  ll := import("@platforma-sdk/workflow-tengo:ll")
4
4
 
5
+ RTYPE_NULL := { Name: "Null", Version: "1" }
6
+
5
7
  RTYPE_JSON := { Name: "json/object", Version: "1" }
6
8
 
7
9
  RTYPE_MAP := { Name: "std/map", Version: "1" }
8
- // @TODO this should be deleted once we align on map type name
10
+
9
11
  RTYPE_MAP_ALT := { Name: "StdMap", Version: "1" }
10
12
  RTYPE_MAP_EPH := { Name: "EphStdMap", Version: "1" }
11
13
 
@@ -34,7 +36,7 @@ RTYPE_WORKDIR_FILL_RULES := { Name: "WorkdirFill/rules", Version: "1" }
34
36
  RTYPE_WORKDIR_SAVE := { Name: "WorkdirSave", Version: "1" }
35
37
  RTYPE_WORKDIR_SAVE_RULES := { Name: "WorkdirSave/rules", Version: "1" }
36
38
 
37
- /** Main resource type of representing a PL error */
39
+
38
40
  RTYPE_JSON_ERROR := { Name: "json/resourceError", Version: "1"}
39
41
 
40
42
  FTYPE_OTW := "OTW" // Generic one-time writable field. The value of this field can be set only once.
@@ -50,6 +52,7 @@ export ll.toStrict({
50
52
  FTYPE_OUTPUT : FTYPE_OUTPUT,
51
53
  FTYPE_DYNAMIC : FTYPE_DYNAMIC,
52
54
 
55
+ RTYPE_NULL : RTYPE_NULL,
53
56
  RTYPE_BINARY_MAP : RTYPE_BINARY_MAP,
54
57
  RTYPE_BINARY_VALUE : RTYPE_BINARY_VALUE,
55
58
  RTYPE_BLOB_MAP : RTYPE_BLOB_MAP,
@@ -33,8 +33,8 @@ runRBuilder := func(operationMode, wd, rPackage, rDescriptor) {
33
33
  envTyped("RENV_PATHS_CACHE", t, path.join("{R}", "renv-root", "cache"))
34
34
 
35
35
  if (operationMode != "dev-local") {
36
- // In production we can use only locally cached packages: most of commercials have
37
- // Platforma Backend executed in a very restricted environment with limited access to the internet.
36
+
37
+
38
38
  builder.envTyped("RENV_CONFIG_REPOS_OVERRIDE", t, path.join("{R}", "packages"))
39
39
  }
40
40
 
@@ -67,67 +67,67 @@ rVenvBuilder := func() {
67
67
  return self
68
68
  },
69
69
 
70
- /**
71
- * Sets the cache time in milliseconds.
72
- *
73
- * @param millis: number
74
- */
70
+
71
+
72
+
73
+
74
+
75
75
  cacheMillis: func(millis) {
76
76
  ll.assert(is_int(millis) && millis > 0, "exec.R.cacheMillis: cache time must be a number of milliseconds")
77
77
  cache = millis * times.millisecond
78
78
  return self
79
79
  },
80
80
 
81
- /**
82
- * Sets the cache time in seconds.
83
- *
84
- * @param seconds: number
85
- */
81
+
82
+
83
+
84
+
85
+
86
86
  cacheSeconds: func(seconds) {
87
87
  ll.assert(is_int(seconds) && seconds > 0, "exec.R.cacheSeconds: cache time must be a number of seconds")
88
88
  cache = seconds * times.second
89
89
  return self
90
90
  },
91
91
 
92
- /**
93
- * Sets the cache time in minutes.
94
- *
95
- * @param minutes: number
96
- */
92
+
93
+
94
+
95
+
96
+
97
97
  cacheMinutes: func(minutes) {
98
98
  ll.assert(is_int(minutes) && minutes > 0, "exec.R.cacheMinutes: cache time must be a number of minutes")
99
99
  cache = minutes * times.minute
100
100
  return self
101
101
  },
102
102
 
103
- /**
104
- * Sets the cache time in hours.
105
- *
106
- * @param hours: number
107
- */
103
+
104
+
105
+
106
+
107
+
108
108
  cacheHours: func(hours) {
109
109
  ll.assert(is_int(hours) && hours > 0, "exec.R.cacheHours: cache time must be a number of hours")
110
110
  cache = hours * times.hour
111
111
  return self
112
112
  },
113
113
 
114
- /**
115
- * Sets the cache time in days
116
- *
117
- * @param days: number
118
- */
114
+
115
+
116
+
117
+
118
+
119
119
  cacheDays: func(days) {
120
120
  ll.assert(is_int(days) && days > 0, "exec.R.cacheDays: cache time must be a number of days")
121
121
  cache = days * times.hour * 24
122
122
  return self
123
123
  },
124
124
 
125
- /**
126
- * @deprecated, use cacheMillis, cacheSeconds, cacheMinutes, cacheHours and cacheDays instead.
127
- * Sets the cache time.
128
- *
129
- * @param time: duration - the cache time from 'times' library.
130
- */
125
+
126
+
127
+
128
+
129
+
130
+
131
131
  cache: func(time) {
132
132
  ll.assert(
133
133
  is_int(time) && time > times.millisecond,
@@ -156,20 +156,20 @@ rVenvBuilder := func() {
156
156
 
157
157
  self := undefined
158
158
  self = ll.toStrict(oop.inherit(tpl, {
159
- /**
160
- * R virtual environment with all dependencies installed.
161
- *
162
- * @return renv: smart.field - a reference to the R portable run environment.
163
- */
159
+
160
+
161
+
162
+
163
+
164
164
  venv: func() {
165
165
  return tpl.output(_OUTPUT_RUN_ENV, cache)
166
166
  },
167
167
 
168
- /**
169
- * R runtime used for R virtual environment creation.
170
- *
171
- * @return R: smart.Field - a reference to the R runtime.
172
- */
168
+
169
+
170
+
171
+
172
+
173
173
  R: func() {
174
174
  return rPkg
175
175
  }
@@ -1,6 +1,6 @@
1
- /** Everything about software descriptors
2
- * The scheme is here:
3
- * https://github.com/milaboratory/platforma/blob/main/tools/package-builder/src/core/renderer.ts#L161 */
1
+
2
+
3
+
4
4
 
5
5
 
6
6
  runEnvScheme := {
@@ -1,9 +1,9 @@
1
- /**
2
- * Internal 'exec' module library.
3
- *
4
- * NOT INTENDEND FOR USE OUTSIDE 'exec' MODULE.
5
- * May completely change API from release to release.
6
- */
1
+
2
+
3
+
4
+
5
+
6
+
7
7
 
8
8
  ll := import("@platforma-sdk/workflow-tengo:ll")
9
9
  feats := import("@platforma-sdk/workflow-tengo:feats")
@@ -22,7 +22,7 @@ constants := import("@platforma-sdk/workflow-tengo:exec.constants")
22
22
  desc := import("@platforma-sdk/workflow-tengo:exec.descriptor")
23
23
  validation := import("@platforma-sdk/workflow-tengo:validation")
24
24
 
25
- // Variables, substituted in command arguments and environment variable values.
25
+
26
26
  _ARG_VAR_PKG := "pkg" // abs path to software package
27
27
  _ARG_VAR_JAVA := "java" // abs path to 'java' run environment
28
28
  _ARG_VAR_PYTHON := "python" // abs path to 'python' run environment
@@ -30,7 +30,7 @@ _ARG_VAR_R := "R" // abs path to 'R' run environment runtime
30
30
  _ARG_VAR_R_VENV := "rVenv" // abs path to 'R' portable virtual environment
31
31
  _ARG_VAR_MNZ := "monetization" // monetization env value
32
32
 
33
- /** Converts the args above to the expressions. */
33
+
34
34
  _expr := func(varName) {
35
35
  return "{" + varName + "}"
36
36
  }
@@ -42,13 +42,13 @@ _newTypedArg := func(type, value) {
42
42
  })
43
43
  }
44
44
 
45
- /**
46
- * Create new argument with a type. The type can be either string, expression or variable.
47
- * Decides whether we need a simple argument or an expression one.
48
- * Until 15 Mar 2025, we keep deprecated variable arguments.
49
- *
50
- * @param isString: boolean - whether it is a string or a difficult (expression) argument.
51
- */
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
52
  _newArg := func(isString, value) {
53
53
  if isString {
54
54
  return _newTypedArg(constants.ARG_TYPE_STRING, value)
@@ -60,7 +60,7 @@ _newArg := func(isString, value) {
60
60
  }
61
61
 
62
62
  _newRefVar := func(varName, refName, reference) {
63
- // deprecated, remove on 15 Mar 2025
63
+
64
64
  if !feats.commandExpressions {
65
65
  return ll.toStrict({
66
66
  varName: "{" + varName + "}",
@@ -178,8 +178,8 @@ _loadRRunEnvironment := func(operationMode, descriptor, softName, softPkg) {
178
178
  }
179
179
 
180
180
  if (operationMode != "dev-local") {
181
- // In production we can use only locally cached packages: most of commercials have
182
- // Platforma Backend executed in a very restricted environment with limited access to the internet.
181
+
182
+
183
183
  envs["RENV_CONFIG_REPOS_OVERRIDE"] = _newArg(false, path.join(_expr(_ARG_VAR_R), "packages"))
184
184
  }
185
185
 
@@ -207,17 +207,17 @@ _loadRunEnvironment := func(operationMode, descriptor, softName, softPackage) {
207
207
  ll.panic("run environment type %q is not currently supported by workflow-sdk", descriptor.runEnv.type)
208
208
  }
209
209
 
210
- /**
211
- * @param operationMode: "remote" | "dev-local"
212
- */
210
+
211
+
212
+
213
213
  _binPackageCallOptions := func(operationMode, softwareName, variables, descriptor, softPackage) {
214
214
  customPaths := []
215
215
  envs := ll.toStrict({})
216
216
  args := []
217
217
  runEnvType := "binary"
218
218
 
219
- // Real command should be:
220
- // [<runEnv bin>] [<runEnv options>] [<entrypoint bin>] [<entrypoint options>] <cmd> <args>
219
+
220
+
221
221
  if (maps.containsKey(descriptor, "runEnv")) {
222
222
  runEnvInfo := _loadRunEnvironment(operationMode, descriptor, softwareName, softPackage)
223
223
 
@@ -280,10 +280,10 @@ _remotePackageCallOptions := func(softwareName, binaryDescriptor) {
280
280
  return _binPackageCallOptions("remote", softwareName, variables, binaryDescriptor, softPackage)
281
281
  }
282
282
 
283
- /** Turns a given software to a list of options that needs to be passed to run cmd builder.
284
- * Creates resources to install a software
285
- * and runs R or Python env builder templates
286
- * if it's necessary. */
283
+
284
+
285
+
286
+
287
287
  swToRunCmdOptions := func(softwareName, softwareVersion, softwareDescriptor) {
288
288
  ll.assert(is_string(softwareName),
289
289
  "exec.internal.swToRunCmdOptions: software name must be a string, got %v", softwareName)
@@ -303,8 +303,8 @@ swToRunCmdOptions := func(softwareName, softwareVersion, softwareDescriptor) {
303
303
  softwareName, softwareVersion)
304
304
  }
305
305
 
306
- // Clone result fields explicitly here
307
- // just to have a gist of what the function returns.
306
+
307
+
308
308
  return ll.toStrict({
309
309
  runEnvType: result.runEnvType,
310
310
  variables: result.variables,
@@ -320,9 +320,9 @@ binaryRunOptions := func(runOptions, mnzEnvs) {
320
320
 
321
321
  runCmdOpts := undefined
322
322
  if (is_undefined(ll.fromStrict(runOptions).software)) {
323
- //
324
- // Simple local command run, no software packages involved (backward compatibility)
325
- //
323
+
324
+
325
+
326
326
  runCmdOpts = _directCallOptions(runOptions)
327
327
  } else {
328
328
  software := runOptions.software
@@ -331,10 +331,10 @@ binaryRunOptions := func(runOptions, mnzEnvs) {
331
331
  runCmdOpts = swToRunCmdOptions(software.name, software.version, descriptor)
332
332
  }
333
333
 
334
- // adds exec builder's defined options from run options.
335
- // If argsTyped or envsTyped are set (which is a new API from exec.builder),
336
- // then pass them directly.
337
- // Otherwise, pass args and envs the old way, without possible expression evaluating.
334
+
335
+
336
+
337
+
338
338
  opts := ll.fromStrict(runOptions)
339
339
  shouldUseNewTyped := !is_undefined(opts.argsTyped) || !is_undefined(opts.envsTyped)
340
340
 
@@ -351,8 +351,8 @@ binaryRunOptions := func(runOptions, mnzEnvs) {
351
351
  }
352
352
 
353
353
  for name, val in mnzEnvs { // can be empty
354
- // if it's not empty, then we create an env that has
355
- // a result of monetization client.
354
+
355
+
356
356
  runCmdOpts.envs[name] = _newArg(false, _expr(_ARG_VAR_MNZ))
357
357
 
358
358
  runCmdOpts.variables = append(runCmdOpts.variables,
@@ -366,18 +366,18 @@ binaryRunOptions := func(runOptions, mnzEnvs) {
366
366
  prepareCommandRun := func(wd, opts) {
367
367
  runBuilder := runcmd.builder(wd)
368
368
 
369
- // Make installed packages to be available for the command run
369
+
370
370
  for varInfo in opts.variables {
371
371
  runBuilder.ref(varInfo.refName, varInfo.reference)
372
372
  runBuilder.substitutionRule(varInfo.varName, varInfo.refName)
373
373
  }
374
374
 
375
- // Patch command's PATH env variable
375
+
376
376
  for p in opts.customPaths {
377
377
  runBuilder.addToPath(p.type, p.value)
378
378
  }
379
379
 
380
- // Configure environment variables required for correct command run environment setup
380
+
381
381
  for name, value in opts.envs {
382
382
  runBuilder.envTyped(name, value.type, value.value)
383
383
  }