@travetto/pack 4.1.2 → 5.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +18 -15
- package/package.json +4 -4
- package/src/types.ts +3 -3
- package/support/bin/docker-operation.ts +6 -5
- package/support/bin/operation.ts +43 -44
- package/support/bin/shell.ts +23 -11
- package/support/bin/util.ts +21 -13
- package/support/cli.pack_docker.ts +18 -9
- package/support/pack.base.ts +10 -6
- package/support/rollup/config.ts +3 -2
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ $ trv pack --help
|
|
|
29
29
|
Usage: pack [options]
|
|
30
30
|
|
|
31
31
|
Options:
|
|
32
|
-
-
|
|
32
|
+
-b, --build-dir <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)
|
|
@@ -42,6 +42,7 @@ Options:
|
|
|
42
42
|
-r, --rollup-configuration <string> Rollup configuration file (default: "@travetto/pack/support/rollup/build")
|
|
43
43
|
--env-file <string> Env Flag File Name (default: ".env")
|
|
44
44
|
--manifest-file <string> Manifest File Name (default: "manifest.json")
|
|
45
|
+
-wr, --include-workspace-resources Include workspace resources (default: false)
|
|
45
46
|
-m, --module <module> Module to run for
|
|
46
47
|
-h, --help display help for command
|
|
47
48
|
```
|
|
@@ -93,7 +94,7 @@ $ trv pack:zip --help
|
|
|
93
94
|
Usage: pack:zip [options]
|
|
94
95
|
|
|
95
96
|
Options:
|
|
96
|
-
-
|
|
97
|
+
-b, --build-dir <string> Workspace for building (default: "/tmp/<temp-folder>")
|
|
97
98
|
--clean, --no-clean Clean workspace (default: true)
|
|
98
99
|
-o, --output <string> Output location (default: "travetto_pack.zip")
|
|
99
100
|
--main-scripts, --no-main-scripts Create entry scripts (default: true)
|
|
@@ -106,6 +107,7 @@ Options:
|
|
|
106
107
|
-r, --rollup-configuration <string> Rollup configuration file (default: "@travetto/pack/support/rollup/build")
|
|
107
108
|
--env-file <string> Env Flag File Name (default: ".env")
|
|
108
109
|
--manifest-file <string> Manifest File Name (default: "manifest.json")
|
|
110
|
+
-wr, --include-workspace-resources Include workspace resources (default: false)
|
|
109
111
|
-m, --module <module> Module to run for
|
|
110
112
|
-h, --help display help for command
|
|
111
113
|
```
|
|
@@ -120,7 +122,7 @@ $ trv pack:docker --help
|
|
|
120
122
|
Usage: pack:docker [options]
|
|
121
123
|
|
|
122
124
|
Options:
|
|
123
|
-
-
|
|
125
|
+
-b, --build-dir <string> Workspace for building (default: "/tmp/<temp-folder>")
|
|
124
126
|
--clean, --no-clean Clean workspace (default: true)
|
|
125
127
|
-o, --output <string> Output location
|
|
126
128
|
--main-scripts, --no-main-scripts Create entry scripts (default: true)
|
|
@@ -133,8 +135,9 @@ Options:
|
|
|
133
135
|
-r, --rollup-configuration <string> Rollup configuration file (default: "@travetto/pack/support/rollup/build")
|
|
134
136
|
--env-file <string> Env Flag File Name (default: ".env")
|
|
135
137
|
--manifest-file <string> Manifest File Name (default: "manifest.json")
|
|
138
|
+
-wr, --include-workspace-resources Include workspace resources (default: false)
|
|
136
139
|
-df, --docker-factory <string> Docker Factory source (default: "@travetto/pack/support/pack.dockerfile")
|
|
137
|
-
-di, --docker-image <string> Docker Image to extend (default: "node:
|
|
140
|
+
-di, --docker-image <string> Docker Image to extend (default: "node:22-alpine")
|
|
138
141
|
-dn, --docker-name <string> Docker Image Name (default: "travetto_pack")
|
|
139
142
|
-dt, --docker-tag <string> Docker Image Tag (default: ["latest"])
|
|
140
143
|
-dp, --docker-port <number> Docker Image Port (default: [])
|
|
@@ -183,6 +186,7 @@ echo "NODE_ENV=production" > $DIST/.env
|
|
|
183
186
|
echo "TRV_MANIFEST=manifest.json" >> $DIST/.env
|
|
184
187
|
echo "TRV_MODULE=$MOD" >> $DIST/.env
|
|
185
188
|
echo "TRV_CLI_IPC=" >> $DIST/.env
|
|
189
|
+
echo "TRV_RESOURCE_OVERRIDES=@#resources=@@#resources" >> $DIST/.env
|
|
186
190
|
|
|
187
191
|
# Writing package.json
|
|
188
192
|
|
|
@@ -203,16 +207,15 @@ chmod 755 $DIST/todo-app.sh
|
|
|
203
207
|
|
|
204
208
|
echo "Writing entry scripts todo-app.cmd args=(run:rest)"
|
|
205
209
|
|
|
206
|
-
echo "" > $DIST/todo-app.cmd
|
|
207
|
-
echo "cd %~p0" >> $DIST/todo-app.cmd
|
|
210
|
+
echo "cd %~p0" > $DIST/todo-app.cmd
|
|
208
211
|
echo "node todo-app.js run:rest %*" >> $DIST/todo-app.cmd
|
|
209
212
|
chmod 755 $DIST/todo-app.cmd
|
|
210
213
|
|
|
211
|
-
# Copying over resources
|
|
214
|
+
# Copying over module resources
|
|
212
215
|
|
|
213
|
-
echo "Copying over resources"
|
|
216
|
+
echo "Copying over module resources"
|
|
214
217
|
|
|
215
|
-
cp -r -p $ROOT/resources $DIST/resources
|
|
218
|
+
cp -r -p $ROOT/resources/* $DIST/resources
|
|
216
219
|
|
|
217
220
|
# Writing Manifest manifest.json
|
|
218
221
|
|
|
@@ -237,21 +240,21 @@ cd $TRV_OUT
|
|
|
237
240
|
npx rollup -c $TRV_OUT/node_modules/@travetto/pack/support/rollup/build.js
|
|
238
241
|
cd $ROOT
|
|
239
242
|
|
|
240
|
-
# Pulling Docker Base Image node:
|
|
243
|
+
# Pulling Docker Base Image node:22-alpine
|
|
241
244
|
|
|
242
|
-
echo "Pulling Docker Base Image node:
|
|
245
|
+
echo "Pulling Docker Base Image node:22-alpine"
|
|
243
246
|
|
|
244
|
-
docker pull node:
|
|
247
|
+
docker pull node:22-alpine
|
|
245
248
|
|
|
246
|
-
# Detected Image OS node:
|
|
249
|
+
# Detected Image OS node:22-alpine as alpine
|
|
247
250
|
|
|
248
|
-
echo "Detected Image OS node:
|
|
251
|
+
echo "Detected Image OS node:22-alpine as alpine"
|
|
249
252
|
|
|
250
253
|
# Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile
|
|
251
254
|
|
|
252
255
|
echo "Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile"
|
|
253
256
|
|
|
254
|
-
echo "FROM node:
|
|
257
|
+
echo "FROM node:22-alpine" > $DIST/Dockerfile
|
|
255
258
|
echo "RUN addgroup -g 2000 app && adduser -D -G app -u 2000 app" >> $DIST/Dockerfile
|
|
256
259
|
echo "RUN mkdir /app && chown app:app /app" >> $DIST/Dockerfile
|
|
257
260
|
echo "COPY --chown=\"app:app\" . /app" >> $DIST/Dockerfile
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/pack",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-rc.0",
|
|
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": "^15.2.3",
|
|
31
31
|
"@rollup/plugin-terser": "^0.4.4",
|
|
32
|
-
"@travetto/base": "^
|
|
33
|
-
"@travetto/terminal": "^
|
|
32
|
+
"@travetto/base": "^5.0.0-rc.0",
|
|
33
|
+
"@travetto/terminal": "^5.0.0-rc.0",
|
|
34
34
|
"rollup": "^4.18.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@travetto/cli": "^
|
|
37
|
+
"@travetto/cli": "^5.0.0-rc.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependenciesMeta": {
|
|
40
40
|
"@travetto/cli": {
|
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
|
+
buildDir: string;
|
|
6
6
|
output: string;
|
|
7
7
|
clean: boolean;
|
|
8
8
|
ejectFile?: string;
|
|
@@ -13,6 +13,7 @@ export type CommonPackConfig = {
|
|
|
13
13
|
envFile: string;
|
|
14
14
|
env?: string;
|
|
15
15
|
manifestFile: string;
|
|
16
|
+
workspaceResourceFolder: string;
|
|
16
17
|
|
|
17
18
|
// Bundle
|
|
18
19
|
rollupConfiguration: string;
|
|
@@ -49,8 +50,6 @@ export type DockerPackConfig = {
|
|
|
49
50
|
export type ShellCommandImpl = {
|
|
50
51
|
var(name: string): string;
|
|
51
52
|
createFile(file: string, text: string[], mode?: string): string[][];
|
|
52
|
-
scriptOpen(): string[];
|
|
53
|
-
chdirScript(): string[];
|
|
54
53
|
callCommandWithAllArgs(cmd: string, ...args: string[]): string[];
|
|
55
54
|
copy(src: string, dest: string): string[];
|
|
56
55
|
copyRecursive(src: string, dest: string, inclusive?: boolean): string[];
|
|
@@ -61,6 +60,7 @@ export type ShellCommandImpl = {
|
|
|
61
60
|
comment(message: string): string[];
|
|
62
61
|
echo(text: string): string[];
|
|
63
62
|
zip(output: string): string[];
|
|
63
|
+
script(lines: string[], chdir?: boolean): { ext: string, contents: string[] };
|
|
64
64
|
};
|
|
65
65
|
|
|
66
66
|
export type DockerPackFactory = (cfg: DockerPackConfig) => (string | Promise<string>);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
+
import { RuntimeIndex } from '@travetto/manifest';
|
|
4
5
|
import { cliTpl } from '@travetto/cli';
|
|
5
6
|
|
|
6
7
|
import { ActiveShellCommand } from './shell';
|
|
@@ -30,7 +31,7 @@ export class DockerPackOperation {
|
|
|
30
31
|
* Write Docker File
|
|
31
32
|
*/
|
|
32
33
|
static async* writeDockerFile(cfg: DockerPackConfig): AsyncIterable<string[]> {
|
|
33
|
-
const dockerFile = path.resolve(cfg.
|
|
34
|
+
const dockerFile = path.resolve(cfg.buildDir, 'Dockerfile');
|
|
34
35
|
|
|
35
36
|
const factory = RuntimeIndex.getFromImport(cfg.dockerFactory);
|
|
36
37
|
if (!factory) {
|
|
@@ -76,11 +77,11 @@ export class DockerPackOperation {
|
|
|
76
77
|
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Building Docker Container' }} ${{ param: cfg.dockerTag?.join(',') }}`);
|
|
77
78
|
|
|
78
79
|
if (cfg.ejectFile) {
|
|
79
|
-
yield ActiveShellCommand.chdir(cfg.
|
|
80
|
+
yield ActiveShellCommand.chdir(cfg.buildDir);
|
|
80
81
|
yield cmd;
|
|
81
|
-
yield ActiveShellCommand.chdir(path.
|
|
82
|
+
yield ActiveShellCommand.chdir(path.resolve());
|
|
82
83
|
} else {
|
|
83
|
-
await PackUtil.runCommand(cmd, { cwd: cfg.
|
|
84
|
+
await PackUtil.runCommand(cmd, { cwd: cfg.buildDir, stdio: [0, 'pipe', 2] });
|
|
84
85
|
const [image] = JSON.parse(await PackUtil.runCommand(['docker', 'inspect', cfg.dockerImage]));
|
|
85
86
|
yield [cliTpl`${{ title: 'Built Docker Container ' }} ${{ identifier: 'sizeMb' }}=${{ param: Math.trunc(image.Size / 2 ** 20) }}`];
|
|
86
87
|
}
|
package/support/bin/operation.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
+
import { RuntimeIndex, RuntimeContext } from '@travetto/manifest';
|
|
4
5
|
import { cliTpl } from '@travetto/cli';
|
|
5
6
|
import { Env } from '@travetto/base';
|
|
6
7
|
|
|
@@ -30,20 +31,20 @@ export class PackOperation {
|
|
|
30
31
|
return;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Cleaning Output' }} ${{ path: cfg.
|
|
34
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Cleaning Output' }} ${{ path: cfg.buildDir }}`);
|
|
34
35
|
|
|
35
36
|
if (cfg.ejectFile) {
|
|
36
|
-
yield ActiveShellCommand.rmRecursive(cfg.
|
|
37
|
+
yield ActiveShellCommand.rmRecursive(cfg.buildDir);
|
|
37
38
|
if (cfg.output) {
|
|
38
39
|
yield ActiveShellCommand.rmRecursive(cfg.output);
|
|
39
40
|
}
|
|
40
|
-
yield ActiveShellCommand.mkdir(cfg.
|
|
41
|
+
yield ActiveShellCommand.mkdir(cfg.buildDir);
|
|
41
42
|
} else {
|
|
42
|
-
await fs.rm(cfg.
|
|
43
|
+
await fs.rm(cfg.buildDir, { recursive: true, force: true });
|
|
43
44
|
if (cfg.output) {
|
|
44
45
|
await fs.rm(cfg.output, { recursive: true, force: true });
|
|
45
46
|
}
|
|
46
|
-
await fs.mkdir(cfg.
|
|
47
|
+
await fs.mkdir(cfg.buildDir, { recursive: true });
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -65,7 +66,7 @@ export class PackOperation {
|
|
|
65
66
|
['BUNDLE_COMPRESS', cfg.minify],
|
|
66
67
|
['BUNDLE_SOURCEMAP', cfg.sourcemap],
|
|
67
68
|
['BUNDLE_SOURCES', cfg.includeSources],
|
|
68
|
-
['BUNDLE_OUTPUT', cfg.
|
|
69
|
+
['BUNDLE_OUTPUT', cfg.buildDir],
|
|
69
70
|
['BUNDLE_FORMAT', RuntimeContext.workspace.type],
|
|
70
71
|
['BUNDLE_ENV_FILE', cfg.envFile]
|
|
71
72
|
] as const)
|
|
@@ -86,10 +87,10 @@ export class PackOperation {
|
|
|
86
87
|
);
|
|
87
88
|
yield ActiveShellCommand.chdir(cwd);
|
|
88
89
|
yield bundleCommand;
|
|
89
|
-
yield ActiveShellCommand.chdir(path.
|
|
90
|
+
yield ActiveShellCommand.chdir(path.resolve());
|
|
90
91
|
} else {
|
|
91
92
|
await PackUtil.runCommand(bundleCommand, { cwd, env: { ...process.env, ...env } });
|
|
92
|
-
const stat = await fs.stat(path.resolve(cfg.
|
|
93
|
+
const stat = await fs.stat(path.resolve(cfg.buildDir, cfg.mainFile));
|
|
93
94
|
yield [cliTpl`${{ title: 'Bundled Output ' }} ${{ identifier: 'sizeKb' }}=${{ param: Math.trunc(stat.size / 2 ** 10) }}`];
|
|
94
95
|
}
|
|
95
96
|
}
|
|
@@ -105,12 +106,12 @@ export class PackOperation {
|
|
|
105
106
|
|
|
106
107
|
if (cfg.ejectFile) {
|
|
107
108
|
yield* ActiveShellCommand.createFile(
|
|
108
|
-
path.resolve(cfg.
|
|
109
|
+
path.resolve(cfg.buildDir, file),
|
|
109
110
|
[JSON.stringify(pkg)]
|
|
110
111
|
);
|
|
111
112
|
} else {
|
|
112
113
|
await PackUtil.writeRawFile(
|
|
113
|
-
path.resolve(cfg.
|
|
114
|
+
path.resolve(cfg.buildDir, file),
|
|
114
115
|
[JSON.stringify(pkg, null, 2)]
|
|
115
116
|
);
|
|
116
117
|
}
|
|
@@ -120,24 +121,30 @@ export class PackOperation {
|
|
|
120
121
|
* Define .env.js file to control manifest location
|
|
121
122
|
*/
|
|
122
123
|
static async * writeEnv(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
123
|
-
const file = path.resolve(cfg.
|
|
124
|
+
const file = path.resolve(cfg.buildDir, cfg.envFile);
|
|
124
125
|
const env = {
|
|
125
126
|
...Env.NODE_ENV.export('production'),
|
|
126
127
|
...Env.TRV_MANIFEST.export(cfg.manifestFile),
|
|
127
128
|
...Env.TRV_MODULE.export(cfg.module),
|
|
128
|
-
...Env.TRV_CLI_IPC.export(undefined)
|
|
129
|
+
...Env.TRV_CLI_IPC.export(undefined),
|
|
130
|
+
...Env.TRV_RESOURCE_OVERRIDES.export({
|
|
131
|
+
'@#resources': '@@#resources',
|
|
132
|
+
...(cfg.includeWorkspaceResources ? {
|
|
133
|
+
'@@#resources': `@@#${cfg.workspaceResourceFolder}`
|
|
134
|
+
} : {})
|
|
135
|
+
})
|
|
129
136
|
};
|
|
130
137
|
|
|
131
138
|
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Writing' }} ${{ path: file }}`);
|
|
132
139
|
|
|
133
140
|
if (cfg.ejectFile) {
|
|
134
141
|
yield* ActiveShellCommand.createFile(
|
|
135
|
-
path.resolve(cfg.
|
|
142
|
+
path.resolve(cfg.buildDir, file),
|
|
136
143
|
PackUtil.buildEnvFile(env)
|
|
137
144
|
);
|
|
138
145
|
} else {
|
|
139
146
|
await PackUtil.writeRawFile(
|
|
140
|
-
path.resolve(cfg.
|
|
147
|
+
path.resolve(cfg.buildDir, file),
|
|
141
148
|
PackUtil.buildEnvFile(env)
|
|
142
149
|
);
|
|
143
150
|
}
|
|
@@ -152,27 +159,21 @@ export class PackOperation {
|
|
|
152
159
|
}
|
|
153
160
|
|
|
154
161
|
const title = 'Writing entry scripts';
|
|
162
|
+
for (const sh of [ShellCommands.posix, ShellCommands.win32]) {
|
|
163
|
+
const { ext, contents } = sh.script(
|
|
155
164
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
text: [
|
|
161
|
-
ShellCommands[type].scriptOpen(),
|
|
162
|
-
ShellCommands[type].chdirScript(),
|
|
163
|
-
ShellCommands[type].callCommandWithAllArgs('node', cfg.mainFile, ...cfg.entryArguments),
|
|
164
|
-
].map(x => x.join(' '))
|
|
165
|
-
}));
|
|
165
|
+
sh.callCommandWithAllArgs('node', cfg.mainFile, ...cfg.entryArguments), true
|
|
166
|
+
);
|
|
167
|
+
const file = `${cfg.mainName}${ext}`;
|
|
168
|
+
const args = cfg.entryArguments.join(' ');
|
|
166
169
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
yield* ActiveShellCommand.createFile(path.resolve(cfg.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
yield* PackOperation.title(cfg, fileTitle);
|
|
175
|
-
await PackUtil.writeRawFile(path.resolve(cfg.workspace, file), text, '755');
|
|
170
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title }} ${{ path: file }} args=(${{ param: args }})`);
|
|
171
|
+
|
|
172
|
+
if (cfg.ejectFile) {
|
|
173
|
+
yield* ActiveShellCommand.createFile(path.resolve(cfg.buildDir, file), contents, '755');
|
|
174
|
+
|
|
175
|
+
} else {
|
|
176
|
+
await PackUtil.writeRawFile(path.resolve(cfg.buildDir, file), contents, '755');
|
|
176
177
|
}
|
|
177
178
|
}
|
|
178
179
|
}
|
|
@@ -187,13 +188,12 @@ export class PackOperation {
|
|
|
187
188
|
|
|
188
189
|
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Copying over workspace resources' }}`);
|
|
189
190
|
|
|
190
|
-
const dest = path.resolve(cfg.
|
|
191
|
+
const dest = path.resolve(cfg.buildDir, cfg.workspaceResourceFolder);
|
|
191
192
|
const src = RuntimeContext.workspaceRelative('resources');
|
|
192
193
|
|
|
193
194
|
if (cfg.ejectFile) {
|
|
194
195
|
yield ActiveShellCommand.copyRecursive(src, dest, true);
|
|
195
196
|
} else {
|
|
196
|
-
await fs.mkdir(dest, { recursive: true });
|
|
197
197
|
await PackUtil.copyRecursive(src, dest, true);
|
|
198
198
|
}
|
|
199
199
|
}
|
|
@@ -205,19 +205,18 @@ export class PackOperation {
|
|
|
205
205
|
const resources = {
|
|
206
206
|
count: RuntimeIndex.mainModule.files.resources?.length ?? 0,
|
|
207
207
|
src: path.resolve(RuntimeIndex.mainModule.sourcePath, 'resources'),
|
|
208
|
-
dest: path.resolve(cfg.
|
|
208
|
+
dest: path.resolve(cfg.buildDir, 'resources')
|
|
209
209
|
};
|
|
210
210
|
|
|
211
211
|
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Copying over module resources' }}`);
|
|
212
212
|
|
|
213
213
|
if (cfg.ejectFile) {
|
|
214
214
|
if (resources.count) {
|
|
215
|
-
yield ActiveShellCommand.copyRecursive(resources.src, path.resolve(cfg.
|
|
215
|
+
yield ActiveShellCommand.copyRecursive(resources.src, path.resolve(cfg.buildDir, 'resources'), true);
|
|
216
216
|
}
|
|
217
217
|
} else {
|
|
218
218
|
if (resources.count) {
|
|
219
|
-
await
|
|
220
|
-
await PackUtil.copyRecursive(resources.src, resources.dest);
|
|
219
|
+
await PackUtil.copyRecursive(resources.src, resources.dest, true);
|
|
221
220
|
}
|
|
222
221
|
}
|
|
223
222
|
}
|
|
@@ -226,7 +225,7 @@ export class PackOperation {
|
|
|
226
225
|
* Produce the output manifest, only including prod dependencies
|
|
227
226
|
*/
|
|
228
227
|
static async * writeManifest(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
229
|
-
const out = path.resolve(cfg.
|
|
228
|
+
const out = path.resolve(cfg.buildDir, cfg.manifestFile);
|
|
230
229
|
const cmd = ['npx', 'trvc', 'manifest', '--prod', out];
|
|
231
230
|
const env = { ...Env.TRV_MODULE.export(cfg.module) };
|
|
232
231
|
|
|
@@ -247,13 +246,13 @@ export class PackOperation {
|
|
|
247
246
|
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Compressing' }} ${{ path: cfg.output }}`);
|
|
248
247
|
|
|
249
248
|
if (cfg.ejectFile) {
|
|
250
|
-
yield ActiveShellCommand.chdir(cfg.workspace);
|
|
251
249
|
await ActiveShellCommand.mkdir(path.dirname(cfg.output));
|
|
250
|
+
yield ActiveShellCommand.chdir(cfg.buildDir);
|
|
252
251
|
yield ActiveShellCommand.zip(cfg.output);
|
|
253
|
-
yield ActiveShellCommand.chdir(path.
|
|
252
|
+
yield ActiveShellCommand.chdir(path.resolve());
|
|
254
253
|
} else {
|
|
255
254
|
await fs.mkdir(path.dirname(cfg.output), { recursive: true });
|
|
256
|
-
await PackUtil.runCommand(ActiveShellCommand.zip(cfg.output), { cwd: cfg.
|
|
255
|
+
await PackUtil.runCommand(ActiveShellCommand.zip(cfg.output), { cwd: cfg.buildDir });
|
|
257
256
|
}
|
|
258
257
|
}
|
|
259
258
|
}
|
package/support/bin/shell.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import util from 'node:util';
|
|
2
|
-
|
|
3
|
-
import { path } from '@travetto/manifest';
|
|
2
|
+
import path from 'node:path';
|
|
4
3
|
|
|
5
4
|
import { ShellCommandImpl } from '../../src/types';
|
|
6
5
|
|
|
@@ -13,12 +12,12 @@ const escapedArgs = (args: string[]): string[] => args.map(x =>
|
|
|
13
12
|
x.includes(' ') || x.includes('"') ? `'${x}'` : (x.includes("'") ? `"${x}"` : x)
|
|
14
13
|
);
|
|
15
14
|
|
|
15
|
+
const toWin = (file: string): string => file.replace(/[\\\/]+/g, path.win32.sep);
|
|
16
|
+
|
|
16
17
|
export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
|
|
17
18
|
win32: {
|
|
18
19
|
var: (name: string) => `%${name}%`,
|
|
19
|
-
|
|
20
|
-
chdirScript: () => ['cd', '%~p0'],
|
|
21
|
-
callCommandWithAllArgs: (cmd, ...args) => [cmd, ...escapedArgs(args), '%*'],
|
|
20
|
+
callCommandWithAllArgs: (cmd, ...args) => [[cmd, ...escapedArgs(args), '%*'].join(' ')],
|
|
22
21
|
createFile: (file, text) => [
|
|
23
22
|
['@echo', 'off'],
|
|
24
23
|
...text.map((line, i) =>
|
|
@@ -27,20 +26,25 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
|
|
|
27
26
|
],
|
|
28
27
|
copy: (src, dest) => ['copy', src, dest],
|
|
29
28
|
copyRecursive: (src, dest, inclusive) =>
|
|
30
|
-
['xcopy', '/y', '/h', '/s', inclusive ? `${
|
|
29
|
+
['xcopy', '/y', '/h', '/s', inclusive ? `${toWin(src)}\\*.*` : toWin(src), toWin(dest)],
|
|
31
30
|
rmRecursive: (dest) => ['rmdir', '/Q', '/S', dest],
|
|
32
31
|
mkdir: (dest) => ['md', dest],
|
|
33
32
|
export: (key, value) => ['set', `${key}=${value}`],
|
|
34
33
|
chdir: (dest) => ['cd', dest],
|
|
35
34
|
comment: (message) => ['\nREM', util.stripVTControlCharacters(message), '\n'],
|
|
36
35
|
echo: (message) => ['echo', `"${escape(util.stripVTControlCharacters(message))}"\n`],
|
|
37
|
-
zip: (outputFile) => ['powershell', 'Compress-Archive', '-Path', '.', '-DestinationPath', outputFile]
|
|
36
|
+
zip: (outputFile) => ['powershell', 'Compress-Archive', '-Path', '.', '-DestinationPath', outputFile],
|
|
37
|
+
script: (lines: string[], changeDir: boolean = false) => ({
|
|
38
|
+
ext: '.cmd',
|
|
39
|
+
contents: [
|
|
40
|
+
...(changeDir ? ['cd %~p0'] : []),
|
|
41
|
+
...lines,
|
|
42
|
+
]
|
|
43
|
+
})
|
|
38
44
|
},
|
|
39
45
|
posix: {
|
|
40
46
|
var: (name: string) => `$${name}`,
|
|
41
|
-
|
|
42
|
-
chdirScript: () => ['cd', '$(dirname "$0")'],
|
|
43
|
-
callCommandWithAllArgs: (cmd, ...args) => [cmd, ...escapedArgs(args), '$@'],
|
|
47
|
+
callCommandWithAllArgs: (cmd, ...args) => [[cmd, ...escapedArgs(args), '$@'].join(' ')],
|
|
44
48
|
createFile: (file, text, mode) => [
|
|
45
49
|
...text.map((line, i) =>
|
|
46
50
|
['echo', `"${escape(line)}"`, i === 0 ? '>' : '>>', file]),
|
|
@@ -55,7 +59,15 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
|
|
|
55
59
|
chdir: (dest) => ['cd', dest],
|
|
56
60
|
comment: (message) => ['\n#', util.stripVTControlCharacters(message), '\n'],
|
|
57
61
|
echo: (message) => ['echo', `"${escape(util.stripVTControlCharacters(message))}"\n`],
|
|
58
|
-
zip: (outputFile) => ['zip', '-r', outputFile, '.']
|
|
62
|
+
zip: (outputFile) => ['zip', '-r', outputFile, '.'],
|
|
63
|
+
script: (lines: string[], changeDir: boolean = false) => ({
|
|
64
|
+
ext: '.sh',
|
|
65
|
+
contents: [
|
|
66
|
+
'#!/bin/sh',
|
|
67
|
+
...(changeDir ? ['cd $(dirname "$0")'] : []),
|
|
68
|
+
...lines,
|
|
69
|
+
]
|
|
70
|
+
})
|
|
59
71
|
},
|
|
60
72
|
};
|
|
61
73
|
|
package/support/bin/util.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import { spawn, SpawnOptions } from 'node:child_process';
|
|
3
|
+
import path from 'node:path';
|
|
3
4
|
|
|
4
|
-
import {
|
|
5
|
+
import { RuntimeIndex } from '@travetto/manifest';
|
|
5
6
|
import { AppError, ExecUtil } from '@travetto/base';
|
|
6
7
|
|
|
7
8
|
import { ActiveShellCommand } from './shell';
|
|
@@ -20,13 +21,19 @@ export class PackUtil {
|
|
|
20
21
|
* Remove directory, determine if errors should be ignored
|
|
21
22
|
* @param src The folder to copy
|
|
22
23
|
* @param dest The folder to copy to
|
|
23
|
-
* @param ignore Should errors be ignored
|
|
24
24
|
*/
|
|
25
|
-
static async copyRecursive(src: string, dest: string, inclusive: boolean = false,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
static async copyRecursive(src: string, dest: string, inclusive: boolean = false, ignoreFailure = false): Promise<void> {
|
|
26
|
+
try {
|
|
27
|
+
let final = dest;
|
|
28
|
+
if (!inclusive) {
|
|
29
|
+
final = path.resolve(dest, path.basename(src));
|
|
30
|
+
}
|
|
31
|
+
await fs.mkdir(final, { recursive: true });
|
|
32
|
+
await fs.cp(src, final, { recursive: true });
|
|
33
|
+
} catch (err) {
|
|
34
|
+
if (!ignoreFailure) {
|
|
35
|
+
throw new Error(`Failed to copy ${src} to ${dest}`);
|
|
36
|
+
}
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
39
|
|
|
@@ -34,15 +41,14 @@ export class PackUtil {
|
|
|
34
41
|
* Finalize eject output
|
|
35
42
|
*/
|
|
36
43
|
static async writeEjectOutput(workspace: string, module: string, output: AsyncIterable<string>, file: string): Promise<void> {
|
|
37
|
-
const vars = { DIST: workspace, TRV_OUT: RuntimeIndex.outputRoot, ROOT: path.
|
|
44
|
+
const vars = { DIST: workspace, TRV_OUT: RuntimeIndex.outputRoot, ROOT: path.resolve(), MOD: module };
|
|
38
45
|
|
|
39
46
|
const replaceArgs = (text: string): string => Object.entries(vars)
|
|
40
47
|
.reduce((str, [k, v]) => str.replaceAll(v, ActiveShellCommand.var(k)), text);
|
|
41
48
|
|
|
42
|
-
const preamble =
|
|
43
|
-
ActiveShellCommand.
|
|
44
|
-
|
|
45
|
-
].join('\n');
|
|
49
|
+
const preamble = ActiveShellCommand.script(
|
|
50
|
+
Object.entries(vars).map(([k, v]) => ActiveShellCommand.export(k, v).join(' ')),
|
|
51
|
+
).contents;
|
|
46
52
|
|
|
47
53
|
let stream: fs.FileHandle | undefined;
|
|
48
54
|
|
|
@@ -54,7 +60,9 @@ export class PackUtil {
|
|
|
54
60
|
|
|
55
61
|
const write = (text: string): Promise<unknown> | unknown => stream ? stream.write(`${text}\n`) : process.stdout.write(`${text}\n`);
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
for (const line of preamble) {
|
|
64
|
+
write(line);
|
|
65
|
+
}
|
|
58
66
|
for await (const line of output) {
|
|
59
67
|
await write(replaceArgs(line));
|
|
60
68
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { RuntimeIndex } from '@travetto/manifest';
|
|
2
4
|
import { CliCommand, CliFlag, CliUtil, CliValidationError } from '@travetto/cli';
|
|
3
5
|
import { Ignore, Required } from '@travetto/schema';
|
|
4
6
|
|
|
@@ -6,9 +8,7 @@ import { DockerPackOperation } from './bin/docker-operation';
|
|
|
6
8
|
import { BasePackCommand, PackOperationShape } from './pack.base';
|
|
7
9
|
import { DockerPackConfig } from '../src/types';
|
|
8
10
|
|
|
9
|
-
const NODE_MAJOR =
|
|
10
|
-
const DEFAULT_USER_ID = 2000;
|
|
11
|
-
const DEFAULT_USER = 'app';
|
|
11
|
+
const NODE_MAJOR = process.version.match(/\d+/)?.[0] ?? '22';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Standard docker support for pack
|
|
@@ -40,6 +40,15 @@ export class PackDockerCommand extends BasePackCommand {
|
|
|
40
40
|
@Ignore()
|
|
41
41
|
dockerRuntime: DockerPackConfig['dockerRuntime'];
|
|
42
42
|
|
|
43
|
+
@Ignore()
|
|
44
|
+
appFolder = 'app';
|
|
45
|
+
|
|
46
|
+
@Ignore()
|
|
47
|
+
defaultUser = this.appFolder;
|
|
48
|
+
|
|
49
|
+
@Ignore()
|
|
50
|
+
defaultUserId = 2000;
|
|
51
|
+
|
|
43
52
|
async validate(...args: string[]): Promise<CliValidationError[] | undefined> {
|
|
44
53
|
const errs: CliValidationError[] = [];
|
|
45
54
|
if (this.dockerPort?.length) {
|
|
@@ -65,11 +74,11 @@ export class PackDockerCommand extends BasePackCommand {
|
|
|
65
74
|
const groupIsNum = /^\d+$/.test(groupOrGid);
|
|
66
75
|
const userIsNum = /^\d+$/.test(userOrUid);
|
|
67
76
|
|
|
68
|
-
const uid = userIsNum ? +userOrUid :
|
|
69
|
-
const gid = groupIsNum ? +groupOrGid :
|
|
70
|
-
const group = (!groupIsNum ? groupOrGid : undefined) ||
|
|
71
|
-
const user = (!userIsNum ? userOrUid : undefined) ||
|
|
72
|
-
this.dockerRuntime = { user, uid, group, gid, folder: `/${
|
|
77
|
+
const uid = userIsNum ? +userOrUid : this.defaultUserId;
|
|
78
|
+
const gid = groupIsNum ? +groupOrGid : this.defaultUserId;
|
|
79
|
+
const group = (!groupIsNum ? groupOrGid : undefined) || this.defaultUser;
|
|
80
|
+
const user = (!userIsNum ? userOrUid : undefined) || this.defaultUser;
|
|
81
|
+
this.dockerRuntime = { user, uid, group, gid, folder: `/${this.appFolder}`, packages: this.dockerRuntimePackages };
|
|
73
82
|
}
|
|
74
83
|
|
|
75
84
|
preHelp(): void {
|
package/support/pack.base.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
2
3
|
|
|
3
4
|
import { CliCommandShape, CliFlag, ParsedState, cliTpl } from '@travetto/cli';
|
|
4
|
-
import {
|
|
5
|
+
import { RuntimeIndex, RuntimeContext } from '@travetto/manifest';
|
|
5
6
|
import { TimeUtil } from '@travetto/base';
|
|
6
7
|
import { Terminal } from '@travetto/terminal';
|
|
7
8
|
import { Ignore, Required, Schema } from '@travetto/schema';
|
|
@@ -26,8 +27,8 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
26
27
|
@Ignore()
|
|
27
28
|
_parsed: ParsedState;
|
|
28
29
|
|
|
29
|
-
@CliFlag({ desc: 'Workspace for building', short: '
|
|
30
|
-
|
|
30
|
+
@CliFlag({ desc: 'Workspace for building', short: 'b' })
|
|
31
|
+
buildDir: string = path.resolve(os.tmpdir(), RuntimeIndex.mainModule.sourcePath.replace(/[\/\\: ]/g, '_'));
|
|
31
32
|
|
|
32
33
|
@CliFlag({ desc: 'Clean workspace' })
|
|
33
34
|
clean = true;
|
|
@@ -81,6 +82,9 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
81
82
|
@Ignore()
|
|
82
83
|
entryArguments: string[] = [];
|
|
83
84
|
|
|
85
|
+
@Ignore()
|
|
86
|
+
workspaceResourceFolder: string = 'resources-workspace';
|
|
87
|
+
|
|
84
88
|
getOperations(): PackOperationShape<this>[] {
|
|
85
89
|
return [
|
|
86
90
|
PackOperation.clean,
|
|
@@ -109,7 +113,7 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
109
113
|
// Resolve all files to absolute paths
|
|
110
114
|
this.output = this.output ? path.resolve(this.output) : undefined!;
|
|
111
115
|
this.ejectFile = this.ejectFile ? path.resolve(this.ejectFile) : undefined;
|
|
112
|
-
this.
|
|
116
|
+
this.buildDir = path.resolve(this.buildDir);
|
|
113
117
|
|
|
114
118
|
// Update entry points
|
|
115
119
|
this.entryArguments = [...this.entryArguments ?? [], ...args, ...this._parsed.unknown];
|
|
@@ -121,14 +125,14 @@ export abstract class BasePackCommand implements CliCommandShape {
|
|
|
121
125
|
|
|
122
126
|
// Eject to file
|
|
123
127
|
if (this.ejectFile) {
|
|
124
|
-
await PackUtil.writeEjectOutput(this.
|
|
128
|
+
await PackUtil.writeEjectOutput(this.buildDir, this.module, stream, this.ejectFile);
|
|
125
129
|
} else {
|
|
126
130
|
const start = Date.now();
|
|
127
131
|
const term = new Terminal();
|
|
128
132
|
|
|
129
133
|
await term.streamLines(stream);
|
|
130
134
|
|
|
131
|
-
let msg = cliTpl`${{ success: 'Success' }} (${{ identifier: TimeUtil.
|
|
135
|
+
let msg = cliTpl`${{ success: 'Success' }} (${{ identifier: TimeUtil.asClock(Date.now() - start) }}) ${{ subtitle: 'module' }}=${{ param: this.module }}`;
|
|
132
136
|
if (this.output) {
|
|
133
137
|
msg = cliTpl`${msg} ${{ subtitle: 'output' }}=${{ path: this.output }}`;
|
|
134
138
|
}
|
package/support/rollup/config.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
2
|
|
|
3
|
+
import type { OutputOptions } from 'rollup';
|
|
3
4
|
import type terser from '@rollup/plugin-terser';
|
|
4
5
|
|
|
5
|
-
import { ManifestModule, ManifestModuleUtil, NodeModuleType,
|
|
6
|
+
import { ManifestModule, ManifestModuleUtil, NodeModuleType, RuntimeIndex, RuntimeContext } from '@travetto/manifest';
|
|
6
7
|
import { EnvProp } from '@travetto/base';
|
|
7
8
|
import { CoreRollupConfig } from '../../src/types';
|
|
8
9
|
|