@platforma-sdk/tengo-builder 1.17.5 → 1.17.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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.map +1 -1
- package/dist/compiler/main.d.ts.map +1 -1
- package/dist/compiler/source.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 +8 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +52 -47
- 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 +4 -4
- 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 +62 -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/test.artifacts.ts +24 -24
- package/src/compiler/util.ts +7 -5
- 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.7",
|
|
4
4
|
"description": "Pl Tengo Template Builder",
|
|
5
5
|
"bin": {
|
|
6
6
|
"pl-tengo": "./bin/run.js"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"license": "UNLICENSED",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@milaboratories/tengo-tester": "^1.5.
|
|
15
|
+
"@milaboratories/tengo-tester": "^1.5.2",
|
|
16
16
|
"@oclif/core": "^4.0.37",
|
|
17
17
|
"canonicalize": "^2.0.0",
|
|
18
18
|
"winston": "^3.17.0",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"@jest/globals": "^29.7.0",
|
|
28
28
|
"ts-jest": "^29.2.5",
|
|
29
29
|
"@milaboratories/platforma-build-configs": "1.0.2",
|
|
30
|
-
"@milaboratories/
|
|
31
|
-
"@milaboratories/
|
|
30
|
+
"@milaboratories/oclif-index": "1.1.1",
|
|
31
|
+
"@milaboratories/eslint-config": "^1.0.1"
|
|
32
32
|
},
|
|
33
33
|
"oclif": {
|
|
34
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,56 +1,58 @@
|
|
|
1
|
-
import { ArtifactSource } from './source';
|
|
1
|
+
import type { ArtifactSource } from './source';
|
|
2
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';
|
|
14
|
-
import { TemplateData } from '@milaboratories/pl-model-backend';
|
|
16
|
+
import type { TemplateData } from '@milaboratories/pl-model-backend';
|
|
15
17
|
|
|
16
18
|
export interface TemplatesAndLibs {
|
|
17
|
-
templates: Template[]
|
|
18
|
-
libs: ArtifactSource[]
|
|
19
|
-
software: ArtifactSource[]
|
|
20
|
-
assets: ArtifactSource[]
|
|
19
|
+
templates: Template[];
|
|
20
|
+
libs: ArtifactSource[];
|
|
21
|
+
software: ArtifactSource[];
|
|
22
|
+
assets: ArtifactSource[];
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export class TengoTemplateCompiler {
|
|
24
26
|
constructor(
|
|
25
|
-
private readonly compileMode: CompileMode
|
|
27
|
+
private readonly compileMode: CompileMode,
|
|
26
28
|
) { }
|
|
27
29
|
|
|
28
|
-
private readonly libs = new ArtifactStore<ArtifactSource>(src => src.fullName);
|
|
29
|
-
private readonly software = new ArtifactStore<ArtifactSource>(src => src.fullName);
|
|
30
|
-
private readonly assets = new ArtifactStore<ArtifactSource>(src => src.fullName);
|
|
31
|
-
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);
|
|
32
34
|
|
|
33
35
|
private populateTemplateDataFromDependencies(fullName: FullArtifactName,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
data: TemplateData,
|
|
37
|
+
deps: TypedArtifactName[],
|
|
38
|
+
trace: string[]) {
|
|
37
39
|
for (const dep of deps) {
|
|
38
40
|
switch (dep.type) {
|
|
39
41
|
case 'library': {
|
|
40
42
|
const lib = this.getLibOrError(dep);
|
|
41
43
|
|
|
42
|
-
const recursionStart = trace.indexOf(artifactNameToString(dep))
|
|
44
|
+
const recursionStart = trace.indexOf(artifactNameToString(dep));
|
|
43
45
|
if (recursionStart >= 0) {
|
|
44
|
-
|
|
45
|
-
throw new Error(errorMessage)
|
|
46
|
+
const errorMessage = `library import recursion detected: ${trace.slice(recursionStart).join(' -> ')} -> ${artifactNameToString(dep)}`;
|
|
47
|
+
throw new Error(errorMessage);
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
const tplLib = {
|
|
49
51
|
...formatArtefactNameAndVersion(lib.fullName),
|
|
50
|
-
src: lib.src
|
|
51
|
-
}
|
|
52
|
+
src: lib.src,
|
|
53
|
+
};
|
|
52
54
|
|
|
53
|
-
applyLibraryCompilerOptions(lib.compilerOptions, tplLib)
|
|
55
|
+
applyLibraryCompilerOptions(lib.compilerOptions, tplLib);
|
|
54
56
|
data.libs[artifactNameToString(dep)] = tplLib;
|
|
55
57
|
|
|
56
58
|
// populate with transient library dependencies
|
|
@@ -58,25 +60,27 @@ export class TengoTemplateCompiler {
|
|
|
58
60
|
|
|
59
61
|
break;
|
|
60
62
|
}
|
|
61
|
-
case 'software':
|
|
63
|
+
case 'software': {
|
|
62
64
|
const software = this.getSoftwareOrError(dep);
|
|
63
65
|
data.software[artifactNameToString(dep)] = {
|
|
64
66
|
...formatArtefactNameAndVersion(software.fullName),
|
|
65
|
-
src: software.src
|
|
66
|
-
}
|
|
67
|
+
src: software.src,
|
|
68
|
+
};
|
|
67
69
|
|
|
68
70
|
break;
|
|
69
|
-
|
|
71
|
+
}
|
|
72
|
+
case 'asset': {
|
|
70
73
|
const asset = this.getAssetOrError(dep);
|
|
71
74
|
// Yes, we temporarily put assets into 'software' section of template, so controller can
|
|
72
75
|
// handle it the right way without updates
|
|
73
76
|
data.software[artifactNameToString(dep)] = {
|
|
74
77
|
...formatArtefactNameAndVersion(asset.fullName),
|
|
75
|
-
src: asset.src
|
|
76
|
-
}
|
|
78
|
+
src: asset.src,
|
|
79
|
+
};
|
|
77
80
|
|
|
78
81
|
break;
|
|
79
|
-
|
|
82
|
+
}
|
|
83
|
+
case 'template': {
|
|
80
84
|
if (typedArtifactNamesEquals(fullName, dep))
|
|
81
85
|
// skipping self reference
|
|
82
86
|
continue;
|
|
@@ -84,10 +88,11 @@ export class TengoTemplateCompiler {
|
|
|
84
88
|
const tpl = this.getTemplateOrError(dep);
|
|
85
89
|
data.templates[artifactNameToString(dep)] = tpl.data;
|
|
86
90
|
break;
|
|
91
|
+
}
|
|
87
92
|
case 'test':
|
|
88
93
|
throw new Error(
|
|
89
94
|
`dependencies tree error: tests should never be part of template: ${typedArtifactNameToString(dep)} is dependency of ${artifactNameToString(fullName)}`,
|
|
90
|
-
)
|
|
95
|
+
);
|
|
91
96
|
default:
|
|
92
97
|
assertNever(dep.type);
|
|
93
98
|
}
|
|
@@ -107,7 +112,7 @@ export class TengoTemplateCompiler {
|
|
|
107
112
|
libs: {},
|
|
108
113
|
software: {},
|
|
109
114
|
assets: {},
|
|
110
|
-
src: tplSrc.src
|
|
115
|
+
src: tplSrc.src,
|
|
111
116
|
};
|
|
112
117
|
|
|
113
118
|
applyTemplateCompilerOptions(tplSrc.compilerOptions, tplData);
|
|
@@ -121,15 +126,15 @@ export class TengoTemplateCompiler {
|
|
|
121
126
|
}
|
|
122
127
|
|
|
123
128
|
addLib(lib: ArtifactSource) {
|
|
124
|
-
const libFromMap = this.libs.add(lib.compileMode, lib, false)
|
|
129
|
+
const libFromMap = this.libs.add(lib.compileMode, lib, false);
|
|
125
130
|
if (libFromMap)
|
|
126
131
|
throw new Error(
|
|
127
|
-
`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)}`,
|
|
128
133
|
);
|
|
129
134
|
}
|
|
130
135
|
|
|
131
136
|
allLibs(): ArtifactSource[] {
|
|
132
|
-
return this.libs.array(this.compileMode)
|
|
137
|
+
return this.libs.array(this.compileMode);
|
|
133
138
|
}
|
|
134
139
|
|
|
135
140
|
getLib(name: TypedArtifactName): ArtifactSource | undefined {
|
|
@@ -146,15 +151,15 @@ export class TengoTemplateCompiler {
|
|
|
146
151
|
}
|
|
147
152
|
|
|
148
153
|
addSoftware(software: ArtifactSource) {
|
|
149
|
-
const swFromMap = this.software.add(software.compileMode, software, false)
|
|
154
|
+
const swFromMap = this.software.add(software.compileMode, software, false);
|
|
150
155
|
if (swFromMap)
|
|
151
156
|
throw new Error(
|
|
152
|
-
`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)}`,
|
|
153
158
|
);
|
|
154
159
|
}
|
|
155
160
|
|
|
156
161
|
allSoftware(): ArtifactSource[] {
|
|
157
|
-
return this.software.array(this.compileMode)
|
|
162
|
+
return this.software.array(this.compileMode);
|
|
158
163
|
}
|
|
159
164
|
|
|
160
165
|
getSoftware(name: TypedArtifactName): ArtifactSource | undefined {
|
|
@@ -172,15 +177,15 @@ export class TengoTemplateCompiler {
|
|
|
172
177
|
}
|
|
173
178
|
|
|
174
179
|
addAsset(asset: ArtifactSource) {
|
|
175
|
-
const assetFromMap = this.assets.add(asset.compileMode, asset, false)
|
|
180
|
+
const assetFromMap = this.assets.add(asset.compileMode, asset, false);
|
|
176
181
|
if (assetFromMap)
|
|
177
182
|
throw new Error(
|
|
178
|
-
`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)}`,
|
|
179
184
|
);
|
|
180
185
|
}
|
|
181
186
|
|
|
182
187
|
allAssets(): ArtifactSource[] {
|
|
183
|
-
return this.assets.array(this.compileMode)
|
|
188
|
+
return this.assets.array(this.compileMode);
|
|
184
189
|
}
|
|
185
190
|
|
|
186
191
|
getAsset(name: TypedArtifactName): ArtifactSource | undefined {
|
|
@@ -201,12 +206,12 @@ export class TengoTemplateCompiler {
|
|
|
201
206
|
const tplFromMap = this.templates.add(tpl.compileMode, tpl, false);
|
|
202
207
|
if (tplFromMap)
|
|
203
208
|
throw new Error(
|
|
204
|
-
`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)}`,
|
|
205
210
|
);
|
|
206
211
|
}
|
|
207
212
|
|
|
208
213
|
allTemplates(): Template[] {
|
|
209
|
-
return this.templates.array(this.compileMode)
|
|
214
|
+
return this.templates.array(this.compileMode);
|
|
210
215
|
}
|
|
211
216
|
|
|
212
217
|
getTemplate(name: TypedArtifactName): Template | undefined {
|
|
@@ -242,7 +247,7 @@ export class TengoTemplateCompiler {
|
|
|
242
247
|
}
|
|
243
248
|
|
|
244
249
|
checkLibs() {
|
|
245
|
-
this.libs.forEach(this.compileMode, lib => {
|
|
250
|
+
this.libs.forEach(this.compileMode, (lib) => {
|
|
246
251
|
for (const dep of lib.dependencies) {
|
|
247
252
|
if (dep.type === 'test')
|
|
248
253
|
throw new Error(`test should never be dependency of production code: ${typedArtifactNameToString(dep)} test is dependency of ${fullNameToString(lib.fullName)}`);
|
|
@@ -271,12 +276,12 @@ export class TengoTemplateCompiler {
|
|
|
271
276
|
this.addAsset(src);
|
|
272
277
|
ret.assets.push(src);
|
|
273
278
|
} else {
|
|
274
|
-
current.push(src)
|
|
279
|
+
current.push(src);
|
|
275
280
|
}
|
|
276
281
|
}
|
|
277
282
|
|
|
278
283
|
while (current.length > 0) {
|
|
279
|
-
const unprocessed: { src: ArtifactSource
|
|
284
|
+
const unprocessed: { src: ArtifactSource; err: Error }[] = [];
|
|
280
285
|
|
|
281
286
|
for (const src of current) {
|
|
282
287
|
//
|
|
@@ -286,17 +291,17 @@ export class TengoTemplateCompiler {
|
|
|
286
291
|
//
|
|
287
292
|
// This is equivalent to topological sorting of input sources.
|
|
288
293
|
//
|
|
289
|
-
const unsatisfied = src.dependencies.filter(dep =>
|
|
290
|
-
!this.getArtefact(dep)
|
|
294
|
+
const unsatisfied = src.dependencies.filter((dep) =>
|
|
295
|
+
!this.getArtefact(dep)
|
|
291
296
|
// allow self reference for templates
|
|
292
|
-
!(src.fullName.type === 'template' && typedArtifactNamesEquals(src.fullName, dep))
|
|
293
|
-
)
|
|
297
|
+
&& !(src.fullName.type === 'template' && typedArtifactNamesEquals(src.fullName, dep)),
|
|
298
|
+
);
|
|
294
299
|
if (unsatisfied.length > 0) {
|
|
295
|
-
let errorMessage = `Unsatisfied dependencies in ${fullNameToString(src.fullName)}:\n
|
|
300
|
+
let errorMessage = `Unsatisfied dependencies in ${fullNameToString(src.fullName)}:\n`;
|
|
296
301
|
for (const dep of unsatisfied) {
|
|
297
302
|
errorMessage += ` - ${typedArtifactNameToString(dep)}\n`;
|
|
298
303
|
}
|
|
299
|
-
unprocessed.push({ src, err: Error(errorMessage) })
|
|
304
|
+
unprocessed.push({ src, err: Error(errorMessage) });
|
|
300
305
|
|
|
301
306
|
continue;
|
|
302
307
|
}
|
|
@@ -323,11 +328,12 @@ export class TengoTemplateCompiler {
|
|
|
323
328
|
try {
|
|
324
329
|
const tpl = this.compileAndAddTemplate(src);
|
|
325
330
|
ret.templates.push(tpl);
|
|
326
|
-
} catch (
|
|
327
|
-
|
|
331
|
+
} catch (error: unknown) {
|
|
332
|
+
const err = error as Error;
|
|
333
|
+
let errorMessage = `Unsatisfied dependencies in ${fullNameToString(src.fullName)}:\n`;
|
|
328
334
|
errorMessage += ` - ${err.message}\n`;
|
|
329
335
|
|
|
330
|
-
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
|
|
331
337
|
}
|
|
332
338
|
break;
|
|
333
339
|
case 'test':
|
|
@@ -344,7 +350,7 @@ export class TengoTemplateCompiler {
|
|
|
344
350
|
let errorMessage = '';
|
|
345
351
|
|
|
346
352
|
for (const u of unprocessed) {
|
|
347
|
-
errorMessage += `\n${u.err.message}
|
|
353
|
+
errorMessage += `\n${u.err.message}`;
|
|
348
354
|
}
|
|
349
355
|
throw new Error(errorMessage);
|
|
350
356
|
}
|