@travetto/pack 3.0.0-rc.6 → 3.0.0-rc.8
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/__index__.ts +1 -5
- package/package.json +9 -5
- package/support/bin/config.ts +81 -0
- package/support/bin/docker-operation.ts +92 -0
- package/support/bin/operation.ts +255 -0
- package/support/bin/rollup-esm-dynamic-import.ts +55 -0
- package/support/bin/rollup.ts +34 -0
- package/support/bin/shell.ts +53 -0
- package/support/bin/types.ts +61 -15
- package/support/bin/util.ts +39 -154
- package/support/cli.pack.ts +10 -6
- package/support/cli.pack_docker.ts +27 -21
- package/support/cli.pack_zip.ts +18 -13
- package/support/pack.base.ts +136 -0
- package/support/bin/assemble/operation.ts +0 -59
- package/support/bin/assemble/util.ts +0 -139
- package/support/bin/docker.ts +0 -97
- package/support/bin/pack.ts +0 -69
- package/support/bin/zip.ts +0 -51
- package/support/cli.pack-base.ts +0 -97
- package/support/cli.pack_assemble.ts +0 -21
- package/support/cli.pack_docker-export.ts +0 -55
- package/support/pack.config.ts +0 -60
package/support/bin/types.ts
CHANGED
|
@@ -1,19 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { ListOptionConfig, OptionConfig } from '@travetto/cli';
|
|
2
|
+
|
|
3
|
+
export type CommonPackConfig = {
|
|
4
4
|
workspace: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
output: string;
|
|
6
|
+
clean: boolean;
|
|
7
|
+
ejectFile: string;
|
|
8
|
+
module: string;
|
|
9
|
+
|
|
10
|
+
// Bundle
|
|
11
|
+
entryPoint: string;
|
|
12
|
+
entryCommand: string;
|
|
13
|
+
entryArguments: string[];
|
|
14
|
+
minify: boolean;
|
|
15
|
+
sourcemap: boolean;
|
|
16
|
+
includeSources: boolean;
|
|
8
17
|
};
|
|
9
18
|
|
|
10
|
-
export type
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
export type CommonPackOptions = {
|
|
20
|
+
workspace: OptionConfig<string>;
|
|
21
|
+
output: OptionConfig<string>;
|
|
22
|
+
clean: OptionConfig<boolean>;
|
|
23
|
+
ejectFile: OptionConfig<string>;
|
|
24
|
+
|
|
25
|
+
// Bundle
|
|
26
|
+
entryPoint: OptionConfig<string>;
|
|
27
|
+
entryCommand: OptionConfig<string>;
|
|
28
|
+
minify: OptionConfig<boolean>;
|
|
29
|
+
sourcemap: OptionConfig<boolean>;
|
|
30
|
+
includeSources: OptionConfig<boolean>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type DockerPackConfig = {
|
|
34
|
+
dockerImage: string;
|
|
35
|
+
dockerName: string;
|
|
36
|
+
dockerTag: string[];
|
|
37
|
+
dockerPort: string[];
|
|
38
|
+
dockerPush: boolean;
|
|
39
|
+
dockerRegistry: string;
|
|
40
|
+
} & CommonPackConfig;
|
|
41
|
+
|
|
42
|
+
export type DockerPackOptions = {
|
|
43
|
+
dockerImage: OptionConfig<string>;
|
|
44
|
+
dockerName: OptionConfig<string>;
|
|
45
|
+
dockerTag: ListOptionConfig<string>;
|
|
46
|
+
dockerPort: ListOptionConfig<string>;
|
|
47
|
+
dockerPush: OptionConfig<boolean>;
|
|
48
|
+
dockerRegistry: OptionConfig<string>;
|
|
49
|
+
} & CommonPackOptions;
|
|
50
|
+
|
|
51
|
+
export type ShellCommandImpl = {
|
|
52
|
+
var(name: string): string;
|
|
53
|
+
createFile(file: string, text: string[], mode?: string): string[][];
|
|
54
|
+
scriptOpen(): string[];
|
|
55
|
+
chdirScript(): string[];
|
|
56
|
+
callCommandWithAllArgs(cmd: string, ...args: string[]): string[];
|
|
57
|
+
copy(src: string, dest: string): string[];
|
|
58
|
+
copyRecursive(src: string, dest: string): string[];
|
|
59
|
+
rmRecursive(dest: string): string[];
|
|
60
|
+
mkdir(dest: string): string[];
|
|
61
|
+
export(key: string, value: string): string[];
|
|
62
|
+
chdir(dest: string): string[];
|
|
63
|
+
comment(message: string): string[];
|
|
64
|
+
zip(output: string): string[];
|
|
19
65
|
};
|
package/support/bin/util.ts
CHANGED
|
@@ -1,162 +1,19 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
|
|
3
|
-
import glob from 'picomatch';
|
|
4
|
-
|
|
5
3
|
import { path, RootIndex } from '@travetto/manifest';
|
|
6
|
-
import { cliTpl } from '@travetto/cli';
|
|
7
4
|
import { ExecUtil } from '@travetto/base';
|
|
8
|
-
import { stripAnsiCodes } from '@travetto/terminal';
|
|
9
5
|
|
|
10
|
-
import {
|
|
6
|
+
import { ActiveShellCommand } from './shell';
|
|
11
7
|
|
|
12
|
-
/**
|
|
13
|
-
* Shared packing utils
|
|
14
|
-
*/
|
|
15
8
|
export class PackUtil {
|
|
16
|
-
|
|
17
|
-
static #modes: Partial<CommonConfig>[];
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Build configuration object for an operation with a set of configs
|
|
21
|
-
*/
|
|
22
|
-
static buildConfig<T extends CommonConfig>(
|
|
23
|
-
op: { defaults?: Partial<T>, overrides?: Partial<T>, extend?(src: Partial<T>, dest: Partial<T>): Partial<T> },
|
|
24
|
-
configs: Partial<T>[]
|
|
25
|
-
): T {
|
|
26
|
-
const inputs = [
|
|
27
|
-
op.defaults! ?? {},
|
|
28
|
-
...configs,
|
|
29
|
-
op.overrides! ?? {}
|
|
30
|
-
].filter(x => Object.keys(x).length > 0);
|
|
31
|
-
|
|
32
|
-
const res = inputs.reduce((out: Partial<T>, config: Partial<T>): Partial<T> => {
|
|
33
|
-
const final = {
|
|
34
|
-
active: config.active ?? out.active,
|
|
35
|
-
workspace: config.workspace ?? out.workspace,
|
|
36
|
-
preProcess: [...(config.preProcess! ?? []), ...(out.preProcess ?? [])],
|
|
37
|
-
postProcess: [...(config.postProcess! ?? []), ...(out.postProcess ?? [])],
|
|
38
|
-
...op.extend?.(config, out)
|
|
39
|
-
};
|
|
40
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
41
|
-
return final as Partial<T>;
|
|
42
|
-
}, {});
|
|
43
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
44
|
-
return res as T;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Find pack modes with associated metadata
|
|
49
|
-
*/
|
|
50
|
-
static async modeList(): Promise<Partial<CommonConfig>[]> {
|
|
51
|
-
if (!this.#modes) {
|
|
52
|
-
this.#modes = await Promise.all(
|
|
53
|
-
RootIndex.findSupport({ filter: f => /\/pack[.].*[.]/.test(f) })
|
|
54
|
-
.map(async (x) => {
|
|
55
|
-
const req: Partial<CommonConfig> = (await import(x.output)).config;
|
|
56
|
-
req.file = x.import.replace(/^node_modules\//, '');
|
|
57
|
-
return req;
|
|
58
|
-
})
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
return this.#modes;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Build file include/exclude lists/checker
|
|
67
|
-
*/
|
|
68
|
-
static excludeChecker(files: string[], base: string): (file: string) => boolean {
|
|
69
|
-
const all = files.map(x => {
|
|
70
|
-
const negate = x.startsWith('!') || x.startsWith('^');
|
|
71
|
-
x = negate ? x.substring(1) : x;
|
|
72
|
-
x = x.replace(/^[.][/]/g, `${base}/`);
|
|
73
|
-
const match: (f: string) => boolean = glob(x, { nocase: true, dot: true, basename: true, contains: true, cwd: base });
|
|
74
|
-
Object.defineProperty(match, 'source', { value: x });
|
|
75
|
-
return [match, negate] as const;
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
return (f: string): boolean => {
|
|
79
|
-
let exclude = undefined;
|
|
80
|
-
f = path.resolve(base, f);
|
|
81
|
-
for (const [match, n] of all) {
|
|
82
|
-
if ((n || exclude === undefined) && match(f)) {
|
|
83
|
-
if (n) { // Fast exit if negating
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
exclude = match;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return !!exclude;
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Update .env.js with new env data
|
|
95
|
-
*/
|
|
96
|
-
static async writeEnvJs(workspace: string, env: Record<string, string | undefined>): Promise<void> {
|
|
97
|
-
const out = path.resolve(workspace, '.env.js');
|
|
98
|
-
let src = '';
|
|
99
|
-
if (!!(await fs.stat(out).catch(() => { }))) {
|
|
100
|
-
src = await fs.readFile(out, 'utf8');
|
|
101
|
-
}
|
|
102
|
-
const lines = Object.entries(env).map(([k, v]) => v ? `process.env['${k}'] = \`${v.replace(/`/g, '\\`')}\`;` : '');
|
|
103
|
-
const content = `${src}\n${lines.join('\n')}`;
|
|
104
|
-
await fs.writeFile(out, content, { encoding: 'utf8' });
|
|
105
|
-
}
|
|
106
|
-
|
|
107
9
|
/**
|
|
108
|
-
*
|
|
10
|
+
* Generate env.js
|
|
109
11
|
*/
|
|
110
|
-
static
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
let i = 0;
|
|
117
|
-
function stdout(msg?: string): void {
|
|
118
|
-
if (i++ > 0) {
|
|
119
|
-
process.stdout.write(cliTpl`${spacer}${{ param: 'done' }}\n`);
|
|
120
|
-
}
|
|
121
|
-
if (msg) {
|
|
122
|
-
process.stdout.write(cliTpl`${spacer}${{ output: '᳁' }} ${{ path: msg.padEnd(width - 15) }} ... `);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
async function runPhase(phase: 'preProcess' | 'postProcess'): Promise<void> {
|
|
127
|
-
for (const el of cfg[phase] ?? []) {
|
|
128
|
-
const [name, fn] = Object.entries(el)[0];
|
|
129
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
130
|
-
await stdout(name as string);
|
|
131
|
-
await fn(cfg);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
let message: string | undefined;
|
|
136
|
-
|
|
137
|
-
process.stdout.write(`${spacer}${title}\n`);
|
|
138
|
-
process.stdout.write(`${spacer}${'-'.repeat(width)}\n`);
|
|
139
|
-
|
|
140
|
-
await runPhase('preProcess');
|
|
141
|
-
|
|
142
|
-
for await (const msg of op.exec(cfg)) {
|
|
143
|
-
if (msg.includes('Success')) { // We are done
|
|
144
|
-
message = msg;
|
|
145
|
-
break;
|
|
146
|
-
} else {
|
|
147
|
-
stdout(msg);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
await runPhase('postProcess');
|
|
152
|
-
|
|
153
|
-
// Wrap up
|
|
154
|
-
stdout();
|
|
155
|
-
|
|
156
|
-
if (message !== undefined) {
|
|
157
|
-
process.stdout.write(`${spacer}${'-'.repeat(width)}\n`);
|
|
158
|
-
process.stdout.write(`${spacer}${message}\n`);
|
|
159
|
-
}
|
|
12
|
+
static buildEnvJS(env: Record<string, string | number | boolean | undefined>): string[] {
|
|
13
|
+
const entries = Object.entries(env)
|
|
14
|
+
.filter(([k, v]) => (v !== undefined))
|
|
15
|
+
.map(([k, v]) => [k, `${v}`]);
|
|
16
|
+
return entries.map(([k, v]) => `process.env.${k} = '${v}';`);
|
|
160
17
|
}
|
|
161
18
|
|
|
162
19
|
/**
|
|
@@ -166,13 +23,41 @@ export class PackUtil {
|
|
|
166
23
|
* @param ignore Should errors be ignored
|
|
167
24
|
*/
|
|
168
25
|
static async copyRecursive(src: string, dest: string, ignore = false): Promise<void> {
|
|
169
|
-
const [cmd, args] =
|
|
170
|
-
['xcopy', ['/y', '/h', '/s', path.toNative(src), path.toNative(dest)]] :
|
|
171
|
-
['cp', ['-r', '-p', src, dest]];
|
|
172
|
-
|
|
26
|
+
const [cmd, ...args] = ActiveShellCommand.copyRecursive(src, dest);
|
|
173
27
|
const res = await ExecUtil.spawn(cmd, args, { catchAsResult: true }).result;
|
|
174
28
|
if (res.code && !ignore) {
|
|
175
29
|
throw new Error(`Failed to copy ${src} to ${dest}`);
|
|
176
30
|
}
|
|
177
31
|
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Finalize eject output
|
|
35
|
+
*/
|
|
36
|
+
static async writeEjectOutput(
|
|
37
|
+
workspace: string,
|
|
38
|
+
module: string,
|
|
39
|
+
output: string[],
|
|
40
|
+
file: string
|
|
41
|
+
): Promise<void> {
|
|
42
|
+
const vars = {
|
|
43
|
+
DIST: workspace,
|
|
44
|
+
TRV_OUT: RootIndex.outputRoot,
|
|
45
|
+
ROOT: path.cwd(),
|
|
46
|
+
MOD: module
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const content = [
|
|
50
|
+
ActiveShellCommand.scriptOpen(),
|
|
51
|
+
...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
|
+
].join('\n');
|
|
55
|
+
|
|
56
|
+
if (file === '-' || file === '/dev/stdout') {
|
|
57
|
+
console.log!(content);
|
|
58
|
+
} else {
|
|
59
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
60
|
+
await fs.writeFile(file, content, 'utf8');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
178
63
|
}
|
package/support/cli.pack.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { BasePackCommand } from './pack.base';
|
|
2
|
+
import { CommonPackConfig, CommonPackOptions } from './bin/types';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Standard pack support
|
|
6
|
+
*/
|
|
7
|
+
export class PackCommand extends BasePackCommand<CommonPackOptions, CommonPackConfig> {
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
name = 'pack';
|
|
10
|
+
|
|
11
|
+
getOptions(): CommonPackOptions {
|
|
12
|
+
return this.getCommonOptions();
|
|
9
13
|
}
|
|
10
14
|
}
|
|
@@ -1,29 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DockerPackConfig, DockerPackOptions } from './bin/types';
|
|
2
|
+
import { DockerPackOperation } from './bin/docker-operation';
|
|
3
|
+
import { BasePackCommand, PackOperationShape } from './pack.base';
|
|
2
4
|
|
|
3
|
-
import { BaseOptions, BasePackCommand } from './cli.pack-base';
|
|
4
|
-
import { Docker, DockerConfig } from './bin/docker';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
port: ListOptionConfig<string>;
|
|
11
|
-
push: OptionConfig<boolean>;
|
|
12
|
-
registry: OptionConfig<string>;
|
|
13
|
-
};
|
|
6
|
+
/**
|
|
7
|
+
* Standard docker support for pack
|
|
8
|
+
*/
|
|
9
|
+
export class PackDockerCommand extends BasePackCommand<DockerPackOptions, DockerPackConfig> {
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
operation = Docker;
|
|
11
|
+
name = 'pack:docker';
|
|
17
12
|
|
|
18
|
-
getOptions():
|
|
13
|
+
getOptions(): DockerPackOptions {
|
|
14
|
+
const opts = this.getCommonOptions();
|
|
19
15
|
return {
|
|
20
|
-
...
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
...opts,
|
|
17
|
+
dockerImage: this.option({ short: 'di', desc: 'Docker Image to extend', def: 'node:18-alpine3.16' }),
|
|
18
|
+
dockerName: this.option({ short: 'dn', desc: 'Docker Image Name', def: this.monoRoot ? '<module>' : this.getSimpleModuleName() }),
|
|
19
|
+
dockerTag: this.listOption({ short: 'dt', desc: 'Docker Image Tag', def: ['latest'] }),
|
|
20
|
+
dockerPort: this.listOption({ short: 'dp', desc: 'Docker Image Port' }),
|
|
21
|
+
dockerPush: this.boolOption({ short: 'dx', desc: 'Docker Push Tags' }),
|
|
22
|
+
dockerRegistry: this.option({ short: 'dr', desc: 'Docker Registry' })
|
|
27
23
|
};
|
|
28
24
|
}
|
|
25
|
+
|
|
26
|
+
getOperations(): PackOperationShape<DockerPackConfig>[] {
|
|
27
|
+
return [
|
|
28
|
+
...super.getOperations(),
|
|
29
|
+
DockerPackOperation.writeDockerFile,
|
|
30
|
+
DockerPackOperation.pullDockerBaseImage,
|
|
31
|
+
DockerPackOperation.buildDockerContainer,
|
|
32
|
+
DockerPackOperation.pushDockerContainer
|
|
33
|
+
];
|
|
34
|
+
}
|
|
29
35
|
}
|
package/support/cli.pack_zip.ts
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CommonPackConfig, CommonPackOptions } from './bin/types';
|
|
2
|
+
import { PackOperation } from './bin/operation';
|
|
3
|
+
import { BasePackCommand, PackOperationShape } from './pack.base';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Standard zip support for pack
|
|
7
|
+
*/
|
|
8
|
+
export class PackZipCommand extends BasePackCommand<CommonPackOptions, CommonPackConfig> {
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
output: OptionConfig<string>;
|
|
8
|
-
};
|
|
10
|
+
name = 'pack:zip';
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
getOptions(): CommonPackOptions {
|
|
13
|
+
const opts = this.getCommonOptions();
|
|
14
|
+
opts.output.def = this.monoRoot ? '<module>.zip' : `${this.getSimpleModuleName()}.zip`;
|
|
15
|
+
return opts;
|
|
16
|
+
}
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
return
|
|
15
|
-
...
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
getOperations(): PackOperationShape<CommonPackConfig>[] {
|
|
19
|
+
return [
|
|
20
|
+
...super.getOperations(),
|
|
21
|
+
PackOperation.compress
|
|
22
|
+
];
|
|
18
23
|
}
|
|
19
24
|
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
|
|
3
|
+
import { CliCommand, cliTpl } from '@travetto/cli';
|
|
4
|
+
import { path, RootIndex } from '@travetto/manifest';
|
|
5
|
+
import { TimeUtil } from '@travetto/base';
|
|
6
|
+
import { GlobalTerminal } from '@travetto/terminal';
|
|
7
|
+
|
|
8
|
+
import { CommonPackConfig, CommonPackOptions } from './bin/types';
|
|
9
|
+
import { PackOperation } from './bin/operation';
|
|
10
|
+
import { PackUtil } from './bin/util';
|
|
11
|
+
|
|
12
|
+
export type PackOperationShape<T extends CommonPackConfig> = ((config: T) => AsyncIterable<string[]>);
|
|
13
|
+
|
|
14
|
+
export abstract class BasePackCommand<T extends CommonPackOptions, S extends CommonPackConfig> extends CliCommand<{}> {
|
|
15
|
+
|
|
16
|
+
get monoRoot(): boolean {
|
|
17
|
+
return !!RootIndex.manifest.monoRepo && path.cwd() === RootIndex.manifest.workspacePath;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getArgs(): string | undefined {
|
|
21
|
+
return this.monoRoot ? '<module> [args...]' : '[args...]';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getCommonOptions(): CommonPackOptions {
|
|
25
|
+
return {
|
|
26
|
+
workspace: this.option({ short: 'w', desc: 'Workspace for building' }),
|
|
27
|
+
clean: this.boolOption({ short: 'c', desc: 'Clean workspace', def: true }),
|
|
28
|
+
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' }),
|
|
32
|
+
minify: this.boolOption({ short: 'm', desc: 'Minify output', def: true }),
|
|
33
|
+
sourcemap: this.boolOption({ short: 'sm', desc: 'Bundle source maps' }),
|
|
34
|
+
includeSources: this.boolOption({ short: 'is', desc: 'Include source with source maps' }),
|
|
35
|
+
ejectFile: this.option({ short: 'x', desc: 'Eject commands to file' }),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
abstract getOptions(): T;
|
|
40
|
+
|
|
41
|
+
get cmd(): S {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
43
|
+
return super.cmd as S;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getSimpleModuleName(): string {
|
|
47
|
+
return RootIndex.mainPackage.name.replace(/[\/]/, '_').replace(/@/, '');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
getOperations(): PackOperationShape<S>[] {
|
|
51
|
+
const ops: ((config: S) => AsyncIterable<string[]>)[] = [];
|
|
52
|
+
|
|
53
|
+
if (this.cmd.clean) {
|
|
54
|
+
ops.push(PackOperation.clean);
|
|
55
|
+
}
|
|
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
|
+
}
|
|
69
|
+
|
|
70
|
+
getModule(moduleName: string): string {
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
72
|
+
let module = this.monoRoot ? moduleName : RootIndex.mainModule.name;
|
|
73
|
+
module = RootIndex.getModuleByFolder(module)?.name ?? module;
|
|
74
|
+
|
|
75
|
+
// Reinitialize for module
|
|
76
|
+
if (this.monoRoot) {
|
|
77
|
+
RootIndex.reinitForModule(module);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return module;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async buildConfig(): Promise<S> {
|
|
84
|
+
this.cmd.workspace ??= path.resolve(os.tmpdir(), RootIndex.mainModule.sourcePath.replace(/[\/\\: ]/g, '_'));
|
|
85
|
+
this.cmd.entryCommand ??= path.basename(this.cmd.entryPoint).replace(/[.][tj]s$/, '');
|
|
86
|
+
this.cmd.module = RootIndex.mainModule.name;
|
|
87
|
+
return this.cmd;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async action(module: string, args: string[]): Promise<void> {
|
|
91
|
+
const start = Date.now();
|
|
92
|
+
if (!module && this.monoRoot) {
|
|
93
|
+
this.showHelp(new Error('The module needs to specified when running from a monorepo root'));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module = this.getModule(module);
|
|
97
|
+
|
|
98
|
+
const cfg = await this.buildConfig();
|
|
99
|
+
cfg.entryArguments = args;
|
|
100
|
+
|
|
101
|
+
for (const k in this.cmd) {
|
|
102
|
+
const v = this.cmd[k];
|
|
103
|
+
if (typeof v === 'string' && /<module>/.test(v)) {
|
|
104
|
+
// @ts-expect-error
|
|
105
|
+
this.cmd[k] = v.replace(/<module>/g, this.getSimpleModuleName());
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Resolve all files to absolute paths
|
|
110
|
+
if (this.cmd.output) {
|
|
111
|
+
this.cmd.output = path.resolve(this.cmd.output);
|
|
112
|
+
}
|
|
113
|
+
if (this.cmd.ejectFile) {
|
|
114
|
+
this.cmd.ejectFile = path.resolve(this.cmd.ejectFile);
|
|
115
|
+
}
|
|
116
|
+
this.cmd.workspace = path.resolve(this.cmd.workspace);
|
|
117
|
+
|
|
118
|
+
const stream = PackOperation.runOperations(cfg, this.getOperations());
|
|
119
|
+
|
|
120
|
+
// Eject to file
|
|
121
|
+
if (this.cmd.ejectFile) {
|
|
122
|
+
const output: string[] = [];
|
|
123
|
+
for await (const line of stream) {
|
|
124
|
+
output.push(line);
|
|
125
|
+
}
|
|
126
|
+
await PackUtil.writeEjectOutput(this.cmd.workspace, cfg.module, output, this.cmd.ejectFile);
|
|
127
|
+
} else {
|
|
128
|
+
await GlobalTerminal.streamLinesWithWaiting(stream, { initialDelay: 0, cycleDelay: 100, end: true });
|
|
129
|
+
let msg = cliTpl`${{ success: 'Success' }} (${{ identifier: TimeUtil.prettyDeltaSinceTime(start) }}) ${{ subtitle: 'module' }}=${{ param: this.cmd.module }}`;
|
|
130
|
+
if (this.cmd.output) {
|
|
131
|
+
msg = cliTpl`${msg} ${{ subtitle: 'output' }}=${{ path: this.cmd.output }}`;
|
|
132
|
+
}
|
|
133
|
+
await GlobalTerminal.writeLines(msg);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
|
|
3
|
-
import { path } from '@travetto/manifest';
|
|
4
|
-
import { cliTpl } from '@travetto/cli';
|
|
5
|
-
import { Env } from '@travetto/base';
|
|
6
|
-
|
|
7
|
-
import { PackUtil } from '../util';
|
|
8
|
-
import { CommonConfig, PackOperation } from '../types';
|
|
9
|
-
import { AssembleUtil } from './util';
|
|
10
|
-
export interface AssembleConfig extends CommonConfig {
|
|
11
|
-
keepSource: boolean;
|
|
12
|
-
readonly: boolean;
|
|
13
|
-
add: Record<string, string>[];
|
|
14
|
-
exclude: string[];
|
|
15
|
-
env: Record<string, string | undefined>;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Utils for packing source code and minimizing space usage
|
|
20
|
-
*/
|
|
21
|
-
export const Assemble: PackOperation<AssembleConfig, 'assemble'> = {
|
|
22
|
-
key: 'assemble',
|
|
23
|
-
title: 'Assembling',
|
|
24
|
-
context(cfg: AssembleConfig) {
|
|
25
|
-
return `[readonly=${cfg.readonly},source=${cfg.keepSource}]`;
|
|
26
|
-
},
|
|
27
|
-
overrides: {
|
|
28
|
-
keepSource: Env.getBoolean('PACK_ASSEMBLE_KEEP_SOURCE'),
|
|
29
|
-
readonly: Env.getBoolean('PACK_ASSEMBLE_READONLY')
|
|
30
|
-
},
|
|
31
|
-
extend(src: Partial<AssembleConfig>, dest: Partial<AssembleConfig>): Partial<AssembleConfig> {
|
|
32
|
-
return {
|
|
33
|
-
keepSource: src.keepSource ?? dest.keepSource,
|
|
34
|
-
readonly: src.readonly ?? dest.readonly,
|
|
35
|
-
add: [...(src.add ?? []), ...(dest.add ?? [])],
|
|
36
|
-
exclude: [...(src.exclude ?? []), ...(dest.exclude ?? [])],
|
|
37
|
-
env: { ...(src.env ?? {}), ...(dest.env ?? {}) },
|
|
38
|
-
};
|
|
39
|
-
},
|
|
40
|
-
buildConfig(configs: Partial<AssembleConfig>[]): AssembleConfig {
|
|
41
|
-
return PackUtil.buildConfig(this, configs);
|
|
42
|
-
},
|
|
43
|
-
/**
|
|
44
|
-
* Assemble the project into a workspace directory, optimized for space and runtime
|
|
45
|
-
*/
|
|
46
|
-
async * exec({ workspace, add, exclude, env, keepSource }: AssembleConfig) {
|
|
47
|
-
const ws = path.resolve(workspace!);
|
|
48
|
-
yield 'Cleaning Workspace'; {
|
|
49
|
-
await fs.rm(ws, { recursive: true, force: true }).catch(() => { });
|
|
50
|
-
await fs.mkdir(ws);
|
|
51
|
-
}
|
|
52
|
-
yield 'Create Entrypoint'; await AssembleUtil.copyEntryPoint(ws);
|
|
53
|
-
yield 'Copying Prod Dependencies'; await AssembleUtil.copyProdDependencies(ws, keepSource);
|
|
54
|
-
yield 'Excluding Files'; await AssembleUtil.excludeFiles(ws, exclude);
|
|
55
|
-
yield 'Copying Added Content'; await AssembleUtil.copyAddedContent(ws, add);
|
|
56
|
-
yield 'Removing Empty Folders'; await AssembleUtil.removeEmptyFolders(ws);
|
|
57
|
-
yield cliTpl`${{ success: 'Successfully' }} assembled project at ${{ path: workspace }}`;
|
|
58
|
-
}
|
|
59
|
-
};
|