@travetto/pack 7.0.0-rc.1 → 7.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/package.json +4 -4
- package/src/config-util.ts +35 -35
- package/src/types.ts +10 -10
- package/support/bin/docker-operation.ts +29 -29
- package/support/bin/operation.ts +90 -89
- package/support/bin/preamble.ts +4 -4
- package/support/bin/shell.ts +20 -20
- package/support/bin/util.ts +13 -13
- package/support/cli.pack_docker.ts +10 -10
- package/support/pack.base.ts +17 -17
- package/support/pack.dockerfile.ts +1 -1
- package/support/rollup/config.ts +20 -20
- package/support/rollup/rollup-travetto-entry.ts +5 -5
- package/support/rollup/rollup-travetto-sourcemaps.ts +2 -2
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ $ trv pack --help
|
|
|
29
29
|
Usage: pack [options] [args...:string]
|
|
30
30
|
|
|
31
31
|
Options:
|
|
32
|
-
-b, --
|
|
32
|
+
-b, --buildDir <string> Workspace for building (default: "/tmp/<temp-folder>")
|
|
33
33
|
--clean, --no-clean Clean workspace (default: true)
|
|
34
34
|
-o, --output <string> Output location
|
|
35
35
|
--main-scripts, --no-main-scripts Create entry scripts (default: true)
|
|
@@ -95,7 +95,7 @@ $ trv pack:zip --help
|
|
|
95
95
|
Usage: pack:zip [options] [args...:string]
|
|
96
96
|
|
|
97
97
|
Options:
|
|
98
|
-
-b, --
|
|
98
|
+
-b, --buildDir <string> Workspace for building (default: "/tmp/<temp-folder>")
|
|
99
99
|
--clean, --no-clean Clean workspace (default: true)
|
|
100
100
|
-o, --output <string> Output location (default: "travetto_pack.zip")
|
|
101
101
|
--main-scripts, --no-main-scripts Create entry scripts (default: true)
|
|
@@ -124,7 +124,7 @@ $ trv pack:docker --help
|
|
|
124
124
|
Usage: pack:docker [options] [args...:string]
|
|
125
125
|
|
|
126
126
|
Options:
|
|
127
|
-
-b, --
|
|
127
|
+
-b, --buildDir <string> Workspace for building (default: "/tmp/<temp-folder>")
|
|
128
128
|
--clean, --no-clean Clean workspace (default: true)
|
|
129
129
|
-o, --output <string> Output location
|
|
130
130
|
--main-scripts, --no-main-scripts Create entry scripts (default: true)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/pack",
|
|
3
|
-
"version": "7.0.0-rc.
|
|
3
|
+
"version": "7.0.0-rc.2",
|
|
4
4
|
"description": "Code packing utilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"travetto",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"@rollup/plugin-json": "^6.1.0",
|
|
30
30
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
31
31
|
"@rollup/plugin-terser": "^0.4.4",
|
|
32
|
-
"@travetto/runtime": "^7.0.0-rc.
|
|
33
|
-
"@travetto/terminal": "^7.0.0-rc.
|
|
32
|
+
"@travetto/runtime": "^7.0.0-rc.2",
|
|
33
|
+
"@travetto/terminal": "^7.0.0-rc.2",
|
|
34
34
|
"rollup": "^4.53.3"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@travetto/cli": "^7.0.0-rc.
|
|
37
|
+
"@travetto/cli": "^7.0.0-rc.2"
|
|
38
38
|
},
|
|
39
39
|
"peerDependenciesMeta": {
|
|
40
40
|
"@travetto/cli": {
|
package/src/config-util.ts
CHANGED
|
@@ -7,15 +7,15 @@ export class PackConfigUtil {
|
|
|
7
7
|
/**
|
|
8
8
|
* Docker setup
|
|
9
9
|
*/
|
|
10
|
-
static dockerInit(
|
|
11
|
-
return `FROM ${
|
|
10
|
+
static dockerInit(config: DockerPackConfig): string {
|
|
11
|
+
return `FROM ${config.dockerImage}`;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Install docker pages in either apk or apt environments
|
|
16
16
|
*/
|
|
17
|
-
static dockerPackageInstall(
|
|
18
|
-
const { os, packages } =
|
|
17
|
+
static dockerPackageInstall(config: DockerPackConfig): string {
|
|
18
|
+
const { os, packages } = config.dockerRuntime;
|
|
19
19
|
if (packages?.length) {
|
|
20
20
|
switch (os) {
|
|
21
21
|
case 'alpine': return `RUN apk --update add ${packages.join(' ')} && rm -rf /var/cache/apk/*`;
|
|
@@ -32,9 +32,9 @@ export class PackConfigUtil {
|
|
|
32
32
|
/**
|
|
33
33
|
* Install docker pages in either apk or apt environments
|
|
34
34
|
*/
|
|
35
|
-
static dockerNodePackageInstall(
|
|
35
|
+
static dockerNodePackageInstall(config: DockerPackConfig): string {
|
|
36
36
|
const out: string[] = [];
|
|
37
|
-
for (const item of
|
|
37
|
+
for (const item of config.externalDependencies ?? []) {
|
|
38
38
|
const [name, directive] = item.split(':');
|
|
39
39
|
switch (directive) {
|
|
40
40
|
case 'from-source':
|
|
@@ -44,7 +44,7 @@ export class PackConfigUtil {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
if (out.length) {
|
|
47
|
-
out.unshift(`WORKDIR ${
|
|
47
|
+
out.unshift(`WORKDIR ${config.dockerRuntime.folder}`);
|
|
48
48
|
}
|
|
49
49
|
return out.join('\n');
|
|
50
50
|
}
|
|
@@ -52,22 +52,22 @@ export class PackConfigUtil {
|
|
|
52
52
|
/**
|
|
53
53
|
* Setup docker ports
|
|
54
54
|
*/
|
|
55
|
-
static dockerPorts(
|
|
56
|
-
return (
|
|
55
|
+
static dockerPorts(config: DockerPackConfig): string {
|
|
56
|
+
return (config.dockerPort?.map(port => `EXPOSE ${port}`) ?? []).join('\n');
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* Setup docker user
|
|
61
61
|
*/
|
|
62
|
-
static dockerUser(
|
|
63
|
-
const { os, user, group,
|
|
62
|
+
static dockerUser(config: DockerPackConfig): string {
|
|
63
|
+
const { os, user, group, userId, groupId } = config.dockerRuntime;
|
|
64
64
|
if (user === 'root') {
|
|
65
65
|
return '';
|
|
66
66
|
} else {
|
|
67
67
|
switch (os) {
|
|
68
|
-
case 'alpine': return `RUN addgroup -g ${
|
|
68
|
+
case 'alpine': return `RUN addgroup -g ${groupId} ${group} && adduser -D -G ${group} -u ${userId} ${user}`;
|
|
69
69
|
case 'debian':
|
|
70
|
-
case 'centos': return `RUN groupadd --gid ${
|
|
70
|
+
case 'centos': return `RUN groupadd --gid ${groupId} ${group} && useradd -u ${userId} -g ${group} ${user}`;
|
|
71
71
|
case 'unknown':
|
|
72
72
|
default: throw new Error('Unable to add user/group for an unknown os');
|
|
73
73
|
}
|
|
@@ -77,17 +77,17 @@ export class PackConfigUtil {
|
|
|
77
77
|
/**
|
|
78
78
|
* Setup Env Vars for NODE_OPTIONS and other standard environment variables
|
|
79
79
|
*/
|
|
80
|
-
static dockerEnvVars(
|
|
80
|
+
static dockerEnvVars(config: DockerPackConfig): string {
|
|
81
81
|
return [
|
|
82
|
-
`ENV NODE_OPTIONS="${[...(
|
|
82
|
+
`ENV NODE_OPTIONS="${[...(config.sourcemap ? ['--enable-source-maps'] : [])].join(' ')}"`,
|
|
83
83
|
].join('\n');
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
87
|
* Setup docker runtime folder
|
|
88
88
|
*/
|
|
89
|
-
static dockerAppFolder(
|
|
90
|
-
const { folder, user, group } =
|
|
89
|
+
static dockerAppFolder(config: DockerPackConfig): string {
|
|
90
|
+
const { folder, user, group } = config.dockerRuntime;
|
|
91
91
|
return [
|
|
92
92
|
`RUN mkdir ${folder} && chown ${user}:${group} ${folder}`,
|
|
93
93
|
].join('\n');
|
|
@@ -96,45 +96,45 @@ export class PackConfigUtil {
|
|
|
96
96
|
/**
|
|
97
97
|
* Docker app files copied with proper permissions
|
|
98
98
|
*/
|
|
99
|
-
static dockerAppFiles(
|
|
100
|
-
const { user, group, folder } =
|
|
99
|
+
static dockerAppFiles(config: DockerPackConfig): string {
|
|
100
|
+
const { user, group, folder } = config.dockerRuntime;
|
|
101
101
|
return `COPY --chown="${user}:${group}" . ${folder}`;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
105
|
* Entrypoint creation for a docker configuration
|
|
106
106
|
*/
|
|
107
|
-
static dockerEntrypoint(
|
|
108
|
-
const { user, folder } =
|
|
107
|
+
static dockerEntrypoint(config: DockerPackConfig): string {
|
|
108
|
+
const { user, folder } = config.dockerRuntime;
|
|
109
109
|
return [
|
|
110
110
|
`USER ${user}`,
|
|
111
111
|
`WORKDIR ${folder}`,
|
|
112
|
-
`ENTRYPOINT ["${folder}/${
|
|
112
|
+
`ENTRYPOINT ["${folder}/${config.mainName}.sh"]`,
|
|
113
113
|
].join('\n');
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
116
116
|
* Common docker environment setup
|
|
117
117
|
*/
|
|
118
|
-
static dockerWorkspace(
|
|
118
|
+
static dockerWorkspace(config: DockerPackConfig): string {
|
|
119
119
|
return [
|
|
120
|
-
this.dockerPorts(
|
|
121
|
-
this.dockerUser(
|
|
122
|
-
this.dockerPackageInstall(
|
|
123
|
-
this.dockerAppFolder(
|
|
124
|
-
this.dockerAppFiles(
|
|
125
|
-
this.dockerEnvVars(
|
|
126
|
-
].filter(
|
|
120
|
+
this.dockerPorts(config),
|
|
121
|
+
this.dockerUser(config),
|
|
122
|
+
this.dockerPackageInstall(config),
|
|
123
|
+
this.dockerAppFolder(config),
|
|
124
|
+
this.dockerAppFiles(config),
|
|
125
|
+
this.dockerEnvVars(config),
|
|
126
|
+
].filter(line => !!line).join('\n');
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
130
|
* Common docker file setup
|
|
131
131
|
*/
|
|
132
|
-
static dockerStandardFile(
|
|
132
|
+
static dockerStandardFile(config: DockerPackConfig): string {
|
|
133
133
|
return [
|
|
134
|
-
this.dockerInit(
|
|
135
|
-
this.dockerWorkspace(
|
|
136
|
-
this.dockerNodePackageInstall(
|
|
137
|
-
this.dockerEntrypoint(
|
|
134
|
+
this.dockerInit(config),
|
|
135
|
+
this.dockerWorkspace(config),
|
|
136
|
+
this.dockerNodePackageInstall(config),
|
|
137
|
+
this.dockerEntrypoint(config)
|
|
138
138
|
].join('\n');
|
|
139
139
|
}
|
|
140
140
|
}
|
package/src/types.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type OutputOptions } from 'rollup';
|
|
|
2
2
|
import type terser from '@rollup/plugin-terser';
|
|
3
3
|
|
|
4
4
|
export type CommonPackConfig = {
|
|
5
|
-
|
|
5
|
+
buildDirectory: string;
|
|
6
6
|
output: string;
|
|
7
7
|
clean: boolean;
|
|
8
8
|
ejectFile?: string;
|
|
@@ -40,29 +40,29 @@ export type DockerPackConfig = {
|
|
|
40
40
|
packages?: string[];
|
|
41
41
|
folder: string;
|
|
42
42
|
user: string;
|
|
43
|
-
|
|
43
|
+
userId: number;
|
|
44
44
|
group: string;
|
|
45
|
-
|
|
45
|
+
groupId: number;
|
|
46
46
|
};
|
|
47
47
|
} & CommonPackConfig;
|
|
48
48
|
|
|
49
|
-
export type
|
|
49
|
+
export type ShellCommandProvider = {
|
|
50
50
|
var(name: string): string;
|
|
51
51
|
createFile(file: string, text: string[], mode?: string): string[][];
|
|
52
52
|
callCommandWithAllArgs(cmd: string, ...args: string[]): string[];
|
|
53
|
-
copy(
|
|
54
|
-
copyRecursive(
|
|
55
|
-
rmRecursive(
|
|
56
|
-
mkdir(
|
|
53
|
+
copy(sourceFile: string, destinationFile: string): string[];
|
|
54
|
+
copyRecursive(sourceDirectory: string, destinationDirectory: string, inclusive?: boolean): string[];
|
|
55
|
+
rmRecursive(destinationDirectory: string): string[];
|
|
56
|
+
mkdir(destinationDirectory: string): string[];
|
|
57
57
|
export(key: string, value: string): string[];
|
|
58
|
-
chdir(
|
|
58
|
+
chdir(destinationDirectory: string): string[];
|
|
59
59
|
comment(message: string): string[];
|
|
60
60
|
echo(text: string): string[];
|
|
61
61
|
zip(output: string): string[];
|
|
62
62
|
script(lines: string[], chdir?: boolean): { ext: string, contents: string[] };
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
export type DockerPackFactory = (
|
|
65
|
+
export type DockerPackFactory = (config: DockerPackConfig) => (string | Promise<string>);
|
|
66
66
|
export type DockerPackFactoryModule = { factory: DockerPackFactory };
|
|
67
67
|
|
|
68
68
|
export type CoreRollupConfig = {
|
|
@@ -11,17 +11,17 @@ import { PackUtil } from './util.ts';
|
|
|
11
11
|
|
|
12
12
|
export class DockerPackOperation {
|
|
13
13
|
|
|
14
|
-
static getDockerTags(
|
|
15
|
-
return (
|
|
14
|
+
static getDockerTags(config: DockerPackConfig): string[] {
|
|
15
|
+
return (config.dockerTag ?? []).map(tag => config.dockerRegistry ? `${config.dockerRegistry}/${config.dockerName}:${tag}` : `${config.dockerName}:${tag}`);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Detect image os
|
|
20
20
|
*/
|
|
21
|
-
static async* detectDockerImageOs(
|
|
21
|
+
static async* detectDockerImageOs(config: DockerPackConfig): AsyncIterable<string[]> {
|
|
22
22
|
// Read os before writing
|
|
23
|
-
|
|
24
|
-
['docker', 'run', '--rm', '--entrypoint', '/bin/sh',
|
|
23
|
+
config.dockerRuntime.os = await PackUtil.runCommand(
|
|
24
|
+
['docker', 'run', '--rm', '--entrypoint', '/bin/sh', config.dockerImage, '-c', 'cat /etc/*release*']
|
|
25
25
|
).then(out => {
|
|
26
26
|
const found = out.match(/\b(?:debian|alpine|centos)\b/i)?.[0].toLowerCase();
|
|
27
27
|
switch (found) {
|
|
@@ -29,20 +29,20 @@ export class DockerPackOperation {
|
|
|
29
29
|
default: return 'unknown';
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
|
-
yield* PackOperation.title(
|
|
32
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Detected Image OS' }} ${{ param: config.dockerImage }} as ${{ param: config.dockerRuntime.os }}`);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Write Docker File
|
|
37
37
|
*/
|
|
38
|
-
static async* writeDockerFile(
|
|
39
|
-
const dockerFile = path.resolve(
|
|
40
|
-
const mod = await Runtime.importFrom<DockerPackFactoryModule>(
|
|
41
|
-
const content = (await mod.factory(
|
|
38
|
+
static async* writeDockerFile(config: DockerPackConfig): AsyncIterable<string[]> {
|
|
39
|
+
const dockerFile = path.resolve(config.buildDirectory, 'Dockerfile');
|
|
40
|
+
const mod = await Runtime.importFrom<DockerPackFactoryModule>(config.dockerFactory);
|
|
41
|
+
const content = (await mod.factory(config)).trim();
|
|
42
42
|
|
|
43
|
-
yield* PackOperation.title(
|
|
43
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Generating Docker File' }} ${{ path: dockerFile }} ${{ param: config.dockerFactory }}`);
|
|
44
44
|
|
|
45
|
-
if (
|
|
45
|
+
if (config.ejectFile) {
|
|
46
46
|
yield* ActiveShellCommand.createFile(dockerFile, content.split(/\n/));
|
|
47
47
|
} else {
|
|
48
48
|
await fs.writeFile(dockerFile, content, 'utf8');
|
|
@@ -52,12 +52,12 @@ export class DockerPackOperation {
|
|
|
52
52
|
/**
|
|
53
53
|
* Pull Docker Base Image
|
|
54
54
|
*/
|
|
55
|
-
static async* pullDockerBaseImage(
|
|
56
|
-
const command = ['docker', 'pull',
|
|
55
|
+
static async* pullDockerBaseImage(config: DockerPackConfig): AsyncIterable<string[]> {
|
|
56
|
+
const command = ['docker', 'pull', config.dockerImage];
|
|
57
57
|
|
|
58
|
-
yield* PackOperation.title(
|
|
58
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Pulling Docker Base Image' }} ${{ param: config.dockerImage }}`);
|
|
59
59
|
|
|
60
|
-
if (
|
|
60
|
+
if (config.ejectFile) {
|
|
61
61
|
yield command;
|
|
62
62
|
} else {
|
|
63
63
|
await PackUtil.runCommand(command);
|
|
@@ -67,22 +67,22 @@ export class DockerPackOperation {
|
|
|
67
67
|
/**
|
|
68
68
|
* Building Docker Container
|
|
69
69
|
*/
|
|
70
|
-
static async* buildDockerContainer(
|
|
70
|
+
static async* buildDockerContainer(config: DockerPackConfig): AsyncIterable<string[]> {
|
|
71
71
|
const cmd = [
|
|
72
72
|
'docker', 'build',
|
|
73
|
-
...(
|
|
74
|
-
...DockerPackOperation.getDockerTags(
|
|
73
|
+
...(config.dockerBuildPlatform ? ['--platform', config.dockerBuildPlatform] : []),
|
|
74
|
+
...DockerPackOperation.getDockerTags(config).flatMap(tag => ['-t', tag]), '.'
|
|
75
75
|
];
|
|
76
76
|
|
|
77
|
-
yield* PackOperation.title(
|
|
77
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Building Docker Container' }} ${{ param: config.dockerTag?.join(',') }}`);
|
|
78
78
|
|
|
79
|
-
if (
|
|
80
|
-
yield ActiveShellCommand.chdir(
|
|
79
|
+
if (config.ejectFile) {
|
|
80
|
+
yield ActiveShellCommand.chdir(config.buildDirectory);
|
|
81
81
|
yield cmd;
|
|
82
82
|
yield ActiveShellCommand.chdir(path.resolve());
|
|
83
83
|
} else {
|
|
84
|
-
await PackUtil.runCommand(cmd, { cwd:
|
|
85
|
-
const [image]: [{ Size: number }] = JSON.parse(await PackUtil.runCommand(['docker', 'inspect',
|
|
84
|
+
await PackUtil.runCommand(cmd, { cwd: config.buildDirectory, stdio: [0, 'pipe', 2] });
|
|
85
|
+
const [image]: [{ Size: number }] = JSON.parse(await PackUtil.runCommand(['docker', 'inspect', config.dockerImage]));
|
|
86
86
|
yield [cliTpl`${{ title: 'Built Docker Container ' }} ${{ identifier: 'sizeMb' }}=${{ param: Math.trunc(image.Size / 2 ** 20) }}`];
|
|
87
87
|
}
|
|
88
88
|
}
|
|
@@ -90,16 +90,16 @@ export class DockerPackOperation {
|
|
|
90
90
|
/**
|
|
91
91
|
* Push Docker Container
|
|
92
92
|
*/
|
|
93
|
-
static async* pushDockerContainer(
|
|
94
|
-
if (!
|
|
93
|
+
static async* pushDockerContainer(config: DockerPackConfig): AsyncIterable<string[]> {
|
|
94
|
+
if (!config.dockerPush) {
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
|
-
const tags = DockerPackOperation.getDockerTags(
|
|
97
|
+
const tags = DockerPackOperation.getDockerTags(config);
|
|
98
98
|
const cmd = ['docker', 'image', 'push'];
|
|
99
99
|
|
|
100
|
-
yield* PackOperation.title(
|
|
100
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Push Container to registry' }} ${{ param: config.dockerRegistry }}`);
|
|
101
101
|
|
|
102
|
-
if (
|
|
102
|
+
if (config.ejectFile) {
|
|
103
103
|
for (const tag of tags) {
|
|
104
104
|
yield [...cmd, tag];
|
|
105
105
|
}
|
package/support/bin/operation.ts
CHANGED
|
@@ -13,8 +13,8 @@ import { ActiveShellCommand, ShellCommands } from './shell.ts';
|
|
|
13
13
|
*/
|
|
14
14
|
export class PackOperation {
|
|
15
15
|
|
|
16
|
-
static async * title(
|
|
17
|
-
if (
|
|
16
|
+
static async * title(config: CommonPackConfig, title: string): AsyncIterable<string[]> {
|
|
17
|
+
if (config.ejectFile) {
|
|
18
18
|
yield ActiveShellCommand.comment(title);
|
|
19
19
|
yield ActiveShellCommand.echo(title);
|
|
20
20
|
} else {
|
|
@@ -25,72 +25,73 @@ export class PackOperation {
|
|
|
25
25
|
/**
|
|
26
26
|
* Clean out pack workspace, removing all content
|
|
27
27
|
*/
|
|
28
|
-
static async * clean(
|
|
29
|
-
if (!
|
|
28
|
+
static async * clean(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
29
|
+
if (!config.clean) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
yield* PackOperation.title(
|
|
33
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Cleaning Output' }} ${{ path: config.buildDirectory }}`);
|
|
34
34
|
|
|
35
|
-
if (
|
|
36
|
-
yield ActiveShellCommand.rmRecursive(
|
|
37
|
-
if (
|
|
38
|
-
yield ActiveShellCommand.rmRecursive(
|
|
35
|
+
if (config.ejectFile) {
|
|
36
|
+
yield ActiveShellCommand.rmRecursive(config.buildDirectory);
|
|
37
|
+
if (config.output) {
|
|
38
|
+
yield ActiveShellCommand.rmRecursive(config.output);
|
|
39
39
|
}
|
|
40
|
-
yield ActiveShellCommand.mkdir(
|
|
40
|
+
yield ActiveShellCommand.mkdir(config.buildDirectory);
|
|
41
41
|
} else {
|
|
42
|
-
await fs.rm(
|
|
43
|
-
if (
|
|
44
|
-
await fs.rm(
|
|
42
|
+
await fs.rm(config.buildDirectory, { recursive: true, force: true });
|
|
43
|
+
if (config.output) {
|
|
44
|
+
await fs.rm(config.output, { recursive: true, force: true });
|
|
45
45
|
}
|
|
46
|
-
await fs.mkdir(
|
|
46
|
+
await fs.mkdir(config.buildDirectory, { recursive: true });
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Invoke bundler (rollup) to produce output in workspace folder
|
|
52
52
|
*/
|
|
53
|
-
static async * bundle(
|
|
53
|
+
static async * bundle(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
54
54
|
const cwd = RuntimeIndex.outputRoot;
|
|
55
55
|
const out = RuntimeIndex.manifest.build.outputFolder;
|
|
56
56
|
|
|
57
|
-
const bundleCommand = ['npx', 'rollup', '-c', RuntimeIndex.resolveFileImport(
|
|
57
|
+
const bundleCommand = ['npx', 'rollup', '-c', RuntimeIndex.resolveFileImport(config.rollupConfiguration)];
|
|
58
58
|
|
|
59
|
-
const entryPointFile = RuntimeIndex.getFromImport(
|
|
59
|
+
const entryPointFile = RuntimeIndex.getFromImport(config.entryPoint)!.outputFile.split(`${out}/`)[1];
|
|
60
60
|
|
|
61
61
|
const env = {
|
|
62
62
|
...Object.fromEntries(([
|
|
63
63
|
['BUNDLE_ENTRY', entryPointFile],
|
|
64
|
-
['BUNDLE_MAIN_FILE',
|
|
65
|
-
['BUNDLE_COMPRESS',
|
|
66
|
-
['BUNDLE_SOURCEMAP',
|
|
67
|
-
['BUNDLE_SOURCES',
|
|
68
|
-
['BUNDLE_OUTPUT',
|
|
64
|
+
['BUNDLE_MAIN_FILE', config.mainFile],
|
|
65
|
+
['BUNDLE_COMPRESS', config.minify],
|
|
66
|
+
['BUNDLE_SOURCEMAP', config.sourcemap],
|
|
67
|
+
['BUNDLE_SOURCES', config.includeSources],
|
|
68
|
+
['BUNDLE_OUTPUT', config.buildDirectory],
|
|
69
69
|
['BUNDLE_FORMAT', Runtime.workspace.type],
|
|
70
|
-
['BUNDLE_ENV_FILE',
|
|
71
|
-
['BUNDLE_EXTERNAL',
|
|
70
|
+
['BUNDLE_ENV_FILE', config.envFile],
|
|
71
|
+
['BUNDLE_EXTERNAL', config.externalDependencies.map(mod => mod.split(':')[0]).join(',')]
|
|
72
72
|
] as const)
|
|
73
|
-
.filter(
|
|
74
|
-
.map(
|
|
73
|
+
.filter(pair => pair[1] === false || pair[1])
|
|
74
|
+
.map(pair => [pair[0], `${pair[1]}`])
|
|
75
75
|
),
|
|
76
|
-
...Env.TRV_MANIFEST.export(RuntimeIndex.getModule(
|
|
76
|
+
...Env.TRV_MANIFEST.export(RuntimeIndex.getModule(config.module)!.outputPath),
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
-
const
|
|
80
|
-
.map(
|
|
79
|
+
const properties = (['minify', 'sourcemap', 'entryPoint'] as const)
|
|
80
|
+
.map(key => cliTpl`${{ subtitle: key }}=${{ param: config[key] }}`).join(' ');
|
|
81
81
|
|
|
82
|
-
yield* PackOperation.title(
|
|
82
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Bundling Output' }} ${properties}`);
|
|
83
83
|
|
|
84
|
-
if (
|
|
85
|
-
yield* Object
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
if (config.ejectFile) {
|
|
85
|
+
yield* Object
|
|
86
|
+
.entries(env)
|
|
87
|
+
.filter(pair => !!pair[1])
|
|
88
|
+
.map(pair => ActiveShellCommand.export(pair[0], pair[1]));
|
|
88
89
|
yield ActiveShellCommand.chdir(cwd);
|
|
89
90
|
yield bundleCommand;
|
|
90
91
|
yield ActiveShellCommand.chdir(path.resolve());
|
|
91
92
|
} else {
|
|
92
93
|
await PackUtil.runCommand(bundleCommand, { cwd, env: { ...process.env, ...env }, stdio: [0, 'pipe', 2] });
|
|
93
|
-
const stat = await fs.stat(path.resolve(
|
|
94
|
+
const stat = await fs.stat(path.resolve(config.buildDirectory, config.mainFile));
|
|
94
95
|
yield [cliTpl`${{ title: 'Bundled Output ' }} ${{ identifier: 'sizeKb' }}=${{ param: Math.trunc(stat.size / 2 ** 10) }}`];
|
|
95
96
|
}
|
|
96
97
|
}
|
|
@@ -98,20 +99,20 @@ export class PackOperation {
|
|
|
98
99
|
/**
|
|
99
100
|
* Write out package.json, to help define how output .js file should be interpreted
|
|
100
101
|
*/
|
|
101
|
-
static async * writePackageJson(
|
|
102
|
+
static async * writePackageJson(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
102
103
|
const file = 'package.json';
|
|
103
|
-
const pkg = { type: Runtime.workspace.type, main:
|
|
104
|
+
const pkg = { type: Runtime.workspace.type, main: config.mainFile };
|
|
104
105
|
|
|
105
|
-
yield* PackOperation.title(
|
|
106
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Writing' }} ${{ path: file }}`);
|
|
106
107
|
|
|
107
|
-
if (
|
|
108
|
+
if (config.ejectFile) {
|
|
108
109
|
yield* ActiveShellCommand.createFile(
|
|
109
|
-
path.resolve(
|
|
110
|
+
path.resolve(config.buildDirectory, file),
|
|
110
111
|
[JSON.stringify(pkg)]
|
|
111
112
|
);
|
|
112
113
|
} else {
|
|
113
114
|
await PackUtil.writeRawFile(
|
|
114
|
-
path.resolve(
|
|
115
|
+
path.resolve(config.buildDirectory, file),
|
|
115
116
|
[JSON.stringify(pkg, null, 2)]
|
|
116
117
|
);
|
|
117
118
|
}
|
|
@@ -120,31 +121,31 @@ export class PackOperation {
|
|
|
120
121
|
/**
|
|
121
122
|
* Define .env.js file to control manifest location
|
|
122
123
|
*/
|
|
123
|
-
static async * writeEnv(
|
|
124
|
-
const file = path.resolve(
|
|
124
|
+
static async * writeEnv(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
125
|
+
const file = path.resolve(config.buildDirectory, config.envFile);
|
|
125
126
|
const env = {
|
|
126
127
|
...Env.NODE_ENV.export('production'),
|
|
127
|
-
...Env.TRV_MANIFEST.export(
|
|
128
|
-
...Env.TRV_MODULE.export(
|
|
128
|
+
...Env.TRV_MANIFEST.export(config.manifestFile),
|
|
129
|
+
...Env.TRV_MODULE.export(config.module),
|
|
129
130
|
...Env.TRV_CLI_IPC.export(undefined),
|
|
130
131
|
...Env.TRV_RESOURCE_OVERRIDES.export({
|
|
131
132
|
'@#resources': '@@#resources',
|
|
132
|
-
...(
|
|
133
|
-
'@@#resources': `@@#${
|
|
133
|
+
...(config.includeWorkspaceResources ? {
|
|
134
|
+
'@@#resources': `@@#${config.workspaceResourceFolder}`
|
|
134
135
|
} : {})
|
|
135
136
|
})
|
|
136
137
|
};
|
|
137
138
|
|
|
138
|
-
yield* PackOperation.title(
|
|
139
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Writing' }} ${{ path: file }}`);
|
|
139
140
|
|
|
140
|
-
if (
|
|
141
|
+
if (config.ejectFile) {
|
|
141
142
|
yield* ActiveShellCommand.createFile(
|
|
142
|
-
path.resolve(
|
|
143
|
+
path.resolve(config.buildDirectory, file),
|
|
143
144
|
PackUtil.buildEnvFile(env)
|
|
144
145
|
);
|
|
145
146
|
} else {
|
|
146
147
|
await PackUtil.writeRawFile(
|
|
147
|
-
path.resolve(
|
|
148
|
+
path.resolve(config.buildDirectory, file),
|
|
148
149
|
PackUtil.buildEnvFile(env)
|
|
149
150
|
);
|
|
150
151
|
}
|
|
@@ -153,26 +154,26 @@ export class PackOperation {
|
|
|
153
154
|
/**
|
|
154
155
|
* Create launcher scripts (.sh, .cmd) to run output
|
|
155
156
|
*/
|
|
156
|
-
static async * writeEntryScript(
|
|
157
|
-
if (!
|
|
157
|
+
static async * writeEntryScript(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
158
|
+
if (!config.mainScripts && !config.entryPoint.includes('@travetto/cli')) {
|
|
158
159
|
return;
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
const title = 'Writing entry scripts';
|
|
162
163
|
for (const sh of [ShellCommands.posix, ShellCommands.win32]) {
|
|
163
164
|
const { ext, contents } = sh.script(
|
|
164
|
-
sh.callCommandWithAllArgs('node',
|
|
165
|
+
sh.callCommandWithAllArgs('node', config.mainFile, ...config.entryArguments), true
|
|
165
166
|
);
|
|
166
|
-
const file = `${
|
|
167
|
-
const args =
|
|
167
|
+
const file = `${config.mainName}${ext}`;
|
|
168
|
+
const args = config.entryArguments.join(' ');
|
|
168
169
|
|
|
169
|
-
yield* PackOperation.title(
|
|
170
|
+
yield* PackOperation.title(config, cliTpl`${{ title }} ${{ path: file }} args=(${{ param: args }})`);
|
|
170
171
|
|
|
171
|
-
if (
|
|
172
|
-
yield* ActiveShellCommand.createFile(path.resolve(
|
|
172
|
+
if (config.ejectFile) {
|
|
173
|
+
yield* ActiveShellCommand.createFile(path.resolve(config.buildDirectory, file), contents, '755');
|
|
173
174
|
|
|
174
175
|
} else {
|
|
175
|
-
await PackUtil.writeRawFile(path.resolve(
|
|
176
|
+
await PackUtil.writeRawFile(path.resolve(config.buildDirectory, file), contents, '755');
|
|
176
177
|
}
|
|
177
178
|
}
|
|
178
179
|
}
|
|
@@ -180,42 +181,42 @@ export class PackOperation {
|
|
|
180
181
|
/**
|
|
181
182
|
* Copy over repo /resources folder into workspace, will get packaged into final output
|
|
182
183
|
*/
|
|
183
|
-
static async * copyMonoRepoResources(
|
|
184
|
-
if (!
|
|
184
|
+
static async * copyMonoRepoResources(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
185
|
+
if (!config.includeWorkspaceResources) {
|
|
185
186
|
return;
|
|
186
187
|
}
|
|
187
188
|
|
|
188
|
-
yield* PackOperation.title(
|
|
189
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Copying over workspace resources' }}`);
|
|
189
190
|
|
|
190
|
-
const
|
|
191
|
-
const
|
|
191
|
+
const destinationDirectory = path.resolve(config.buildDirectory, config.workspaceResourceFolder);
|
|
192
|
+
const sourceDirectory = Runtime.workspaceRelative('resources');
|
|
192
193
|
|
|
193
|
-
if (
|
|
194
|
-
yield ActiveShellCommand.copyRecursive(
|
|
194
|
+
if (config.ejectFile) {
|
|
195
|
+
yield ActiveShellCommand.copyRecursive(sourceDirectory, destinationDirectory, true);
|
|
195
196
|
} else {
|
|
196
|
-
await PackUtil.copyRecursive(
|
|
197
|
+
await PackUtil.copyRecursive(sourceDirectory, destinationDirectory, true);
|
|
197
198
|
}
|
|
198
199
|
}
|
|
199
200
|
|
|
200
201
|
/**
|
|
201
202
|
* Copy over /resources folder into workspace, will get packaged into final output
|
|
202
203
|
*/
|
|
203
|
-
static async * copyResources(
|
|
204
|
+
static async * copyResources(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
204
205
|
const resources = {
|
|
205
206
|
count: RuntimeIndex.mainModule.files.resources?.length ?? 0,
|
|
206
|
-
|
|
207
|
-
|
|
207
|
+
sourceDirectory: path.resolve(Runtime.mainSourcePath, 'resources'),
|
|
208
|
+
destinationDirectory: path.resolve(config.buildDirectory, 'resources')
|
|
208
209
|
};
|
|
209
210
|
|
|
210
|
-
yield* PackOperation.title(
|
|
211
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Copying over module resources' }}`);
|
|
211
212
|
|
|
212
|
-
if (
|
|
213
|
+
if (config.ejectFile) {
|
|
213
214
|
if (resources.count) {
|
|
214
|
-
yield ActiveShellCommand.copyRecursive(resources.
|
|
215
|
+
yield ActiveShellCommand.copyRecursive(resources.sourceDirectory, path.resolve(config.buildDirectory, 'resources'), true);
|
|
215
216
|
}
|
|
216
217
|
} else {
|
|
217
218
|
if (resources.count) {
|
|
218
|
-
await PackUtil.copyRecursive(resources.
|
|
219
|
+
await PackUtil.copyRecursive(resources.sourceDirectory, resources.destinationDirectory, true);
|
|
219
220
|
}
|
|
220
221
|
}
|
|
221
222
|
}
|
|
@@ -223,15 +224,15 @@ export class PackOperation {
|
|
|
223
224
|
/**
|
|
224
225
|
* Produce the output manifest, only including prod dependencies
|
|
225
226
|
*/
|
|
226
|
-
static async * writeManifest(
|
|
227
|
-
const out = path.resolve(
|
|
227
|
+
static async * writeManifest(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
228
|
+
const out = path.resolve(config.buildDirectory, config.manifestFile);
|
|
228
229
|
const cmd = ['npx', 'trvc', 'manifest', '--prod', out];
|
|
229
|
-
const env = { ...Env.TRV_MODULE.export(
|
|
230
|
+
const env = { ...Env.TRV_MODULE.export(config.module) };
|
|
230
231
|
|
|
231
|
-
yield* PackOperation.title(
|
|
232
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Writing Manifest' }} ${{ path: config.manifestFile }}`);
|
|
232
233
|
|
|
233
|
-
if (
|
|
234
|
-
yield [...Object.entries(env).map(([
|
|
234
|
+
if (config.ejectFile) {
|
|
235
|
+
yield [...Object.entries(env).map(([key, value]) => `${key}=${value}`), ...cmd];
|
|
235
236
|
} else {
|
|
236
237
|
await PackUtil.runCommand(cmd, { env: { ...process.env, ...env } });
|
|
237
238
|
}
|
|
@@ -240,18 +241,18 @@ export class PackOperation {
|
|
|
240
241
|
/**
|
|
241
242
|
* Generate ZIP file for workspace
|
|
242
243
|
*/
|
|
243
|
-
static async * compress(
|
|
244
|
+
static async * compress(config: CommonPackConfig): AsyncIterable<string[]> {
|
|
244
245
|
|
|
245
|
-
yield* PackOperation.title(
|
|
246
|
+
yield* PackOperation.title(config, cliTpl`${{ title: 'Compressing' }} ${{ path: config.output }}`);
|
|
246
247
|
|
|
247
|
-
if (
|
|
248
|
-
await ActiveShellCommand.mkdir(path.dirname(
|
|
249
|
-
yield ActiveShellCommand.chdir(
|
|
250
|
-
yield ActiveShellCommand.zip(
|
|
248
|
+
if (config.ejectFile) {
|
|
249
|
+
await ActiveShellCommand.mkdir(path.dirname(config.output));
|
|
250
|
+
yield ActiveShellCommand.chdir(config.buildDirectory);
|
|
251
|
+
yield ActiveShellCommand.zip(config.output);
|
|
251
252
|
yield ActiveShellCommand.chdir(path.resolve());
|
|
252
253
|
} else {
|
|
253
|
-
await fs.mkdir(path.dirname(
|
|
254
|
-
await PackUtil.runCommand(ActiveShellCommand.zip(
|
|
254
|
+
await fs.mkdir(path.dirname(config.output), { recursive: true });
|
|
255
|
+
await PackUtil.runCommand(ActiveShellCommand.zip(config.output), { cwd: config.buildDirectory });
|
|
255
256
|
}
|
|
256
257
|
}
|
|
257
258
|
}
|
package/support/bin/preamble.ts
CHANGED
|
@@ -4,15 +4,15 @@ import { readFileSync as readSyncPreamble } from 'node:fs';
|
|
|
4
4
|
const objectProto = Object.prototype.__proto__;
|
|
5
5
|
Object.defineProperty(Object.prototype, '__proto__', {
|
|
6
6
|
get() { return objectProto; },
|
|
7
|
-
set(
|
|
7
|
+
set(value) { Object.setPrototypeOf(this, value); }
|
|
8
8
|
});
|
|
9
9
|
|
|
10
10
|
if (!process.env.TRV_MODULE && '%%ENV_FILE%%') {
|
|
11
11
|
try {
|
|
12
12
|
readSyncPreamble('%%ENV_FILE%%', 'utf8')
|
|
13
13
|
.split('\n')
|
|
14
|
-
.map(
|
|
15
|
-
.filter(
|
|
16
|
-
.forEach(
|
|
14
|
+
.map(line => line.match(/\s*(?<key>[^ =]+)\s*=\s*(?<value>\S+)/)?.groups)
|
|
15
|
+
.filter(pair => !!pair)
|
|
16
|
+
.forEach(pair => process.env[pair.key] = pair.value);
|
|
17
17
|
} catch { }
|
|
18
18
|
}
|
package/support/bin/shell.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import util from 'node:util';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { ShellCommandProvider } from '../../src/types.ts';
|
|
5
5
|
|
|
6
6
|
const escape = (text: string): string =>
|
|
7
7
|
text
|
|
8
8
|
.replaceAll('"', '\\"')
|
|
9
9
|
.replaceAll('$', '\\$');
|
|
10
10
|
|
|
11
|
-
const escapedArgs = (args: string[]): string[] => args.map(
|
|
12
|
-
|
|
11
|
+
const escapedArgs = (args: string[]): string[] => args.map(arg =>
|
|
12
|
+
arg.includes(' ') || arg.includes('"') ? `'${arg}'` : (arg.includes("'") ? `"${arg}"` : arg)
|
|
13
13
|
);
|
|
14
14
|
|
|
15
15
|
const toWin = (file: string): string => file.replace(/[\\\/]+/g, path.win32.sep);
|
|
16
16
|
|
|
17
|
-
export const ShellCommands: Record<'win32' | 'posix',
|
|
17
|
+
export const ShellCommands: Record<'win32' | 'posix', ShellCommandProvider> = {
|
|
18
18
|
win32: {
|
|
19
19
|
var: (name: string) => `%${name}%`,
|
|
20
20
|
callCommandWithAllArgs: (cmd, ...args) => [[cmd, ...escapedArgs(args), '%*'].join(' ')],
|
|
@@ -24,20 +24,20 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
|
|
|
24
24
|
['echo', `"${escape(line)}"`, i === 0 ? '>' : '>>', file]
|
|
25
25
|
)
|
|
26
26
|
],
|
|
27
|
-
copy: (
|
|
28
|
-
copyRecursive: (
|
|
29
|
-
['xcopy', '/y', '/h', '/s', inclusive ? `${toWin(
|
|
30
|
-
rmRecursive: (
|
|
31
|
-
mkdir: (
|
|
27
|
+
copy: (sourceFile, destinationFile) => ['copy', sourceFile, destinationFile],
|
|
28
|
+
copyRecursive: (sourceDirectory, destinationDirectory, inclusive) =>
|
|
29
|
+
['xcopy', '/y', '/h', '/s', inclusive ? `${toWin(sourceDirectory)}\\*.*` : toWin(sourceDirectory), toWin(destinationDirectory)],
|
|
30
|
+
rmRecursive: (destinationDirectory) => ['rmdir', '/Q', '/S', destinationDirectory],
|
|
31
|
+
mkdir: (destinationDirectory) => ['md', destinationDirectory],
|
|
32
32
|
export: (key, value) => ['set', `${key}=${value}`],
|
|
33
|
-
chdir: (
|
|
33
|
+
chdir: (destinationDirectory) => ['cd', destinationDirectory],
|
|
34
34
|
comment: (message) => ['\nREM', util.stripVTControlCharacters(message), '\n'],
|
|
35
35
|
echo: (message) => ['echo', `"${escape(util.stripVTControlCharacters(message))}"\n`],
|
|
36
36
|
zip: (outputFile) => ['powershell', 'Compress-Archive', '-Path', '.', '-DestinationPath', outputFile],
|
|
37
|
-
script: (lines: string[],
|
|
37
|
+
script: (lines: string[], changeDirectory: boolean = false) => ({
|
|
38
38
|
ext: '.cmd',
|
|
39
39
|
contents: [
|
|
40
|
-
...(
|
|
40
|
+
...(changeDirectory ? ['cd %~p0'] : []),
|
|
41
41
|
...lines,
|
|
42
42
|
]
|
|
43
43
|
})
|
|
@@ -50,21 +50,21 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
|
|
|
50
50
|
['echo', `"${escape(line)}"`, i === 0 ? '>' : '>>', file]),
|
|
51
51
|
...(mode ? [['chmod', mode, file]] : [])
|
|
52
52
|
],
|
|
53
|
-
copy: (
|
|
54
|
-
copyRecursive: (
|
|
55
|
-
['cp', '-r', '-p', inclusive ? `${
|
|
56
|
-
rmRecursive: (
|
|
57
|
-
mkdir: (
|
|
53
|
+
copy: (sourceFile, destinationFile) => ['cp', sourceFile, destinationFile],
|
|
54
|
+
copyRecursive: (sourceDirectory, destinationDirectory, inclusive) =>
|
|
55
|
+
['cp', '-r', '-p', inclusive ? `${sourceDirectory}/*` : sourceDirectory, destinationDirectory],
|
|
56
|
+
rmRecursive: (destinationDirectory) => ['rm', '-rf', destinationDirectory],
|
|
57
|
+
mkdir: (destinationDirectory) => ['mkdir', '-p', destinationDirectory],
|
|
58
58
|
export: (key, value) => ['export', `${key}=${value}`],
|
|
59
|
-
chdir: (
|
|
59
|
+
chdir: (destinationDirectory) => ['cd', destinationDirectory],
|
|
60
60
|
comment: (message) => ['\n#', util.stripVTControlCharacters(message), '\n'],
|
|
61
61
|
echo: (message) => ['echo', `"${escape(util.stripVTControlCharacters(message))}"\n`],
|
|
62
62
|
zip: (outputFile) => ['zip', '-r', outputFile, '.'],
|
|
63
|
-
script: (lines: string[],
|
|
63
|
+
script: (lines: string[], changeDirectory: boolean = false) => ({
|
|
64
64
|
ext: '.sh',
|
|
65
65
|
contents: [
|
|
66
66
|
'#!/bin/sh',
|
|
67
|
-
...(
|
|
67
|
+
...(changeDirectory ? ['cd $(dirname "$0")'] : []),
|
|
68
68
|
...lines,
|
|
69
69
|
]
|
|
70
70
|
})
|
package/support/bin/util.ts
CHANGED
|
@@ -12,26 +12,26 @@ export class PackUtil {
|
|
|
12
12
|
*/
|
|
13
13
|
static buildEnvFile(env: Record<string, string | number | boolean | undefined>): string[] {
|
|
14
14
|
return Object.entries(env)
|
|
15
|
-
.filter(([,
|
|
16
|
-
.map(([
|
|
15
|
+
.filter(([, value]) => (value !== undefined))
|
|
16
|
+
.map(([key, value]) => `${key}=${value}`);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Remove directory, determine if errors should be ignored
|
|
21
|
-
* @param
|
|
22
|
-
* @param
|
|
21
|
+
* @param sourceDirectory The folder to copy
|
|
22
|
+
* @param destinationDirectory The folder to copy to
|
|
23
23
|
*/
|
|
24
|
-
static async copyRecursive(
|
|
24
|
+
static async copyRecursive(sourceDirectory: string, destinationDirectory: string, inclusive: boolean = false, ignoreFailure = false): Promise<void> {
|
|
25
25
|
try {
|
|
26
|
-
let final =
|
|
26
|
+
let final = destinationDirectory;
|
|
27
27
|
if (!inclusive) {
|
|
28
|
-
final = path.resolve(
|
|
28
|
+
final = path.resolve(destinationDirectory, path.basename(sourceDirectory));
|
|
29
29
|
}
|
|
30
30
|
await fs.mkdir(final, { recursive: true });
|
|
31
|
-
await fs.cp(
|
|
31
|
+
await fs.cp(sourceDirectory, final, { recursive: true });
|
|
32
32
|
} catch {
|
|
33
33
|
if (!ignoreFailure) {
|
|
34
|
-
throw new Error(`Failed to copy ${
|
|
34
|
+
throw new Error(`Failed to copy ${sourceDirectory} to ${destinationDirectory}`);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -43,10 +43,10 @@ export class PackUtil {
|
|
|
43
43
|
const vars = { DIST: workspace, TRV_OUT: RuntimeIndex.outputRoot, ROOT: path.resolve(), MOD: module };
|
|
44
44
|
|
|
45
45
|
const replaceArgs = (text: string): string => Object.entries(vars)
|
|
46
|
-
.reduce((
|
|
46
|
+
.reduce((result, [key, value]) => result.replaceAll(value, ActiveShellCommand.var(key)), text);
|
|
47
47
|
|
|
48
48
|
const preamble = ActiveShellCommand.script(
|
|
49
|
-
Object.entries(vars).map(([
|
|
49
|
+
Object.entries(vars).map(([key, value]) => ActiveShellCommand.export(key, value).join(' ')),
|
|
50
50
|
).contents;
|
|
51
51
|
|
|
52
52
|
let stream: fs.FileHandle | undefined;
|
|
@@ -73,10 +73,10 @@ export class PackUtil {
|
|
|
73
73
|
/**
|
|
74
74
|
* Track result response
|
|
75
75
|
*/
|
|
76
|
-
static async runCommand(cmd: string[],
|
|
76
|
+
static async runCommand(cmd: string[], options: SpawnOptions = {}): Promise<string> {
|
|
77
77
|
const { valid, code, stderr, message, stdout } = await ExecUtil.getResult(spawn(cmd[0], cmd.slice(1), {
|
|
78
78
|
stdio: [0, 'pipe', 'pipe'],
|
|
79
|
-
...
|
|
79
|
+
...options,
|
|
80
80
|
}), { catch: true });
|
|
81
81
|
|
|
82
82
|
if (!valid) {
|
|
@@ -27,7 +27,7 @@ export class PackDockerCommand extends BasePackCommand {
|
|
|
27
27
|
dockerName: string;
|
|
28
28
|
/** Docker Runtime user */
|
|
29
29
|
@CliFlag({ short: 'ru', full: 'runtime-user', envVars: ['PACK_DOCKER_RUNTIME_USER'] })
|
|
30
|
-
|
|
30
|
+
dockerRuntimeUser?: string;
|
|
31
31
|
/** Docker Runtime Packages */
|
|
32
32
|
@CliFlag({ short: 'rp', full: 'runtime-package', envVars: ['PACK_DOCKER_RUNTIME_PACKAGES'] })
|
|
33
33
|
dockerRuntimePackages: string[] = [];
|
|
@@ -85,15 +85,15 @@ export class PackDockerCommand extends BasePackCommand {
|
|
|
85
85
|
this.dockerName ??= CliUtil.getSimpleModuleName('<module>', this.module || undefined);
|
|
86
86
|
|
|
87
87
|
// Finalize user/group and ids
|
|
88
|
-
const [
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
const group = (!
|
|
95
|
-
const user = (!
|
|
96
|
-
this.dockerRuntime = { user,
|
|
88
|
+
const [userOrUserId, groupOrGroupId = userOrUserId] = (this.dockerRuntimeUser ?? '').split(':');
|
|
89
|
+
const groupIsNumber = /^\d+$/.test(groupOrGroupId);
|
|
90
|
+
const userIsNumber = /^\d+$/.test(userOrUserId);
|
|
91
|
+
|
|
92
|
+
const userId = userIsNumber ? +userOrUserId : this.defaultUserId;
|
|
93
|
+
const groupId = groupIsNumber ? +groupOrGroupId : this.defaultUserId;
|
|
94
|
+
const group = (!groupIsNumber ? groupOrGroupId : undefined) || this.defaultUser;
|
|
95
|
+
const user = (!userIsNumber ? userOrUserId : undefined) || this.defaultUser;
|
|
96
|
+
this.dockerRuntime = { user, userId, group, groupId, folder: `/${this.appFolder}`, packages: this.dockerRuntimePackages };
|
|
97
97
|
|
|
98
98
|
if (this.dockerStageOnly) {
|
|
99
99
|
if (this.dockerRegistry) {
|
package/support/pack.base.ts
CHANGED
|
@@ -17,19 +17,19 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
17
17
|
|
|
18
18
|
static get entryPoints(): string[] {
|
|
19
19
|
return RuntimeIndex.find({
|
|
20
|
-
module:
|
|
21
|
-
folder:
|
|
22
|
-
file:
|
|
20
|
+
module: mod => mod.prod,
|
|
21
|
+
folder: folder => folder === 'support',
|
|
22
|
+
file: file => file.sourceFile.includes('entry.')
|
|
23
23
|
})
|
|
24
|
-
.map(
|
|
24
|
+
.map(file => file.import.replace(/[.][^.]+s$/, ''));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
@Ignore()
|
|
28
28
|
_parsed: ParsedState;
|
|
29
29
|
|
|
30
30
|
/** Workspace for building */
|
|
31
|
-
@CliFlag({ short: 'b' })
|
|
32
|
-
|
|
31
|
+
@CliFlag({ short: 'b', full: 'buildDir' })
|
|
32
|
+
buildDirectory: string = path.resolve(os.tmpdir(), Runtime.mainSourcePath.replace(/[\/\\: ]/g, '_'));
|
|
33
33
|
|
|
34
34
|
/** Clean workspace */
|
|
35
35
|
clean = true;
|
|
@@ -116,8 +116,8 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
116
116
|
* Run all operations
|
|
117
117
|
*/
|
|
118
118
|
async * runOperations(): AsyncIterable<string> {
|
|
119
|
-
for (const
|
|
120
|
-
for await (const msg of
|
|
119
|
+
for (const operation of this.getOperations()) {
|
|
120
|
+
for await (const msg of operation(this)) {
|
|
121
121
|
yield msg.join(' ');
|
|
122
122
|
}
|
|
123
123
|
}
|
|
@@ -128,11 +128,11 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
128
128
|
*/
|
|
129
129
|
getBinaryDependencies(): string[] {
|
|
130
130
|
return [...RuntimeIndex.getModuleList('all')]
|
|
131
|
-
.map(
|
|
132
|
-
.filter(
|
|
133
|
-
.filter(
|
|
134
|
-
.map(
|
|
135
|
-
.map(
|
|
131
|
+
.map(name => RuntimeIndex.getModule(name))
|
|
132
|
+
.filter(mod => !!mod)
|
|
133
|
+
.filter(mod => mod.prod)
|
|
134
|
+
.map(mod => PackageUtil.readPackage(mod?.sourcePath))
|
|
135
|
+
.map(pkg => pkg?.travetto?.build?.binaryDependencies ?? [])
|
|
136
136
|
.flat();
|
|
137
137
|
}
|
|
138
138
|
|
|
@@ -141,7 +141,7 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
141
141
|
// Resolve all files to absolute paths
|
|
142
142
|
this.output = this.output ? path.resolve(this.output) : undefined!;
|
|
143
143
|
this.ejectFile = this.ejectFile ? path.resolve(this.ejectFile) : undefined;
|
|
144
|
-
this.
|
|
144
|
+
this.buildDirectory = path.resolve(this.buildDirectory);
|
|
145
145
|
|
|
146
146
|
// Update entry points
|
|
147
147
|
this.entryArguments = [...this.entryArguments ?? [], ...args, ...this._parsed.unknown];
|
|
@@ -150,14 +150,14 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
150
150
|
this.mainFile = `${this.mainName}.js`;
|
|
151
151
|
|
|
152
152
|
// Collect binary dependencies
|
|
153
|
-
const
|
|
154
|
-
this.externalDependencies = [...this.externalDependencies, ...
|
|
153
|
+
const dependencies = await this.getBinaryDependencies();
|
|
154
|
+
this.externalDependencies = [...this.externalDependencies, ...dependencies];
|
|
155
155
|
|
|
156
156
|
const stream = this.runOperations();
|
|
157
157
|
|
|
158
158
|
// Eject to file
|
|
159
159
|
if (this.ejectFile) {
|
|
160
|
-
await PackUtil.writeEjectOutput(this.
|
|
160
|
+
await PackUtil.writeEjectOutput(this.buildDirectory, this.module, stream, this.ejectFile);
|
|
161
161
|
} else {
|
|
162
162
|
const start = Date.now();
|
|
163
163
|
const term = new Terminal();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { DockerPackFactory } from '../src/types.ts';
|
|
2
2
|
import { PackConfigUtil } from '../src/config-util.ts';
|
|
3
3
|
|
|
4
|
-
export const factory: DockerPackFactory =
|
|
4
|
+
export const factory: DockerPackFactory = config => PackConfigUtil.dockerStandardFile(config);
|
package/support/rollup/config.ts
CHANGED
|
@@ -8,17 +8,17 @@ import { EnvProp, Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
|
8
8
|
|
|
9
9
|
import { CoreRollupConfig } from '../../src/types.ts';
|
|
10
10
|
|
|
11
|
-
function getFilesFromModule(
|
|
11
|
+
function getFilesFromModule(mod: ManifestModule): string[] {
|
|
12
12
|
return [
|
|
13
|
-
...
|
|
14
|
-
...
|
|
15
|
-
...(
|
|
16
|
-
...(
|
|
17
|
-
.filter(
|
|
13
|
+
...mod.files.$index ?? [],
|
|
14
|
+
...mod.files.src ?? [],
|
|
15
|
+
...(mod.files.bin ?? []).filter(file => !(/bin\/trv[.]js$/.test(file[0]) && mod.name === '@travetto/cli')),
|
|
16
|
+
...(mod.files.support ?? [])
|
|
17
|
+
.filter(file => !/support\/(test|doc|pack)/.test(file[0]))
|
|
18
18
|
]
|
|
19
|
-
.filter(([,
|
|
20
|
-
.filter(
|
|
21
|
-
.map(([
|
|
19
|
+
.filter(([, type]) => type === 'ts' || type === 'js' || type === 'json')
|
|
20
|
+
.filter(([, , , role]) => (role ?? 'std') === 'std') // Only include standard files
|
|
21
|
+
.map(([file]) => ManifestModuleUtil.withOutputExtension(path.resolve(mod.outputFolder, file)));
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function getFormat(value: string = 'commonjs'): NodeModuleType {
|
|
@@ -31,17 +31,17 @@ function getFormat(value: string = 'commonjs'): NodeModuleType {
|
|
|
31
31
|
|
|
32
32
|
export function getOutput(): OutputOptions {
|
|
33
33
|
const format = getFormat(process.env.BUNDLE_FORMAT);
|
|
34
|
-
const
|
|
34
|
+
const output = process.env.BUNDLE_OUTPUT!;
|
|
35
35
|
const mainFile = process.env.BUNDLE_MAIN_FILE!;
|
|
36
36
|
return {
|
|
37
37
|
format,
|
|
38
38
|
interop: format === 'commonjs' ? 'auto' : undefined,
|
|
39
|
-
sourcemapPathTransform: (
|
|
40
|
-
Runtime.stripWorkspacePath(path.resolve(path.dirname(map),
|
|
39
|
+
sourcemapPathTransform: (source, map): string =>
|
|
40
|
+
Runtime.stripWorkspacePath(path.resolve(path.dirname(map), source)),
|
|
41
41
|
sourcemap: new EnvProp('BUNDLE_SOURCEMAP').bool ?? false,
|
|
42
42
|
sourcemapExcludeSources: !(new EnvProp('BUNDLE_SOURCES').bool ?? false),
|
|
43
43
|
compact: new EnvProp('BUNDLE_COMPRESS').bool ?? true,
|
|
44
|
-
file: path.resolve(
|
|
44
|
+
file: path.resolve(output, mainFile),
|
|
45
45
|
inlineDynamicImports: true
|
|
46
46
|
};
|
|
47
47
|
}
|
|
@@ -52,16 +52,16 @@ export function getEntry(): string {
|
|
|
52
52
|
|
|
53
53
|
export function getFiles(entry?: string): string[] {
|
|
54
54
|
return [...RuntimeIndex.getModuleList('all')]
|
|
55
|
-
.map(
|
|
56
|
-
.filter(
|
|
55
|
+
.map(name => RuntimeIndex.getManifestModule(name))
|
|
56
|
+
.filter(mod => mod.prod)
|
|
57
57
|
.flatMap(getFilesFromModule)
|
|
58
|
-
.filter(
|
|
58
|
+
.filter(file => (!entry || !file.endsWith(entry)) && !file.includes('@travetto/pack/support/'));
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
export function getIgnoredModules(): ManifestModule[] {
|
|
62
62
|
return [...RuntimeIndex.getModuleList('all')]
|
|
63
|
-
.map(
|
|
64
|
-
.filter(
|
|
63
|
+
.map(name => RuntimeIndex.getManifestModule(name))
|
|
64
|
+
.filter(mod => !mod.prod);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
export function getMinifyConfig(): Parameters<typeof terser>[0] {
|
|
@@ -85,11 +85,11 @@ export function getCoreConfig(): CoreRollupConfig {
|
|
|
85
85
|
const ignoreModules = getIgnoredModules();
|
|
86
86
|
const ignoreFiles = ignoreModules.flatMap(getFilesFromModule);
|
|
87
87
|
const minify = getMinifyConfig();
|
|
88
|
-
const envFile = new EnvProp('BUNDLE_ENV_FILE').
|
|
88
|
+
const envFile = new EnvProp('BUNDLE_ENV_FILE').value;
|
|
89
89
|
const external = new EnvProp('BUNDLE_EXTERNAL').list ?? [];
|
|
90
90
|
|
|
91
91
|
return {
|
|
92
92
|
output, entry, files, envFile, minify, external,
|
|
93
|
-
ignore: new Set([...ignoreModules.map(
|
|
93
|
+
ignore: new Set([...ignoreModules.map(mod => mod.name), ...ignoreFiles]),
|
|
94
94
|
};
|
|
95
95
|
}
|
|
@@ -9,15 +9,15 @@ export const GLOBAL_IMPORT = '__trv_imp';
|
|
|
9
9
|
|
|
10
10
|
export function travettoEntryPlugin(config: CoreRollupConfig): Plugin {
|
|
11
11
|
const imports = config.files
|
|
12
|
-
.map(
|
|
13
|
-
.flatMap(
|
|
12
|
+
.map(file => file.split('node_modules/').pop()!)
|
|
13
|
+
.flatMap(file => file.endsWith('/__index__.js') ? [file.replace('/__index__.js', ''), file] : [file]);
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const operation = config.output.format === 'module' ? 'import' : 'require';
|
|
16
16
|
const importer = `
|
|
17
17
|
function trvImp(path) {
|
|
18
18
|
switch (path) {
|
|
19
|
-
${imports.map(
|
|
20
|
-
default: return ${
|
|
19
|
+
${imports.map(file => ` case '${file}': return ${operation}('${file}')`).join('\n')}
|
|
20
|
+
default: return ${operation}(path); // Fall back for built-ins
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
globalThis.${GLOBAL_IMPORT} = trvImp;
|
|
@@ -33,8 +33,8 @@ export function travettoSourcemaps(config: CoreRollupConfig): Plugin {
|
|
|
33
33
|
return { code, map };
|
|
34
34
|
}
|
|
35
35
|
return { code, map: null };
|
|
36
|
-
} catch (
|
|
37
|
-
this.warn({ message: toString(
|
|
36
|
+
} catch (error) {
|
|
37
|
+
this.warn({ message: toString(error), id });
|
|
38
38
|
return null;
|
|
39
39
|
}
|
|
40
40
|
},
|