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.
Files changed (3) hide show
  1. package/index.d.mts +1 -0
  2. package/index.mjs +164 -0
  3. 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
+ }