Skip to content

Commit

Permalink
feat: support $NODE_DEBUG_OPTION (#71)
Browse files Browse the repository at this point in the history
* feat: support $NODE_DEBUG_OPTION

* chore: use debug

* feat: egg-bin debug should detect debugger type

* fix: remove unknown options from yargs new version

* fix: debug at node 6 will not auto exit

* chore: test use promise rather than done

* chore: improve cov
  • Loading branch information
atian25 authored Aug 30, 2017
1 parent 9dad304 commit 1340ce7
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 50 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ All the commands support these specific v8 options:
$ egg-bin [command] --debug --es_staging
```

if `process.env.NODE_DEBUG_OPTION` is provided (WebStorm etc), will use it as debug options.

### dev

Start dev cluster on `local` env, it will start a master, an agent and a worker.
Expand Down
2 changes: 1 addition & 1 deletion lib/cmd/cov.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* istanbul ignore next */
'use strict';

const debug = require('debug')('egg-bin:cov');
const debug = require('debug')('egg-bin');
const path = require('path');
const rimraf = require('mz-modules/rimraf');
const testExclude = require('test-exclude');
Expand Down
15 changes: 14 additions & 1 deletion lib/cmd/debug.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
'use strict';

const semver = require('semver');
const Command = require('./dev');

class DebugCommand extends Command {
constructor(rawArgv) {
super(rawArgv);
const newDebugger = semver.gte(process.version, '8.0.0');
this.usage = 'Usage: egg-bin debug [dir] [options]';
this.options = {
// set default to empty so `--inspect` will always pass to fork
inspect: {
description: 'V8 Inspector port',
default: '',
default() {
/* istanbul ignore next */
return newDebugger ? '' : undefined;
},
},
'inspect-brk': {
description: 'whether break at start',
},

debug: {
description: 'legacy debugger',
default() {
/* istanbul ignore next */
return newDebugger ? undefined : '';
},
},
};
process.env.EGG_DEBUG = 'true';
}
Expand Down
2 changes: 1 addition & 1 deletion lib/cmd/dev.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const debug = require('debug')('egg-bin:dev');
const debug = require('debug')('egg-bin');
const Command = require('../command');
const path = require('path');
const utils = require('egg-utils');
Expand Down
2 changes: 1 addition & 1 deletion lib/cmd/test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const debug = require('debug')('egg-bin:test');
const debug = require('debug')('egg-bin');
const fs = require('fs');
const path = require('path');
const globby = require('globby');
Expand Down
67 changes: 44 additions & 23 deletions lib/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const BaseCommand = require('common-bin');
const changeCase = require('change-case');
const parser = require('yargs-parser');

class Command extends BaseCommand {
/**
Expand All @@ -13,30 +14,19 @@ class Command extends BaseCommand {
const context = super.context;
const argv = context.argv;

// extract execArgv to special item
const execArgvObj = {};
let execArgvObj = {};
let debugPort;
const match = (key, arr) => arr.some(x => x instanceof RegExp ? x.test(key) : x === key); // eslint-disable-line no-confusing-arrow
for (const key of Object.keys(argv)) {
let isMatch = false;

// debug / debug-brk / debug-port / inspect / inspect-brk / inspect-port
if (match(key, [ /^debug.*/, /^inspect.*/ ])) {
isMatch = true;
// extract debug port
if (debugPort === undefined || typeof argv[key] === 'number') {
debugPort = argv[key];
}
} else if (match(key, [ 'es_staging', 'expose_debug_as', /^harmony.*/ ])) {
isMatch = true;
}

if (isMatch) {
execArgvObj[key] = argv[key];
argv[key] = undefined;
// also remove `debugBrk`
argv[changeCase.camelCase(key)] = undefined;
}

// extract from command argv
debugPort = findDebugPort(argv);
execArgvObj = extractExecArgv(argv);

// extract from WebStorm env `$NODE_DEBUG_OPTION`
if (context.env.NODE_DEBUG_OPTION) {
console.log('Use $NODE_DEBUG_OPTION: %s', context.env.NODE_DEBUG_OPTION);
const argvFromEnv = parser(context.env.NODE_DEBUG_OPTION);
debugPort = findDebugPort(argvFromEnv);
Object.assign(execArgvObj, extractExecArgv(argvFromEnv));
}

context.execArgv = this.helper.unparseArgv(execArgvObj);
Expand All @@ -50,4 +40,35 @@ class Command extends BaseCommand {
}
}

function match(key, arr) {
return arr.some(x => x instanceof RegExp ? x.test(key) : x === key); // eslint-disable-line no-confusing-arrow
}

function findDebugPort(argv) {
let debugPort;

for (const key of Object.keys(argv)) {
if (match(key, [ /^debug.*/, /^inspect.*/ ]) && typeof argv[key] === 'number') {
debugPort = argv[key];
}
}
return debugPort;
}

// pick and remove all execArgv from origin `argv`
function extractExecArgv(argv) {
const execArgvObj = {};
for (const key of Object.keys(argv)) {
// debug / debug-brk / debug-port / inspect / inspect-brk / inspect-port
if (match(key, [ /^debug.*/, /^inspect.*/, 'es_staging', 'expose_debug_as', /^harmony.*/ ])) {
execArgvObj[key] = argv[key];
// remove from origin obj
argv[key] = undefined;
// also remove `debugBrk`
argv[changeCase.camelCase(key)] = undefined;
}
}
return execArgvObj;
}

module.exports = Command;
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@
"autod": "^2.9.0",
"change-case": "^3.0.1",
"co-mocha": "^1.2.0",
"common-bin": "^2.4.0",
"debug": "^2.6.8",
"common-bin": "^2.6.1",
"debug": "^3.0.1",
"detect-port": "^1.2.1",
"egg-utils": "^2.2.0",
"globby": "^6.1.0",
"intelli-espower-loader": "^1.0.1",
"mocha": "^3.5.0",
"mz-modules": "^1.0.0",
"mz-modules": "^2.0.0",
"nyc": "^11.1.0",
"power-assert": "^1.4.4",
"semver": "^5.4.1",
"test-exclude": "^4.1.1",
"yargs-parser": "^7.0.0",
"ypkgfiles": "^1.4.0"
},
"devDependencies": {
Expand All @@ -32,8 +34,8 @@
"cross-env": "^3.1.3",
"egg-ci": "^1.8.0",
"enzyme": "^2.0.0",
"eslint": "^4.3.0",
"eslint-config-egg": "^5.0.0",
"eslint": "^4.5.0",
"eslint-config-egg": "^5.1.0",
"jsdom": "^8.0.1",
"mm": "^2.1.0",
"mz": "^2.6.0",
Expand Down
2 changes: 1 addition & 1 deletion test/egg-bin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('test/egg-bin.test.js', () => {
describe('global options', () => {
it('should show version', done => {
coffee.fork(eggBin, [ '--version' ], { cwd })
.debug()
// .debug()
.expect('stdout', /\d+\.\d+\.\d+/)
.expect('code', 0)
.end(done);
Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/demo-app/node_modules/aliyun-egg/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions test/lib/cmd/autod.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,19 @@ const coffee = require('coffee');
const eggBin = require.resolve('../../../bin/egg-bin.js');

describe('test/lib/cmd/autod.test.js', () => {
it('should autod modify', function* () {
const cwd = path.join(__dirname, '../../fixtures/autod-missing');
yield coffee.fork(eggBin, [ 'autod' ], { cwd })
// .debug()
.expect('stdout', /"urllib": "\d+.\d+.\d+/)
.expect('code', 0)
.end();
});

it('should autod check fail', function* () {
const cwd = path.join(__dirname, '../../fixtures/autod-missing');
yield coffee.fork(eggBin, [ 'autod', '--check' ], { cwd })
.debug()
// .debug()
.expect('code', 1)
.expect('stderr', /\[ERROR\] Missing dependencies: \["urllib"\]/)
.end();
Expand All @@ -18,7 +27,7 @@ describe('test/lib/cmd/autod.test.js', () => {
it('should autod check pass', function* () {
const cwd = path.join(__dirname, '../../fixtures/autod-exists');
yield coffee.fork(eggBin, [ 'autod', '--check' ], { cwd })
.debug()
// .debug()
.expect('code', 0)
.end();
});
Expand Down
11 changes: 4 additions & 7 deletions test/lib/cmd/cov.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ describe('test/lib/cmd/cov.test.js', () => {
mm(process.env, 'TESTS', 'test/**/*.test.js');
mm(process.env, 'NYC_CWD', cwd);
const child = coffee.fork(eggBin, [ 'cov' ], { cwd })
.debug()
// .debug()
.beforeScript(path.join(__dirname, 'mock-win32.js'))
.expect('stdout', /should success/)
.expect('stdout', /a\.test\.js/)
Expand Down Expand Up @@ -79,8 +79,7 @@ describe('test/lib/cmd/cov.test.js', () => {
child.expect('stdout', /Statements {3}: 75% \( 3[\/|\\]4 \)/);
}

yield child.expect('code', 0)
.end();
yield child.expect('code', 0).end();
assert(fs.existsSync(path.join(cwd, 'coverage/coverage-final.json')));
assert(fs.existsSync(path.join(cwd, 'coverage/lcov-report/index.html')));
assert(fs.existsSync(path.join(cwd, 'coverage/lcov.info')));
Expand All @@ -101,8 +100,7 @@ describe('test/lib/cmd/cov.test.js', () => {
child.expect('stdout', /Statements {3}: 75% \( 3[\/|\\]4 \)/);
}

yield child.expect('code', 0)
.end();
yield child.expect('code', 0).end();
assert(fs.existsSync(path.join(cwd, 'coverage/coverage-final.json')));
assert(fs.existsSync(path.join(cwd, 'coverage/lcov-report/index.html')));
assert(fs.existsSync(path.join(cwd, 'coverage/lcov.info')));
Expand All @@ -123,8 +121,7 @@ describe('test/lib/cmd/cov.test.js', () => {
child.expect('stdout', /Statements {3}: 75% \( 3[\/|\\]4 \)/);
}

yield child.expect('code', 0)
.end();
yield child.expect('code', 0).end();
assert(fs.existsSync(path.join(cwd, 'coverage/coverage-final.json')));
assert(fs.existsSync(path.join(cwd, 'coverage/lcov-report/index.html')));
assert(fs.existsSync(path.join(cwd, 'coverage/lcov.info')));
Expand Down
25 changes: 17 additions & 8 deletions test/lib/cmd/debug.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('test/lib/cmd/debug.test.js', () => {

it('should startCluster success', () => {
return coffee.fork(eggBin, [ 'debug' ], { cwd })
.debug()
// .debug()
.expect('stderr', /Debugger listening/)
// node 8 missing "chrome-devtools" url
// .expect('stderr', /chrome-devtools:/)
Expand All @@ -22,17 +22,26 @@ describe('test/lib/cmd/debug.test.js', () => {
.end();
});

it('should startCluster with port', done => {
coffee.fork(eggBin, [ 'debug', '--port', '6001' ], { cwd })
it('should startCluster with port', () => {
return coffee.fork(eggBin, [ 'debug', '--port', '6001' ], { cwd })
// .debug()
.expect('stderr', /Debugger listening/)
.expect('stdout', /"port":6001/)
.expect('stdout', /"workers":1/)
.expect('stdout', /"baseDir":".*?demo-app"/)
.expect('stdout', /"framework":".*?aliyun-egg"/)
.expect('stdout', /--inspect/)
.expect('code', 0)
.end(done);
.end();
});

it('should debug with $NODE_DEBUG_OPTION', () => {
const env = Object.assign({}, process.env, { NODE_DEBUG_OPTION: '--inspect=5555' });
return coffee.fork(eggBin, [ 'debug' ], { cwd, env })
// .debug()
.expect('stderr', /Debugger listening.*5555/)
.expect('stdout', /"workers":1/)
.expect('code', 0)
.end();
});

describe('auto detect available port', () => {
Expand All @@ -44,13 +53,13 @@ describe('test/lib/cmd/debug.test.js', () => {

after(() => server.close());

it('should auto detect available port', done => {
coffee.fork(eggBin, [ 'debug' ], { cwd })
it('should auto detect available port', () => {
return coffee.fork(eggBin, [ 'debug' ], { cwd })
// .debug()
.expect('stdout', /,"workers":1/)
.expect('stderr', /\[egg-bin] server port 7001 is in use/)
.expect('code', 0)
.end(done);
.end();
});
});
});

0 comments on commit 1340ce7

Please sign in to comment.