Commit def0883

Anton Golub <antongolub@antongolub.com>
2024-03-27 00:06:06
feat: export kill helper (#744)
* feat: export `kill` helper from core * test: check index exports
1 parent fac8630
src/core.ts
@@ -67,6 +67,7 @@ export interface Options {
   spawn: typeof spawn
   spawnSync: typeof spawnSync
   log: typeof log
+  kill: typeof kill
 }
 
 const storage = new AsyncLocalStorage<Options>()
@@ -95,6 +96,7 @@ export const defaults: Options = {
   spawn,
   spawnSync,
   log,
+  kill,
 }
 const isWin = process.platform == 'win32'
 try {
@@ -173,13 +175,6 @@ export const $: Shell & Options = new Proxy<Shell & Options>(
   }
 )
 
-function substitute(arg: ProcessPromise | any) {
-  if (arg?.stdout) {
-    return arg.stdout.replace(/\n$/, '')
-  }
-  return `${arg}`
-}
-
 type Resolve = (out: ProcessOutput) => void
 type IO = StdioPipe | StdioNull
 
@@ -412,15 +407,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
       throw new Error('Trying to kill a process without creating one.')
     if (!this.child.pid) throw new Error('The process pid is undefined.')
 
-    let children = await ps.tree({ pid: this.child.pid, recursive: true })
-    for (const p of children) {
-      try {
-        process.kill(+p.pid, signal)
-      } catch (e) {}
-    }
-    try {
-      process.kill(-this.child.pid, signal)
-    } catch (e) {}
+    return $.kill(this.child.pid, signal)
   }
 
   stdio(stdin: IO, stdout: IO = 'pipe', stderr: IO = 'pipe'): ProcessPromise {
@@ -573,6 +560,18 @@ export function cd(dir: string | ProcessOutput) {
   $[processCwd] = process.cwd()
 }
 
+export async function kill(pid: number, signal?: string) {
+  let children = await ps.tree({ pid, recursive: true })
+  for (const p of children) {
+    try {
+      process.kill(+p.pid, signal)
+    } catch (e) {}
+  }
+  try {
+    process.kill(-pid, signal)
+  } catch (e) {}
+}
+
 export type LogEntry =
   | {
       kind: 'cmd'
src/util.ts
@@ -12,7 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import { promisify } from 'node:util'
 import { chalk } from './vendor.js'
 
 export function noop() {}
test/all.test.js
@@ -19,6 +19,7 @@ import './experimental.test.js'
 import './extra.test.js'
 import './global.test.js'
 import './goods.test.js'
+import './index.test.js'
 import './package.test.js'
-import './win32.test.js'
 import './util.test.js'
+import './win32.test.js'
test/index.test.js
@@ -0,0 +1,98 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import assert from 'node:assert'
+import { describe, test } from 'node:test'
+import {
+  nothrow,
+  quiet,
+  $,
+  log,
+  cd,
+  kill,
+  ProcessOutput,
+  ProcessPromise,
+  defaults,
+  minimist,
+  chalk,
+  fs,
+  which,
+  YAML,
+  ssh,
+  ps,
+  quote,
+  quotePowerShell,
+  within,
+  argv,
+  os,
+  updateArgv,
+  globby,
+  glob,
+  sleep,
+  fetch,
+  echo,
+  question,
+  stdin,
+  retry,
+  expBackoff,
+  spinner,
+  path,
+} from '../build/index.js'
+
+describe('index', () => {
+  test('has proper exports', () => {
+    // index
+    assert(nothrow)
+    assert(quiet)
+
+    // core
+    assert($)
+    assert(ProcessOutput)
+    assert(ProcessPromise)
+    assert(cd)
+    assert(log)
+    assert(kill)
+    assert(defaults)
+    assert(within)
+
+    // goods
+    assert(argv)
+    assert(os)
+    assert(updateArgv)
+    assert(globby)
+    assert(glob)
+    assert(sleep)
+    assert(fetch)
+    assert(echo)
+    assert(question)
+    assert(stdin)
+    assert(retry)
+    assert(expBackoff)
+    assert(spinner)
+    assert(path)
+
+    // vendor
+    assert(minimist)
+    assert(chalk)
+    assert(fs)
+    assert(which)
+    assert(YAML)
+    assert(ssh)
+    assert(ps)
+
+    // utils
+    assert(quote)
+    assert(quotePowerShell)
+  })
+})