@platforma-sdk/tengo-builder 1.17.4 → 1.17.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/dist/commands/build.d.ts +4 -4
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/check.d.ts +1 -1
- package/dist/commands/dump/all.d.ts.map +1 -1
- package/dist/commands/dump/assets.d.ts.map +1 -1
- package/dist/commands/dump/libs.d.ts.map +1 -1
- package/dist/commands/dump/software.d.ts.map +1 -1
- package/dist/commands/dump/templates.d.ts.map +1 -1
- package/dist/commands/dump/tests.d.ts.map +1 -1
- package/dist/commands/test.d.ts +1 -1
- package/dist/compiler/artifactset.d.ts.map +1 -1
- package/dist/compiler/compiler.d.ts.map +1 -1
- package/dist/compiler/compileroptions.d.ts +1 -1
- package/dist/compiler/compileroptions.d.ts.map +1 -1
- package/dist/compiler/main.d.ts.map +1 -1
- package/dist/compiler/source.d.ts.map +1 -1
- package/dist/compiler/template.d.ts +1 -47
- package/dist/compiler/template.d.ts.map +1 -1
- package/dist/compiler/test.artifacts.d.ts.map +1 -1
- package/dist/compiler/util.d.ts.map +1 -1
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +153 -150
- package/dist/index.mjs.map +1 -1
- package/dist/shared/basecmd.d.ts +4 -4
- package/dist/shared/basecmd.d.ts.map +1 -1
- package/dist/shared/dump.d.ts.map +1 -1
- package/dist/shared/proc.d.ts +2 -2
- package/dist/shared/proc.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/commands/build.ts +12 -11
- package/src/commands/check.ts +2 -2
- package/src/commands/dump/all.ts +8 -8
- package/src/commands/dump/assets.ts +8 -8
- package/src/commands/dump/libs.ts +11 -12
- package/src/commands/dump/software.ts +8 -8
- package/src/commands/dump/templates.ts +8 -9
- package/src/commands/dump/tests.ts +8 -8
- package/src/commands/test.ts +1 -1
- package/src/compiler/artifactset.ts +14 -13
- package/src/compiler/compiler.ts +63 -56
- package/src/compiler/compileroptions.ts +12 -12
- package/src/compiler/main.ts +29 -27
- package/src/compiler/package.ts +1 -1
- package/src/compiler/source.ts +53 -51
- package/src/compiler/template.ts +23 -75
- package/src/compiler/test.artifacts.ts +24 -24
- package/src/compiler/util.ts +7 -5
- package/src/index.ts +1 -1
- package/src/shared/basecmd.ts +16 -16
- package/src/shared/dump.ts +22 -21
- package/src/shared/proc.ts +6 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/tengo-builder",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.6",
|
|
4
4
|
"description": "Pl Tengo Template Builder",
|
|
5
5
|
"bin": {
|
|
6
6
|
"pl-tengo": "./bin/run.js"
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"@milaboratories/tengo-tester": "^1.5.0",
|
|
16
16
|
"@oclif/core": "^4.0.37",
|
|
17
17
|
"canonicalize": "^2.0.0",
|
|
18
|
-
"winston": "^3.17.0"
|
|
18
|
+
"winston": "^3.17.0",
|
|
19
|
+
"@milaboratories/pl-model-backend": "^1.0.1"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
22
|
"typescript": "~5.5.4",
|
|
@@ -26,7 +27,8 @@
|
|
|
26
27
|
"@jest/globals": "^29.7.0",
|
|
27
28
|
"ts-jest": "^29.2.5",
|
|
28
29
|
"@milaboratories/platforma-build-configs": "1.0.2",
|
|
29
|
-
"@milaboratories/oclif-index": "1.1.
|
|
30
|
+
"@milaboratories/oclif-index": "1.1.1",
|
|
31
|
+
"@milaboratories/eslint-config": "^1.0.1"
|
|
30
32
|
},
|
|
31
33
|
"oclif": {
|
|
32
34
|
"bin": "pl-tengo",
|
package/src/commands/build.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { SpawnSyncReturns
|
|
1
|
+
import type { SpawnSyncReturns } from 'node:child_process';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
2
3
|
import { Command } from '@oclif/core';
|
|
3
4
|
import { compile, savePacks, getPackageInfo } from '../compiler/main';
|
|
4
5
|
import { createLogger } from '../compiler/util';
|
|
@@ -6,7 +7,7 @@ import { CtagsFlags, GlobalFlags } from '../shared/basecmd';
|
|
|
6
7
|
import * as fs from 'node:fs';
|
|
7
8
|
import * as fsp from 'node:fs/promises';
|
|
8
9
|
import * as path from 'node:path';
|
|
9
|
-
import * as winston from 'winston';
|
|
10
|
+
import type * as winston from 'winston';
|
|
10
11
|
|
|
11
12
|
export default class Build extends Command {
|
|
12
13
|
static override description = 'build tengo sources into single distributable pack file';
|
|
@@ -15,7 +16,7 @@ export default class Build extends Command {
|
|
|
15
16
|
|
|
16
17
|
static override flags = {
|
|
17
18
|
...GlobalFlags,
|
|
18
|
-
...CtagsFlags
|
|
19
|
+
...CtagsFlags,
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
public async run(): Promise<void> {
|
|
@@ -39,13 +40,13 @@ export default class Build extends Command {
|
|
|
39
40
|
const recordsCjs = compiledDist.templates
|
|
40
41
|
.map(
|
|
41
42
|
(tpl) =>
|
|
42
|
-
` '${tpl.fullName.id}': { type: 'from-file', path: require.resolve('./tengo/tpl/${tpl.fullName.id}.plj.gz') }
|
|
43
|
+
` '${tpl.fullName.id}': { type: 'from-file', path: require.resolve('./tengo/tpl/${tpl.fullName.id}.plj.gz') }`,
|
|
43
44
|
)
|
|
44
45
|
.join(',\n');
|
|
45
46
|
const recordsMjs = compiledDist.templates
|
|
46
47
|
.map(
|
|
47
48
|
(tpl) =>
|
|
48
|
-
` '${tpl.fullName.id}': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/${tpl.fullName.id}.plj.gz') }
|
|
49
|
+
` '${tpl.fullName.id}': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/${tpl.fullName.id}.plj.gz') }`,
|
|
49
50
|
)
|
|
50
51
|
.join(',\n');
|
|
51
52
|
cjs += recordsCjs;
|
|
@@ -92,7 +93,7 @@ function checkAndGenerateCtags(
|
|
|
92
93
|
flags: {
|
|
93
94
|
'tags-file': string;
|
|
94
95
|
'tags-additional-args': string[];
|
|
95
|
-
}
|
|
96
|
+
},
|
|
96
97
|
) {
|
|
97
98
|
const fileName = path.resolve(flags['tags-file']);
|
|
98
99
|
const rootDir = path.dirname(fileName);
|
|
@@ -103,8 +104,8 @@ function checkAndGenerateCtags(
|
|
|
103
104
|
|
|
104
105
|
logger.info(
|
|
105
106
|
`Generating tags for tengo autocompletion from "${rootDir}" \
|
|
106
|
-
in "${fileName}", additional arguments: "${additionalArgs}".
|
|
107
|
-
Found ${tengoFiles.length} tengo files
|
|
107
|
+
in "${fileName}", additional arguments: "${additionalArgs.join('" "')}".
|
|
108
|
+
Found ${tengoFiles.length} tengo files...`,
|
|
108
109
|
);
|
|
109
110
|
|
|
110
111
|
// see https://docs.ctags.io/en/lates// t/man/ctags-optlib.7.html#perl-pod
|
|
@@ -121,13 +122,13 @@ Found ${tengoFiles.length} tengo files...`
|
|
|
121
122
|
'--kinddef-tengo=c,constant,constant',
|
|
122
123
|
'--regex-tengo=/^\\s*(.*) := ("|\\{).*/\\1/c/',
|
|
123
124
|
'-R',
|
|
124
|
-
...tengoFiles
|
|
125
|
+
...tengoFiles,
|
|
125
126
|
],
|
|
126
127
|
{
|
|
127
128
|
env: process.env,
|
|
128
129
|
stdio: 'inherit',
|
|
129
|
-
cwd: rootDir
|
|
130
|
-
}
|
|
130
|
+
cwd: rootDir,
|
|
131
|
+
},
|
|
131
132
|
);
|
|
132
133
|
|
|
133
134
|
if (result.error?.message.includes('ENOENT')) {
|
package/src/commands/check.ts
CHANGED
package/src/commands/dump/all.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Command } from '@oclif/core'
|
|
2
|
-
import { createLogger } from '../../compiler/util'
|
|
3
|
-
import { dumpAll } from '../../shared/dump'
|
|
4
|
-
import { stdout } from 'process'
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { createLogger } from '../../compiler/util';
|
|
3
|
+
import { dumpAll } from '../../shared/dump';
|
|
4
|
+
import { stdout } from 'node:process';
|
|
5
5
|
|
|
6
6
|
export default class DumpAll extends Command {
|
|
7
|
-
static override description = 'parse sources in current package and dump all found artifacts to stdout'
|
|
7
|
+
static override description = 'parse sources in current package and dump all found artifacts to stdout';
|
|
8
8
|
|
|
9
9
|
static override examples = [
|
|
10
10
|
'<%= config.bin %> <%= command.id %>',
|
|
11
|
-
]
|
|
11
|
+
];
|
|
12
12
|
|
|
13
13
|
public async run(): Promise<void> {
|
|
14
|
-
const logger = createLogger()
|
|
15
|
-
dumpAll(logger, stdout)
|
|
14
|
+
const logger = createLogger();
|
|
15
|
+
dumpAll(logger, stdout);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Command } from '@oclif/core'
|
|
2
|
-
import { createLogger } from '../../compiler/util'
|
|
3
|
-
import { dumpAssets } from '../../shared/dump'
|
|
4
|
-
import { stdout } from 'process'
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { createLogger } from '../../compiler/util';
|
|
3
|
+
import { dumpAssets } from '../../shared/dump';
|
|
4
|
+
import { stdout } from 'node:process';
|
|
5
5
|
|
|
6
6
|
export default class DumpAssets extends Command {
|
|
7
|
-
static override description = 'parse sources in current package and dump all found
|
|
7
|
+
static override description = 'parse sources in current package and dump all found assets to stdout';
|
|
8
8
|
|
|
9
9
|
static override examples = [
|
|
10
10
|
'<%= config.bin %> <%= command.id %>',
|
|
11
|
-
]
|
|
11
|
+
];
|
|
12
12
|
|
|
13
13
|
public async run(): Promise<void> {
|
|
14
|
-
const logger = createLogger()
|
|
15
|
-
dumpAssets(logger, stdout)
|
|
14
|
+
const logger = createLogger();
|
|
15
|
+
dumpAssets(logger, stdout);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
import { Command, Flags } from '@oclif/core'
|
|
2
|
-
import { createLogger } from '../../compiler/util'
|
|
3
|
-
import { dumpLibs } from '../../shared/dump'
|
|
4
|
-
import { stdout } from 'process'
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { createLogger } from '../../compiler/util';
|
|
3
|
+
import { dumpLibs } from '../../shared/dump';
|
|
4
|
+
import { stdout } from 'node:process';
|
|
5
5
|
|
|
6
6
|
export default class DumpLibs extends Command {
|
|
7
|
-
static override description = 'parse sources in current package and dump all found
|
|
7
|
+
static override description = 'parse sources in current package and dump all found libs to stdout';
|
|
8
8
|
|
|
9
9
|
static override examples = [
|
|
10
10
|
'<%= config.bin %> <%= command.id %>',
|
|
11
|
-
]
|
|
11
|
+
];
|
|
12
12
|
|
|
13
13
|
static override flags = {
|
|
14
|
-
deps: Flags.boolean({name: 'deps', description: 'add also all libraries found in node_modules'}),
|
|
15
|
-
}
|
|
14
|
+
deps: Flags.boolean({ name: 'deps', description: 'add also all libraries found in node_modules' }),
|
|
15
|
+
};
|
|
16
16
|
|
|
17
17
|
public async run(): Promise<void> {
|
|
18
|
-
const {flags} = await this.parse(DumpLibs)
|
|
18
|
+
const { flags } = await this.parse(DumpLibs);
|
|
19
19
|
|
|
20
|
-
const logger = createLogger()
|
|
21
|
-
dumpLibs(logger, flags.deps, stdout)
|
|
20
|
+
const logger = createLogger();
|
|
21
|
+
dumpLibs(logger, flags.deps, stdout);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Command } from '@oclif/core'
|
|
2
|
-
import { createLogger } from '../../compiler/util'
|
|
3
|
-
import { dumpSoftware } from '../../shared/dump'
|
|
4
|
-
import { stdout } from 'process'
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { createLogger } from '../../compiler/util';
|
|
3
|
+
import { dumpSoftware } from '../../shared/dump';
|
|
4
|
+
import { stdout } from 'node:process';
|
|
5
5
|
|
|
6
6
|
export default class DumpSoftware extends Command {
|
|
7
|
-
static override description = 'parse sources in current package and dump all found
|
|
7
|
+
static override description = 'parse sources in current package and dump all found software to stdout';
|
|
8
8
|
|
|
9
9
|
static override examples = [
|
|
10
10
|
'<%= config.bin %> <%= command.id %>',
|
|
11
|
-
]
|
|
11
|
+
];
|
|
12
12
|
|
|
13
13
|
public async run(): Promise<void> {
|
|
14
|
-
const logger = createLogger()
|
|
15
|
-
dumpSoftware(logger, stdout)
|
|
14
|
+
const logger = createLogger();
|
|
15
|
+
dumpSoftware(logger, stdout);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import { Command } from '@oclif/core'
|
|
2
|
-
import { createLogger } from '../../compiler/util'
|
|
3
|
-
import { dumpTemplates } from '../../shared/dump'
|
|
4
|
-
import { stdout } from 'process'
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { createLogger } from '../../compiler/util';
|
|
3
|
+
import { dumpTemplates } from '../../shared/dump';
|
|
4
|
+
import { stdout } from 'node:process';
|
|
5
5
|
|
|
6
6
|
export default class DumpTemplates extends Command {
|
|
7
|
-
static override description = 'parse sources in current package and dump all found templates to stdout'
|
|
7
|
+
static override description = 'parse sources in current package and dump all found templates to stdout';
|
|
8
8
|
|
|
9
9
|
static override examples = [
|
|
10
10
|
'<%= config.bin %> <%= command.id %>',
|
|
11
|
-
]
|
|
11
|
+
];
|
|
12
12
|
|
|
13
13
|
public async run(): Promise<void> {
|
|
14
|
-
const logger = createLogger()
|
|
15
|
-
dumpTemplates(logger, stdout)
|
|
14
|
+
const logger = createLogger();
|
|
15
|
+
dumpTemplates(logger, stdout);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Command } from '@oclif/core'
|
|
2
|
-
import { createLogger } from '../../compiler/util'
|
|
3
|
-
import { dumpTests } from '../../shared/dump'
|
|
4
|
-
import { stdout } from 'process'
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { createLogger } from '../../compiler/util';
|
|
3
|
+
import { dumpTests } from '../../shared/dump';
|
|
4
|
+
import { stdout } from 'node:process';
|
|
5
5
|
|
|
6
6
|
export default class DumpTests extends Command {
|
|
7
|
-
static override description = 'parse sources in current package and dump all found tests to stdout'
|
|
7
|
+
static override description = 'parse sources in current package and dump all found tests to stdout';
|
|
8
8
|
|
|
9
9
|
static override examples = [
|
|
10
10
|
'<%= config.bin %> <%= command.id %>',
|
|
11
|
-
]
|
|
11
|
+
];
|
|
12
12
|
|
|
13
13
|
public async run(): Promise<void> {
|
|
14
|
-
const logger = createLogger()
|
|
15
|
-
dumpTests(logger, stdout)
|
|
14
|
+
const logger = createLogger();
|
|
15
|
+
dumpTests(logger, stdout);
|
|
16
16
|
}
|
|
17
17
|
}
|
package/src/commands/test.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { CompileMode, TypedArtifactName
|
|
1
|
+
import type { CompileMode, TypedArtifactName } from './package';
|
|
2
|
+
import { artifactKey } from './package';
|
|
2
3
|
import { assertNever } from './util';
|
|
3
4
|
|
|
4
5
|
export class ArtifactMap<T> {
|
|
@@ -22,35 +23,35 @@ export class ArtifactMap<T> {
|
|
|
22
23
|
|
|
23
24
|
get array(): T[] {
|
|
24
25
|
const ret: T[] = [];
|
|
25
|
-
this.map.forEach(obj => ret.push(obj));
|
|
26
|
+
this.map.forEach((obj) => ret.push(obj));
|
|
26
27
|
return ret;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
forEach(callback: (value: T, key: TypedArtifactName) => void) {
|
|
30
|
-
this.map.forEach(v => callback(v, this.nameExtractor(v)));
|
|
31
|
+
this.map.forEach((v) => callback(v, this.nameExtractor(v)));
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
export function createArtifactNameSet(): ArtifactMap<TypedArtifactName> {
|
|
35
|
-
return new ArtifactMap<TypedArtifactName>(obj => obj);
|
|
36
|
+
return new ArtifactMap<TypedArtifactName>((obj) => obj);
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
export class ArtifactStore<T> {
|
|
39
|
-
private readonly dev: ArtifactMap<T
|
|
40
|
-
private readonly dist: ArtifactMap<T
|
|
40
|
+
private readonly dev: ArtifactMap<T>;
|
|
41
|
+
private readonly dist: ArtifactMap<T>;
|
|
41
42
|
|
|
42
43
|
constructor(private readonly nameExtractor: (obj: T) => TypedArtifactName) {
|
|
43
|
-
this.dev = new ArtifactMap<T>(nameExtractor)
|
|
44
|
-
this.dist = new ArtifactMap<T>(nameExtractor)
|
|
44
|
+
this.dev = new ArtifactMap<T>(nameExtractor);
|
|
45
|
+
this.dist = new ArtifactMap<T>(nameExtractor);
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
add(mode: CompileMode, obj: T, replace: boolean = true): T | undefined {
|
|
48
49
|
switch (mode) {
|
|
49
50
|
case 'dist':
|
|
50
|
-
return this.dist.add(obj, replace)
|
|
51
|
+
return this.dist.add(obj, replace);
|
|
51
52
|
|
|
52
53
|
default:
|
|
53
|
-
assertNever(mode)
|
|
54
|
+
assertNever(mode);
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
|
|
@@ -60,17 +61,17 @@ export class ArtifactStore<T> {
|
|
|
60
61
|
return this.dist.get(name);
|
|
61
62
|
|
|
62
63
|
default:
|
|
63
|
-
assertNever(mode)
|
|
64
|
+
assertNever(mode);
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
array(mode: CompileMode): T[] {
|
|
68
69
|
const ret: T[] = [];
|
|
69
|
-
this.forEach(mode, obj => ret.push(obj));
|
|
70
|
+
this.forEach(mode, (obj) => ret.push(obj));
|
|
70
71
|
return ret;
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
forEach(mode: CompileMode, callback: (value: T, key: TypedArtifactName) => void) {
|
|
74
|
-
this.dist.forEach(
|
|
75
|
+
this.dist.forEach((obj, k) => callback(this.get(mode, k) ?? obj, k));
|
|
75
76
|
}
|
|
76
77
|
}
|
package/src/compiler/compiler.ts
CHANGED
|
@@ -1,55 +1,58 @@
|
|
|
1
|
-
import { ArtifactSource } from './source';
|
|
2
|
-
import { Template
|
|
1
|
+
import type { ArtifactSource } from './source';
|
|
2
|
+
import { Template } from './template';
|
|
3
|
+
import type {
|
|
4
|
+
TypedArtifactName, FullArtifactName,
|
|
5
|
+
CompileMode,
|
|
6
|
+
} from './package';
|
|
3
7
|
import {
|
|
4
|
-
TypedArtifactName,
|
|
5
8
|
fullNameToString,
|
|
6
9
|
typedArtifactNameToString,
|
|
7
10
|
artifactNameToString,
|
|
8
|
-
formatArtefactNameAndVersion, typedArtifactNamesEquals,
|
|
9
|
-
CompileMode
|
|
11
|
+
formatArtefactNameAndVersion, typedArtifactNamesEquals,
|
|
10
12
|
} from './package';
|
|
11
13
|
import { ArtifactStore } from './artifactset';
|
|
12
14
|
import { assertNever } from './util';
|
|
13
15
|
import { applyLibraryCompilerOptions, applyTemplateCompilerOptions } from './compileroptions';
|
|
16
|
+
import type { TemplateData } from '@milaboratories/pl-model-backend';
|
|
14
17
|
|
|
15
18
|
export interface TemplatesAndLibs {
|
|
16
|
-
templates: Template[]
|
|
17
|
-
libs: ArtifactSource[]
|
|
18
|
-
software: ArtifactSource[]
|
|
19
|
-
assets: ArtifactSource[]
|
|
19
|
+
templates: Template[];
|
|
20
|
+
libs: ArtifactSource[];
|
|
21
|
+
software: ArtifactSource[];
|
|
22
|
+
assets: ArtifactSource[];
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
export class TengoTemplateCompiler {
|
|
23
26
|
constructor(
|
|
24
|
-
private readonly compileMode: CompileMode
|
|
27
|
+
private readonly compileMode: CompileMode,
|
|
25
28
|
) { }
|
|
26
29
|
|
|
27
|
-
private readonly libs = new ArtifactStore<ArtifactSource>(src => src.fullName);
|
|
28
|
-
private readonly software = new ArtifactStore<ArtifactSource>(src => src.fullName);
|
|
29
|
-
private readonly assets = new ArtifactStore<ArtifactSource>(src => src.fullName);
|
|
30
|
-
private readonly templates = new ArtifactStore<Template>(tpl => tpl.fullName);
|
|
30
|
+
private readonly libs = new ArtifactStore<ArtifactSource>((src) => src.fullName);
|
|
31
|
+
private readonly software = new ArtifactStore<ArtifactSource>((src) => src.fullName);
|
|
32
|
+
private readonly assets = new ArtifactStore<ArtifactSource>((src) => src.fullName);
|
|
33
|
+
private readonly templates = new ArtifactStore<Template>((tpl) => tpl.fullName);
|
|
31
34
|
|
|
32
35
|
private populateTemplateDataFromDependencies(fullName: FullArtifactName,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
data: TemplateData,
|
|
37
|
+
deps: TypedArtifactName[],
|
|
38
|
+
trace: string[]) {
|
|
36
39
|
for (const dep of deps) {
|
|
37
40
|
switch (dep.type) {
|
|
38
41
|
case 'library': {
|
|
39
42
|
const lib = this.getLibOrError(dep);
|
|
40
43
|
|
|
41
|
-
const recursionStart = trace.indexOf(artifactNameToString(dep))
|
|
44
|
+
const recursionStart = trace.indexOf(artifactNameToString(dep));
|
|
42
45
|
if (recursionStart >= 0) {
|
|
43
|
-
|
|
44
|
-
throw new Error(errorMessage)
|
|
46
|
+
const errorMessage = `library import recursion detected: ${trace.slice(recursionStart).join(' -> ')} -> ${artifactNameToString(dep)}`;
|
|
47
|
+
throw new Error(errorMessage);
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
const tplLib = {
|
|
48
51
|
...formatArtefactNameAndVersion(lib.fullName),
|
|
49
|
-
src: lib.src
|
|
50
|
-
}
|
|
52
|
+
src: lib.src,
|
|
53
|
+
};
|
|
51
54
|
|
|
52
|
-
applyLibraryCompilerOptions(lib.compilerOptions, tplLib)
|
|
55
|
+
applyLibraryCompilerOptions(lib.compilerOptions, tplLib);
|
|
53
56
|
data.libs[artifactNameToString(dep)] = tplLib;
|
|
54
57
|
|
|
55
58
|
// populate with transient library dependencies
|
|
@@ -57,25 +60,27 @@ export class TengoTemplateCompiler {
|
|
|
57
60
|
|
|
58
61
|
break;
|
|
59
62
|
}
|
|
60
|
-
case 'software':
|
|
63
|
+
case 'software': {
|
|
61
64
|
const software = this.getSoftwareOrError(dep);
|
|
62
65
|
data.software[artifactNameToString(dep)] = {
|
|
63
66
|
...formatArtefactNameAndVersion(software.fullName),
|
|
64
|
-
src: software.src
|
|
65
|
-
}
|
|
67
|
+
src: software.src,
|
|
68
|
+
};
|
|
66
69
|
|
|
67
70
|
break;
|
|
68
|
-
|
|
71
|
+
}
|
|
72
|
+
case 'asset': {
|
|
69
73
|
const asset = this.getAssetOrError(dep);
|
|
70
74
|
// Yes, we temporarily put assets into 'software' section of template, so controller can
|
|
71
75
|
// handle it the right way without updates
|
|
72
76
|
data.software[artifactNameToString(dep)] = {
|
|
73
77
|
...formatArtefactNameAndVersion(asset.fullName),
|
|
74
|
-
src: asset.src
|
|
75
|
-
}
|
|
78
|
+
src: asset.src,
|
|
79
|
+
};
|
|
76
80
|
|
|
77
81
|
break;
|
|
78
|
-
|
|
82
|
+
}
|
|
83
|
+
case 'template': {
|
|
79
84
|
if (typedArtifactNamesEquals(fullName, dep))
|
|
80
85
|
// skipping self reference
|
|
81
86
|
continue;
|
|
@@ -83,10 +88,11 @@ export class TengoTemplateCompiler {
|
|
|
83
88
|
const tpl = this.getTemplateOrError(dep);
|
|
84
89
|
data.templates[artifactNameToString(dep)] = tpl.data;
|
|
85
90
|
break;
|
|
91
|
+
}
|
|
86
92
|
case 'test':
|
|
87
93
|
throw new Error(
|
|
88
94
|
`dependencies tree error: tests should never be part of template: ${typedArtifactNameToString(dep)} is dependency of ${artifactNameToString(fullName)}`,
|
|
89
|
-
)
|
|
95
|
+
);
|
|
90
96
|
default:
|
|
91
97
|
assertNever(dep.type);
|
|
92
98
|
}
|
|
@@ -106,7 +112,7 @@ export class TengoTemplateCompiler {
|
|
|
106
112
|
libs: {},
|
|
107
113
|
software: {},
|
|
108
114
|
assets: {},
|
|
109
|
-
src: tplSrc.src
|
|
115
|
+
src: tplSrc.src,
|
|
110
116
|
};
|
|
111
117
|
|
|
112
118
|
applyTemplateCompilerOptions(tplSrc.compilerOptions, tplData);
|
|
@@ -120,15 +126,15 @@ export class TengoTemplateCompiler {
|
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
addLib(lib: ArtifactSource) {
|
|
123
|
-
const libFromMap = this.libs.add(lib.compileMode, lib, false)
|
|
129
|
+
const libFromMap = this.libs.add(lib.compileMode, lib, false);
|
|
124
130
|
if (libFromMap)
|
|
125
131
|
throw new Error(
|
|
126
|
-
`compiler already contain such library: adding = ${fullNameToString(lib.fullName)}, contains = ${fullNameToString(libFromMap.fullName)}
|
|
132
|
+
`compiler already contain such library: adding = ${fullNameToString(lib.fullName)}, contains = ${fullNameToString(libFromMap.fullName)}`,
|
|
127
133
|
);
|
|
128
134
|
}
|
|
129
135
|
|
|
130
136
|
allLibs(): ArtifactSource[] {
|
|
131
|
-
return this.libs.array(this.compileMode)
|
|
137
|
+
return this.libs.array(this.compileMode);
|
|
132
138
|
}
|
|
133
139
|
|
|
134
140
|
getLib(name: TypedArtifactName): ArtifactSource | undefined {
|
|
@@ -145,15 +151,15 @@ export class TengoTemplateCompiler {
|
|
|
145
151
|
}
|
|
146
152
|
|
|
147
153
|
addSoftware(software: ArtifactSource) {
|
|
148
|
-
const swFromMap = this.software.add(software.compileMode, software, false)
|
|
154
|
+
const swFromMap = this.software.add(software.compileMode, software, false);
|
|
149
155
|
if (swFromMap)
|
|
150
156
|
throw new Error(
|
|
151
|
-
`compiler already contain info for software: adding = ${fullNameToString(software.fullName)}, contains = ${fullNameToString(swFromMap.fullName)}
|
|
157
|
+
`compiler already contain info for software: adding = ${fullNameToString(software.fullName)}, contains = ${fullNameToString(swFromMap.fullName)}`,
|
|
152
158
|
);
|
|
153
159
|
}
|
|
154
160
|
|
|
155
161
|
allSoftware(): ArtifactSource[] {
|
|
156
|
-
return this.software.array(this.compileMode)
|
|
162
|
+
return this.software.array(this.compileMode);
|
|
157
163
|
}
|
|
158
164
|
|
|
159
165
|
getSoftware(name: TypedArtifactName): ArtifactSource | undefined {
|
|
@@ -171,15 +177,15 @@ export class TengoTemplateCompiler {
|
|
|
171
177
|
}
|
|
172
178
|
|
|
173
179
|
addAsset(asset: ArtifactSource) {
|
|
174
|
-
const assetFromMap = this.assets.add(asset.compileMode, asset, false)
|
|
180
|
+
const assetFromMap = this.assets.add(asset.compileMode, asset, false);
|
|
175
181
|
if (assetFromMap)
|
|
176
182
|
throw new Error(
|
|
177
|
-
`compiler already contain info for asset: adding = ${fullNameToString(asset.fullName)}, contains = ${fullNameToString(assetFromMap.fullName)}
|
|
183
|
+
`compiler already contain info for asset: adding = ${fullNameToString(asset.fullName)}, contains = ${fullNameToString(assetFromMap.fullName)}`,
|
|
178
184
|
);
|
|
179
185
|
}
|
|
180
186
|
|
|
181
187
|
allAssets(): ArtifactSource[] {
|
|
182
|
-
return this.assets.array(this.compileMode)
|
|
188
|
+
return this.assets.array(this.compileMode);
|
|
183
189
|
}
|
|
184
190
|
|
|
185
191
|
getAsset(name: TypedArtifactName): ArtifactSource | undefined {
|
|
@@ -200,12 +206,12 @@ export class TengoTemplateCompiler {
|
|
|
200
206
|
const tplFromMap = this.templates.add(tpl.compileMode, tpl, false);
|
|
201
207
|
if (tplFromMap)
|
|
202
208
|
throw new Error(
|
|
203
|
-
`compiler already contain such template: adding = ${fullNameToString(tpl.fullName)}, contains = ${fullNameToString(tplFromMap.fullName)}
|
|
209
|
+
`compiler already contain such template: adding = ${fullNameToString(tpl.fullName)}, contains = ${fullNameToString(tplFromMap.fullName)}`,
|
|
204
210
|
);
|
|
205
211
|
}
|
|
206
212
|
|
|
207
213
|
allTemplates(): Template[] {
|
|
208
|
-
return this.templates.array(this.compileMode)
|
|
214
|
+
return this.templates.array(this.compileMode);
|
|
209
215
|
}
|
|
210
216
|
|
|
211
217
|
getTemplate(name: TypedArtifactName): Template | undefined {
|
|
@@ -241,7 +247,7 @@ export class TengoTemplateCompiler {
|
|
|
241
247
|
}
|
|
242
248
|
|
|
243
249
|
checkLibs() {
|
|
244
|
-
this.libs.forEach(this.compileMode, lib => {
|
|
250
|
+
this.libs.forEach(this.compileMode, (lib) => {
|
|
245
251
|
for (const dep of lib.dependencies) {
|
|
246
252
|
if (dep.type === 'test')
|
|
247
253
|
throw new Error(`test should never be dependency of production code: ${typedArtifactNameToString(dep)} test is dependency of ${fullNameToString(lib.fullName)}`);
|
|
@@ -270,12 +276,12 @@ export class TengoTemplateCompiler {
|
|
|
270
276
|
this.addAsset(src);
|
|
271
277
|
ret.assets.push(src);
|
|
272
278
|
} else {
|
|
273
|
-
current.push(src)
|
|
279
|
+
current.push(src);
|
|
274
280
|
}
|
|
275
281
|
}
|
|
276
282
|
|
|
277
283
|
while (current.length > 0) {
|
|
278
|
-
const unprocessed: { src: ArtifactSource
|
|
284
|
+
const unprocessed: { src: ArtifactSource; err: Error }[] = [];
|
|
279
285
|
|
|
280
286
|
for (const src of current) {
|
|
281
287
|
//
|
|
@@ -285,17 +291,17 @@ export class TengoTemplateCompiler {
|
|
|
285
291
|
//
|
|
286
292
|
// This is equivalent to topological sorting of input sources.
|
|
287
293
|
//
|
|
288
|
-
const unsatisfied = src.dependencies.filter(dep =>
|
|
289
|
-
!this.getArtefact(dep)
|
|
294
|
+
const unsatisfied = src.dependencies.filter((dep) =>
|
|
295
|
+
!this.getArtefact(dep)
|
|
290
296
|
// allow self reference for templates
|
|
291
|
-
!(src.fullName.type === 'template' && typedArtifactNamesEquals(src.fullName, dep))
|
|
292
|
-
)
|
|
297
|
+
&& !(src.fullName.type === 'template' && typedArtifactNamesEquals(src.fullName, dep)),
|
|
298
|
+
);
|
|
293
299
|
if (unsatisfied.length > 0) {
|
|
294
|
-
let errorMessage = `Unsatisfied dependencies in ${fullNameToString(src.fullName)}:\n
|
|
300
|
+
let errorMessage = `Unsatisfied dependencies in ${fullNameToString(src.fullName)}:\n`;
|
|
295
301
|
for (const dep of unsatisfied) {
|
|
296
302
|
errorMessage += ` - ${typedArtifactNameToString(dep)}\n`;
|
|
297
303
|
}
|
|
298
|
-
unprocessed.push({ src, err: Error(errorMessage) })
|
|
304
|
+
unprocessed.push({ src, err: Error(errorMessage) });
|
|
299
305
|
|
|
300
306
|
continue;
|
|
301
307
|
}
|
|
@@ -322,11 +328,12 @@ export class TengoTemplateCompiler {
|
|
|
322
328
|
try {
|
|
323
329
|
const tpl = this.compileAndAddTemplate(src);
|
|
324
330
|
ret.templates.push(tpl);
|
|
325
|
-
} catch (
|
|
326
|
-
|
|
331
|
+
} catch (error: unknown) {
|
|
332
|
+
const err = error as Error;
|
|
333
|
+
let errorMessage = `Unsatisfied dependencies in ${fullNameToString(src.fullName)}:\n`;
|
|
327
334
|
errorMessage += ` - ${err.message}\n`;
|
|
328
335
|
|
|
329
|
-
unprocessed.push({ src, err: Error(errorMessage) }) // one or more dependencies are not resolvable yet
|
|
336
|
+
unprocessed.push({ src, err: Error(errorMessage) }); // one or more dependencies are not resolvable yet
|
|
330
337
|
}
|
|
331
338
|
break;
|
|
332
339
|
case 'test':
|
|
@@ -343,7 +350,7 @@ export class TengoTemplateCompiler {
|
|
|
343
350
|
let errorMessage = '';
|
|
344
351
|
|
|
345
352
|
for (const u of unprocessed) {
|
|
346
|
-
errorMessage += `\n${u.err.message}
|
|
353
|
+
errorMessage += `\n${u.err.message}`;
|
|
347
354
|
}
|
|
348
355
|
throw new Error(errorMessage);
|
|
349
356
|
}
|