@travetto/pack 3.0.3 → 3.1.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/README.md +86 -87
- package/package.json +3 -3
- package/support/bin/operation.ts +4 -27
- package/support/bin/shell.ts +2 -2
- package/support/bin/types.ts +6 -31
- package/support/bin/util.ts +22 -20
- package/support/cli.pack.ts +4 -9
- package/support/cli.pack_docker.ts +23 -27
- package/support/cli.pack_zip.ts +7 -9
- package/support/pack.base.ts +77 -109
- package/support/pack.dockerfile.ts +1 -1
package/README.md
CHANGED
|
@@ -26,20 +26,21 @@ There are three primary cli commands for packing your code:
|
|
|
26
26
|
```bash
|
|
27
27
|
$ trv pack --help
|
|
28
28
|
|
|
29
|
-
Usage:
|
|
29
|
+
Usage: pack [options]
|
|
30
30
|
|
|
31
31
|
Options:
|
|
32
|
-
-w, --workspace <
|
|
33
|
-
|
|
34
|
-
-o, --output <
|
|
35
|
-
-
|
|
36
|
-
-f, --main-name <
|
|
37
|
-
-e, --entry-point <
|
|
38
|
-
|
|
39
|
-
-sm, --sourcemap
|
|
40
|
-
-is, --include-sources
|
|
41
|
-
-x, --eject-file <
|
|
42
|
-
-
|
|
32
|
+
-w, --workspace <string> Workspace for building (default: "/tmp/<temp-folder>")
|
|
33
|
+
--clean, --no-clean Clean workspace (default: true)
|
|
34
|
+
-o, --output <string> Output location
|
|
35
|
+
--main-scripts, --no-main-scripts Create entry scripts (default: true)
|
|
36
|
+
-f, --main-name <string> Main name for build artifact
|
|
37
|
+
-e, --entry-point <string> Entry point (default: "@travetto/cli/support/entry.cli")
|
|
38
|
+
--minify, --no-minify Minify output (default: true)
|
|
39
|
+
-sm, --sourcemap Bundle source maps (default: false)
|
|
40
|
+
-is, --include-sources Include source with source maps (default: false)
|
|
41
|
+
-x, --eject-file <string> Eject commands to file
|
|
42
|
+
-m, --module <string> Module to run for
|
|
43
|
+
-h, --help display help for command
|
|
43
44
|
```
|
|
44
45
|
|
|
45
46
|
This command line operation will compile your project, and produce a ready to use workspace as a deliverable. Additionally, you can pass in a file to the `eject-file` flag that will allow for a script to be produced (base on the host operating system).
|
|
@@ -86,20 +87,21 @@ This command is nearly identical to the standard `pack` operation, except for th
|
|
|
86
87
|
```bash
|
|
87
88
|
$ trv pack:zip --help
|
|
88
89
|
|
|
89
|
-
Usage:
|
|
90
|
+
Usage: pack:zip [options]
|
|
90
91
|
|
|
91
92
|
Options:
|
|
92
|
-
-w, --workspace <
|
|
93
|
-
|
|
94
|
-
-o, --output <
|
|
95
|
-
-
|
|
96
|
-
-f, --main-name <
|
|
97
|
-
-e, --entry-point <
|
|
98
|
-
|
|
99
|
-
-sm, --sourcemap
|
|
100
|
-
-is, --include-sources
|
|
101
|
-
-x, --eject-file <
|
|
102
|
-
-
|
|
93
|
+
-w, --workspace <string> Workspace for building (default: "/tmp/<temp-folder>")
|
|
94
|
+
--clean, --no-clean Clean workspace (default: true)
|
|
95
|
+
-o, --output <string> Output location (default: "travetto_pack.zip")
|
|
96
|
+
--main-scripts, --no-main-scripts Create entry scripts (default: true)
|
|
97
|
+
-f, --main-name <string> Main name for build artifact
|
|
98
|
+
-e, --entry-point <string> Entry point (default: "@travetto/cli/support/entry.cli")
|
|
99
|
+
--minify, --no-minify Minify output (default: true)
|
|
100
|
+
-sm, --sourcemap Bundle source maps (default: false)
|
|
101
|
+
-is, --include-sources Include source with source maps (default: false)
|
|
102
|
+
-x, --eject-file <string> Eject commands to file
|
|
103
|
+
-m, --module <string> Module to run for
|
|
104
|
+
-h, --help display help for command
|
|
103
105
|
```
|
|
104
106
|
|
|
105
107
|
## CLI - pack:docker
|
|
@@ -109,27 +111,28 @@ This command starts off identical to the standard `pack` operation, but it conta
|
|
|
109
111
|
```bash
|
|
110
112
|
$ trv pack:docker --help
|
|
111
113
|
|
|
112
|
-
Usage:
|
|
114
|
+
Usage: pack:docker [options]
|
|
113
115
|
|
|
114
116
|
Options:
|
|
115
|
-
-w, --workspace <
|
|
116
|
-
|
|
117
|
-
-o, --output <
|
|
118
|
-
-
|
|
119
|
-
-f, --main-name <
|
|
120
|
-
-e, --entry-point <
|
|
121
|
-
|
|
122
|
-
-sm, --sourcemap
|
|
123
|
-
-is, --include-sources
|
|
124
|
-
-x, --eject-file <
|
|
125
|
-
-df, --docker-factory <
|
|
126
|
-
-di, --docker-image <
|
|
127
|
-
-dn, --docker-name <
|
|
128
|
-
-dt, --docker-tag <
|
|
129
|
-
-dp, --docker-port <
|
|
130
|
-
-dx, --docker-push
|
|
131
|
-
-dr, --docker-registry <
|
|
132
|
-
-
|
|
117
|
+
-w, --workspace <string> Workspace for building (default: "/tmp/<temp-folder>")
|
|
118
|
+
--clean, --no-clean Clean workspace (default: true)
|
|
119
|
+
-o, --output <string> Output location
|
|
120
|
+
--main-scripts, --no-main-scripts Create entry scripts (default: true)
|
|
121
|
+
-f, --main-name <string> Main name for build artifact
|
|
122
|
+
-e, --entry-point <string> Entry point (default: "@travetto/cli/support/entry.cli")
|
|
123
|
+
--minify, --no-minify Minify output (default: true)
|
|
124
|
+
-sm, --sourcemap Bundle source maps (default: false)
|
|
125
|
+
-is, --include-sources Include source with source maps (default: false)
|
|
126
|
+
-x, --eject-file <string> Eject commands to file
|
|
127
|
+
-df, --docker-factory <string> Docker Factory source (default: "@travetto/pack/support/pack.dockerfile")
|
|
128
|
+
-di, --docker-image <string> Docker Image to extend (default: "node:18-alpine3.16")
|
|
129
|
+
-dn, --docker-name <string> Docker Image Name (default: "travetto_pack")
|
|
130
|
+
-dt, --docker-tag <string> Docker Image Tag (default: ["latest"])
|
|
131
|
+
-dp, --docker-port <number> Docker Image Port (default: [])
|
|
132
|
+
-dx, --docker-push Docker Push Tags (default: false)
|
|
133
|
+
-dr, --docker-registry <string> Docker Registry
|
|
134
|
+
-m, --module <string> Module to run for
|
|
135
|
+
-h, --help display help for command
|
|
133
136
|
```
|
|
134
137
|
|
|
135
138
|
The additional flags provided are allow for specifying the base image, the final docker image name (and tags), and which registry to push to (if any). Additionally, there are flags for exposing which ports the image should expect to open as well. When using the `--eject-file` flag, the output script will produce the entire Dockerfile output inline, so that it can be easily modified as needed.
|
|
@@ -145,82 +148,78 @@ As indicated, any of the pack operations can be ejected, and produce an output t
|
|
|
145
148
|
|
|
146
149
|
**Terminal: Sample Ejected File**
|
|
147
150
|
```bash
|
|
148
|
-
$ trv pack:docker -x /dev/stdout run
|
|
151
|
+
$ trv pack:docker -x /dev/stdout run:rest
|
|
149
152
|
|
|
150
153
|
#!/bin/sh
|
|
151
|
-
export DIST=/tmp
|
|
154
|
+
export DIST=/tmp/<temp-folder>
|
|
152
155
|
export TRV_OUT=<workspace-root>/.trv_output
|
|
153
156
|
export ROOT=<workspace-root>/related/todo-app
|
|
154
157
|
export MOD=@travetto/todo-app
|
|
155
158
|
|
|
156
159
|
# Cleaning Output $DIST
|
|
157
160
|
|
|
158
|
-
echo "Cleaning Output $DIST
|
|
159
|
-
|
|
161
|
+
echo "Cleaning Output $DIST"
|
|
162
|
+
|
|
160
163
|
rm -rf $DIST
|
|
161
164
|
mkdir -p $DIST
|
|
162
165
|
|
|
163
166
|
# Writing .env.js
|
|
164
167
|
|
|
165
|
-
echo "Writing .env.js
|
|
166
|
-
|
|
168
|
+
echo "Writing .env.js"
|
|
169
|
+
|
|
167
170
|
echo "process.env.TRV_MANIFEST = 'node_modules/$MOD';" > $DIST/.env.js
|
|
171
|
+
echo "process.env.TRV_MODULE = '$MOD';" >> $DIST/.env.js
|
|
168
172
|
echo "process.env.TRV_CLI_IPC = '';" >> $DIST/.env.js
|
|
169
173
|
|
|
170
174
|
# Writing package.json
|
|
171
175
|
|
|
172
|
-
echo "Writing package.json
|
|
173
|
-
|
|
176
|
+
echo "Writing package.json"
|
|
177
|
+
|
|
174
178
|
echo "{\"type\":\"commonjs\"}" > $DIST/package.json
|
|
175
179
|
|
|
176
|
-
# Writing entry scripts
|
|
180
|
+
# Writing entry scripts todo-app.sh args=(run:rest)
|
|
181
|
+
|
|
182
|
+
echo "Writing entry scripts todo-app.sh args=(run:rest)"
|
|
177
183
|
|
|
178
|
-
echo "
|
|
179
|
-
"
|
|
180
|
-
echo "
|
|
181
|
-
|
|
182
|
-
echo "node entry.cli.js run rest \$@" >> $DIST/entry.cli.sh
|
|
183
|
-
chmod 755 $DIST/entry.cli.sh
|
|
184
|
+
echo "#!/bin/sh" > $DIST/todo-app.sh
|
|
185
|
+
echo "cd \$(dirname \"\$0\")" >> $DIST/todo-app.sh
|
|
186
|
+
echo "node todo-app.js run:rest \$@" >> $DIST/todo-app.sh
|
|
187
|
+
chmod 755 $DIST/todo-app.sh
|
|
184
188
|
|
|
185
|
-
# Writing entry scripts
|
|
189
|
+
# Writing entry scripts todo-app.cmd args=(run:rest)
|
|
186
190
|
|
|
187
|
-
echo "Writing entry scripts
|
|
188
|
-
|
|
189
|
-
echo "" > $DIST/
|
|
190
|
-
echo "cd %~p0" >> $DIST/
|
|
191
|
-
echo "node
|
|
192
|
-
chmod 755 $DIST/
|
|
191
|
+
echo "Writing entry scripts todo-app.cmd args=(run:rest)"
|
|
192
|
+
|
|
193
|
+
echo "" > $DIST/todo-app.cmd
|
|
194
|
+
echo "cd %~p0" >> $DIST/todo-app.cmd
|
|
195
|
+
echo "node todo-app.js run:rest %*" >> $DIST/todo-app.cmd
|
|
196
|
+
chmod 755 $DIST/todo-app.cmd
|
|
193
197
|
|
|
194
198
|
# Copying over resources
|
|
195
199
|
|
|
196
|
-
echo "Copying over resources
|
|
197
|
-
|
|
200
|
+
echo "Copying over resources"
|
|
201
|
+
|
|
198
202
|
mkdir -p $DIST/node_modules/$MOD
|
|
199
203
|
cp $TRV_OUT/node_modules/$MOD/package.json $DIST/node_modules/$MOD/package.json
|
|
200
204
|
mkdir -p $DIST/node_modules/@travetto/manifest
|
|
201
205
|
cp $TRV_OUT/node_modules/@travetto/manifest/package.json $DIST/node_modules/@travetto/manifest/package.json
|
|
202
206
|
cp -r -p $ROOT/resources $DIST/resources
|
|
203
207
|
|
|
204
|
-
# Generating App Cache node_modules/$MOD/trv-app-cache.json
|
|
205
|
-
|
|
206
|
-
echo "Generating App Cache node_modules/$MOD/trv-app-cache.json
|
|
207
|
-
"
|
|
208
|
-
mkdir -p $DIST/node_modules/$MOD
|
|
209
|
-
DEBUG=0 TRV_MODULE=$MOD npx trv main @travetto/app/support/bin/list > $DIST/node_modules/$MOD/trv-app-cache.json
|
|
210
|
-
|
|
211
208
|
# Writing Manifest node_modules/$MOD
|
|
212
209
|
|
|
213
|
-
echo "Writing Manifest node_modules/$MOD
|
|
214
|
-
|
|
210
|
+
echo "Writing Manifest node_modules/$MOD"
|
|
211
|
+
|
|
215
212
|
TRV_MODULE=$MOD npx trv manifest $DIST/node_modules/$MOD prod
|
|
216
213
|
|
|
217
|
-
# Bundling Output minify=true sourcemap= entryPoint=@travetto/cli/support/entry.cli
|
|
214
|
+
# Bundling Output minify=true sourcemap=false entryPoint=@travetto/cli/support/entry.cli
|
|
215
|
+
|
|
216
|
+
echo "Bundling Output minify=true sourcemap=false entryPoint=@travetto/cli/support/entry.cli"
|
|
218
217
|
|
|
219
|
-
echo "Bundling Output minify=true sourcemap= entryPoint=@travetto/cli/support/entry.cli
|
|
220
|
-
"
|
|
221
218
|
export BUNDLE_ENTRY=node_modules/@travetto/cli/support/entry.cli.js
|
|
222
|
-
export BUNDLE_MAIN_FILE=
|
|
219
|
+
export BUNDLE_MAIN_FILE=todo-app.js
|
|
223
220
|
export BUNDLE_COMPRESS=true
|
|
221
|
+
export BUNDLE_SOURCEMAP=false
|
|
222
|
+
export BUNDLE_SOURCES=false
|
|
224
223
|
export BUNDLE_OUTPUT=$DIST
|
|
225
224
|
export BUNDLE_FORMAT=commonjs
|
|
226
225
|
export TRV_MANIFEST=$TRV_OUT/node_modules/$MOD
|
|
@@ -230,24 +229,24 @@ cd $ROOT
|
|
|
230
229
|
|
|
231
230
|
# Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile
|
|
232
231
|
|
|
233
|
-
echo "Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile
|
|
234
|
-
|
|
232
|
+
echo "Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile"
|
|
233
|
+
|
|
235
234
|
echo "FROM node:18-alpine3.16" > $DIST/Dockerfile
|
|
236
235
|
echo "WORKDIR /app" >> $DIST/Dockerfile
|
|
237
236
|
echo "COPY . ." >> $DIST/Dockerfile
|
|
238
237
|
echo "" >> $DIST/Dockerfile
|
|
239
|
-
echo "ENTRYPOINT [\"/app/
|
|
238
|
+
echo "ENTRYPOINT [\"/app/todo-app.sh\"]" >> $DIST/Dockerfile
|
|
240
239
|
|
|
241
240
|
# Pulling Docker Base Image node:18-alpine3.16
|
|
242
241
|
|
|
243
|
-
echo "Pulling Docker Base Image node:18-alpine3.16
|
|
244
|
-
|
|
242
|
+
echo "Pulling Docker Base Image node:18-alpine3.16"
|
|
243
|
+
|
|
245
244
|
docker pull node:18-alpine3.16
|
|
246
245
|
|
|
247
246
|
# Building Docker Container latest
|
|
248
247
|
|
|
249
|
-
echo "Building Docker Container latest
|
|
250
|
-
|
|
248
|
+
echo "Building Docker Container latest"
|
|
249
|
+
|
|
251
250
|
cd $DIST
|
|
252
251
|
docker build -t travetto_todo-app:latest .
|
|
253
252
|
cd $ROOT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/pack",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.1.0-rc.0",
|
|
4
4
|
"description": "Code packing utilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"travetto",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"@rollup/plugin-json": "^6.0.0",
|
|
29
29
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
30
30
|
"@rollup/plugin-terser": "^0.4.0",
|
|
31
|
-
"@travetto/base": "^3.0.
|
|
31
|
+
"@travetto/base": "^3.1.0-rc.0",
|
|
32
32
|
"rollup": "^3.17.2",
|
|
33
33
|
"rollup-plugin-sourcemaps": "^0.6.3"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@travetto/cli": "^3.0.
|
|
36
|
+
"@travetto/cli": "^3.1.0-rc.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependenciesMeta": {
|
|
39
39
|
"@travetto/cli": {
|
package/support/bin/operation.ts
CHANGED
|
@@ -12,6 +12,9 @@ async function writeRawFile(file: string, contents: string, mode?: string): Prom
|
|
|
12
12
|
await fs.writeFile(file, contents, { encoding: 'utf8', mode });
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* General pack operations
|
|
17
|
+
*/
|
|
15
18
|
export class PackOperation {
|
|
16
19
|
|
|
17
20
|
static async * title(cfg: CommonPackConfig, title: string): AsyncIterable<string[]> {
|
|
@@ -118,6 +121,7 @@ export class PackOperation {
|
|
|
118
121
|
const file = '.env.js';
|
|
119
122
|
const env = {
|
|
120
123
|
TRV_MANIFEST: `node_modules/${cfg.module}`,
|
|
124
|
+
TRV_MODULE: cfg.module,
|
|
121
125
|
TRV_CLI_IPC: ''
|
|
122
126
|
};
|
|
123
127
|
|
|
@@ -212,33 +216,6 @@ export class PackOperation {
|
|
|
212
216
|
}
|
|
213
217
|
}
|
|
214
218
|
|
|
215
|
-
/**
|
|
216
|
-
* Generate the trv-app-cache.json for @travetto/app, which is needed for 'running' programs
|
|
217
|
-
*/
|
|
218
|
-
static async * primeAppCache(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
219
|
-
const isRun = /entry[.]cli/.test(cfg.entryPoint) && cfg.entryArguments.filter(x => !x.startsWith('-'))[0] === 'run';
|
|
220
|
-
if (!isRun) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const appCacheCmd = ['npx', 'trv', 'main', '@travetto/app/support/bin/list'];
|
|
225
|
-
const sub = path.join(RootIndex.manifest.modules[RootIndex.mainModule.name].outputFolder, 'trv-app-cache.json');
|
|
226
|
-
const env = { DEBUG: '0', TRV_MODULE: cfg.module };
|
|
227
|
-
const appCache = path.resolve(cfg.workspace, sub);
|
|
228
|
-
|
|
229
|
-
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Generating App Cache' }} ${{ path: sub }}`);
|
|
230
|
-
|
|
231
|
-
if (cfg.ejectFile) {
|
|
232
|
-
yield ActiveShellCommand.mkdir(path.dirname(appCache));
|
|
233
|
-
yield [...Object.entries(env).map(x => `${x[0]}=${x[1]}`), ...appCacheCmd, '>', appCache];
|
|
234
|
-
} else {
|
|
235
|
-
const { stdout } = await ExecUtil.spawn(appCacheCmd[0], appCacheCmd.slice(1), { env }).result;
|
|
236
|
-
|
|
237
|
-
await fs.mkdir(path.dirname(appCache), { recursive: true });
|
|
238
|
-
await fs.writeFile(appCache, stdout, 'utf8');
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
219
|
/**
|
|
243
220
|
* Produce the output manifest, only including prod dependencies
|
|
244
221
|
*/
|
package/support/bin/shell.ts
CHANGED
|
@@ -27,7 +27,7 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
|
|
|
27
27
|
export: (key, value) => ['set', `${key}=${value}`],
|
|
28
28
|
chdir: (dest) => ['cd', dest],
|
|
29
29
|
comment: (message) => ['\nREM', stripAnsiCodes(message), '\n'],
|
|
30
|
-
echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}\n
|
|
30
|
+
echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}"\n`],
|
|
31
31
|
zip: (outputFile) => ['powershell', 'Compress-Archive', '-Path', '.', '-DestinationPath', outputFile]
|
|
32
32
|
},
|
|
33
33
|
posix: {
|
|
@@ -47,7 +47,7 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
|
|
|
47
47
|
export: (key, value) => ['export', `${key}=${value}`],
|
|
48
48
|
chdir: (dest) => ['cd', dest],
|
|
49
49
|
comment: (message) => ['\n#', stripAnsiCodes(message), '\n'],
|
|
50
|
-
echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}\n
|
|
50
|
+
echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}"\n`],
|
|
51
51
|
zip: (outputFile) => ['zip', '-r', outputFile, '.']
|
|
52
52
|
},
|
|
53
53
|
};
|
package/support/bin/types.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { ListOptionConfig, OptionConfig } from '@travetto/cli';
|
|
2
|
-
|
|
3
1
|
export type CommonPackConfig = {
|
|
4
2
|
workspace: string;
|
|
5
3
|
output: string;
|
|
6
4
|
clean: boolean;
|
|
7
|
-
ejectFile
|
|
5
|
+
ejectFile?: string;
|
|
8
6
|
mainName: string;
|
|
9
|
-
mainScripts
|
|
7
|
+
mainScripts?: boolean;
|
|
10
8
|
module: string;
|
|
11
9
|
|
|
12
10
|
// Bundle
|
|
@@ -17,40 +15,17 @@ export type CommonPackConfig = {
|
|
|
17
15
|
includeSources: boolean;
|
|
18
16
|
};
|
|
19
17
|
|
|
20
|
-
export type CommonPackOptions = {
|
|
21
|
-
workspace: OptionConfig<string>;
|
|
22
|
-
output: OptionConfig<string>;
|
|
23
|
-
clean: OptionConfig<boolean>;
|
|
24
|
-
ejectFile: OptionConfig<string>;
|
|
25
|
-
mainName: OptionConfig<string>;
|
|
26
|
-
mainScripts: OptionConfig<boolean>;
|
|
27
|
-
|
|
28
|
-
// Bundle
|
|
29
|
-
entryPoint: OptionConfig<string>;
|
|
30
|
-
minify: OptionConfig<boolean>;
|
|
31
|
-
sourcemap: OptionConfig<boolean>;
|
|
32
|
-
includeSources: OptionConfig<boolean>;
|
|
33
|
-
};
|
|
34
18
|
|
|
35
19
|
export type DockerPackConfig = {
|
|
36
20
|
dockerFactory: string;
|
|
37
21
|
dockerImage: string;
|
|
38
22
|
dockerName: string;
|
|
39
|
-
dockerTag
|
|
40
|
-
dockerPort
|
|
41
|
-
dockerPush
|
|
42
|
-
dockerRegistry
|
|
23
|
+
dockerTag?: string[];
|
|
24
|
+
dockerPort?: number[];
|
|
25
|
+
dockerPush?: boolean;
|
|
26
|
+
dockerRegistry?: string;
|
|
43
27
|
} & CommonPackConfig;
|
|
44
28
|
|
|
45
|
-
export type DockerPackOptions = {
|
|
46
|
-
dockerFactory: OptionConfig<string>;
|
|
47
|
-
dockerImage: OptionConfig<string>;
|
|
48
|
-
dockerName: OptionConfig<string>;
|
|
49
|
-
dockerTag: ListOptionConfig<string>;
|
|
50
|
-
dockerPort: ListOptionConfig<string>;
|
|
51
|
-
dockerPush: OptionConfig<boolean>;
|
|
52
|
-
dockerRegistry: OptionConfig<string>;
|
|
53
|
-
} & CommonPackOptions;
|
|
54
29
|
|
|
55
30
|
export type ShellCommandImpl = {
|
|
56
31
|
var(name: string): string;
|
package/support/bin/util.ts
CHANGED
|
@@ -33,31 +33,33 @@ export class PackUtil {
|
|
|
33
33
|
/**
|
|
34
34
|
* Finalize eject output
|
|
35
35
|
*/
|
|
36
|
-
static async writeEjectOutput(
|
|
37
|
-
workspace:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
DIST: workspace,
|
|
44
|
-
TRV_OUT: RootIndex.outputRoot,
|
|
45
|
-
ROOT: path.cwd(),
|
|
46
|
-
MOD: module
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const content = [
|
|
36
|
+
static async writeEjectOutput(workspace: string, module: string, output: AsyncIterable<string>, file: string): Promise<void> {
|
|
37
|
+
const vars = { DIST: workspace, TRV_OUT: RootIndex.outputRoot, ROOT: path.cwd(), MOD: module };
|
|
38
|
+
|
|
39
|
+
const replaceArgs = (text: string): string => Object.entries(vars)
|
|
40
|
+
.reduce((str, [k, v]) => str.replaceAll(v, ActiveShellCommand.var(k)), text);
|
|
41
|
+
|
|
42
|
+
const preamble = [
|
|
50
43
|
ActiveShellCommand.scriptOpen(),
|
|
51
44
|
...Object.entries(vars).map(([k, v]) => ActiveShellCommand.export(k, v).join(' ')),
|
|
52
|
-
Object.entries(vars).reduce((text, [k, v]) => text.replaceAll(v, ActiveShellCommand.var(k)), output.join('\n')),
|
|
53
|
-
'', ''
|
|
54
45
|
].join('\n');
|
|
55
46
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
let stream: fs.FileHandle | undefined;
|
|
48
|
+
|
|
49
|
+
if (!(file === '-' || file === '/dev/stdout')) {
|
|
59
50
|
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
60
|
-
await fs.
|
|
51
|
+
await fs.truncate(file);
|
|
52
|
+
stream = await fs.open(file, 'utf8');
|
|
61
53
|
}
|
|
54
|
+
|
|
55
|
+
const write = (text: string): Promise<unknown> | unknown => stream ? stream.write(`${text}\n`) : process.stdout.write(`${text}\n`);
|
|
56
|
+
|
|
57
|
+
await write(preamble);
|
|
58
|
+
for await (const line of output) {
|
|
59
|
+
await write(replaceArgs(line));
|
|
60
|
+
}
|
|
61
|
+
await write('\n');
|
|
62
|
+
|
|
63
|
+
await stream?.close();
|
|
62
64
|
}
|
|
63
65
|
}
|
package/support/cli.pack.ts
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
+
import { CliCommand } from '@travetto/cli';
|
|
2
|
+
|
|
1
3
|
import { BasePackCommand } from './pack.base';
|
|
2
|
-
import { CommonPackConfig, CommonPackOptions } from './bin/types';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Standard pack support
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
name = 'pack';
|
|
10
|
-
|
|
11
|
-
getOptions(): CommonPackOptions {
|
|
12
|
-
return this.getCommonOptions();
|
|
13
|
-
}
|
|
14
|
-
}
|
|
8
|
+
@CliCommand({ fields: ['module'] })
|
|
9
|
+
export class PackCommand extends BasePackCommand { }
|
|
@@ -1,42 +1,38 @@
|
|
|
1
1
|
import { path, RootIndex } from '@travetto/manifest';
|
|
2
|
+
import { CliCommand, CliFlag, CliUtil } from '@travetto/cli';
|
|
2
3
|
|
|
3
|
-
import { DockerPackConfig, DockerPackOptions } from './bin/types';
|
|
4
4
|
import { DockerPackOperation } from './bin/docker-operation';
|
|
5
5
|
import { BasePackCommand, PackOperationShape } from './pack.base';
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Standard docker support for pack
|
|
10
9
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
10
|
+
@CliCommand({ fields: ['module'] })
|
|
11
|
+
export class PackDockerCommand extends BasePackCommand {
|
|
12
|
+
@CliFlag({ desc: 'Docker Factory source ', short: 'df', envVars: ['PACK_DOCKER_FACTORY'] })
|
|
13
|
+
dockerFactory = '@travetto/pack/support/pack.dockerfile';
|
|
14
|
+
@CliFlag({ desc: 'Docker Image to extend ', short: 'di', envVars: ['PACK_DOCKER_IMAGE'] })
|
|
15
|
+
dockerImage = 'node:18-alpine3.16';
|
|
16
|
+
@CliFlag({ desc: 'Docker Image Name ', short: 'dn', envVars: ['PACK_DOCKER_IMAGE'] })
|
|
17
|
+
dockerName = CliUtil.monoRoot ? '<module>' : CliUtil.getSimpleModuleName();
|
|
18
|
+
@CliFlag({ desc: 'Docker Image Tag ', short: 'dt', envVars: ['PACK_DOCKER_TAGS'] })
|
|
19
|
+
dockerTag: string[] = ['latest'];
|
|
20
|
+
@CliFlag({ desc: 'Docker Image Port ', short: 'dp', envVars: ['PACK_DOCKER_PORT'] })
|
|
21
|
+
dockerPort: number[] = [];
|
|
22
|
+
@CliFlag({ desc: 'Docker Push Tags ', short: 'dx', envVars: ['PACK_DOCKER_PUSH'] })
|
|
23
|
+
dockerPush = false;
|
|
24
|
+
@CliFlag({ desc: 'Docker Registry ', short: 'dr', envVars: ['PACK_DOCKER_REGISTRY'] })
|
|
25
|
+
dockerRegistry?: string;
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
|
|
27
|
+
finalize(unknownArgs: string[]): void {
|
|
28
|
+
super.finalize(unknownArgs);
|
|
29
|
+
if (this.dockerFactory.startsWith('.')) {
|
|
30
|
+
this.dockerFactory = RootIndex.getFromSource(path.resolve(this.dockerFactory))?.import ?? this.dockerFactory;
|
|
33
31
|
}
|
|
34
|
-
|
|
35
|
-
cfg.dockerTag ??= [];
|
|
36
|
-
return cfg;
|
|
32
|
+
this.dockerName = this.dockerName.replace('<module>', CliUtil.getSimpleModuleName(this.module ?? ''));
|
|
37
33
|
}
|
|
38
34
|
|
|
39
|
-
getOperations(): PackOperationShape<
|
|
35
|
+
getOperations(): PackOperationShape<this>[] {
|
|
40
36
|
return [
|
|
41
37
|
...super.getOperations(),
|
|
42
38
|
DockerPackOperation.writeDockerFile,
|
package/support/cli.pack_zip.ts
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CliCommand, CliUtil } from '@travetto/cli';
|
|
2
|
+
|
|
2
3
|
import { PackOperation } from './bin/operation';
|
|
3
4
|
import { BasePackCommand, PackOperationShape } from './pack.base';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Standard zip support for pack
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
name = 'pack:zip';
|
|
9
|
+
@CliCommand({ fields: ['module'] })
|
|
10
|
+
export class PackZipCommand extends BasePackCommand {
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
opts.output.def = this.monoRoot ? '<module>.zip' : `${this.getSimpleModuleName()}.zip`;
|
|
15
|
-
return opts;
|
|
12
|
+
initialize(): void {
|
|
13
|
+
this.output = CliUtil.monoRoot ? '<module>.zip' : `${CliUtil.getSimpleModuleName()}.zip`;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
getOperations(): PackOperationShape<
|
|
16
|
+
getOperations(): PackOperationShape<this>[] {
|
|
19
17
|
return [
|
|
20
18
|
...super.getOperations(),
|
|
21
19
|
PackOperation.compress
|
package/support/pack.base.ts
CHANGED
|
@@ -1,149 +1,117 @@
|
|
|
1
1
|
import os from 'os';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { CliCommandShape, CliFlag, cliTpl, CliUtil } from '@travetto/cli';
|
|
4
4
|
import { path, RootIndex } from '@travetto/manifest';
|
|
5
5
|
import { TimeUtil } from '@travetto/base';
|
|
6
6
|
import { GlobalTerminal } from '@travetto/terminal';
|
|
7
|
+
import { Ignore, Required, Schema } from '@travetto/schema';
|
|
7
8
|
|
|
8
|
-
import { CommonPackConfig, CommonPackOptions } from './bin/types';
|
|
9
9
|
import { PackOperation } from './bin/operation';
|
|
10
10
|
import { PackUtil } from './bin/util';
|
|
11
11
|
|
|
12
|
-
export type PackOperationShape<T
|
|
12
|
+
export type PackOperationShape<T> = ((config: T) => AsyncIterable<string[]>);
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
PackOperation.writeEnv,
|
|
17
|
-
PackOperation.writePackageJson,
|
|
18
|
-
PackOperation.writeEntryScript,
|
|
19
|
-
PackOperation.copyResources,
|
|
20
|
-
PackOperation.primeAppCache,
|
|
21
|
-
PackOperation.writeManifest,
|
|
22
|
-
PackOperation.bundle,
|
|
23
|
-
];
|
|
14
|
+
@Schema()
|
|
15
|
+
export abstract class BasePackCommand implements CliCommandShape {
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
get monoRoot(): boolean {
|
|
28
|
-
return !!RootIndex.manifest.monoRepo && path.cwd() === RootIndex.manifest.workspacePath;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
get entryPoints(): string[] {
|
|
17
|
+
static get entryPoints(): string[] {
|
|
32
18
|
return RootIndex.findSupport({ filter: x => x.includes('entry.') })
|
|
33
19
|
.map(x => x.import.replace(/[.][^.]+s$/, ''));
|
|
34
20
|
}
|
|
35
21
|
|
|
36
|
-
|
|
37
|
-
return this.monoRoot ? '<module> [args...]' : '[args...]';
|
|
38
|
-
}
|
|
22
|
+
#unknownArgs?: string[];
|
|
39
23
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
workspace: this.option({ short: 'w', desc: 'Workspace for building' }),
|
|
44
|
-
clean: this.boolOption({ short: 'c', desc: 'Clean workspace', def: true }),
|
|
45
|
-
output: this.option({ short: 'o', desc: 'Output location' }),
|
|
46
|
-
mainScripts: this.option({ short: 'es', desc: 'Create entry scripts' }),
|
|
47
|
-
mainName: this.option({ short: 'f', desc: 'Main name for build artifact' }),
|
|
48
|
-
entryPoint: this.option({ short: 'e', desc: 'Entry point', def: mainEntry }),
|
|
49
|
-
minify: this.boolOption({ short: 'm', desc: 'Minify output', def: true }),
|
|
50
|
-
sourcemap: this.boolOption({ short: 'sm', desc: 'Bundle source maps' }),
|
|
51
|
-
includeSources: this.boolOption({ short: 'is', desc: 'Include source with source maps' }),
|
|
52
|
-
ejectFile: this.option({ short: 'x', desc: 'Eject commands to file' }),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
24
|
+
@CliFlag({ desc: 'Workspace for building', short: 'w' })
|
|
25
|
+
workspace: string = path.resolve(os.tmpdir(), RootIndex.mainModule.sourcePath.replace(/[\/\\: ]/g, '_'));
|
|
55
26
|
|
|
56
|
-
|
|
27
|
+
@CliFlag({ desc: 'Clean workspace' })
|
|
28
|
+
clean = true;
|
|
57
29
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
30
|
+
@CliFlag({ desc: 'Output location', short: 'o' })
|
|
31
|
+
@Required(false)
|
|
32
|
+
output: string;
|
|
62
33
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
34
|
+
@CliFlag({ desc: 'Create entry scripts', short: 'es' })
|
|
35
|
+
mainScripts: boolean = true;
|
|
36
|
+
|
|
37
|
+
@CliFlag({ desc: 'Main name for build artifact', short: 'f' })
|
|
38
|
+
@Required(false)
|
|
39
|
+
mainName: string;
|
|
40
|
+
|
|
41
|
+
@CliFlag({ desc: 'Entry point', short: 'e' })
|
|
42
|
+
@Required(false)
|
|
43
|
+
entryPoint: string = '@travetto/cli/support/entry.cli';
|
|
66
44
|
|
|
67
|
-
|
|
68
|
-
|
|
45
|
+
@CliFlag({ desc: 'Minify output' })
|
|
46
|
+
minify = true;
|
|
47
|
+
|
|
48
|
+
@CliFlag({ desc: 'Bundle source maps', short: 'sm' })
|
|
49
|
+
sourcemap = false;
|
|
50
|
+
|
|
51
|
+
@CliFlag({ desc: 'Include source with source maps', short: 'is' })
|
|
52
|
+
includeSources = false;
|
|
53
|
+
|
|
54
|
+
@CliFlag({ desc: 'Eject commands to file', short: 'x' })
|
|
55
|
+
ejectFile?: string;
|
|
56
|
+
|
|
57
|
+
@Ignore()
|
|
58
|
+
module: string;
|
|
59
|
+
|
|
60
|
+
/** Entry arguments */
|
|
61
|
+
@Ignore()
|
|
62
|
+
entryArguments: string[] = [];
|
|
63
|
+
|
|
64
|
+
getOperations(): PackOperationShape<this>[] {
|
|
65
|
+
return [
|
|
66
|
+
PackOperation.clean,
|
|
67
|
+
PackOperation.writeEnv,
|
|
68
|
+
PackOperation.writePackageJson,
|
|
69
|
+
PackOperation.writeEntryScript,
|
|
70
|
+
PackOperation.copyResources,
|
|
71
|
+
PackOperation.writeManifest,
|
|
72
|
+
PackOperation.bundle,
|
|
73
|
+
];
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
/**
|
|
72
77
|
* Run all operations
|
|
73
78
|
*/
|
|
74
|
-
async * runOperations(
|
|
79
|
+
async * runOperations(): AsyncIterable<string> {
|
|
75
80
|
for (const op of this.getOperations()) {
|
|
76
|
-
for await (const msg of op(
|
|
81
|
+
for await (const msg of op(this)) {
|
|
77
82
|
yield msg.join(' ');
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
86
|
|
|
87
|
+
finalize(unknown: string[]): void {
|
|
88
|
+
this.#unknownArgs = unknown;
|
|
82
89
|
|
|
83
|
-
|
|
84
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
85
|
-
let module = this.monoRoot ? moduleName : RootIndex.mainModule.name;
|
|
86
|
-
module = RootIndex.getModuleByFolder(module)?.name ?? module;
|
|
87
|
-
|
|
88
|
-
// Reinitialize for module
|
|
89
|
-
if (this.monoRoot) {
|
|
90
|
-
RootIndex.reinitForModule(module);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return module;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async buildConfig(): Promise<S> {
|
|
97
|
-
this.cmd.workspace ??= path.resolve(os.tmpdir(), RootIndex.mainModule.sourcePath.replace(/[\/\\: ]/g, '_'));
|
|
98
|
-
this.cmd.module = RootIndex.mainModule.name;
|
|
99
|
-
this.cmd.mainName ??= path.basename(this.cmd.entryPoint);
|
|
100
|
-
return this.cmd;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async action(module: string, args: string[]): Promise<void> {
|
|
104
|
-
if (Array.isArray(module)) {
|
|
105
|
-
args = module;
|
|
106
|
-
module = RootIndex.mainModule.name;
|
|
107
|
-
}
|
|
108
|
-
const start = Date.now();
|
|
109
|
-
if (!module && this.monoRoot) {
|
|
110
|
-
return this.showHelp(new Error('The module needs to specified when running from a monorepo root'));
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
module = this.getModule(module);
|
|
114
|
-
|
|
115
|
-
const cfg = await this.buildConfig();
|
|
116
|
-
cfg.entryArguments = Array.isArray(args) ? args : [];
|
|
117
|
-
|
|
118
|
-
for (const k in this.cmd) {
|
|
119
|
-
if (Object.hasOwn(this.cmd, k)) {
|
|
120
|
-
const v = this.cmd[k];
|
|
121
|
-
if (typeof v === 'string' && /<module>/.test(v)) {
|
|
122
|
-
// @ts-expect-error
|
|
123
|
-
this.cmd[k] = v.replace(/<module>/g, this.getSimpleModuleName());
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
90
|
+
this.output = this.output?.replace('<module>', CliUtil.getSimpleModuleName(this.module ?? ''));
|
|
127
91
|
|
|
128
92
|
// Resolve all files to absolute paths
|
|
129
|
-
if (this.
|
|
130
|
-
this.
|
|
93
|
+
if (this.output) {
|
|
94
|
+
this.output = path.resolve(this.output);
|
|
131
95
|
}
|
|
132
|
-
if (this.
|
|
133
|
-
this.
|
|
96
|
+
if (this.ejectFile) {
|
|
97
|
+
this.ejectFile = path.resolve(this.ejectFile);
|
|
134
98
|
}
|
|
135
|
-
this.
|
|
99
|
+
this.workspace = path.resolve(this.workspace);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async main(args: string[] = []): Promise<void> {
|
|
103
|
+
this.entryArguments = [...args, ...this.#unknownArgs ?? []];
|
|
104
|
+
this.module ||= RootIndex.mainModule.name;
|
|
105
|
+
this.mainName ??= path.basename(this.module);
|
|
136
106
|
|
|
137
|
-
const stream = this.runOperations(
|
|
107
|
+
const stream = this.runOperations();
|
|
138
108
|
|
|
139
109
|
// Eject to file
|
|
140
|
-
if (this.
|
|
141
|
-
|
|
142
|
-
for await (const line of stream) {
|
|
143
|
-
output.push(line);
|
|
144
|
-
}
|
|
145
|
-
await PackUtil.writeEjectOutput(this.cmd.workspace, cfg.module, output, this.cmd.ejectFile);
|
|
110
|
+
if (this.ejectFile) {
|
|
111
|
+
await PackUtil.writeEjectOutput(this.workspace, this.module, stream, this.ejectFile);
|
|
146
112
|
} else {
|
|
113
|
+
const start = Date.now();
|
|
114
|
+
|
|
147
115
|
await GlobalTerminal.streamLinesWithWaiting(stream, {
|
|
148
116
|
initialDelay: 0,
|
|
149
117
|
cycleDelay: 100,
|
|
@@ -151,9 +119,9 @@ export abstract class BasePackCommand<T extends CommonPackOptions, S extends Com
|
|
|
151
119
|
position: 'inline',
|
|
152
120
|
committedPrefix: String.fromCharCode(171)
|
|
153
121
|
});
|
|
154
|
-
let msg = cliTpl`${{ success: 'Success' }} (${{ identifier: TimeUtil.prettyDeltaSinceTime(start) }}) ${{ subtitle: 'module' }}=${{ param: this.
|
|
155
|
-
if (this.
|
|
156
|
-
msg = cliTpl`${msg} ${{ subtitle: 'output' }}=${{ path: this.
|
|
122
|
+
let msg = cliTpl`${{ success: 'Success' }} (${{ identifier: TimeUtil.prettyDeltaSinceTime(start) }}) ${{ subtitle: 'module' }}=${{ param: this.module }}`;
|
|
123
|
+
if (this.output) {
|
|
124
|
+
msg = cliTpl`${msg} ${{ subtitle: 'output' }}=${{ path: this.output }}`;
|
|
157
125
|
}
|
|
158
126
|
await GlobalTerminal.writeLines(msg);
|
|
159
127
|
}
|
|
@@ -4,6 +4,6 @@ export const factory: DockerPackFactory = cfg => `
|
|
|
4
4
|
FROM ${cfg.dockerImage}
|
|
5
5
|
WORKDIR /app
|
|
6
6
|
COPY . .
|
|
7
|
-
${cfg.dockerPort
|
|
7
|
+
${cfg.dockerPort?.map(port => `EXPOSE ${port}`).join('\n') ?? ''}
|
|
8
8
|
ENTRYPOINT ["/app/${cfg.mainName}.sh"]
|
|
9
9
|
`;
|