From 90209fa8eaa8ebb8b88eb729d812bf753aed4664 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Thu, 21 Dec 2023 21:51:39 +0100 Subject: [PATCH 01/17] update: unix-kill resolve on exit. add error listener --- .mocharc.yml | 1 + src/lib/killer.ts | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.mocharc.yml b/.mocharc.yml index f8726ea..f945fba 100644 --- a/.mocharc.yml +++ b/.mocharc.yml @@ -1,3 +1,4 @@ timeout: 4000 require: - ts-node/register +full-trace: true diff --git a/src/lib/killer.ts b/src/lib/killer.ts index addcadd..483aaa5 100644 --- a/src/lib/killer.ts +++ b/src/lib/killer.ts @@ -67,7 +67,7 @@ export class Killer { xargs.stdout.pipe(process.stdin); xargs.stderr.on('data', logStderrData('xargs')); - xargs.on('close', (code) => { + xargs.on('exit', (code) => { if (code !== 0) { return reject(); } @@ -75,6 +75,8 @@ export class Killer { resolve(undefined); }); + xargs.on('error', (err) => reject(err)); + function logStderrData(command: string) { return (data: any) => console.error(`${command} - ${data.toString()}`); } From 3330c5a9b2c85373cd74b672e520c03a4096b380 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Fri, 22 Dec 2023 15:57:00 +0100 Subject: [PATCH 02/17] add error listeners to each piped method --- package-lock.json | 137 +++++------------------------------ package.json | 2 + src/bin/kill-port-process.ts | 3 + src/lib/killer.ts | 16 +++- test/bin.spec.ts | 1 + test/killPortProcess.spec.ts | 10 ++- 6 files changed, 45 insertions(+), 124 deletions(-) create mode 100644 test/bin.spec.ts diff --git a/package-lock.json b/package-lock.json index f2507f4..e50e5f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "3.2.1", "license": "ISC", "dependencies": { + "debug": "4.3.4", "get-them-args": "1.3.2", "pid-from-port": "1.1.3" }, @@ -17,16 +18,15 @@ }, "devDependencies": { "@types/chai": "4.3.11", + "@types/debug": "4.1.12", "@types/mocha": "10.0.6", "@types/node": "20.10.5", - "@types/node-fetch": "2.6.6", "@types/pid-from-port": "1.1.2", "@typescript-eslint/eslint-plugin": "6.15.0", "@typescript-eslint/parser": "6.15.0", "chai": "4.3.10", "eslint": "8.56.0", "mocha": "10.2.0", - "node-fetch": "2.7.0", "ts-node": "10.9.2", "typescript": "5.3.3" }, @@ -247,6 +247,15 @@ "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", "dev": true }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -259,6 +268,12 @@ "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", "dev": true }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true + }, "node_modules/@types/node": { "version": "20.10.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", @@ -268,16 +283,6 @@ "undici-types": "~5.26.4" } }, - "node_modules/@types/node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, "node_modules/@types/pid-from-port": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@types/pid-from-port/-/pid-from-port-1.1.2.tgz", @@ -583,12 +588,6 @@ "node": "*" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -791,18 +790,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -829,7 +816,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -872,15 +858,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -1283,20 +1260,6 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1710,27 +1673,6 @@ "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1896,8 +1838,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.3", @@ -1917,26 +1858,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -2389,12 +2310,6 @@ "node": ">=8.0" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, "node_modules/ts-api-utils": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", @@ -2526,22 +2441,6 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index a92f30d..85047fc 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,13 @@ "author": "Daniel Hillmann", "license": "ISC", "dependencies": { + "debug": "4.3.4", "get-them-args": "1.3.2", "pid-from-port": "1.1.3" }, "devDependencies": { "@types/chai": "4.3.11", + "@types/debug": "4.1.12", "@types/mocha": "10.0.6", "@types/node": "20.10.5", "@types/pid-from-port": "1.1.2", diff --git a/src/bin/kill-port-process.ts b/src/bin/kill-port-process.ts index 4fa9085..05d1bc4 100644 --- a/src/bin/kill-port-process.ts +++ b/src/bin/kill-port-process.ts @@ -21,6 +21,9 @@ import { killPortProcess, Options } from '../lib/index'; const flags = parseFlagsFromArgs(args); const options = formatOptions(flags); + console.log('flags::', flags); + console.log('options::', options); + await killPortProcess(ports, options); })(); diff --git a/src/lib/killer.ts b/src/lib/killer.ts index 483aaa5..44b47b5 100644 --- a/src/lib/killer.ts +++ b/src/lib/killer.ts @@ -1,6 +1,7 @@ import { spawn } from 'child_process'; import { platform } from 'os'; import * as pidFromPort from 'pid-from-port'; +import createDebug, { Debugger } from 'debug'; export type Signal = 'SIGTERM' | 'SIGKILL' @@ -9,14 +10,19 @@ type KillOptions = { } export class Killer { - protected ports: number[]; + private readonly ports: number[]; + private readonly debug: Debugger; constructor(ports: number[]) { this.ports = ports; + this.debug = createDebug('kill-port-process'); } public async kill(options: KillOptions) { const killFunc = platform() === 'win32' ? this.win32Kill : this.unixKill; + + this.debug('kill func selected:', killFunc.name); + const promises = this.ports.map((port) => killFunc(port, options.signal)); return Promise.all(promises); @@ -58,24 +64,28 @@ export class Killer { lsof.stdout.pipe(grep.stdin); lsof.stderr.on('data', logStderrData('lsof')); + lsof.on('error', (err) => reject(err)); grep.stdout.pipe(awk.stdin); grep.stderr.on('data', logStderrData('grep')); + grep.on('error', (err) => reject(err)); awk.stdout.pipe(xargs.stdin); awk.stderr.on('data', logStderrData('awk')); + awk.on('error', (err) => reject(err)); xargs.stdout.pipe(process.stdin); xargs.stderr.on('data', logStderrData('xargs')); + xargs.on('error', (err) => reject(err)); + xargs.on('exit', (code) => { if (code !== 0) { - return reject(); + return reject(new Error(`xargs process exited with code ${code}`)); } resolve(undefined); }); - xargs.on('error', (err) => reject(err)); function logStderrData(command: string) { return (data: any) => console.error(`${command} - ${data.toString()}`); diff --git a/test/bin.spec.ts b/test/bin.spec.ts new file mode 100644 index 0000000..70b786d --- /dev/null +++ b/test/bin.spec.ts @@ -0,0 +1 @@ +// TODO diff --git a/test/killPortProcess.spec.ts b/test/killPortProcess.spec.ts index f220453..c421aa9 100644 --- a/test/killPortProcess.spec.ts +++ b/test/killPortProcess.spec.ts @@ -39,8 +39,14 @@ function killProcess(flags: string[] = []) { const child = spawn('node', args); return new Promise((resolve, reject) => { - child.on('close', (code, signal) => resolve({ message: 'closed', code })); - child.on('exit', (code, signal) => resolve({ message: 'closed', code })); + const resolveWithResult = (code: any, signal: any) => resolve({ + message: 'closed', + code, + ...(signal && { signal }) + }); + + child.on('close', resolveWithResult); + child.on('exit', resolveWithResult); child.on('error', (err) => reject(err)); }); From 6f51f748c650efd6106a34aa93acc0dcb2636f03 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Fri, 22 Dec 2023 15:58:01 +0100 Subject: [PATCH 03/17] remove postversion script --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 85047fc..1d79c3f 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,11 @@ "build": "tsc", "eslint": "eslint . --ext .ts", "lint": "npm run eslint", + "git-tags": "git push && git push --tags", "test": "mocha test/*.spec.ts", "pretest": "npm run build", "prepare": "npm run build && npm test", - "preversion": "npm run build && npm test", - "postversion": "git push && git push --tags" + "preversion": "npm run build && npm test" }, "keywords": [ "process", From 00b9714ab08c1434061823afccb58f557073289e Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Fri, 22 Dec 2023 15:58:16 +0100 Subject: [PATCH 04/17] 4.0.0-beta.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e50e5f7..56d0fd0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "kill-port-process", - "version": "3.2.1", + "version": "4.0.0-beta.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "kill-port-process", - "version": "3.2.1", + "version": "4.0.0-beta.0", "license": "ISC", "dependencies": { "debug": "4.3.4", diff --git a/package.json b/package.json index 1d79c3f..4297a8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kill-port-process", - "version": "3.2.1", + "version": "4.0.0-beta.0", "description": "Easily kill hanging processes on ports - on any platform!", "main": "dist/lib/index.js", "bin": { From d8cb22d1088e0be7d33da8ab62a21af1025773d9 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Fri, 22 Dec 2023 15:59:54 +0100 Subject: [PATCH 05/17] remove xargs error listener --- src/lib/killer.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/killer.ts b/src/lib/killer.ts index 44b47b5..27a2c62 100644 --- a/src/lib/killer.ts +++ b/src/lib/killer.ts @@ -76,7 +76,6 @@ export class Killer { xargs.stdout.pipe(process.stdin); xargs.stderr.on('data', logStderrData('xargs')); - xargs.on('error', (err) => reject(err)); xargs.on('exit', (code) => { if (code !== 0) { From b054b60ba6bc7f92e737fdb5ce8e695fadf23401 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Fri, 22 Dec 2023 16:01:11 +0100 Subject: [PATCH 06/17] remove error listeners --- src/lib/killer.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lib/killer.ts b/src/lib/killer.ts index 27a2c62..4242adf 100644 --- a/src/lib/killer.ts +++ b/src/lib/killer.ts @@ -64,15 +64,12 @@ export class Killer { lsof.stdout.pipe(grep.stdin); lsof.stderr.on('data', logStderrData('lsof')); - lsof.on('error', (err) => reject(err)); grep.stdout.pipe(awk.stdin); grep.stderr.on('data', logStderrData('grep')); - grep.on('error', (err) => reject(err)); awk.stdout.pipe(xargs.stdin); awk.stderr.on('data', logStderrData('awk')); - awk.on('error', (err) => reject(err)); xargs.stdout.pipe(process.stdin); xargs.stderr.on('data', logStderrData('xargs')); From 67cf65220a64b7449e6921496febb93f92b99d19 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Fri, 22 Dec 2023 16:08:40 +0100 Subject: [PATCH 07/17] attmept specific error code handlers --- src/lib/killer.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/lib/killer.ts b/src/lib/killer.ts index 4242adf..4793742 100644 --- a/src/lib/killer.ts +++ b/src/lib/killer.ts @@ -28,7 +28,7 @@ export class Killer { return Promise.all(promises); } - private async win32Kill(port: number, signal: Signal) { + private async win32Kill(port: number) { const pid = await pidFromPort(port).catch((error) => console.error('Failed to get pid of port', port, error)); if (!pid) { @@ -75,13 +75,27 @@ export class Killer { xargs.stderr.on('data', logStderrData('xargs')); xargs.on('exit', (code) => { - if (code !== 0) { - return reject(new Error(`xargs process exited with code ${code}`)); + const error = handleErrorCode(code); + if (error) { + reject(error); } resolve(undefined); }); + function handleErrorCode(code: number | null) { + if (!code) { + return null; + } + + // see possible exit codes: https://www.commandlinux.com/man-page/man1/xargs.1.html + switch (code) { + case 1: + return new Error(`xargs process exited with code ${code}`) + case 127: + return new Error('xargs command not found'); + } + } function logStderrData(command: string) { return (data: any) => console.error(`${command} - ${data.toString()}`); From 2a3aa03295e07d4dc2751b3a97991d8b4c309fb4 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Fri, 22 Dec 2023 16:30:26 +0100 Subject: [PATCH 08/17] add mroe node versions --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb837e1..c35c101 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [18.x, 20.x, 21.x] + node-version: [10.x, 12.x, 14.x, 16.x, 18.x, 20.x, 21.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ os: [macos-latest, ubuntu-latest, windows-latest] From 53b7d4ce1cd11ce814ff97dd50734a26e6a2dfba Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Fri, 22 Dec 2023 16:32:12 +0100 Subject: [PATCH 09/17] remove debug --- package-lock.json | 21 +++------------------ package.json | 2 -- src/lib/killer.ts | 5 ----- 3 files changed, 3 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index 56d0fd0..321370d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "4.0.0-beta.0", "license": "ISC", "dependencies": { - "debug": "4.3.4", "get-them-args": "1.3.2", "pid-from-port": "1.1.3" }, @@ -18,7 +17,6 @@ }, "devDependencies": { "@types/chai": "4.3.11", - "@types/debug": "4.1.12", "@types/mocha": "10.0.6", "@types/node": "20.10.5", "@types/pid-from-port": "1.1.2", @@ -247,15 +245,6 @@ "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", "dev": true }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dev": true, - "dependencies": { - "@types/ms": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -268,12 +257,6 @@ "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", "dev": true }, - "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", - "dev": true - }, "node_modules/@types/node": { "version": "20.10.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", @@ -816,6 +799,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1838,7 +1822,8 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/nanoid": { "version": "3.3.3", diff --git a/package.json b/package.json index 4297a8c..5759f91 100644 --- a/package.json +++ b/package.json @@ -28,13 +28,11 @@ "author": "Daniel Hillmann", "license": "ISC", "dependencies": { - "debug": "4.3.4", "get-them-args": "1.3.2", "pid-from-port": "1.1.3" }, "devDependencies": { "@types/chai": "4.3.11", - "@types/debug": "4.1.12", "@types/mocha": "10.0.6", "@types/node": "20.10.5", "@types/pid-from-port": "1.1.2", diff --git a/src/lib/killer.ts b/src/lib/killer.ts index 4793742..a076b92 100644 --- a/src/lib/killer.ts +++ b/src/lib/killer.ts @@ -1,7 +1,6 @@ import { spawn } from 'child_process'; import { platform } from 'os'; import * as pidFromPort from 'pid-from-port'; -import createDebug, { Debugger } from 'debug'; export type Signal = 'SIGTERM' | 'SIGKILL' @@ -11,18 +10,14 @@ type KillOptions = { export class Killer { private readonly ports: number[]; - private readonly debug: Debugger; constructor(ports: number[]) { this.ports = ports; - this.debug = createDebug('kill-port-process'); } public async kill(options: KillOptions) { const killFunc = platform() === 'win32' ? this.win32Kill : this.unixKill; - this.debug('kill func selected:', killFunc.name); - const promises = this.ports.map((port) => killFunc(port, options.signal)); return Promise.all(promises); From ef108cb29e5c70dbb580965e129ed5c5a1528fb5 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Fri, 22 Dec 2023 16:34:56 +0100 Subject: [PATCH 10/17] formatting --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c35c101..02b59b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,10 @@ jobs: matrix: node-version: [10.x, 12.x, 14.x, 16.x, 18.x, 20.x, 21.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - os: [macos-latest, ubuntu-latest, windows-latest] + os: + - macos-latest + - ubuntu-latest + - windows-latest steps: - uses: actions/checkout@v3 From 3e82c9fe1c2859bf99ba2a309a4755e71f0a2fe6 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Fri, 22 Dec 2023 17:00:32 +0100 Subject: [PATCH 11/17] start replacing fetch to increase node versions compatibility --- test/bin.spec.ts | 1 - test/index.spec.ts | 34 +++++++++++++++++++--------------- 2 files changed, 19 insertions(+), 16 deletions(-) delete mode 100644 test/bin.spec.ts diff --git a/test/bin.spec.ts b/test/bin.spec.ts deleted file mode 100644 index 70b786d..0000000 --- a/test/bin.spec.ts +++ /dev/null @@ -1 +0,0 @@ -// TODO diff --git a/test/index.spec.ts b/test/index.spec.ts index 9863d26..02436b4 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -1,4 +1,5 @@ import { expect } from 'chai'; +import * as pidFromPort from 'pid-from-port' import { killPortProcess } from '../src/lib/index'; import { startFakeServer } from './helpers'; @@ -35,34 +36,37 @@ describe('lib/index', () => { }); }); - describe('when called with a single port', () => { + describe.only('when called with a single port', () => { + const port = 1234; + let actualListen: string; let expectedListen: string; - before('start a fake server', (done) => startFakeServer(1234, (data: any) => { + before('start a fake server', (done) => startFakeServer(port, (data: any) => { actualListen = data.toString(); expectedListen = 'Listening on 1234'; done(); })); - let actualKillError: any; - let actualFetchError: any; + let actualError: any; before('kill port, make request', async () => { await killPortProcess(1234) - .catch((reason) => actualKillError = reason); - await fetch(getLocalHost(1234), { method: 'GET' }) - .catch((reason) => actualFetchError = reason); + + try { + await pidFromPort(port) + } catch (error) { + actualError = error; + } }); + it('should actually listen on a server', () => { expect(actualListen).to.be.equal(expectedListen); }); - it('should not throw an error', () => { - expect(actualKillError).to.be.undefined; - }); - it('should be true', () => { - expect(actualFetchError) - .to.be.an.instanceOf(TypeError) - .that.nested.property('cause.code') - .to.be.oneOf(['ECONNREFUSED', 'ECONNRESET']); + + it('should return an error accessing port', () => { + expect(actualError) + .to.be.an.instanceOf(Error) + .with.property('message') + .that.equal(`Couldn't find a process with port \`${port}\``); }); }); From 90daa8fc9437a8c220becf1882050c74fe5aeadb Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Sat, 23 Dec 2023 09:09:38 +0100 Subject: [PATCH 12/17] replace node 'fetch' in tests --- .github/workflows/ci.yml | 1 + test/index.spec.ts | 82 +++++++++++++++++++--------------------- 2 files changed, 40 insertions(+), 43 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 02b59b7..66a62a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,7 @@ jobs: - macos-latest - ubuntu-latest - windows-latest + - steps: - uses: actions/checkout@v3 diff --git a/test/index.spec.ts b/test/index.spec.ts index 02436b4..cd67c40 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -36,7 +36,7 @@ describe('lib/index', () => { }); }); - describe.only('when called with a single port', () => { + describe('when called with a single port', () => { const port = 1234; let actualListen: string; @@ -47,7 +47,7 @@ describe('lib/index', () => { done(); })); - let actualError: any; + let actualError: unknown; before('kill port, make request', async () => { await killPortProcess(1234) @@ -87,39 +87,36 @@ describe('lib/index', () => { done(); })); - let actualKillError: any; - let actualFetchErrorOne: any; - let actualFetchErrorTwo: any; + let actualErrors: string[]; before('kill port, make request', async () => { - await killPortProcess([5678, 6789]) - .catch((reason) => actualKillError = reason); - await Promise.all([ - fetch(getLocalHost(5678), { method: 'GET' }) - .catch((reason) => actualFetchErrorOne = reason), - fetch(getLocalHost(6789), { method: 'GET' }) - .catch((reason) => actualFetchErrorTwo = reason), - ]); + await killPortProcess([5678, 6789]); + + const res = await Promise.allSettled([pidFromPort(5678), pidFromPort(6789)]); + actualErrors = res.reduce((acc, cur) => { + if (cur.status === 'rejected') { + acc.push(cur.reason.message); + } + + return acc; + }, []); }); + it('should actually listen on server one', () => { expect(actualListenOne).to.equal(expectedListenOne); }); it('should actually listen on server two', () => { expect(actualListenTwo).to.equal(expectedListenTwo); }); - it('should not throw an error calling killPortProcess', () => { - expect(actualKillError).to.be.undefined; - }); + it('should throw an error on fetch one when sending a request to the terminated server', () => { - expect(actualFetchErrorOne) - .to.be.an.instanceOf(TypeError) - .that.nested.property('cause.code') - .to.be.oneOf(['ECONNREFUSED', 'ECONNRESET']); - }); - it('should throw an error on fetch two when sending a request to the terminated server', () => { - expect(actualFetchErrorTwo) - .to.be.an.instanceOf(TypeError) - .that.nested.property('cause.code') - .to.be.oneOf(['ECONNREFUSED', 'ECONNRESET']); + const expected = [ + "Couldn't find a process with port `5678`", + "Couldn't find a process with port `6789`", + ]; + + expect(actualErrors) + .to.have.lengthOf(2) + .that.deep.equal(expected); }); }); @@ -138,38 +135,37 @@ describe('lib/index', () => { }); describe('when called with a single port and signal=SIGTERM', () => { + const port = 1234; + let actualListen: string; let expectedListen: string; + before('start a fake server', (done) => startFakeServer(1234, (data: any) => { actualListen = data.toString(); expectedListen = 'Listening on 1234'; done(); })); - let actualKillError: any; - let actualFetchError: any; + let actualPortError: any; before('kill port, make request', async () => { - await killPortProcess(1234, { signal: 'SIGTERM' }) - .catch((reason) => actualKillError = reason); - await fetch(getLocalHost(1234), { method: 'GET' }) - .catch((reason) => actualFetchError = reason); + await killPortProcess(port, { signal: 'SIGTERM' }); + try { + await pidFromPort(port); + } catch (error) { + actualPortError = error; + } }); + it('should actually listen on a server', () => { expect(actualListen).to.be.equal(expectedListen); }); - it('should not throw an error', () => { - expect(actualKillError).to.be.undefined; - }); + it('should be true', () => { - expect(actualFetchError) - .to.be.an.instanceOf(TypeError) - .that.nested.property('cause.code') - .to.be.oneOf(['ECONNREFUSED', 'ECONNRESET']); + expect(actualPortError) + .to.be.an.instanceOf(Error) + .that.property('message') + .that.equal(`Couldn't find a process with port \`${port}\``); }); }); }); }); - -function getLocalHost(port: number | string) { - return `http://localhost:${port}`; -} From 30aaade91222d31f6743a1fbcfc75ee66caf9ae0 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Thu, 28 Dec 2023 09:47:57 +0100 Subject: [PATCH 13/17] Update .github/workflows/ci.yml --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66a62a3..02b59b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,6 @@ jobs: - macos-latest - ubuntu-latest - windows-latest - - steps: - uses: actions/checkout@v3 From 7359370ee62ac35e8b0781db47814f523f8fe702 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Thu, 28 Dec 2023 14:13:21 +0100 Subject: [PATCH 14/17] move link to jsdoc attribute --- src/lib/killer.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/killer.ts b/src/lib/killer.ts index a076b92..5b6bd50 100644 --- a/src/lib/killer.ts +++ b/src/lib/killer.ts @@ -78,12 +78,14 @@ export class Killer { resolve(undefined); }); + /** + * @see https://www.commandlinux.com/man-page/man1/xargs.1.html for possible exit codes + */ function handleErrorCode(code: number | null) { if (!code) { return null; } - // see possible exit codes: https://www.commandlinux.com/man-page/man1/xargs.1.html switch (code) { case 1: return new Error(`xargs process exited with code ${code}`) From 4cb229f53f782d07c44e5cdf3694c9f4125d68a0 Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Thu, 28 Dec 2023 14:29:28 +0100 Subject: [PATCH 15/17] install --- package-lock.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 321370d..33aa8a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,8 +29,7 @@ "typescript": "5.3.3" }, "engines": { - "node": ">=18", - "npm": ">=9" + "node": ">=16" } }, "node_modules/@aashutoshrathi/word-wrap": { From f00bd8c2d301cdcbc1737a458240b0e31f938e9f Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Thu, 28 Dec 2023 14:33:47 +0100 Subject: [PATCH 16/17] README --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 23348fc..6c440c3 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ You can use the CLI calling it with `kill-port `. It takes a single port or a list of ports separated by a space. Valid flags are `-p` and `--port` but are both optional. ```bash +# single port $ kill-port 1234 # or multiple ports, separated by space(s) $ kill-port 1234 2345 @@ -61,6 +62,8 @@ $ kill-port 1234 2345 $ kill-port -p 1234 # or $ kill-port --port 1234 +# with graceful flag +$ kill-port 1234 --graceful ``` #### Flags From 2ee87e9a3608f4d5f5b3509834d8b7142c0e76af Mon Sep 17 00:00:00 2001 From: Daniel Hillmann Date: Thu, 28 Dec 2023 14:34:52 +0100 Subject: [PATCH 17/17] readme --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6c440c3..91f96a6 100644 --- a/README.md +++ b/README.md @@ -51,16 +51,14 @@ npm install kill-port-process -g You can use the CLI calling it with `kill-port `. -It takes a single port or a list of ports separated by a space. Valid flags are `-p` and `--port` but are both optional. - ```bash # single port $ kill-port 1234 -# or multiple ports, separated by space(s) +# multiple ports, separated by space(s) $ kill-port 1234 2345 -# or +# with "-p" flag $ kill-port -p 1234 -# or +# with with "--port" flag $ kill-port --port 1234 # with graceful flag $ kill-port 1234 --graceful @@ -68,7 +66,8 @@ $ kill-port 1234 --graceful #### Flags -* `--graceful` kill the process gracefully. +* `-p` or `--port` (optional): used to specify the port(s) to kill. Takes a single port or a list of ports separated by a space. +* `--graceful` (optional) kill the process gracefully. * **Unix:** Sends a `-15` signal to kill (`SIGTERM`) rather than `-9` (`SIGKILL`) * **Win:** Currently no use