Skip to content

Commit 0984b32

Browse files
fengmk2xudafeng
authored andcommitted
feat: only use server listen to detect port (#13)
use npm scripts instead of Makefile
1 parent 3563702 commit 0984b32

13 files changed

+146
-214
lines changed

.eslintignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
test/fixtures
2+
logs
3+
run
4+
coverage

.eslintrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "eslint-config-egg"
3+
}

.jshintignore

-4
This file was deleted.

.jshintrc

-33
This file was deleted.

.travis.yml

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
sudo: false
12
language: node_js
23
node_js:
3-
- "4"
4-
- "5"
5-
- "6"
6-
sudo: false
7-
script: make travis
8-
after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls"
4+
- '4'
5+
- '6'
6+
- '7'
7+
install:
8+
- npm i npminstall && npminstall
9+
script:
10+
- npm run ci
11+
after_script:
12+
- npminstall codecov && codecov

Makefile

-28
This file was deleted.

README.md

+5-8
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
---
44

55
[![NPM version][npm-image]][npm-url]
6-
[![node version][node-image]][node-url]
76
[![build status][travis-image]][travis-url]
8-
[![Coveralls][coveralls-image]][coveralls-url]
7+
[![Test coverage][codecov-image]][codecov-url]
98
[![npm download][download-image]][download-url]
109

1110
[logo-image]: ./logo.png
@@ -14,22 +13,20 @@
1413
[npm-url]: https://npmjs.org/package/detect-port
1514
[travis-image]: https://img.shields.io/travis/node-modules/detect-port.svg?style=flat-square
1615
[travis-url]: https://travis-ci.org/node-modules/detect-port
17-
[coveralls-image]: https://img.shields.io/coveralls/node-modules/detect-port.svg?style=flat-square
18-
[coveralls-url]: https://coveralls.io/r/node-modules/detect-port?branch=master
19-
[node-image]: https://img.shields.io/badge/node.js-%3E=_4-red.svg?style=flat-square
20-
[node-url]: http://nodejs.org/download/
16+
[codecov-image]: https://codecov.io/gh/node-modules/detect-port/branch/master/graph/badge.svg
17+
[codecov-url]: https://codecov.io/gh/node-modules/detect-port
2118
[download-image]: https://img.shields.io/npm/dm/detect-port.svg?style=flat-square
2219
[download-url]: https://npmjs.org/package/detect-port
2320

2421
> JavaScript Implementation of Port Detector
2522
2623
## Usage
2724

28-
```shell
25+
```bash
2926
$ npm i detect-port --save
3027
```
3128

32-
```javascript
29+
```js
3330
const detect = require('detect-port');
3431

3532
/**

appveyor.yml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
environment:
2+
matrix:
3+
- nodejs_version: '4'
4+
- nodejs_version: '6'
5+
- nodejs_version: '7'
6+
7+
install:
8+
- ps: Install-Product node $env:nodejs_version
9+
- npm i npminstall && node_modules\.bin\npminstall
10+
11+
test_script:
12+
- node --version
13+
- npm --version
14+
- npm run ci
15+
16+
build: off

lib/detect-port.js

+31-65
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,39 @@
11
'use strict';
22

3+
const debug = require('debug')('detect-port');
34
const net = require('net');
45

5-
module.exports = function() {
6-
const args = Array.prototype.slice.call(arguments);
7-
8-
const promise = new Promise((resolve, reject) => {
9-
if (!args.length) {
10-
return reject('wrong number of arguments');
11-
}
12-
13-
const port = parseInt(args[0], 10);
14-
15-
if (isNaN(port)) {
16-
return reject(`wrong type of arguments with: '${args[0]}'`);
17-
}
18-
19-
const loop = port => {
20-
const socket = new net.Socket();
21-
22-
socket.once('error', () => {
23-
socket.removeAllListeners('error');
24-
socket.removeAllListeners('connect');
25-
socket.end();
26-
socket.destroy();
27-
socket.unref();
28-
29-
const server = new net.Server();
30-
31-
server.on('error', () => {
32-
port++;
33-
loop(port);
34-
});
35-
36-
server.listen(port, () => {
37-
server.once('close', () => {
38-
resolve(port);
39-
});
40-
server.close();
41-
});
42-
});
43-
44-
socket.once('connect', () => {
45-
port++;
46-
loop(port);
47-
socket.removeAllListeners('error');
48-
socket.removeAllListeners('connect');
49-
socket.end();
50-
socket.destroy();
51-
socket.unref();
52-
});
6+
module.exports = (port, callback) => {
7+
if (typeof port === 'function') {
8+
callback = port;
9+
port = null;
10+
}
11+
if (typeof callback === 'function') {
12+
return tryListen(port, callback);
13+
}
14+
// promise
15+
return new Promise(resolve => {
16+
tryListen(port, (_, realPort) => {
17+
resolve(realPort);
18+
});
19+
});
20+
};
5321

54-
socket.connect({
55-
port: port
56-
});
57-
};
22+
function tryListen(port, callback) {
23+
port = parseInt(port) || 0;
24+
const server = new net.Server();
5825

59-
loop(port);
26+
server.on('error', err => {
27+
debug('listen %s error: %s', port, err);
28+
port = 0;
29+
server.close();
30+
return tryListen(port, callback);
6031
});
6132

62-
if (args.length > 1) {
63-
const cb = args[1];
64-
65-
promise.then(data => {
66-
process.nextTick(cb.bind(null, null, data));
67-
}, err => {
68-
process.nextTick(cb.bind(null, err));
69-
});
70-
} else {
71-
return promise;
72-
}
73-
};
33+
server.listen({ port }, () => {
34+
port = server.address().port;
35+
server.close();
36+
debug('get free port: %s', port);
37+
callback(null, port);
38+
});
39+
}

package.json

+13-12
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,27 @@
1515
"type": "git",
1616
"url": "git://github.com/node-modules/detect-port.git"
1717
},
18-
"dependencies": {},
18+
"dependencies": {
19+
"debug": "^2.6.0"
20+
},
1921
"devDependencies": {
20-
"co-mocha": "*",
2122
"command-line-test": "^1.0.8",
22-
"istanbul": "*",
23-
"jshint": "*",
24-
"mocha": "2.2.4",
25-
"pre-commit": "^1.1.3",
26-
"should": "~6.0.3"
23+
"egg-bin": "^2.0.0",
24+
"egg-ci": "^1.1.0",
25+
"eslint": "^3.13.1",
26+
"eslint-config-egg": "^3.1.0"
2727
},
2828
"scripts": {
29-
"test": "make test",
30-
"jshint": "make jshint"
29+
"test": "egg-bin test",
30+
"ci": "npm run lint && egg-bin cov",
31+
"lint": "eslint ."
3132
},
32-
"precommit": [
33-
"jshint"
34-
],
3533
"engines": {
3634
"node": ">= 4.2.1"
3735
},
36+
"ci": {
37+
"version": "4, 6, 7"
38+
},
3839
"homepage": "https://github.com/node-modules/detect-port",
3940
"license": "MIT"
4041
}

test/cli.test.js

+20-20
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,43 @@
22

33
const path = require('path');
44
const CliTest = require('command-line-test');
5-
5+
const assert = require('assert');
66
const pkg = require('../package');
77

88
const cliTest = new CliTest();
99
const binFile = path.resolve(pkg.bin[pkg.name]);
1010

1111
describe('command-line tool test', () => {
1212

13-
it('should show version and exit', function *() {
14-
var res = yield cliTest.execFile(binFile, ['-v'], {});
15-
res.stdout.should.equal(pkg.version);
16-
res = yield cliTest.execFile(binFile, ['--version'], {});
17-
res.stdout.should.containEql(pkg.version);
13+
it('should show version and exit', function* () {
14+
let res = yield cliTest.execFile(binFile, [ '-v' ], {});
15+
assert(res.stdout === pkg.version);
16+
res = yield cliTest.execFile(binFile, [ '--version' ], {});
17+
assert(res.stdout.includes(pkg.version));
1818
});
1919

20-
it('should output usage information', function *() {
21-
var res = yield cliTest.execFile(binFile, ['-h'], {});
22-
res.stdout.should.containEql(pkg.description);
23-
res = yield cliTest.execFile(binFile, ['--help'], {});
24-
res.stdout.should.containEql(pkg.description);
25-
res = yield cliTest.execFile(binFile, ['help'], {});
26-
res.stdout.should.containEql(pkg.description);
27-
res = yield cliTest.execFile(binFile, ['xxx'], {});
28-
res.stdout.should.containEql(pkg.description);
20+
it('should output usage information', function* () {
21+
let res = yield cliTest.execFile(binFile, [ '-h' ], {});
22+
assert(res.stdout.includes(pkg.description));
23+
res = yield cliTest.execFile(binFile, [ '--help' ], {});
24+
assert(res.stdout.includes(pkg.description));
25+
res = yield cliTest.execFile(binFile, [ 'help' ], {});
26+
assert(res.stdout.includes(pkg.description));
27+
res = yield cliTest.execFile(binFile, [ 'xxx' ], {});
28+
assert(res.stdout.includes(pkg.description));
2929
});
3030

31-
it('should output available port randomly', function *() {
31+
it('should output available port randomly', function* () {
3232
const res = yield cliTest.execFile(binFile, [], {});
3333
const port = parseInt(res.stdout.split(' ')[3], 10);
34-
port.should.within(9000, 65535);
34+
assert(port >= 9000 && port < 65535);
3535
});
3636

37-
it('should output available port from the given port', function *() {
37+
it('should output available port from the given port', function* () {
3838
const givenPort = 9000;
39-
const res = yield cliTest.execFile(binFile, [givenPort], {});
39+
const res = yield cliTest.execFile(binFile, [ givenPort ], {});
4040
const port = parseInt(res.stdout.split(' ')[3], 10);
41-
port.should.within(givenPort, 65535);
41+
assert(port >= givenPort && port < 65535);
4242
});
4343

4444
});

0 commit comments

Comments
 (0)