kill-me-now 0.0.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.
- package/index.d.mts +1 -0
- package/index.mjs +164 -0
- package/package.json +30 -0
package/index.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function killMeNow (path: string, process?: number, command?: string): Promise<void>
|
package/index.mjs
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import debug from 'debug'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
getLsofArray
|
|
7
|
+
} from '@sequencemedia/lsof'
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
env: {
|
|
11
|
+
DEBUG = 'kill-me-now,kill-me-now:error'
|
|
12
|
+
}
|
|
13
|
+
} = process
|
|
14
|
+
|
|
15
|
+
if (DEBUG) debug.enable(DEBUG)
|
|
16
|
+
|
|
17
|
+
const log = debug('kill-me-now')
|
|
18
|
+
const info = debug('kill-me-now:info')
|
|
19
|
+
const error = debug('kill-me-now:error')
|
|
20
|
+
|
|
21
|
+
log('`kill-me-now` is awake')
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {string} filePath
|
|
25
|
+
* @returns {(openFile: Record<string, string>) => boolean}
|
|
26
|
+
*/
|
|
27
|
+
function getHasOpenFiles (filePath) {
|
|
28
|
+
info('getHasOpenFiles')
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {Record<string, string>} openFile
|
|
32
|
+
* @returns {boolean}
|
|
33
|
+
*/
|
|
34
|
+
function hasFilePath ({ 'FILE PATH': FILEPATH }) {
|
|
35
|
+
info('hasFilePath')
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
FILEPATH.startsWith(filePath)
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {Array<Record<string, string>>} openFiles
|
|
44
|
+
* @returns {boolean}
|
|
45
|
+
*/
|
|
46
|
+
return function hasOpenFiles (openFiles) {
|
|
47
|
+
info('hasOpenFiles')
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
openFiles.some(hasFilePath)
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {string} filePath
|
|
57
|
+
* @returns {(openFile: Record<string, string>) => boolean}
|
|
58
|
+
*/
|
|
59
|
+
function getFilterForFilePath (filePath) {
|
|
60
|
+
info('getFilterForFilePath')
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @param {Record<string, string>} openFile
|
|
64
|
+
* @returns {boolean}
|
|
65
|
+
*/
|
|
66
|
+
return function filterForFilePath ({ 'FILE PATH': FILEPATH }) {
|
|
67
|
+
info('filterForFilePath')
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
FILEPATH.startsWith(filePath)
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {number} process
|
|
77
|
+
* @returns {(openFile: Record<string, string>) => boolean}
|
|
78
|
+
*/
|
|
79
|
+
function getFilterForProcess (process) {
|
|
80
|
+
info('getFilterForProcess')
|
|
81
|
+
|
|
82
|
+
if (process) {
|
|
83
|
+
return function filterForProcess ({ PROCESS }) {
|
|
84
|
+
info('filterForProcess')
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
PROCESS !== process
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return function filter () {
|
|
93
|
+
return true
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @param {string} command
|
|
99
|
+
* @returns {(openFile: Record<string, string>) => boolean}
|
|
100
|
+
*/
|
|
101
|
+
function getFilterForCommand (command) {
|
|
102
|
+
info('getFilterForCommand')
|
|
103
|
+
|
|
104
|
+
if (command) {
|
|
105
|
+
return function filterForCommand ({ COMMAND }) {
|
|
106
|
+
info('filterForCommand')
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
COMMAND === command
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return function filter () {
|
|
115
|
+
return true
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @param {Record<string, string>} openFile
|
|
121
|
+
* @returns {void}
|
|
122
|
+
*/
|
|
123
|
+
function forEach ({ PROCESS }) {
|
|
124
|
+
info('forEach')
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
log(`Killing process ${PROCESS} ...`)
|
|
128
|
+
|
|
129
|
+
process.kill(PROCESS)
|
|
130
|
+
|
|
131
|
+
log(`Killing process ${PROCESS} succeeded.`)
|
|
132
|
+
} catch (e) {
|
|
133
|
+
const {
|
|
134
|
+
code
|
|
135
|
+
} = e
|
|
136
|
+
|
|
137
|
+
if (code !== 'ESRCH') error(e)
|
|
138
|
+
|
|
139
|
+
error(`Killing process ${PROCESS} failed.`)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @param {string} filePath
|
|
145
|
+
* @param {number} [process] Process ID
|
|
146
|
+
* @param {string} [command] Command
|
|
147
|
+
* @returns {Promise<void>}
|
|
148
|
+
*/
|
|
149
|
+
export default async function killMeNow (filePath, process, command) {
|
|
150
|
+
const lsof = await getLsofArray()
|
|
151
|
+
const hasOpenFiles = getHasOpenFiles(filePath)
|
|
152
|
+
|
|
153
|
+
if (lsof.some(hasOpenFiles)) {
|
|
154
|
+
const forFilePath = getFilterForFilePath(filePath)
|
|
155
|
+
const forProcess = getFilterForProcess(process)
|
|
156
|
+
const forCommand = getFilterForCommand(command)
|
|
157
|
+
|
|
158
|
+
lsof.flat()
|
|
159
|
+
.filter(forFilePath)
|
|
160
|
+
.filter(forProcess)
|
|
161
|
+
.filter(forCommand)
|
|
162
|
+
.forEach(forEach)
|
|
163
|
+
}
|
|
164
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kill-me-now",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"main": "./index.mjs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Jonathan Perry for Sequence Media Limited",
|
|
8
|
+
"email": "sequencemedia@sequencemedia.net",
|
|
9
|
+
"url": "https://sequencemedia.net"
|
|
10
|
+
},
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git://github.com/sequencemedia/kill-me-now.git"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"lint": "eslint .",
|
|
18
|
+
"lint:fix": "npm run lint -- --fix"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@sequencemedia/eslint-config-standard": "^0.2.52",
|
|
22
|
+
"@sequencemedia/eslint-config-typescript": "^0.1.82",
|
|
23
|
+
"@types/node": "^22.15.3",
|
|
24
|
+
"eslint": "^9.26.0",
|
|
25
|
+
"globals": "^16.0.0"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@sequencemedia/lsof": "^0.0.2"
|
|
29
|
+
}
|
|
30
|
+
}
|