@travetto/pack 3.0.0-rc.9 → 3.0.1-rc.1
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 +171 -206
- package/__index__.ts +1 -1
- package/package.json +6 -5
- package/support/bin/docker-operation.ts +22 -17
- package/support/bin/operation.ts +56 -41
- package/support/bin/shell.ts +2 -0
- package/support/bin/types.ts +2 -1
- package/support/cli.pack_docker.ts +12 -0
- package/support/pack.base.ts +55 -22
package/README.md
CHANGED
|
@@ -1,267 +1,232 @@
|
|
|
1
1
|
<!-- This file was generated by @travetto/doc and should not be modified directly -->
|
|
2
|
-
<!-- Please modify https://github.com/travetto/travetto/tree/main/module/pack/
|
|
2
|
+
<!-- Please modify https://github.com/travetto/travetto/tree/main/module/pack/DOC.ts and execute "npx trv doc" to rebuild -->
|
|
3
3
|
# Pack
|
|
4
4
|
## Code packing utilities
|
|
5
5
|
|
|
6
6
|
**Install: @travetto/pack**
|
|
7
7
|
```bash
|
|
8
8
|
npm install @travetto/pack
|
|
9
|
+
|
|
10
|
+
# or
|
|
11
|
+
|
|
12
|
+
yarn add @travetto/pack
|
|
9
13
|
```
|
|
10
14
|
|
|
15
|
+
This module provides the necessary tools to produce deliverable output for [Travetto](https://travetto.dev) based projects. The main interaction with this module is through the command line interface, and the operations it provides. Under the covers, the code bundling is performed by [Rollup](https://rollupjs.org/), with specific configuration to support the frameworks runtime expectations.
|
|
16
|
+
|
|
17
|
+
There are three primary cli commands for packing your code:
|
|
18
|
+
|
|
19
|
+
* pack
|
|
20
|
+
* pack:zip
|
|
21
|
+
* pack:docker
|
|
22
|
+
|
|
11
23
|
## CLI - pack
|
|
12
24
|
|
|
13
25
|
**Terminal: Pack usage**
|
|
14
26
|
```bash
|
|
15
27
|
$ trv pack --help
|
|
16
28
|
|
|
17
|
-
Usage: pack [options] [
|
|
29
|
+
Usage: pack [options] [args...]
|
|
18
30
|
|
|
19
31
|
Options:
|
|
20
|
-
-w, --workspace <workspace>
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
-w, --workspace <workspace> Workspace for building
|
|
33
|
+
-c, --no-clean Disables: Clean workspace
|
|
34
|
+
-o, --output <output> Output Location
|
|
35
|
+
-e, --entry-point <entry-point> Entry point (default: "node_modules/@travetto/cli/support/cli.js")
|
|
36
|
+
-ec, --entry-command <entry-command> Entry command
|
|
37
|
+
-m, --no-minify Disables: Minify output
|
|
38
|
+
-sm, --sourcemap Bundle source maps
|
|
39
|
+
-is, --include-sources Include source with source maps
|
|
40
|
+
-x, --eject-file <eject-file> Eject commands to file
|
|
41
|
+
-h, --help display help for command
|
|
27
42
|
```
|
|
28
43
|
|
|
29
|
-
This command line operation will compile your project, and produce a ready to use workspace as a deliverable.
|
|
44
|
+
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).
|
|
30
45
|
|
|
31
|
-
|
|
32
|
-
* assemble
|
|
33
|
-
* zip
|
|
34
|
-
* docker
|
|
46
|
+
Specific to this CLI command, the `output` field determines where the final folder is written that contains all the compiled source.
|
|
35
47
|
|
|
36
|
-
###
|
|
48
|
+
### Entry Point Configuration
|
|
49
|
+
Every application requires an entry point to determine execution flow (and in [Rollup](https://rollupjs.org/)'s case, tree-shaking as well.). By default the [Command Line Interface](https://github.com/travetto/travetto/tree/main/module/cli#readme "CLI infrastructure for Travetto framework") acts as the entry point. This bypasses the [Compiler](https://github.com/travetto/travetto/tree/main/module/compiler#readme "The compiler infrastructure for the Travetto framework") intentionally, as the compiler is not available at runtime.
|
|
37
50
|
|
|
38
|
-
|
|
51
|
+
Within the command line, the `args` are positional arguments that will be passed to the entry point on application run.
|
|
39
52
|
|
|
40
|
-
|
|
41
|
-
1. Cleaning Workspace - Cleans workspace to start with an empty workspace
|
|
42
|
-
1. Copying Dependencies - Computes the prod dependencies and copies them into the new workspace
|
|
43
|
-
1. Copying App Content - Copies over application content (src/, resources/, support/, bin/)
|
|
44
|
-
1. Excluding Pre-Compile Files - Any files that should be excluded pre-compilation, are removed
|
|
45
|
-
1. Compiling - Compiles the code in the new workspace, isolating it from your local development
|
|
46
|
-
1. Excluding Post-Compile Files - Removes any files that should be excluded, post compilation
|
|
47
|
-
1. Copying Added Content - Adds in any additional content that is not in the standard locations
|
|
48
|
-
1. Removing Empty Folders - Purge all empty folders, recursively
|
|
49
|
-
1. Writing Env.js - Write out the .env.js file with computed any env vars that should be set for the deployed app
|
|
50
|
-
1. Remove Source Maps - If keep source is false, all source maps are purged from your app's code
|
|
51
|
-
1. Emptying .ts Files - If keep source is false, all .ts files are emptied, as compilation will not occur at runtime
|
|
52
|
-
|
|
53
|
-
**Code: Assemble Default Config**
|
|
53
|
+
**Code: Packing an application run**
|
|
54
54
|
```typescript
|
|
55
|
-
|
|
56
|
-
active: true,
|
|
57
|
-
cacheDir: 'cache',
|
|
58
|
-
keepSource: true,
|
|
59
|
-
readonly: true,
|
|
60
|
-
env: {
|
|
61
|
-
TRV_DYNAMIC: '0'
|
|
62
|
-
},
|
|
63
|
-
add: [
|
|
64
|
-
{ [mod('@travetto/cli/bin/trv.js')]: mod('.bin/trv') },
|
|
65
|
-
{ [mod('lodash/lodash.min.js')]: mod('lodash/lodash.js') },
|
|
66
|
-
],
|
|
67
|
-
excludeCompile: [
|
|
68
|
-
mod('@travetto/*/doc/'),
|
|
69
|
-
mod('@travetto/*/e2e/'),
|
|
70
|
-
mod('@travetto/*/test/'),
|
|
71
|
-
],
|
|
72
|
-
exclude: [
|
|
73
|
-
'bower.json',
|
|
74
|
-
'LICENSE',
|
|
75
|
-
'LICENCE',
|
|
76
|
-
'*.map',
|
|
77
|
-
'*.md',
|
|
78
|
-
'*.lock',
|
|
79
|
-
'*.html',
|
|
80
|
-
'*.mjs',
|
|
81
|
-
mod('**/*.ts'),
|
|
82
|
-
'*.d.ts',
|
|
55
|
+
$ npx trv pack run myapp
|
|
83
56
|
```
|
|
84
57
|
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
$ trv pack:assemble --help
|
|
88
|
-
|
|
89
|
-
Usage: pack:assemble [options] [mode]
|
|
58
|
+
Would then produce an executable script, in the output folder, that would look like:
|
|
90
59
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
Available Pack Modes:
|
|
98
|
-
* default [support/pack.config.ts]
|
|
99
|
-
* rest/docker [@travetto/rest/support/pack.docker.ts]
|
|
100
|
-
* rest-aws-lambda/main [@travetto/rest-aws-lambda/support/pack.aws-lambda.ts]
|
|
60
|
+
**Code: Entry script for Packed application**
|
|
61
|
+
```typescript
|
|
62
|
+
#!/bin/sh
|
|
63
|
+
cd $(dirname "$0")
|
|
64
|
+
node cli run myapp
|
|
101
65
|
```
|
|
102
66
|
|
|
103
|
-
|
|
67
|
+
And this entry point would be what is executed by [docker](https://www.docker.com/community-edition), or whatever deployment mechanism is being used.
|
|
104
68
|
|
|
105
|
-
|
|
69
|
+
### General Packing Operations
|
|
70
|
+
Every [Pack](https://github.com/travetto/travetto/tree/main/module/pack#readme "Code packing utilities") operation extends from the base command, and that provides some consistent operations that run on every packing command.
|
|
106
71
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
72
|
+
|
|
73
|
+
* `clean` - Empties workspace before beginning, controlled by the `--clean` flag, defaults to on
|
|
74
|
+
* `writeEnv` - Writes the .env.js files that includes the necessary details to start the application. This is primarily to identify the location of the manifest file needed to run.
|
|
75
|
+
* `writePackageJson` - Generates the [Package JSON](https://docs.npmjs.com/cli/v9/configuring-npm/package-json) with the appropriate module type ([CommonJS](https://nodejs.org/api/modules.html) or [Ecmascript Module](https://nodejs.org/api/esm.html)) for interpreting plain `.js` files
|
|
76
|
+
* `writeEntryScript` - Create the entry script based on the `--entry-command`, `args`
|
|
77
|
+
* `copyResources` - Will pull in local `resources/**` files into the final output
|
|
78
|
+
* `primeAppCache` - Runs `trv run` to ensure the appropriate files are generated to allow for running the application. This only applies if the entry point is equivalent to `trv run`
|
|
79
|
+
* `writeManifest` - Produces the `prod`-ready manifest that is used at runtime. Removes all devDependencies from the manifest.json
|
|
80
|
+
* `bundle` - Invokes [Rollup](https://rollupjs.org/) with the appropriate file set to produce a single output .js file. Depending on the module type ([CommonJS](https://nodejs.org/api/modules.html) or [Ecmascript Module](https://nodejs.org/api/esm.html)) the build process differs to handle the dynamic loading that application does at runtime.
|
|
81
|
+
|
|
82
|
+
## CLI - pack:zip
|
|
114
83
|
|
|
115
|
-
|
|
84
|
+
This command is nearly identical to the standard `pack` operation, except for the `output` flag. In this scenario, the `output` flag determines the location and name of the final zip file.
|
|
85
|
+
|
|
86
|
+
**Terminal: Pack:zip usage**
|
|
116
87
|
```bash
|
|
117
88
|
$ trv pack:zip --help
|
|
118
89
|
|
|
119
|
-
Usage: pack:zip [options] [
|
|
90
|
+
Usage: pack:zip [options] [args...]
|
|
120
91
|
|
|
121
92
|
Options:
|
|
122
|
-
-w, --workspace <workspace>
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
93
|
+
-w, --workspace <workspace> Workspace for building
|
|
94
|
+
-c, --no-clean Disables: Clean workspace
|
|
95
|
+
-o, --output <output> Output Location (default: "travetto_pack.zip")
|
|
96
|
+
-e, --entry-point <entry-point> Entry point (default: "node_modules/@travetto/cli/support/cli.js")
|
|
97
|
+
-ec, --entry-command <entry-command> Entry command
|
|
98
|
+
-m, --no-minify Disables: Minify output
|
|
99
|
+
-sm, --sourcemap Bundle source maps
|
|
100
|
+
-is, --include-sources Include source with source maps
|
|
101
|
+
-x, --eject-file <eject-file> Eject commands to file
|
|
102
|
+
-h, --help display help for command
|
|
130
103
|
```
|
|
131
104
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Docker support is an optional step, that can run post assembly. This allows for building a docker image, and currently only supports the base images as the only configuration options.
|
|
105
|
+
## CLI - pack:docker
|
|
135
106
|
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
docker: {
|
|
139
|
-
active: false,
|
|
140
|
-
image: 'node:16-alpine'
|
|
141
|
-
}
|
|
142
|
-
```
|
|
107
|
+
This command starts off identical to the standard `pack` operation, but it contains a few additional flags, and ultimately a few additional operations to support creating of the final [docker](https://www.docker.com/community-edition) image.
|
|
143
108
|
|
|
144
|
-
**Terminal:
|
|
109
|
+
**Terminal: Pack:docker usage**
|
|
145
110
|
```bash
|
|
146
111
|
$ trv pack:docker --help
|
|
147
112
|
|
|
148
|
-
Usage: pack:docker [options] [
|
|
113
|
+
Usage: pack:docker [options] [args...]
|
|
149
114
|
|
|
150
115
|
Options:
|
|
151
|
-
-w, --workspace <workspace>
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
116
|
+
-w, --workspace <workspace> Workspace for building
|
|
117
|
+
-c, --no-clean Disables: Clean workspace
|
|
118
|
+
-o, --output <output> Output Location
|
|
119
|
+
-e, --entry-point <entry-point> Entry point (default: "node_modules/@travetto/cli/support/cli.js")
|
|
120
|
+
-ec, --entry-command <entry-command> Entry command
|
|
121
|
+
-m, --no-minify Disables: Minify output
|
|
122
|
+
-sm, --sourcemap Bundle source maps
|
|
123
|
+
-is, --include-sources Include source with source maps
|
|
124
|
+
-x, --eject-file <eject-file> Eject commands to file
|
|
125
|
+
-df, --docker-factory <docker-factory> Docker Factory source (default: "@travetto/pack/support/pack.dockerfile")
|
|
126
|
+
-di, --docker-image <docker-image> Docker Image to extend (default: "node:18-alpine3.16")
|
|
127
|
+
-dn, --docker-name <docker-name> Docker Image Name (default: "travetto_pack")
|
|
128
|
+
-dt, --docker-tag <docker-tag> Docker Image Tag (default: ["latest"])
|
|
129
|
+
-dp, --docker-port <docker-port> Docker Image Port (default: [])
|
|
130
|
+
-dx, --docker-push Docker Push Tags
|
|
131
|
+
-dr, --docker-registry <docker-registry> Docker Registry
|
|
132
|
+
-h, --help display help for command
|
|
164
133
|
```
|
|
165
134
|
|
|
166
|
-
|
|
167
|
-
Various modules may provide customizations to the default `pack.config.ts` to allow for easy integration with the packing process. A simple example of this is via the [RESTful API](https://github.com/travetto/travetto/tree/main/module/rest#readme "Declarative api for RESTful APIs with support for the dependency injection module.") module, for how to publish lambda packages.
|
|
135
|
+
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.
|
|
168
136
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
active: true,
|
|
180
|
-
keepSource: false,
|
|
181
|
-
exclude: [
|
|
182
|
-
'node_modules/node-forge'
|
|
183
|
-
],
|
|
184
|
-
env: {
|
|
185
|
-
NO_COLOR: '1'
|
|
186
|
-
},
|
|
187
|
-
postProcess: [{
|
|
188
|
-
['Lambda Entrypoint']: cfg =>
|
|
189
|
-
fs.copyFile(
|
|
190
|
-
PathUtil.resolveUnix(__dirname, 'aws-lambda.handler.js'),
|
|
191
|
-
PathUtil.resolveUnix(cfg.workspace, 'index.js')
|
|
192
|
-
)
|
|
193
|
-
}],
|
|
194
|
-
},
|
|
195
|
-
zip: {
|
|
196
|
-
active: true,
|
|
197
|
-
output: 'dist/lambda.zip'
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
```
|
|
137
|
+
In addition to the standard operations, this command adds the following steps:
|
|
138
|
+
|
|
139
|
+
* `writeDockerFile` - Generate the docker file contents
|
|
140
|
+
* `pullDockerBaseImage` - Pull base image, to ensure its available and primed
|
|
141
|
+
* `buildDockerContainer` - Build final container
|
|
142
|
+
* `pushDockerContainer` - Push container with appropriate tags. Only applies if `--docker-push` is specified
|
|
143
|
+
|
|
144
|
+
## Ejected File
|
|
145
|
+
|
|
146
|
+
As indicated, any of the pack operations can be ejected, and produce an output that can be run independent of the pack command. This is helpful when integrating with more complicated build processes.
|
|
201
147
|
|
|
202
|
-
**Terminal:
|
|
148
|
+
**Terminal: Sample Ejected File**
|
|
203
149
|
```bash
|
|
204
|
-
|
|
205
|
-
```
|
|
150
|
+
$ trv pack:docker -x /dev/stdout run rest
|
|
206
151
|
|
|
207
|
-
|
|
152
|
+
#!/bin/sh
|
|
153
|
+
export DIST=/tmp/_home_tim_Code_travetto_related_todo-app
|
|
154
|
+
export TRV_OUT=<workspace-root>/.trv_output
|
|
155
|
+
export ROOT=<workspace-root>/related/todo-app
|
|
156
|
+
export MOD=@travetto/todo-app
|
|
208
157
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
* The default config in `support/pack.config.ts` and
|
|
212
|
-
* The config selected to execute from the cli
|
|
158
|
+
# Cleaning Output $DIST
|
|
213
159
|
|
|
214
|
-
|
|
160
|
+
rm -rf $DIST
|
|
161
|
+
mkdir -p $DIST
|
|
215
162
|
|
|
216
|
-
|
|
217
|
-
```typescript
|
|
218
|
-
import type { AllConfigPartial } from '@travetto/pack';
|
|
219
|
-
|
|
220
|
-
export const config: AllConfigPartial = {
|
|
221
|
-
workspace: 'dist/alt',
|
|
222
|
-
assemble: {
|
|
223
|
-
active: true,
|
|
224
|
-
add: [
|
|
225
|
-
{ assets: 'assets' },
|
|
226
|
-
{ '/secret/location/key.pem': 'resources/key.pem' }
|
|
227
|
-
]
|
|
228
|
-
},
|
|
229
|
-
zip: {
|
|
230
|
-
active: true,
|
|
231
|
-
output: 'dist/build.zip'
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
```
|
|
163
|
+
# Writing .env.js
|
|
235
164
|
|
|
236
|
-
|
|
165
|
+
echo "process.env.TRV_MANIFEST = 'node_modules/$MOD';" > $DIST/.env.js
|
|
166
|
+
echo "process.env.TRV_CLI_IPC = '';" >> $DIST/.env.js
|
|
237
167
|
|
|
238
|
-
|
|
239
|
-
allow their key parameters to be overridden via environment variables.
|
|
168
|
+
# Writing package.json
|
|
240
169
|
|
|
241
|
-
|
|
242
|
-
```typescript
|
|
243
|
-
overrides: {
|
|
244
|
-
keepSource: CliUtil.toBool(process.env.PACK_ASSEMBLE_KEEP_SOURCE),
|
|
245
|
-
readonly: CliUtil.toBool(process.env.PACK_ASSEMBLE_READONLY)
|
|
246
|
-
},
|
|
247
|
-
```
|
|
170
|
+
echo "{\"type\":\"commonjs\"}" > $DIST/package.json
|
|
248
171
|
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
overrides: {
|
|
252
|
-
image: process.env.PACK_DOCKER_IMAGE || undefined,
|
|
253
|
-
name: process.env.PACK_DOCKER_NAME || undefined,
|
|
254
|
-
app: process.env.PACK_DOCKER_APP || undefined,
|
|
255
|
-
port: process.env.PACK_DOCKER_PORT ? [process.env.PACK_DOCKER_PORT] : undefined,
|
|
256
|
-
registry: process.env.PACK_DOCKER_REGISTRY || undefined,
|
|
257
|
-
push: CliUtil.toBool(process.env.PACK_DOCKER_PUSH),
|
|
258
|
-
tag: process.env.PACK_DOCKER_TAG ? [process.env.PACK_DOCKER_TAG] : undefined
|
|
259
|
-
},
|
|
260
|
-
```
|
|
172
|
+
# Writing entry scripts cli.sh args=(run rest)
|
|
261
173
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
174
|
+
echo "#!/bin/sh" > $DIST/cli.sh
|
|
175
|
+
echo "cd \$(dirname \"\$0\")" >> $DIST/cli.sh
|
|
176
|
+
echo "node cli run rest \$@" >> $DIST/cli.sh
|
|
177
|
+
chmod 755 $DIST/cli.sh
|
|
178
|
+
|
|
179
|
+
# Writing entry scripts cli.cmd args=(run rest)
|
|
180
|
+
|
|
181
|
+
echo "" > $DIST/cli.cmd
|
|
182
|
+
echo "cd %~p0" >> $DIST/cli.cmd
|
|
183
|
+
echo "node cli run rest %*" >> $DIST/cli.cmd
|
|
184
|
+
chmod 755 $DIST/cli.cmd
|
|
185
|
+
|
|
186
|
+
# Copying over resources
|
|
187
|
+
|
|
188
|
+
mkdir -p $DIST/node_modules/$MOD
|
|
189
|
+
cp $TRV_OUT/node_modules/$MOD/package.json $DIST/node_modules/$MOD/package.json
|
|
190
|
+
mkdir -p $DIST/node_modules/@travetto/manifest
|
|
191
|
+
cp $TRV_OUT/node_modules/@travetto/manifest/package.json $DIST/node_modules/@travetto/manifest/package.json
|
|
192
|
+
cp -r -p $ROOT/resources $DIST/resources
|
|
193
|
+
|
|
194
|
+
# Generating App Cache node_modules/$MOD/trv-app-cache.json
|
|
195
|
+
|
|
196
|
+
mkdir -p $DIST/node_modules/$MOD
|
|
197
|
+
DEBUG=0 TRV_MODULE=$MOD npx trv main @travetto/app/support/bin/list > $DIST/node_modules/$MOD/trv-app-cache.json
|
|
198
|
+
|
|
199
|
+
# Writing Manifest node_modules/$MOD
|
|
200
|
+
|
|
201
|
+
TRV_MODULE=$MOD npx trv manifest $DIST/node_modules/$MOD prod
|
|
202
|
+
|
|
203
|
+
# Bundling Output minify=true sourcemap= entryPoint=node_modules/@travetto/cli/support/cli.js
|
|
204
|
+
|
|
205
|
+
export BUNDLE_ENTRY=node_modules/@travetto/cli/support/cli.js
|
|
206
|
+
export BUNDLE_ENTRY_NAME=cli
|
|
207
|
+
export BUNDLE_COMPRESS=true
|
|
208
|
+
export BUNDLE_OUTPUT=$DIST
|
|
209
|
+
export BUNDLE_FORMAT=commonjs
|
|
210
|
+
export TRV_MANIFEST=$TRV_OUT/node_modules/$MOD
|
|
211
|
+
cd $TRV_OUT
|
|
212
|
+
npx rollup -c node_modules/@travetto/pack/support/bin/rollup.js
|
|
213
|
+
cd $ROOT
|
|
214
|
+
|
|
215
|
+
# Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile
|
|
216
|
+
|
|
217
|
+
echo "FROM node:18-alpine3.16" > $DIST/Dockerfile
|
|
218
|
+
echo "WORKDIR /app" >> $DIST/Dockerfile
|
|
219
|
+
echo "COPY . ." >> $DIST/Dockerfile
|
|
220
|
+
echo "" >> $DIST/Dockerfile
|
|
221
|
+
echo "ENTRYPOINT [\"/app/cli.sh\"]" >> $DIST/Dockerfile
|
|
222
|
+
|
|
223
|
+
# Pulling Docker Base Image node:18-alpine3.16
|
|
224
|
+
|
|
225
|
+
docker pull node:18-alpine3.16
|
|
226
|
+
|
|
227
|
+
# Building Docker Container latest
|
|
228
|
+
|
|
229
|
+
cd $DIST
|
|
230
|
+
docker build -t travetto_todo-app:latest .
|
|
231
|
+
cd $ROOT
|
|
267
232
|
```
|
package/__index__.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { CommonPackConfig } from './support/bin/types';
|
|
1
|
+
export type { CommonPackConfig, DockerPackFactory, DockerPackConfig } from './support/bin/types';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/pack",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1-rc.1",
|
|
4
4
|
"description": "Code packing utilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"travetto",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"email": "travetto.framework@gmail.com",
|
|
15
15
|
"name": "Travetto Framework"
|
|
16
16
|
},
|
|
17
|
+
"main": "__index__.ts",
|
|
17
18
|
"files": [
|
|
18
19
|
"__index__.ts",
|
|
19
20
|
"support"
|
|
@@ -25,14 +26,14 @@
|
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"@rollup/plugin-commonjs": "^24.0.1",
|
|
27
28
|
"@rollup/plugin-json": "^6.0.0",
|
|
28
|
-
"@rollup/plugin-terser": "^0.4.0",
|
|
29
29
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
30
|
-
"@
|
|
31
|
-
"
|
|
30
|
+
"@rollup/plugin-terser": "^0.4.0",
|
|
31
|
+
"@travetto/base": "^3.0.1-rc.1",
|
|
32
|
+
"rollup": "^3.17.2",
|
|
32
33
|
"rollup-plugin-sourcemaps": "^0.6.3"
|
|
33
34
|
},
|
|
34
35
|
"peerDependencies": {
|
|
35
|
-
"@travetto/cli": "^3.0.
|
|
36
|
+
"@travetto/cli": "^3.0.1-rc.1"
|
|
36
37
|
},
|
|
37
38
|
"peerDependenciesMeta": {
|
|
38
39
|
"@travetto/cli": {
|
|
@@ -6,6 +6,7 @@ import { cliTpl } from '@travetto/cli';
|
|
|
6
6
|
|
|
7
7
|
import { ActiveShellCommand } from './shell';
|
|
8
8
|
import { DockerPackConfig, DockerPackFactoryModule } from './types';
|
|
9
|
+
import { PackOperation } from './operation';
|
|
9
10
|
|
|
10
11
|
export class DockerPackOperation {
|
|
11
12
|
|
|
@@ -18,15 +19,19 @@ export class DockerPackOperation {
|
|
|
18
19
|
*/
|
|
19
20
|
static async* writeDockerFile(cfg: DockerPackConfig): AsyncIterable<string[]> {
|
|
20
21
|
const dockerFile = path.resolve(cfg.workspace, 'Dockerfile');
|
|
21
|
-
|
|
22
|
-
const
|
|
22
|
+
|
|
23
|
+
const factory = RootIndex.getFromImport(cfg.dockerFactory);
|
|
24
|
+
if (!factory) {
|
|
25
|
+
throw new Error(`Unable to resolve docker factory at ${cfg.dockerFactory}`);
|
|
26
|
+
}
|
|
27
|
+
const mod: DockerPackFactoryModule = await import(factory.import);
|
|
23
28
|
const content = (await mod.factory(cfg)).trim();
|
|
24
29
|
|
|
30
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Generating Docker File' }} ${{ path: dockerFile }} ${{ param: cfg.dockerFactory }}`);
|
|
31
|
+
|
|
25
32
|
if (cfg.ejectFile) {
|
|
26
|
-
yield ActiveShellCommand.comment(title);
|
|
27
33
|
yield* ActiveShellCommand.createFile(dockerFile, content.split(/\n/));
|
|
28
34
|
} else {
|
|
29
|
-
yield [title];
|
|
30
35
|
await fs.writeFile(dockerFile, content, 'utf8');
|
|
31
36
|
}
|
|
32
37
|
}
|
|
@@ -35,15 +40,13 @@ export class DockerPackOperation {
|
|
|
35
40
|
* Pull Docker Base Image
|
|
36
41
|
*/
|
|
37
42
|
static async* pullDockerBaseImage(cfg: DockerPackConfig): AsyncIterable<string[]> {
|
|
38
|
-
const title = cliTpl`${{ title: 'Pulling Docker Base Image' }} ${{ param: cfg.dockerImage }}`;
|
|
39
|
-
|
|
40
43
|
const command = ['docker', 'pull', cfg.dockerImage];
|
|
41
44
|
|
|
45
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Pulling Docker Base Image' }} ${{ param: cfg.dockerImage }}`);
|
|
46
|
+
|
|
42
47
|
if (cfg.ejectFile) {
|
|
43
|
-
yield ActiveShellCommand.comment(title);
|
|
44
48
|
yield command;
|
|
45
49
|
} else {
|
|
46
|
-
yield [title];
|
|
47
50
|
await ExecUtil.spawn(command[0], command.slice(1), {}).result;
|
|
48
51
|
}
|
|
49
52
|
}
|
|
@@ -52,16 +55,15 @@ export class DockerPackOperation {
|
|
|
52
55
|
* Building Docker Container
|
|
53
56
|
*/
|
|
54
57
|
static async* buildDockerContainer(cfg: DockerPackConfig): AsyncIterable<string[]> {
|
|
55
|
-
const title = cliTpl`${{ title: 'Building Docker Container' }} ${{ param: cfg.dockerTag?.join(',') }}`;
|
|
56
58
|
const cmd = ['docker', 'build', ...DockerPackOperation.getDockerTags(cfg).flatMap(x => ['-t', x]), '.'];
|
|
57
59
|
|
|
60
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Building Docker Container' }} ${{ param: cfg.dockerTag?.join(',') }}`);
|
|
61
|
+
|
|
58
62
|
if (cfg.ejectFile) {
|
|
59
|
-
yield ActiveShellCommand.comment(title);
|
|
60
63
|
yield ActiveShellCommand.chdir(cfg.workspace);
|
|
61
64
|
yield cmd;
|
|
62
65
|
yield ActiveShellCommand.chdir(path.cwd());
|
|
63
66
|
} else {
|
|
64
|
-
yield [title];
|
|
65
67
|
await ExecUtil.spawn(cmd[0], cmd.slice(1), { cwd: cfg.workspace, stdio: [0, 'pipe', 2] }).result;
|
|
66
68
|
}
|
|
67
69
|
}
|
|
@@ -74,15 +76,18 @@ export class DockerPackOperation {
|
|
|
74
76
|
return;
|
|
75
77
|
}
|
|
76
78
|
const tags = DockerPackOperation.getDockerTags(cfg);
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
+
const cmd = ['docker', 'image', 'push'];
|
|
80
|
+
|
|
81
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Push Container to registry' }} ${{ param: cfg.dockerRegistry }}`);
|
|
79
82
|
|
|
80
83
|
if (cfg.ejectFile) {
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
for (const tag of tags) {
|
|
85
|
+
yield [...cmd, tag];
|
|
86
|
+
}
|
|
83
87
|
} else {
|
|
84
|
-
|
|
85
|
-
|
|
88
|
+
for (const tag of tags) {
|
|
89
|
+
await ExecUtil.spawn(cmd[0], [...cmd.slice(1), tag], { stdio: [0, 'pipe', 2] }).result;
|
|
90
|
+
}
|
|
86
91
|
}
|
|
87
92
|
}
|
|
88
93
|
}
|
package/support/bin/operation.ts
CHANGED
|
@@ -14,22 +14,32 @@ async function writeRawFile(file: string, contents: string, mode?: string): Prom
|
|
|
14
14
|
|
|
15
15
|
export class PackOperation {
|
|
16
16
|
|
|
17
|
+
static async * title(cfg: CommonPackConfig, title: string): AsyncIterable<string[]> {
|
|
18
|
+
if (cfg.ejectFile) {
|
|
19
|
+
yield ActiveShellCommand.comment(title);
|
|
20
|
+
yield ActiveShellCommand.echo(title);
|
|
21
|
+
} else {
|
|
22
|
+
yield [title];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Clean out pack workspace, removing all content
|
|
28
|
+
*/
|
|
17
29
|
static async * clean(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
18
30
|
if (!cfg.clean) {
|
|
19
31
|
return;
|
|
20
32
|
}
|
|
21
33
|
|
|
22
|
-
|
|
34
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Cleaning Output' }} ${{ path: cfg.workspace }}`);
|
|
23
35
|
|
|
24
36
|
if (cfg.ejectFile) {
|
|
25
|
-
yield ActiveShellCommand.comment(title);
|
|
26
37
|
yield ActiveShellCommand.rmRecursive(cfg.workspace);
|
|
27
38
|
if (cfg.output) {
|
|
28
39
|
yield ActiveShellCommand.rmRecursive(cfg.output);
|
|
29
40
|
}
|
|
30
41
|
yield ActiveShellCommand.mkdir(cfg.workspace);
|
|
31
42
|
} else {
|
|
32
|
-
yield [title];
|
|
33
43
|
await fs.rm(cfg.workspace, { recursive: true, force: true });
|
|
34
44
|
if (cfg.output) {
|
|
35
45
|
await fs.rm(cfg.output, { recursive: true, force: true });
|
|
@@ -38,14 +48,18 @@ export class PackOperation {
|
|
|
38
48
|
}
|
|
39
49
|
}
|
|
40
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Invoke bundler (rollup) to produce output in workspace folder
|
|
53
|
+
*/
|
|
41
54
|
static async * bundle(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
42
55
|
const cwd = RootIndex.outputRoot;
|
|
43
56
|
|
|
44
57
|
const bundleCommand = ['npx', 'rollup', '-c', 'node_modules/@travetto/pack/support/bin/rollup.js'];
|
|
45
58
|
|
|
59
|
+
const entryPointFile = RootIndex.getFromImport(cfg.entryPoint)!.outputFile.split(`${RootIndex.manifest.outputFolder}/`)[1];
|
|
60
|
+
|
|
46
61
|
const env = Object.fromEntries(([
|
|
47
|
-
['BUNDLE_ENTRY',
|
|
48
|
-
['BUNDLE_ENTRY_NAME', cfg.entryCommand],
|
|
62
|
+
['BUNDLE_ENTRY', entryPointFile],
|
|
49
63
|
['BUNDLE_COMPRESS', cfg.minify],
|
|
50
64
|
['BUNDLE_SOURCEMAP', cfg.sourcemap],
|
|
51
65
|
['BUNDLE_SOURCES', cfg.includeSources],
|
|
@@ -60,10 +74,9 @@ export class PackOperation {
|
|
|
60
74
|
const props = (['minify', 'sourcemap', 'entryPoint'] as const)
|
|
61
75
|
.map(k => cliTpl`${{ subtitle: k }}=${{ param: cfg[k] }}`).join(' ');
|
|
62
76
|
|
|
63
|
-
|
|
77
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Bundling Output' }} ${props}`);
|
|
64
78
|
|
|
65
79
|
if (cfg.ejectFile) {
|
|
66
|
-
yield ActiveShellCommand.comment(title);
|
|
67
80
|
yield* Object.entries(env).filter(x => !!x[1]).map(x =>
|
|
68
81
|
ActiveShellCommand.export(x[0], x[1])
|
|
69
82
|
);
|
|
@@ -71,24 +84,25 @@ export class PackOperation {
|
|
|
71
84
|
yield bundleCommand;
|
|
72
85
|
yield ActiveShellCommand.chdir(path.cwd());
|
|
73
86
|
} else {
|
|
74
|
-
yield [title];
|
|
75
87
|
await ExecUtil.spawn(bundleCommand[0], bundleCommand.slice(1), { cwd, env, stdio: ['inherit', 'pipe', 'pipe'] }).result;
|
|
76
88
|
}
|
|
77
89
|
}
|
|
78
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Write out package.json, to help define how output .js file should be interpreted
|
|
93
|
+
*/
|
|
79
94
|
static async * writePackageJson(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
80
95
|
const file = 'package.json';
|
|
81
|
-
const title = cliTpl`${{ title: 'Writing' }} ${{ path: file }}`;
|
|
82
96
|
const pkg = { type: RootIndex.manifest.moduleType };
|
|
83
97
|
|
|
98
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Writing' }} ${{ path: file }}`);
|
|
99
|
+
|
|
84
100
|
if (cfg.ejectFile) {
|
|
85
|
-
yield ActiveShellCommand.comment(title);
|
|
86
101
|
yield* ActiveShellCommand.createFile(
|
|
87
102
|
path.resolve(cfg.workspace, file),
|
|
88
103
|
[JSON.stringify(pkg)]
|
|
89
104
|
);
|
|
90
105
|
} else {
|
|
91
|
-
yield [title];
|
|
92
106
|
await writeRawFile(
|
|
93
107
|
path.resolve(cfg.workspace, file),
|
|
94
108
|
JSON.stringify(pkg, null, 2)
|
|
@@ -96,22 +110,24 @@ export class PackOperation {
|
|
|
96
110
|
}
|
|
97
111
|
}
|
|
98
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Define .env.js file to control manifest location
|
|
115
|
+
*/
|
|
99
116
|
static async * writeEnv(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
100
117
|
const file = '.env.js';
|
|
101
|
-
const title = cliTpl`${{ title: 'Writing' }} ${{ path: file }}`;
|
|
102
118
|
const env = {
|
|
103
119
|
TRV_MANIFEST: `node_modules/${cfg.module}`,
|
|
104
120
|
TRV_CLI_IPC: ''
|
|
105
121
|
};
|
|
106
122
|
|
|
123
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Writing' }} ${{ path: file }}`);
|
|
124
|
+
|
|
107
125
|
if (cfg.ejectFile) {
|
|
108
|
-
yield ActiveShellCommand.comment(title);
|
|
109
126
|
yield* ActiveShellCommand.createFile(
|
|
110
127
|
path.resolve(cfg.workspace, file),
|
|
111
128
|
PackUtil.buildEnvJS(env)
|
|
112
129
|
);
|
|
113
130
|
} else {
|
|
114
|
-
yield [title];
|
|
115
131
|
await writeRawFile(
|
|
116
132
|
path.resolve(cfg.workspace, file),
|
|
117
133
|
PackUtil.buildEnvJS(env).join('\n')
|
|
@@ -119,6 +135,9 @@ export class PackOperation {
|
|
|
119
135
|
}
|
|
120
136
|
}
|
|
121
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Create launcher scripts (.sh, .cmd) to run output
|
|
140
|
+
*/
|
|
122
141
|
static async * writeEntryScript(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
123
142
|
const title = 'Writing entry scripts';
|
|
124
143
|
|
|
@@ -129,23 +148,26 @@ export class PackOperation {
|
|
|
129
148
|
text: [
|
|
130
149
|
ShellCommands[type].scriptOpen(),
|
|
131
150
|
ShellCommands[type].chdirScript(),
|
|
132
|
-
ShellCommands[type].callCommandWithAllArgs('node', cfg.
|
|
151
|
+
ShellCommands[type].callCommandWithAllArgs('node', cfg.entrySource, ...cfg.entryArguments),
|
|
133
152
|
].map(x => x.join(' '))
|
|
134
153
|
}));
|
|
135
154
|
|
|
136
155
|
if (cfg.ejectFile) {
|
|
137
156
|
for (const { fileTitle, text, file } of files) {
|
|
138
|
-
yield
|
|
157
|
+
yield* PackOperation.title(cfg, fileTitle);
|
|
139
158
|
yield* ActiveShellCommand.createFile(path.resolve(cfg.workspace, file), text, '755');
|
|
140
159
|
}
|
|
141
160
|
} else {
|
|
142
161
|
for (const { fileTitle, text, file } of files) {
|
|
143
|
-
yield
|
|
162
|
+
yield* PackOperation.title(cfg, fileTitle);
|
|
144
163
|
await writeRawFile(path.resolve(cfg.workspace, file), text.join('\n'), '755');
|
|
145
164
|
}
|
|
146
165
|
}
|
|
147
166
|
}
|
|
148
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Copy over /resources folder into workspace, will get packaged into final output
|
|
170
|
+
*/
|
|
149
171
|
static async * copyResources(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
150
172
|
const resources = {
|
|
151
173
|
count: RootIndex.mainModule.files.resources?.length ?? 0,
|
|
@@ -162,10 +184,9 @@ export class PackOperation {
|
|
|
162
184
|
destFolder: path.resolve(cfg.workspace, mod.outputFolder)
|
|
163
185
|
}));
|
|
164
186
|
|
|
165
|
-
|
|
187
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Copying over resources' }}`);
|
|
166
188
|
|
|
167
189
|
if (cfg.ejectFile) {
|
|
168
|
-
yield ActiveShellCommand.comment(title);
|
|
169
190
|
yield* copyFiles.flatMap(mod => [
|
|
170
191
|
ActiveShellCommand.mkdir(path.dirname(mod.dest)),
|
|
171
192
|
ActiveShellCommand.copy(mod.src, mod.dest)
|
|
@@ -174,8 +195,6 @@ export class PackOperation {
|
|
|
174
195
|
yield ActiveShellCommand.copyRecursive(resources.src, path.resolve(cfg.workspace, 'resources'));
|
|
175
196
|
}
|
|
176
197
|
} else {
|
|
177
|
-
yield [title];
|
|
178
|
-
|
|
179
198
|
for (const { src, dest, destFolder } of copyFiles) {
|
|
180
199
|
await fs.mkdir(destFolder, { recursive: true });
|
|
181
200
|
await fs.copyFile(src, dest);
|
|
@@ -188,25 +207,26 @@ export class PackOperation {
|
|
|
188
207
|
}
|
|
189
208
|
}
|
|
190
209
|
|
|
210
|
+
/**
|
|
211
|
+
* Generate the trv-app-cache.json for @travetto/app, which is needed for 'running' programs
|
|
212
|
+
*/
|
|
191
213
|
static async * primeAppCache(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
192
|
-
const
|
|
193
|
-
if (!
|
|
214
|
+
const isRun = /entry[.]cli/.test(cfg.entryPoint) && cfg.entryArguments.filter(x => !x.startsWith('-'))[0] === 'run';
|
|
215
|
+
if (!isRun) {
|
|
194
216
|
return;
|
|
195
217
|
}
|
|
196
218
|
|
|
197
219
|
const appCacheCmd = ['npx', 'trv', 'main', '@travetto/app/support/bin/list'];
|
|
198
220
|
const sub = path.join(RootIndex.manifest.modules[RootIndex.mainModule.name].outputFolder, 'trv-app-cache.json');
|
|
199
|
-
const title = cliTpl`${{ title: 'Generating App Cache' }} ${{ path: sub }}`;
|
|
200
221
|
const env = { DEBUG: '0', TRV_MODULE: cfg.module };
|
|
201
222
|
const appCache = path.resolve(cfg.workspace, sub);
|
|
202
223
|
|
|
224
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Generating App Cache' }} ${{ path: sub }}`);
|
|
203
225
|
|
|
204
226
|
if (cfg.ejectFile) {
|
|
205
|
-
yield ActiveShellCommand.comment(title);
|
|
206
227
|
yield ActiveShellCommand.mkdir(path.dirname(appCache));
|
|
207
228
|
yield [...Object.entries(env).map(x => `${x[0]}=${x[1]}`), ...appCacheCmd, '>', appCache];
|
|
208
229
|
} else {
|
|
209
|
-
yield [title];
|
|
210
230
|
const { stdout } = await ExecUtil.spawn(appCacheCmd[0], appCacheCmd.slice(1), { env }).result;
|
|
211
231
|
|
|
212
232
|
await fs.mkdir(path.dirname(appCache), { recursive: true });
|
|
@@ -214,42 +234,37 @@ export class PackOperation {
|
|
|
214
234
|
}
|
|
215
235
|
}
|
|
216
236
|
|
|
237
|
+
/**
|
|
238
|
+
* Produce the output manifest, only including prod dependencies
|
|
239
|
+
*/
|
|
217
240
|
static async * writeManifest(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
218
241
|
const out = path.resolve(cfg.workspace, 'node_modules', cfg.module);
|
|
219
242
|
const cmd = ['npx', 'trv', 'manifest', out, 'prod'];
|
|
220
243
|
const env = { TRV_MODULE: cfg.module };
|
|
221
|
-
|
|
244
|
+
|
|
245
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Writing Manifest' }} ${{ path: path.join('node_modules', cfg.module) }}`);
|
|
222
246
|
|
|
223
247
|
if (cfg.ejectFile) {
|
|
224
|
-
yield ActiveShellCommand.comment(title);
|
|
225
248
|
yield [...Object.entries(env).map(([k, v]) => `${k}=${v}`), ...cmd];
|
|
226
249
|
} else {
|
|
227
|
-
yield [title];
|
|
228
250
|
await ExecUtil.spawn(cmd[0], cmd.slice(1), { env, stdio: ['inherit', 'ignore', 'inherit'] }).result;
|
|
229
251
|
}
|
|
230
252
|
}
|
|
231
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Generate ZIP file for workspace
|
|
256
|
+
*/
|
|
232
257
|
static async * compress(cfg: CommonPackConfig): AsyncIterable<string[]> {
|
|
233
|
-
|
|
258
|
+
|
|
259
|
+
yield* PackOperation.title(cfg, cliTpl`${{ title: 'Compressing' }} ${{ path: cfg.output }}`);
|
|
234
260
|
|
|
235
261
|
if (cfg.ejectFile) {
|
|
236
|
-
yield ActiveShellCommand.comment(title);
|
|
237
262
|
yield ActiveShellCommand.chdir(cfg.workspace);
|
|
238
263
|
yield ActiveShellCommand.zip(cfg.output);
|
|
239
264
|
yield ActiveShellCommand.chdir(path.cwd());
|
|
240
265
|
} else {
|
|
241
|
-
yield [title];
|
|
242
266
|
const [cmd, ...args] = ActiveShellCommand.zip(cfg.output);
|
|
243
267
|
await ExecUtil.spawn(cmd, args, { cwd: cfg.workspace }).result;
|
|
244
268
|
}
|
|
245
269
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
static async * runOperations<S>(cfg: S, operations: ((config: S) => AsyncIterable<string[]>)[]): AsyncIterable<string> {
|
|
249
|
-
for (const op of operations) {
|
|
250
|
-
for await (const msg of op(cfg)) {
|
|
251
|
-
yield msg.join(' ');
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
270
|
}
|
package/support/bin/shell.ts
CHANGED
|
@@ -27,6 +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
31
|
zip: (outputFile) => ['powershell', 'Compress-Archive', '-Path', '.', '-DestinationPath', outputFile]
|
|
31
32
|
},
|
|
32
33
|
posix: {
|
|
@@ -46,6 +47,7 @@ export const ShellCommands: Record<'win32' | 'posix', ShellCommandImpl> = {
|
|
|
46
47
|
export: (key, value) => ['export', `${key}=${value}`],
|
|
47
48
|
chdir: (dest) => ['cd', dest],
|
|
48
49
|
comment: (message) => ['\n#', stripAnsiCodes(message), '\n'],
|
|
50
|
+
echo: (message) => ['echo', `"${escape(stripAnsiCodes(message))}\n"`],
|
|
49
51
|
zip: (outputFile) => ['zip', '-r', outputFile, '.']
|
|
50
52
|
},
|
|
51
53
|
};
|
package/support/bin/types.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type CommonPackConfig = {
|
|
|
10
10
|
// Bundle
|
|
11
11
|
entryPoint: string;
|
|
12
12
|
entryCommand: string;
|
|
13
|
+
entrySource: string;
|
|
13
14
|
entryArguments: string[];
|
|
14
15
|
minify: boolean;
|
|
15
16
|
sourcemap: boolean;
|
|
@@ -24,7 +25,6 @@ export type CommonPackOptions = {
|
|
|
24
25
|
|
|
25
26
|
// Bundle
|
|
26
27
|
entryPoint: OptionConfig<string>;
|
|
27
|
-
entryCommand: OptionConfig<string>;
|
|
28
28
|
minify: OptionConfig<boolean>;
|
|
29
29
|
sourcemap: OptionConfig<boolean>;
|
|
30
30
|
includeSources: OptionConfig<boolean>;
|
|
@@ -63,6 +63,7 @@ export type ShellCommandImpl = {
|
|
|
63
63
|
export(key: string, value: string): string[];
|
|
64
64
|
chdir(dest: string): string[];
|
|
65
65
|
comment(message: string): string[];
|
|
66
|
+
echo(text: string): string[];
|
|
66
67
|
zip(output: string): string[];
|
|
67
68
|
};
|
|
68
69
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { path, RootIndex } from '@travetto/manifest';
|
|
2
|
+
|
|
1
3
|
import { DockerPackConfig, DockerPackOptions } from './bin/types';
|
|
2
4
|
import { DockerPackOperation } from './bin/docker-operation';
|
|
3
5
|
import { BasePackCommand, PackOperationShape } from './pack.base';
|
|
@@ -24,6 +26,16 @@ export class PackDockerCommand extends BasePackCommand<DockerPackOptions, Docker
|
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
|
|
29
|
+
async buildConfig(): Promise<DockerPackConfig> {
|
|
30
|
+
const cfg = await super.buildConfig();
|
|
31
|
+
if (cfg.dockerFactory.startsWith('.')) {
|
|
32
|
+
cfg.dockerFactory = RootIndex.getFromSource(path.resolve(cfg.dockerFactory))?.import ?? cfg.dockerFactory;
|
|
33
|
+
}
|
|
34
|
+
cfg.dockerPort ??= [];
|
|
35
|
+
cfg.dockerTag ??= [];
|
|
36
|
+
return cfg;
|
|
37
|
+
}
|
|
38
|
+
|
|
27
39
|
getOperations(): PackOperationShape<DockerPackConfig>[] {
|
|
28
40
|
return [
|
|
29
41
|
...super.getOperations(),
|
package/support/pack.base.ts
CHANGED
|
@@ -11,24 +11,50 @@ import { PackUtil } from './bin/util';
|
|
|
11
11
|
|
|
12
12
|
export type PackOperationShape<T extends CommonPackConfig> = ((config: T) => AsyncIterable<string[]>);
|
|
13
13
|
|
|
14
|
+
const BASIC_OP_SET = [
|
|
15
|
+
PackOperation.clean,
|
|
16
|
+
PackOperation.writeEnv,
|
|
17
|
+
PackOperation.writePackageJson,
|
|
18
|
+
PackOperation.writeEntryScript,
|
|
19
|
+
PackOperation.copyResources,
|
|
20
|
+
PackOperation.primeAppCache,
|
|
21
|
+
PackOperation.writeManifest,
|
|
22
|
+
PackOperation.bundle,
|
|
23
|
+
];
|
|
24
|
+
|
|
14
25
|
export abstract class BasePackCommand<T extends CommonPackOptions, S extends CommonPackConfig> extends CliCommand<{}> {
|
|
15
26
|
|
|
16
27
|
get monoRoot(): boolean {
|
|
17
28
|
return !!RootIndex.manifest.monoRepo && path.cwd() === RootIndex.manifest.workspacePath;
|
|
18
29
|
}
|
|
19
30
|
|
|
31
|
+
get entries(): string[] {
|
|
32
|
+
return RootIndex.findSupport({ filter: x => x.includes('entry.') })
|
|
33
|
+
.map(x => x.import.replace(/[.][^.]+s$/, ''));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Add help output
|
|
38
|
+
*/
|
|
39
|
+
async help(): Promise<string> {
|
|
40
|
+
const entryPoints = this.entries.map(x => cliTpl`${{ subtitle: '*' }} ${{ identifier: x }}`);
|
|
41
|
+
|
|
42
|
+
return ['', cliTpl`${{ title: 'Available Entry Points:' }}`, '', ...entryPoints, ''].join('\n');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
20
46
|
getArgs(): string | undefined {
|
|
21
47
|
return this.monoRoot ? '<module> [args...]' : '[args...]';
|
|
22
48
|
}
|
|
23
49
|
|
|
24
50
|
getCommonOptions(): CommonPackOptions {
|
|
51
|
+
const entries = this.entries;
|
|
52
|
+
const mainEntry = this.entries.find(x => x.startsWith('@travetto/cli'))!;
|
|
25
53
|
return {
|
|
26
54
|
workspace: this.option({ short: 'w', desc: 'Workspace for building' }),
|
|
27
55
|
clean: this.boolOption({ short: 'c', desc: 'Clean workspace', def: true }),
|
|
28
56
|
output: this.option({ short: 'o', desc: 'Output Location' }),
|
|
29
|
-
|
|
30
|
-
entryPoint: this.option({ short: 'e', desc: 'Entry point', def: 'node_modules/@travetto/cli/support/cli.js' }),
|
|
31
|
-
entryCommand: this.option({ short: 'ec', desc: 'Entry command' }),
|
|
57
|
+
entryPoint: this.choiceOption({ short: 'e', desc: 'Entry point', def: mainEntry, choices: entries }),
|
|
32
58
|
minify: this.boolOption({ short: 'm', desc: 'Minify output', def: true }),
|
|
33
59
|
sourcemap: this.boolOption({ short: 'sm', desc: 'Bundle source maps' }),
|
|
34
60
|
includeSources: this.boolOption({ short: 'is', desc: 'Include source with source maps' }),
|
|
@@ -48,25 +74,21 @@ export abstract class BasePackCommand<T extends CommonPackOptions, S extends Com
|
|
|
48
74
|
}
|
|
49
75
|
|
|
50
76
|
getOperations(): PackOperationShape<S>[] {
|
|
51
|
-
|
|
77
|
+
return BASIC_OP_SET.slice(0);
|
|
78
|
+
}
|
|
52
79
|
|
|
53
|
-
|
|
54
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Run all operations
|
|
82
|
+
*/
|
|
83
|
+
async * runOperations(cfg: S): AsyncIterable<string> {
|
|
84
|
+
for (const op of this.getOperations()) {
|
|
85
|
+
for await (const msg of op(cfg)) {
|
|
86
|
+
yield msg.join(' ');
|
|
87
|
+
}
|
|
55
88
|
}
|
|
56
|
-
|
|
57
|
-
ops.push(
|
|
58
|
-
PackOperation.writeEnv,
|
|
59
|
-
PackOperation.writePackageJson,
|
|
60
|
-
PackOperation.writeEntryScript,
|
|
61
|
-
PackOperation.copyResources,
|
|
62
|
-
PackOperation.primeAppCache,
|
|
63
|
-
PackOperation.writeManifest,
|
|
64
|
-
PackOperation.bundle,
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
return ops;
|
|
68
89
|
}
|
|
69
90
|
|
|
91
|
+
|
|
70
92
|
getModule(moduleName: string): string {
|
|
71
93
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
72
94
|
let module = this.monoRoot ? moduleName : RootIndex.mainModule.name;
|
|
@@ -82,15 +104,20 @@ export abstract class BasePackCommand<T extends CommonPackOptions, S extends Com
|
|
|
82
104
|
|
|
83
105
|
async buildConfig(): Promise<S> {
|
|
84
106
|
this.cmd.workspace ??= path.resolve(os.tmpdir(), RootIndex.mainModule.sourcePath.replace(/[\/\\: ]/g, '_'));
|
|
85
|
-
this.cmd.
|
|
107
|
+
this.cmd.entrySource = `${path.basename(this.cmd.entryPoint)}.js`;
|
|
108
|
+
this.cmd.entryCommand = path.basename(this.cmd.entryPoint).replace(/entry[.]/, '');
|
|
86
109
|
this.cmd.module = RootIndex.mainModule.name;
|
|
87
110
|
return this.cmd;
|
|
88
111
|
}
|
|
89
112
|
|
|
90
113
|
async action(module: string, args: string[]): Promise<void> {
|
|
114
|
+
if (Array.isArray(module)) {
|
|
115
|
+
args = module;
|
|
116
|
+
module = RootIndex.mainModule.name;
|
|
117
|
+
}
|
|
91
118
|
const start = Date.now();
|
|
92
119
|
if (!module && this.monoRoot) {
|
|
93
|
-
this.showHelp(new Error('The module needs to specified when running from a monorepo root'));
|
|
120
|
+
return this.showHelp(new Error('The module needs to specified when running from a monorepo root'));
|
|
94
121
|
}
|
|
95
122
|
|
|
96
123
|
module = this.getModule(module);
|
|
@@ -117,7 +144,7 @@ export abstract class BasePackCommand<T extends CommonPackOptions, S extends Com
|
|
|
117
144
|
}
|
|
118
145
|
this.cmd.workspace = path.resolve(this.cmd.workspace);
|
|
119
146
|
|
|
120
|
-
const stream =
|
|
147
|
+
const stream = this.runOperations(cfg);
|
|
121
148
|
|
|
122
149
|
// Eject to file
|
|
123
150
|
if (this.cmd.ejectFile) {
|
|
@@ -127,7 +154,13 @@ export abstract class BasePackCommand<T extends CommonPackOptions, S extends Com
|
|
|
127
154
|
}
|
|
128
155
|
await PackUtil.writeEjectOutput(this.cmd.workspace, cfg.module, output, this.cmd.ejectFile);
|
|
129
156
|
} else {
|
|
130
|
-
await GlobalTerminal.streamLinesWithWaiting(stream, {
|
|
157
|
+
await GlobalTerminal.streamLinesWithWaiting(stream, {
|
|
158
|
+
initialDelay: 0,
|
|
159
|
+
cycleDelay: 100,
|
|
160
|
+
end: false,
|
|
161
|
+
position: 'inline',
|
|
162
|
+
committedPrefix: String.fromCharCode(171)
|
|
163
|
+
});
|
|
131
164
|
let msg = cliTpl`${{ success: 'Success' }} (${{ identifier: TimeUtil.prettyDeltaSinceTime(start) }}) ${{ subtitle: 'module' }}=${{ param: this.cmd.module }}`;
|
|
132
165
|
if (this.cmd.output) {
|
|
133
166
|
msg = cliTpl`${msg} ${{ subtitle: 'output' }}=${{ path: this.cmd.output }}`;
|