From 4de9fad26981bf4f69d103936f905eca9293f712 Mon Sep 17 00:00:00 2001 From: popomore Date: Wed, 11 Oct 2017 16:03:35 +0800 Subject: [PATCH 1/6] refactor: modify the directory of logDir - export this.child - support customize stdout and stderr --- lib/cmd/start.js | 73 ++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/lib/cmd/start.js b/lib/cmd/start.js index 783d304..57ced69 100644 --- a/lib/cmd/start.js +++ b/lib/cmd/start.js @@ -44,6 +44,14 @@ class StartCommand extends Command { description: 'whether run at background daemon mode', type: 'boolean', }, + stdout: { + description: 'A file that stdout redirect to', + type: 'string', + }, + stderr: { + description: 'A file that stderr redirect to', + type: 'string', + }, }; } @@ -53,6 +61,8 @@ class StartCommand extends Command { * run(context) { const argv = Object.assign({}, context.argv); + const HOME = homedir(); + const logDir = path.join(HOME, 'logs'); // egg-script start // egg-script start ./server @@ -68,28 +78,21 @@ class StartCommand extends Command { baseDir, }); - const env = context.env; - env.PWD = baseDir; - env.HOME = homedir(); - env.NODE_ENV = 'production'; - - // cli argv -> process.env.EGG_SERVER_ENV -> `undefined` then egg will use `prod` - if (argv.env) { - // if undefined, should not pass key due to `spwan`, https://github.com/nodejs/node/blob/master/lib/child_process.js#L470 - env.EGG_SERVER_ENV = argv.env; - argv.env = undefined; - } - const pkgInfo = require(path.join(baseDir, 'package.json')); - const logDir = path.join(env.HOME, 'logs', pkgInfo.name); - argv.title = argv.title || `egg-server-${pkgInfo.name}`; + argv.stdout = argv.stdout || path.join(logDir, 'master-stdout.log'); + argv.stderr = argv.stderr || path.join(logDir, 'master-stderr.log'); + + const env = context.env; + env.HOME = HOME; + env.NODE_ENV = 'production'; + // adjust env for win - let envPath = env.PATH || env.Path; + const envPath = env.PATH || env.Path; if (envPath) { // for nodeinstall - envPath = path.join(baseDir, 'node_modules/.bin') + path.delimiter + envPath; + env.PATH = path.join(baseDir, 'node_modules/.bin') + path.delimiter + envPath; } // for alinode @@ -97,12 +100,20 @@ class StartCommand extends Command { env.NODE_LOG_DIR = env.NODE_LOG_DIR || path.join(logDir, 'alinode'); yield mkdirp(env.NODE_LOG_DIR); + // cli argv -> process.env.EGG_SERVER_ENV -> `undefined` then egg will use `prod` + if (argv.env) { + // if undefined, should not pass key due to `spwan`, https://github.com/nodejs/node/blob/master/lib/child_process.js#L470 + env.EGG_SERVER_ENV = argv.env; + argv.env = undefined; + } + // remove unused properties, alias had been remove by `removeAlias` argv._ = undefined; argv.$0 = undefined; argv.daemon = undefined; const options = { + cwd: baseDir, execArgv: context.execArgv, env, stdio: 'inherit', @@ -117,11 +128,11 @@ class StartCommand extends Command { // whether run in the background. if (isDaemon) { this.logger.info(`save log file to ${logDir}`); - const { stdout, stderr } = yield getRotatelog(logDir); + const [ stdout, stderr ] = yield [ getRotatelog(argv.stdout), getRotatelog(argv.stderr) ]; options.stdio = [ 'ignore', stdout, stderr, 'ipc' ]; options.detached = true; - const child = spawn('node', eggArgs, options); + const child = this.child = spawn('node', eggArgs, options); child.on('message', msg => { if (msg && msg.action === 'egg-ready') { this.logger.info(`egg started on ${msg.data.address}`); @@ -137,30 +148,18 @@ class StartCommand extends Command { } } -function* getRotatelog(logDir) { - const stdoutPath = path.join(logDir, 'master-stdout.log'); - const stderrPath = path.join(logDir, 'master-stderr.log'); - - // format style: .20150602.193100 - const timestamp = moment().format('.YYYYMMDD.HHmmss'); - - yield mkdirp(logDir); +function* getRotatelog(logfile) { + yield mkdirp(path.dirname(logfile)); /* istanbul ignore else */ - if (yield fs.exists(stdoutPath)) { + if (yield fs.exists(logfile)) { + // format style: .20150602.193100 + const timestamp = moment().format('.YYYYMMDD.HHmmss'); // Note: rename last log to next start time, not when last log file created - yield fs.rename(stdoutPath, stdoutPath + timestamp); - } - - /* istanbul ignore else */ - if (yield fs.exists(stderrPath)) { - yield fs.rename(stderrPath, stderrPath + timestamp); + yield fs.rename(logfile, logfile + timestamp); } - return yield { - stdout: fs.open(stdoutPath, 'a'), - stderr: fs.open(stderrPath, 'a'), - }; + return yield fs.open(logfile, 'a'); } module.exports = StartCommand; From 597c4406e4928753888c1237b7f73a8af5bec3a4 Mon Sep 17 00:00:00 2001 From: popomore Date: Wed, 11 Oct 2017 17:01:04 +0800 Subject: [PATCH 2/6] f --- lib/cmd/start.js | 1 - test/fixtures/example/app/router.js | 4 +++ test/start.test.js | 40 +++++++++++++++++++++++++++-- test/stop.test.js | 2 +- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/cmd/start.js b/lib/cmd/start.js index 57ced69..398fccf 100644 --- a/lib/cmd/start.js +++ b/lib/cmd/start.js @@ -151,7 +151,6 @@ class StartCommand extends Command { function* getRotatelog(logfile) { yield mkdirp(path.dirname(logfile)); - /* istanbul ignore else */ if (yield fs.exists(logfile)) { // format style: .20150602.193100 const timestamp = moment().format('.YYYYMMDD.HHmmss'); diff --git a/test/fixtures/example/app/router.js b/test/fixtures/example/app/router.js index 425da8a..cd29c09 100644 --- a/test/fixtures/example/app/router.js +++ b/test/fixtures/example/app/router.js @@ -8,4 +8,8 @@ module.exports = app => { app.get('/env', function* () { this.body = app.config.env + ', ' + app.config.pre; }); + + app.get('/path', function* () { + this.body = process.env.PATH; + }); }; diff --git a/test/start.test.js b/test/start.test.js index b07fb9b..8d77b9e 100644 --- a/test/start.test.js +++ b/test/start.test.js @@ -16,7 +16,7 @@ describe('test/start.test.js', () => { const eggBin = require.resolve('../bin/egg-scripts.js'); const fixturePath = path.join(__dirname, 'fixtures/example'); const homePath = homedir(); - const logDir = path.join(homePath, 'logs/example'); + const logDir = path.join(homePath, 'logs'); const waitTime = '10s'; afterEach(() => mm.restore); @@ -262,8 +262,43 @@ describe('test/start.test.js', () => { assert(app.stdout.includes('## EGG_SERVER_ENV is not pass')); assert(app.stdout.includes('## CUSTOM_ENV: pre')); assert(app.stdout.match(/custom-framework started on http:\/\/127\.0\.0\.1:7001/)); - const result = yield httpclient.request('http://127.0.0.1:7001/env'); + let result = yield httpclient.request('http://127.0.0.1:7001/env'); assert(result.data.toString() === 'pre, true'); + result = yield httpclient.request('http://127.0.0.1:7001/path'); + assert(result.data.toString().match(new RegExp(`^${fixturePath}/node_modules/.bin:`))); + }); + }); + + describe('--stdout --stderr', () => { + let app; + + before(function* () { + yield utils.cleanup(fixturePath); + yield rimraf(logDir); + yield mkdirp(logDir); + }); + + after(function* () { + app.proc.kill('SIGTERM'); + yield utils.cleanup(fixturePath); + yield rimraf(path.join(fixturePath, 'stdout.log')); + yield rimraf(path.join(fixturePath, 'stderr.log')); + }); + + it('should start', function* () { + const stdout = path.join(fixturePath, 'stdout.log'); + const stderr = path.join(fixturePath, 'stderr.log'); + app = coffee.fork(eggBin, [ 'start', '--workers=1', '--daemon', `--stdout=${stdout}`, `--stderr=${stderr}`, fixturePath ]); + // app.debug(); + app.expect('code', 0); + + yield sleep(waitTime); + + let content = yield fs.readFile(stdout, 'utf-8'); + assert(content.match(/custom-framework started on http:\/\/127\.0\.0\.1:7001/)); + + content = yield fs.readFile(stderr, 'utf-8'); + assert(content === ''); }); }); @@ -337,4 +372,5 @@ describe('test/start.test.js', () => { assert(result.data.toString() === 'hi, egg'); }); }); + }); diff --git a/test/stop.test.js b/test/stop.test.js index 22f0470..83c7db2 100644 --- a/test/stop.test.js +++ b/test/stop.test.js @@ -14,7 +14,7 @@ describe('test/stop.test.js', () => { const eggBin = require.resolve('../bin/egg-scripts.js'); const fixturePath = path.join(__dirname, 'fixtures/example'); const homePath = homedir(); - const logDir = path.join(homePath, 'logs/example'); + const logDir = path.join(homePath, 'logs'); const waitTime = '10s'; describe('stop without daemon', () => { From 346fd11e0cb6d5ee4415abb1d293c608a2659787 Mon Sep 17 00:00:00 2001 From: popomore Date: Wed, 11 Oct 2017 17:52:48 +0800 Subject: [PATCH 3/6] f --- lib/cmd/start.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/cmd/start.js b/lib/cmd/start.js index 398fccf..b3b1f38 100644 --- a/lib/cmd/start.js +++ b/lib/cmd/start.js @@ -73,7 +73,7 @@ class StartCommand extends Command { const isDaemon = argv.daemon; - argv.framework = utils.getFrameworkPath({ + argv.framework = this.getFrameworkPath({ framework: argv.framework, baseDir, }); @@ -146,6 +146,11 @@ class StartCommand extends Command { this.helper.spawn('node', eggArgs, options); } } + + getFrameworkPath(params) { + return utils.getFrameworkPath(params); + } + } function* getRotatelog(logfile) { From bab863c15b8628a046579a3ad5bb0b8a0cce660f Mon Sep 17 00:00:00 2001 From: popomore Date: Wed, 11 Oct 2017 18:13:12 +0800 Subject: [PATCH 4/6] f --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 902f861..7b051e9 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "test-local": "egg-bin test", "cov": "egg-bin cov", "lint": "eslint .", - "ci": "egg-bin pkgfiles --check && npm run lint && npm run cov", + "ci": "egg-bin pkgfiles -- --check && npm run lint && npm run cov", "autod": "autod" }, "files": [ @@ -57,4 +57,4 @@ }, "author": "TZ ", "license": "MIT" -} \ No newline at end of file +} From 275421ba8d40a368deb6da479bdfbefa2283a380 Mon Sep 17 00:00:00 2001 From: popomore Date: Thu, 12 Oct 2017 09:56:36 +0800 Subject: [PATCH 5/6] f --- package.json | 5 +++-- test/start.test.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7b051e9..59f1435 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,12 @@ "node": ">=6.0.0" }, "scripts": { - "test": "npm run lint -- --fix && npm run test-local", + "pkgfiles": "egg-bin pkgfiles", + "test": "npm run lint -- --fix && npm run pkgfiles && npm run test-local", "test-local": "egg-bin test", "cov": "egg-bin cov", "lint": "eslint .", - "ci": "egg-bin pkgfiles -- --check && npm run lint && npm run cov", + "ci": "npm run pkgfiles -- --check && npm run lint && npm run cov", "autod": "autod" }, "files": [ diff --git a/test/start.test.js b/test/start.test.js index 8d77b9e..9697993 100644 --- a/test/start.test.js +++ b/test/start.test.js @@ -265,7 +265,7 @@ describe('test/start.test.js', () => { let result = yield httpclient.request('http://127.0.0.1:7001/env'); assert(result.data.toString() === 'pre, true'); result = yield httpclient.request('http://127.0.0.1:7001/path'); - assert(result.data.toString().match(new RegExp(`^${fixturePath}/node_modules/.bin:`))); + assert(result.data.toString().match(new RegExp(`^${fixturePath}/node_modules/.bin${path.delimiter}`))); }); }); From 1a7805b12ed7a2510a1cc28206edf7a8911da30a Mon Sep 17 00:00:00 2001 From: popomore Date: Thu, 12 Oct 2017 11:10:08 +0800 Subject: [PATCH 6/6] f --- lib/cmd/start.js | 4 ++-- test/start.test.js | 10 ++++++++-- test/stop.test.js | 14 ++++++++++++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/cmd/start.js b/lib/cmd/start.js index b3b1f38..0e3ed6a 100644 --- a/lib/cmd/start.js +++ b/lib/cmd/start.js @@ -73,7 +73,7 @@ class StartCommand extends Command { const isDaemon = argv.daemon; - argv.framework = this.getFrameworkPath({ + argv.framework = yield this.getFrameworkPath({ framework: argv.framework, baseDir, }); @@ -147,7 +147,7 @@ class StartCommand extends Command { } } - getFrameworkPath(params) { + * getFrameworkPath(params) { return utils.getFrameworkPath(params); } diff --git a/test/start.test.js b/test/start.test.js index 9697993..a034ac9 100644 --- a/test/start.test.js +++ b/test/start.test.js @@ -7,7 +7,6 @@ const sleep = require('mz-modules/sleep'); const rimraf = require('mz-modules/rimraf'); const mkdirp = require('mz-modules/mkdirp'); const coffee = require('coffee'); -const homedir = require('node-homedir'); const httpclient = require('urllib'); const mm = require('mm'); const utils = require('./utils'); @@ -15,10 +14,17 @@ const utils = require('./utils'); describe('test/start.test.js', () => { const eggBin = require.resolve('../bin/egg-scripts.js'); const fixturePath = path.join(__dirname, 'fixtures/example'); - const homePath = homedir(); + const homePath = path.join(__dirname, 'fixtures/home'); const logDir = path.join(homePath, 'logs'); const waitTime = '10s'; + before(function* () { + yield mkdirp(homePath); + }); + after(function* () { + yield rimraf(homePath); + }); + beforeEach(() => mm(process.env, 'MOCK_HOME_DIR', homePath)); afterEach(() => mm.restore); describe('start without daemon', () => { diff --git a/test/stop.test.js b/test/stop.test.js index 83c7db2..2fd109f 100644 --- a/test/stop.test.js +++ b/test/stop.test.js @@ -5,18 +5,28 @@ const assert = require('assert'); const fs = require('mz/fs'); const sleep = require('mz-modules/sleep'); const rimraf = require('mz-modules/rimraf'); +const mkdirp = require('mz-modules/mkdirp'); const coffee = require('coffee'); -const homedir = require('node-homedir'); const httpclient = require('urllib'); +const mm = require('mm'); const utils = require('./utils'); describe('test/stop.test.js', () => { const eggBin = require.resolve('../bin/egg-scripts.js'); const fixturePath = path.join(__dirname, 'fixtures/example'); - const homePath = homedir(); + const homePath = path.join(__dirname, 'fixtures/home'); const logDir = path.join(homePath, 'logs'); const waitTime = '10s'; + before(function* () { + yield mkdirp(homePath); + }); + after(function* () { + yield rimraf(homePath); + }); + beforeEach(() => mm(process.env, 'MOCK_HOME_DIR', homePath)); + afterEach(() => mm.restore); + describe('stop without daemon', () => { let app; let killer;