@eggjs/scripts 3.1.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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -0
  3. package/bin/dev.cmd +3 -0
  4. package/bin/dev.js +5 -0
  5. package/bin/run.cmd +3 -0
  6. package/bin/run.js +5 -0
  7. package/dist/commonjs/baseCommand.d.ts +25 -0
  8. package/dist/commonjs/baseCommand.js +62 -0
  9. package/dist/commonjs/commands/start.d.ts +34 -0
  10. package/dist/commonjs/commands/start.js +350 -0
  11. package/dist/commonjs/commands/stop.d.ts +16 -0
  12. package/dist/commonjs/commands/stop.js +90 -0
  13. package/dist/commonjs/helper.d.ts +10 -0
  14. package/dist/commonjs/helper.js +61 -0
  15. package/dist/commonjs/index.d.ts +3 -0
  16. package/dist/commonjs/index.js +26 -0
  17. package/dist/commonjs/package.json +3 -0
  18. package/dist/commonjs/types.d.ts +9 -0
  19. package/dist/commonjs/types.js +3 -0
  20. package/dist/esm/baseCommand.d.ts +25 -0
  21. package/dist/esm/baseCommand.js +55 -0
  22. package/dist/esm/commands/start.d.ts +34 -0
  23. package/dist/esm/commands/start.js +344 -0
  24. package/dist/esm/commands/stop.d.ts +16 -0
  25. package/dist/esm/commands/stop.js +87 -0
  26. package/dist/esm/helper.d.ts +10 -0
  27. package/dist/esm/helper.js +51 -0
  28. package/dist/esm/index.d.ts +3 -0
  29. package/dist/esm/index.js +5 -0
  30. package/dist/esm/package.json +3 -0
  31. package/dist/esm/types.d.ts +9 -0
  32. package/dist/esm/types.js +2 -0
  33. package/dist/package.json +4 -0
  34. package/package.json +103 -0
  35. package/scripts/start-cluster.cjs +15 -0
  36. package/scripts/start-cluster.mjs +14 -0
  37. package/src/baseCommand.ts +68 -0
  38. package/src/commands/start.ts +384 -0
  39. package/src/commands/stop.ts +100 -0
  40. package/src/helper.ts +62 -0
  41. package/src/index.ts +8 -0
  42. package/src/types.ts +9 -0
@@ -0,0 +1,55 @@
1
+ import { debuglog } from 'node:util';
2
+ import { Command } from '@oclif/core';
3
+ import { readJSON } from 'utility';
4
+ import path from 'node:path';
5
+ const debug = debuglog('@eggjs/scripts/baseCommand');
6
+ export class BaseCommand extends Command {
7
+ // add the --json flag
8
+ static enableJsonFlag = false;
9
+ // define flags that can be inherited by any command that extends BaseCommand
10
+ static baseFlags = {
11
+ // 'log-level': Flags.option({
12
+ // default: 'info',
13
+ // helpGroup: 'GLOBAL',
14
+ // options: ['debug', 'warn', 'error', 'info', 'trace'] as const,
15
+ // summary: 'Specify level for logging.',
16
+ // })(),
17
+ };
18
+ flags;
19
+ args;
20
+ env = { ...process.env };
21
+ pkg;
22
+ isESM;
23
+ pkgEgg;
24
+ globalExecArgv = [];
25
+ async init() {
26
+ await super.init();
27
+ debug('[init] raw args: %o, NODE_ENV: %o', this.argv, this.env.NODE_ENV);
28
+ const { args, flags } = await this.parse({
29
+ flags: this.ctor.flags,
30
+ baseFlags: super.ctor.baseFlags,
31
+ enableJsonFlag: this.ctor.enableJsonFlag,
32
+ args: this.ctor.args,
33
+ strict: this.ctor.strict,
34
+ });
35
+ this.flags = flags;
36
+ this.args = args;
37
+ }
38
+ async initBaseInfo(baseDir) {
39
+ const pkg = await readJSON(path.join(baseDir, 'package.json'));
40
+ this.pkg = pkg;
41
+ this.pkgEgg = pkg.egg ?? {};
42
+ this.isESM = pkg.type === 'module';
43
+ debug('[initBaseInfo] baseDir: %o, pkgEgg: %o, isESM: %o', baseDir, this.pkgEgg, this.isESM);
44
+ }
45
+ async catch(err) {
46
+ // add any custom logic to handle errors from the command
47
+ // or simply return the parent class error handling
48
+ return super.catch(err);
49
+ }
50
+ async finally(_) {
51
+ // called after run and catch regardless of whether or not the command errored
52
+ return super.finally(_);
53
+ }
54
+ }
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZUNvbW1hbmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYmFzZUNvbW1hbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNyQyxPQUFPLEVBQUUsT0FBTyxFQUFxQixNQUFNLGFBQWEsQ0FBQztBQUV6RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ25DLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUU3QixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsNEJBQTRCLENBQUMsQ0FBQztBQUtyRCxNQUFNLE9BQWdCLFdBQXNDLFNBQVEsT0FBTztJQUN6RSxzQkFBc0I7SUFDdEIsTUFBTSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7SUFFOUIsNkVBQTZFO0lBQzdFLE1BQU0sQ0FBQyxTQUFTLEdBQUc7SUFDakIsOEJBQThCO0lBQzlCLHFCQUFxQjtJQUNyQix5QkFBeUI7SUFDekIsbUVBQW1FO0lBQ25FLDJDQUEyQztJQUMzQyxRQUFRO0tBQ1QsQ0FBQztJQUVRLEtBQUssQ0FBWTtJQUNqQixJQUFJLENBQVc7SUFFZixHQUFHLEdBQUcsRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN6QixHQUFHLENBQXNCO0lBQ3pCLEtBQUssQ0FBVTtJQUNmLE1BQU0sQ0FBYTtJQUNuQixjQUFjLEdBQWEsRUFBRSxDQUFDO0lBRWpDLEtBQUssQ0FBQyxJQUFJO1FBQ2YsTUFBTSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbkIsS0FBSyxDQUFDLG1DQUFtQyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN6RSxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQztZQUN2QyxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLO1lBQ3RCLFNBQVMsRUFBRyxLQUFLLENBQUMsSUFBMkIsQ0FBQyxTQUFTO1lBQ3ZELGNBQWMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWM7WUFDeEMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSTtZQUNwQixNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1NBQ3pCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBaUIsQ0FBQztRQUMvQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQWUsQ0FBQztJQUM5QixDQUFDO0lBRVMsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFlO1FBQzFDLE1BQU0sR0FBRyxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDZixJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLElBQUksS0FBSyxRQUFRLENBQUM7UUFDbkMsS0FBSyxDQUFDLG1EQUFtRCxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvRixDQUFDO0lBRVMsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFnQztRQUNwRCx5REFBeUQ7UUFDekQsbURBQW1EO1FBQ25ELE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRVMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFvQjtRQUMxQyw4RUFBOEU7UUFDOUUsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFCLENBQUMifQ==
@@ -0,0 +1,34 @@
1
+ import { BaseCommand } from '../baseCommand.js';
2
+ export interface FrameworkOptions {
3
+ baseDir: string;
4
+ framework?: string;
5
+ }
6
+ export default class Start<T extends typeof Start> extends BaseCommand<T> {
7
+ #private;
8
+ static description: string;
9
+ static examples: string[];
10
+ static args: {
11
+ baseDir: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
12
+ };
13
+ static flags: {
14
+ title: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ framework: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ port: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
+ workers: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
+ env: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
19
+ daemon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
20
+ stdout: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
21
+ stderr: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
22
+ timeout: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
23
+ 'ignore-stderr': import("@oclif/core/interfaces").BooleanFlag<boolean>;
24
+ node: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
25
+ require: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
26
+ sourcemap: import("@oclif/core/interfaces").BooleanFlag<boolean>;
27
+ };
28
+ isReady: boolean;
29
+ protected getFrameworkPath(options: FrameworkOptions): Promise<string>;
30
+ protected getFrameworkName(frameworkPath: string): Promise<string>;
31
+ protected getServerBin(): Promise<string>;
32
+ run(): Promise<void>;
33
+ protected checkStatus(): Promise<void>;
34
+ }
@@ -0,0 +1,344 @@
1
+ import { debuglog, promisify } from 'node:util';
2
+ import path from 'node:path';
3
+ import { scheduler } from 'node:timers/promises';
4
+ import { spawn, execFile as _execFile } from 'node:child_process';
5
+ import { mkdir, rename, stat, open } from 'node:fs/promises';
6
+ import { homedir } from 'node-homedir';
7
+ import { Args, Flags } from '@oclif/core';
8
+ import { getFrameworkPath, importResolve } from '@eggjs/utils';
9
+ import { readJSON, exists, getDateStringParts } from 'utility';
10
+ import { BaseCommand } from '../baseCommand.js';
11
+ import { getSourceDirname } from '../helper.js';
12
+ const debug = debuglog('@eggjs/scripts/commands/start');
13
+ const execFile = promisify(_execFile);
14
+ export default class Start extends BaseCommand {
15
+ static description = 'Start server at prod mode';
16
+ static examples = [
17
+ '<%= config.bin %> <%= command.id %>',
18
+ ];
19
+ static args = {
20
+ baseDir: Args.string({
21
+ description: 'directory of application',
22
+ required: false,
23
+ }),
24
+ };
25
+ static flags = {
26
+ title: Flags.string({
27
+ description: 'process title description, use for kill grep, default to `egg-server-${APP_NAME}`',
28
+ }),
29
+ framework: Flags.string({
30
+ description: 'specify framework that can be absolute path or npm package',
31
+ }),
32
+ port: Flags.integer({
33
+ description: 'listening port, default to `process.env.PORT`',
34
+ char: 'p',
35
+ }),
36
+ workers: Flags.integer({
37
+ char: 'c',
38
+ aliases: ['cluster'],
39
+ description: 'numbers of app workers, default to `process.env.EGG_WORKERS` or `os.cpus().length`',
40
+ }),
41
+ env: Flags.string({
42
+ description: 'server env, default to `process.env.EGG_SERVER_ENV`',
43
+ default: process.env.EGG_SERVER_ENV,
44
+ }),
45
+ daemon: Flags.boolean({
46
+ description: 'whether run at background daemon mode',
47
+ }),
48
+ stdout: Flags.string({
49
+ description: 'customize stdout file',
50
+ }),
51
+ stderr: Flags.string({
52
+ description: 'customize stderr file',
53
+ }),
54
+ timeout: Flags.integer({
55
+ description: 'the maximum timeout(ms) when app starts',
56
+ default: 300 * 1000,
57
+ }),
58
+ 'ignore-stderr': Flags.boolean({
59
+ description: 'whether ignore stderr when app starts',
60
+ }),
61
+ node: Flags.string({
62
+ description: 'customize node command path',
63
+ default: 'node',
64
+ }),
65
+ require: Flags.string({
66
+ summary: 'require the given module',
67
+ char: 'r',
68
+ multiple: true,
69
+ }),
70
+ sourcemap: Flags.boolean({
71
+ summary: 'whether enable sourcemap support, will load `source-map-support` etc',
72
+ aliases: ['ts', 'typescript'],
73
+ }),
74
+ };
75
+ isReady = false;
76
+ #child;
77
+ async getFrameworkPath(options) {
78
+ return getFrameworkPath(options);
79
+ }
80
+ async getFrameworkName(frameworkPath) {
81
+ const pkgPath = path.join(frameworkPath, 'package.json');
82
+ let name = 'egg';
83
+ try {
84
+ const pkg = await readJSON(pkgPath);
85
+ if (pkg.name) {
86
+ name = pkg.name;
87
+ }
88
+ }
89
+ catch {
90
+ // ignore
91
+ }
92
+ return name;
93
+ }
94
+ async getServerBin() {
95
+ const serverBinName = this.isESM ? 'start-cluster.mjs' : 'start-cluster.cjs';
96
+ // for src paths, `./src/commands/start.js`
97
+ let serverBin = path.join(getSourceDirname(), '../scripts', serverBinName);
98
+ if (!(await exists(serverBin))) {
99
+ // for dist paths, `./dist/esm/commands/start.js`
100
+ serverBin = path.join(getSourceDirname(), '../../scripts', serverBinName);
101
+ }
102
+ return serverBin;
103
+ }
104
+ async run() {
105
+ const { args, flags } = this;
106
+ // context.execArgvObj = context.execArgvObj || {};
107
+ // const { argv, env, cwd, execArgvObj } = context;
108
+ const HOME = homedir();
109
+ const logDir = path.join(HOME, 'logs');
110
+ // eggctl start
111
+ // eggctl start ./server
112
+ // eggctl start /opt/app
113
+ const cwd = process.cwd();
114
+ let baseDir = args.baseDir || cwd;
115
+ if (!path.isAbsolute(baseDir)) {
116
+ baseDir = path.join(cwd, baseDir);
117
+ }
118
+ await this.initBaseInfo(baseDir);
119
+ flags.framework = await this.getFrameworkPath({
120
+ framework: flags.framework,
121
+ baseDir,
122
+ });
123
+ const frameworkName = await this.getFrameworkName(flags.framework);
124
+ flags.title = flags.title || `egg-server-${this.pkg.name}`;
125
+ flags.stdout = flags.stdout || path.join(logDir, 'master-stdout.log');
126
+ flags.stderr = flags.stderr || path.join(logDir, 'master-stderr.log');
127
+ if (flags.workers === undefined && process.env.EGG_WORKERS) {
128
+ flags.workers = Number(process.env.EGG_WORKERS);
129
+ }
130
+ // normalize env
131
+ this.env.HOME = HOME;
132
+ this.env.NODE_ENV = 'production';
133
+ // it makes env big but more robust
134
+ this.env.PATH = this.env.Path = [
135
+ // for nodeinstall
136
+ path.join(baseDir, 'node_modules/.bin'),
137
+ // support `.node/bin`, due to npm5 will remove `node_modules/.bin`
138
+ path.join(baseDir, '.node/bin'),
139
+ // adjust env for win
140
+ this.env.PATH || this.env.Path,
141
+ ].filter(x => !!x).join(path.delimiter);
142
+ // for alinode
143
+ this.env.ENABLE_NODE_LOG = 'YES';
144
+ this.env.NODE_LOG_DIR = this.env.NODE_LOG_DIR || path.join(logDir, 'alinode');
145
+ await mkdir(this.env.NODE_LOG_DIR, { recursive: true });
146
+ // cli argv -> process.env.EGG_SERVER_ENV -> `undefined` then egg will use `prod`
147
+ if (flags.env) {
148
+ // if undefined, should not pass key due to `spawn`, https://github.com/nodejs/node/blob/master/lib/child_process.js#L470
149
+ this.env.EGG_SERVER_ENV = flags.env;
150
+ }
151
+ // additional execArgv
152
+ const execArgv = [
153
+ '--no-deprecation',
154
+ '--trace-warnings',
155
+ ];
156
+ if (this.pkgEgg.revert) {
157
+ const reverts = Array.isArray(this.pkgEgg.revert) ? this.pkgEgg.revert : [this.pkgEgg.revert];
158
+ for (const revert of reverts) {
159
+ execArgv.push(`--security-revert=${revert}`);
160
+ }
161
+ }
162
+ // pkg.eggScriptsConfig.require
163
+ const scriptsConfig = this.pkg.eggScriptsConfig;
164
+ if (scriptsConfig?.require) {
165
+ scriptsConfig.require = Array.isArray(scriptsConfig.require) ? scriptsConfig.require : [scriptsConfig.require];
166
+ flags.require = [...scriptsConfig.require, ...(flags.require ?? [])];
167
+ }
168
+ // read argv from eggScriptsConfig in package.json
169
+ if (scriptsConfig) {
170
+ for (const key in scriptsConfig) {
171
+ const v = scriptsConfig[key];
172
+ if (key.startsWith('node-options--')) {
173
+ const newKey = key.replace('node-options--', '');
174
+ if (v === true) {
175
+ // "node-options--allow-wasi": true
176
+ // => --allow-wasi
177
+ execArgv.push(`--${newKey}`);
178
+ }
179
+ else {
180
+ // "node-options--max-http-header-size": "20000"
181
+ // => --max-http-header-size=20000
182
+ execArgv.push(`--${newKey}=${v}`);
183
+ }
184
+ continue;
185
+ }
186
+ const existsValue = Reflect.get(flags, key);
187
+ if (existsValue === undefined) {
188
+ // only set if key is not pass from command line
189
+ Reflect.set(flags, key, v);
190
+ }
191
+ }
192
+ }
193
+ // read `egg.typescript` from package.json
194
+ if (this.pkgEgg.typescript && flags.sourcemap === undefined) {
195
+ flags.sourcemap = true;
196
+ }
197
+ if (flags.sourcemap) {
198
+ const sourceMapSupport = importResolve('source-map-support/register.js', {
199
+ paths: [getSourceDirname()],
200
+ });
201
+ if (this.isESM) {
202
+ execArgv.push('--import', sourceMapSupport);
203
+ }
204
+ else {
205
+ execArgv.push('--require', sourceMapSupport);
206
+ }
207
+ }
208
+ if (flags.port === undefined && process.env.PORT) {
209
+ flags.port = parseInt(process.env.PORT);
210
+ }
211
+ debug('flags: %o, framework: %o, baseDir: %o, execArgv: %o', flags, frameworkName, baseDir, execArgv);
212
+ const command = flags.node;
213
+ const options = {
214
+ env: this.env,
215
+ stdio: 'inherit',
216
+ detached: false,
217
+ cwd: baseDir,
218
+ };
219
+ this.log('Starting %s application at %s', frameworkName, baseDir);
220
+ // remove unused properties from stringify, alias had been remove by `removeAlias`
221
+ const ignoreKeys = ['env', 'daemon', 'stdout', 'stderr', 'timeout', 'ignore-stderr', 'node'];
222
+ const clusterOptions = stringify({
223
+ ...flags,
224
+ baseDir,
225
+ }, ignoreKeys);
226
+ // Note: `spawn` is not like `fork`, had to pass `execArgv` yourself
227
+ const serverBin = await this.getServerBin();
228
+ const eggArgs = [...execArgv, serverBin, clusterOptions, `--title=${flags.title}`];
229
+ const spawnScript = `${command} ${eggArgs.map(a => `'${a}'`).join(' ')}`;
230
+ this.log('Spawn %o', spawnScript);
231
+ // whether run in the background.
232
+ if (flags.daemon) {
233
+ this.log(`Save log file to ${logDir}`);
234
+ const [stdout, stderr] = await Promise.all([
235
+ getRotateLog(flags.stdout),
236
+ getRotateLog(flags.stderr),
237
+ ]);
238
+ options.stdio = ['ignore', stdout, stderr, 'ipc'];
239
+ options.detached = true;
240
+ const child = this.#child = spawn(command, eggArgs, options);
241
+ this.isReady = false;
242
+ child.on('message', (msg) => {
243
+ // https://github.com/eggjs/cluster/blob/master/src/master.ts#L119
244
+ if (msg && msg.action === 'egg-ready') {
245
+ this.isReady = true;
246
+ this.log('%s started on %s', frameworkName, msg.data.address);
247
+ child.unref();
248
+ child.disconnect();
249
+ }
250
+ });
251
+ // check start status
252
+ await this.checkStatus();
253
+ }
254
+ else {
255
+ options.stdio = ['inherit', 'inherit', 'inherit', 'ipc'];
256
+ const child = this.#child = spawn(command, eggArgs, options);
257
+ child.once('exit', code => {
258
+ if (!code)
259
+ return;
260
+ // command should exit after child process exit
261
+ this.exit(code);
262
+ });
263
+ // attach master signal to child
264
+ let signal;
265
+ const signals = ['SIGINT', 'SIGQUIT', 'SIGTERM'];
266
+ signals.forEach(event => {
267
+ process.once(event, () => {
268
+ debug('Kill child %s with %s', child.pid, signal);
269
+ child.kill(event);
270
+ });
271
+ });
272
+ }
273
+ }
274
+ async checkStatus() {
275
+ let count = 0;
276
+ let hasError = false;
277
+ let isSuccess = true;
278
+ const timeout = this.flags.timeout / 1000;
279
+ const stderrFile = this.flags.stderr;
280
+ while (!this.isReady) {
281
+ try {
282
+ const stats = await stat(stderrFile);
283
+ if (stats && stats.size > 0) {
284
+ hasError = true;
285
+ break;
286
+ }
287
+ }
288
+ catch (_) {
289
+ // nothing
290
+ }
291
+ if (count >= timeout) {
292
+ this.logToStderr('Start failed, %ds timeout', timeout);
293
+ isSuccess = false;
294
+ break;
295
+ }
296
+ await scheduler.wait(1000);
297
+ this.log('Wait Start: %d...', ++count);
298
+ }
299
+ if (hasError) {
300
+ try {
301
+ const args = ['-n', '100', stderrFile];
302
+ this.logToStderr('tail %s', args.join(' '));
303
+ const { stdout: headStdout } = await execFile('head', args);
304
+ const { stdout: tailStdout } = await execFile('tail', args);
305
+ this.logToStderr('Got error when startup: ');
306
+ this.logToStderr(headStdout);
307
+ this.logToStderr('...');
308
+ this.logToStderr(tailStdout);
309
+ }
310
+ catch (err) {
311
+ this.logToStderr('ignore tail error: %s', err);
312
+ }
313
+ isSuccess = this.flags['ignore-stderr'];
314
+ this.logToStderr('Start got error, see %o', stderrFile);
315
+ this.logToStderr('Or use `--ignore-stderr` to ignore stderr at startup.');
316
+ }
317
+ if (!isSuccess) {
318
+ this.#child.kill('SIGTERM');
319
+ await scheduler.wait(1000);
320
+ this.exit(1);
321
+ }
322
+ }
323
+ }
324
+ function stringify(obj, ignore) {
325
+ const result = {};
326
+ Object.keys(obj).forEach(key => {
327
+ if (!ignore.includes(key)) {
328
+ result[key] = obj[key];
329
+ }
330
+ });
331
+ return JSON.stringify(result);
332
+ }
333
+ async function getRotateLog(logFile) {
334
+ await mkdir(path.dirname(logFile), { recursive: true });
335
+ if (await exists(logFile)) {
336
+ // format style: .20150602.193100
337
+ const [YYYY, MM, DD, HH, mm, ss] = getDateStringParts();
338
+ const timestamp = `.${YYYY}${MM}${DD}.${HH}${mm}${ss}`;
339
+ // Note: rename last log to next start time, not when last log file created
340
+ await rename(logFile, logFile + timestamp);
341
+ }
342
+ return (await open(logFile, 'a')).fd;
343
+ }
344
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tbWFuZHMvc3RhcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDaEQsT0FBTyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQzdCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsS0FBSyxFQUE4QixRQUFRLElBQUksU0FBUyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUYsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzdELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDMUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUMvRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRWhELE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0FBRXhELE1BQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQU90QyxNQUFNLENBQUMsT0FBTyxPQUFPLEtBQThCLFNBQVEsV0FBYztJQUN2RSxNQUFNLENBQVUsV0FBVyxHQUFHLDJCQUEyQixDQUFDO0lBRTFELE1BQU0sQ0FBVSxRQUFRLEdBQUc7UUFDekIscUNBQXFDO0tBQ3RDLENBQUM7SUFFRixN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
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from '../baseCommand.js';
2
+ import { NodeProcess } from '../helper.js';
3
+ export default class Stop<T extends typeof Stop> extends BaseCommand<T> {
4
+ static description: string;
5
+ static examples: string[];
6
+ static args: {
7
+ baseDir: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
8
+ };
9
+ static flags: {
10
+ title: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ timeout: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
12
+ };
13
+ run(): Promise<void>;
14
+ protected findNodeProcesses(filter: (item: NodeProcess) => boolean): Promise<NodeProcess[]>;
15
+ protected killProcesses(pids: number[], signal?: NodeJS.Signals): void;
16
+ }
@@ -0,0 +1,87 @@
1
+ import { debuglog, format } from 'node:util';
2
+ import { scheduler } from 'node:timers/promises';
3
+ import { Args, Flags } from '@oclif/core';
4
+ import { BaseCommand } from '../baseCommand.js';
5
+ import { isWindows, findNodeProcess, kill } from '../helper.js';
6
+ const debug = debuglog('@eggjs/scripts/commands/stop');
7
+ const osRelated = {
8
+ titleTemplate: isWindows ? '\\"title\\":\\"%s\\"' : '"title":"%s"',
9
+ // node_modules/@eggjs/cluster/dist/commonjs/app_worker.js
10
+ // node_modules/@eggjs/cluster/dist/esm/app_worker.js
11
+ appWorkerPath: /@eggjs[\/\\]cluster[\/\\]dist[\/\\](commonjs|esm)[\/\\]app_worker\.js/i,
12
+ // node_modules/@eggjs/cluster/dist/commonjs/agent_worker.js
13
+ // node_modules/@eggjs/cluster/dist/esm/agent_worker.js
14
+ agentWorkerPath: /@eggjs[\/\\]cluster[\/\\]dist[\/\\](commonjs|esm)[\/\\]agent_worker\.js/i,
15
+ };
16
+ export default class Stop extends BaseCommand {
17
+ static description = 'Stop server';
18
+ static examples = [
19
+ '<%= config.bin %> <%= command.id %>',
20
+ ];
21
+ static args = {
22
+ baseDir: Args.string({
23
+ description: 'directory of application',
24
+ required: false,
25
+ }),
26
+ };
27
+ static flags = {
28
+ title: Flags.string({
29
+ description: 'process title description, use for kill grep',
30
+ }),
31
+ timeout: Flags.integer({
32
+ description: 'the maximum timeout(ms) when app stop',
33
+ default: 5000,
34
+ }),
35
+ };
36
+ async run() {
37
+ const { flags } = this;
38
+ this.log(`stopping egg application${flags.title ? ` with --title=${flags.title}` : ''}`);
39
+ // node ~/eggjs/scripts/scripts/start-cluster.cjs {"title":"egg-server","workers":4,"port":7001,"baseDir":"~/eggjs/test/showcase","framework":"~/eggjs/test/showcase/node_modules/egg"}
40
+ let processList = await this.findNodeProcesses(item => {
41
+ const cmd = item.cmd;
42
+ const matched = flags.title ?
43
+ cmd.includes('start-cluster') && cmd.includes(format(osRelated.titleTemplate, flags.title)) :
44
+ cmd.includes('start-cluster');
45
+ if (matched) {
46
+ debug('find master process: %o', item);
47
+ }
48
+ return matched;
49
+ });
50
+ let pids = processList.map(x => x.pid);
51
+ if (pids.length) {
52
+ this.log('got master pid %j', pids);
53
+ this.killProcesses(pids);
54
+ // wait for 5s to confirm whether any worker process did not kill by master
55
+ await scheduler.wait(flags.timeout);
56
+ }
57
+ else {
58
+ this.logToStderr('can\'t detect any running egg process');
59
+ }
60
+ // node --debug-port=5856 /Users/tz/Workspaces/eggjs/test/showcase/node_modules/_egg-cluster@1.8.0@egg-cluster/lib/agent_worker.js {"framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg","baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","port":7001,"workers":2,"plugins":null,"https":false,"key":"","cert":"","title":"egg-server","clusterPort":52406}
61
+ // node /Users/tz/Workspaces/eggjs/test/showcase/node_modules/_egg-cluster@1.8.0@egg-cluster/lib/app_worker.js {"framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg","baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","port":7001,"workers":2,"plugins":null,"https":false,"key":"","cert":"","title":"egg-server","clusterPort":52406}
62
+ // ~/bin/node --no-deprecation --trace-warnings ~/eggjs/examples/helloworld/node_modules/@eggjs/cluster/dist/commonjs/agent_worker.js {"baseDir":"~/eggjs/examples/helloworld","startMode":"process","framework":"~/eggjs/examples/helloworld/node_modules/egg","title":"egg-server-helloworld","workers":10,"clusterPort":58977}
63
+ processList = await this.findNodeProcesses(item => {
64
+ const cmd = item.cmd;
65
+ const matched = flags.title ?
66
+ (osRelated.appWorkerPath.test(cmd) || osRelated.agentWorkerPath.test(cmd)) && cmd.includes(format(osRelated.titleTemplate, flags.title)) :
67
+ (osRelated.appWorkerPath.test(cmd) || osRelated.agentWorkerPath.test(cmd));
68
+ if (matched) {
69
+ debug('find app/agent worker process: %o', item);
70
+ }
71
+ return matched;
72
+ });
73
+ pids = processList.map(x => x.pid);
74
+ if (pids.length) {
75
+ this.log('got worker/agent pids %j that is not killed by master', pids);
76
+ this.killProcesses(pids);
77
+ }
78
+ this.log('stopped');
79
+ }
80
+ async findNodeProcesses(filter) {
81
+ return findNodeProcess(filter);
82
+ }
83
+ killProcesses(pids, signal = 'SIGTERM') {
84
+ kill(pids, signal);
85
+ }
86
+ }
87
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9zdG9wLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMxQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQWUsSUFBSSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTdFLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0FBRXZELE1BQU0sU0FBUyxHQUFHO0lBQ2hCLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxjQUFjO0lBQ2xFLDBEQUEwRDtJQUMxRCxxREFBcUQ7SUFDckQsYUFBYSxFQUFFLHdFQUF3RTtJQUN2Riw0REFBNEQ7SUFDNUQsdURBQXVEO0lBQ3ZELGVBQWUsRUFBRSwwRUFBMEU7Q0FDNUYsQ0FBQztBQUVGLE1BQU0sQ0FBQyxPQUFPLE9BQU8sSUFBNEIsU0FBUSxXQUFjO0lBQ3JFLE1BQU0sQ0FBVSxXQUFXLEdBQUcsYUFBYSxDQUFDO0lBRTVDLE1BQU0sQ0FBVSxRQUFRLEdBQUc7UUFDekIscUNBQXFDO0tBQ3RDLENBQUM7SUFFRixNQUFNLENBQVUsSUFBSSxHQUFHO1FBQ3JCLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDO1lBQ25CLFdBQVcsRUFBRSwwQkFBMEI7WUFDdkMsUUFBUSxFQUFFLEtBQUs7U0FDaEIsQ0FBQztLQUNILENBQUM7SUFFRixNQUFNLENBQVUsS0FBSyxHQUFHO1FBQ3RCLEtBQUssRUFBRSxLQUFL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
@@ -0,0 +1,10 @@
1
+ export declare const isWindows: boolean;
2
+ export interface NodeProcess {
3
+ pid: number;
4
+ cmd: string;
5
+ }
6
+ export type FilterFunction = (item: NodeProcess) => boolean;
7
+ export declare function findNodeProcess(filterFn?: FilterFunction): Promise<NodeProcess[]>;
8
+ export declare function kill(pids: number[], signal?: string | number): void;
9
+ export declare function getSourceDirname(): string;
10
+ export declare function getSourceFilename(filename: string): string;
@@ -0,0 +1,51 @@
1
+ import { runScript } from 'runscript';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ export const isWindows = process.platform === 'win32';
5
+ const REGEX = isWindows ? /^(.*)\s+(\d+)\s*$/ : /^\s*(\d+)\s+(.*)/;
6
+ export async function findNodeProcess(filterFn) {
7
+ const command = isWindows ?
8
+ 'wmic Path win32_process Where "Name = \'node.exe\'" Get CommandLine,ProcessId' :
9
+ // command, cmd are alias of args, not POSIX standard, so we use args
10
+ 'ps -wweo "pid,args"';
11
+ const stdio = await runScript(command, { stdio: 'pipe' });
12
+ const processList = stdio.stdout.toString().split('\n')
13
+ .reduce((arr, line) => {
14
+ if (!!line && !line.includes('/bin/sh') && line.includes('node')) {
15
+ const m = line.match(REGEX);
16
+ if (m) {
17
+ const item = isWindows ? { pid: parseInt(m[2]), cmd: m[1] } : { pid: parseInt(m[1]), cmd: m[2] };
18
+ if (filterFn?.(item)) {
19
+ arr.push(item);
20
+ }
21
+ }
22
+ }
23
+ return arr;
24
+ }, []);
25
+ return processList;
26
+ }
27
+ export function kill(pids, signal) {
28
+ pids.forEach(pid => {
29
+ try {
30
+ process.kill(pid, signal);
31
+ }
32
+ catch (err) {
33
+ if (err.code !== 'ESRCH') {
34
+ throw err;
35
+ }
36
+ }
37
+ });
38
+ }
39
+ export function getSourceDirname() {
40
+ if (typeof __dirname === 'string') {
41
+ return __dirname;
42
+ }
43
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
44
+ // @ts-ignore
45
+ const __filename = fileURLToPath(import.meta.url);
46
+ return path.dirname(__filename);
47
+ }
48
+ export function getSourceFilename(filename) {
49
+ return path.join(getSourceDirname(), filename);
50
+ }
51
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlbHBlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3RDLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUM3QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRXpDLE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sQ0FBQztBQUV0RCxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQztBQVNuRSxNQUFNLENBQUMsS0FBSyxVQUFVLGVBQWUsQ0FBQyxRQUF5QjtJQUM3RCxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsQ0FBQztRQUN6QiwrRUFBK0UsQ0FBQyxDQUFDO1FBQ2pGLHFFQUFxRTtRQUNyRSxxQkFBcUIsQ0FBQztJQUN4QixNQUFNLEtBQUssR0FBRyxNQUFNLFNBQVMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUMxRCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsTUFBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7U0FDckQsTUFBTSxDQUFnQixDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRTtRQUNyQyxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUNqRSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ04sTUFBTSxJQUFJLEdBQWdCLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDOUcsSUFBSSxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNyQixHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNqQixDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNQLE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUM7QUFFRCxNQUFNLFVBQVUsSUFBSSxDQUFDLElBQWMsRUFBRSxNQUF3QjtJQUMzRCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1FBQ2pCLElBQUksQ0FBQztZQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzVCLENBQUM7UUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO1lBQ2xCLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUUsQ0FBQztnQkFDekIsTUFBTSxHQUFHLENBQUM7WUFDWixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELE1BQU0sVUFBVSxnQkFBZ0I7SUFDOUIsSUFBSSxPQUFPLFNBQVMsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNsQyxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsNkRBQTZEO0lBQzdELGFBQWE7SUFDYixNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNsRCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDbEMsQ0FBQztBQUVELE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxRQUFnQjtJQUNoRCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNqRCxDQUFDIn0=
@@ -0,0 +1,3 @@
1
+ import Start from './commands/start.js';
2
+ export * from './baseCommand.js';
3
+ export { Start, Start as StartCommand, };