UNPKG

1.92 kBPlain TextView Raw
1import execa = require('execa')
2import { dimGrey, grey } from '../colors'
3
4export interface ExecaOptions extends execa.Options {
5 /**
6 * If true - it will reject a promise with an error and NOT do `process.exit`
7 */
8 noProcessExit?: boolean
9}
10
11export async function proxyCommand(
12 cmd: string,
13 args: string[] = [],
14 opt: ExecaOptions = {},
15): Promise<void> {
16 const processArgs = process.argv.slice(2)
17
18 await execWithArgs(cmd, [...args, ...processArgs], {
19 ...opt,
20 })
21}
22
23export async function execCommand(cmd: string, opt: ExecaOptions = {}): Promise<void> {
24 logExec(cmd, [], opt)
25
26 await execa
27 .command(cmd, {
28 stdio: 'inherit',
29 preferLocal: true,
30 ...opt,
31 })
32 .catch(err => handleError(err, cmd, opt))
33}
34
35export async function execWithArgs(
36 cmd: string,
37 args: string[] = [],
38 opt: ExecaOptions = {},
39): Promise<void> {
40 logExec(cmd, args, opt)
41
42 await execa(cmd, args, {
43 stdio: 'inherit',
44 preferLocal: true,
45 ...opt,
46 }).catch(err => handleError(err, cmd, opt))
47}
48
49export async function execShell(cmd: string, opt: ExecaOptions = {}): Promise<void> {
50 await execCommand(cmd, {
51 shell: true,
52 ...opt,
53 })
54}
55
56function handleError(err: execa.ExecaError, cmd: string, opt: ExecaOptions = {}): void {
57 if (opt.noProcessExit) {
58 throw err || new Error(`execCommand failed: ${cmd}`)
59 }
60
61 if (err) {
62 if (err.originalMessage) {
63 console.log(dimGrey(err.originalMessage))
64 } else if (err.shortMessage) {
65 console.log(dimGrey(err.shortMessage))
66 } else {
67 console.error(err)
68 }
69
70 if (err.exitCode) {
71 process.exit(err.exitCode)
72 }
73 }
74
75 process.exit(1)
76}
77
78export function logExec(cmd: string, args: string[] = [], opt: ExecaOptions = {}): void {
79 const cmdline = [
80 ...Object.entries(opt.env || {}).map(([k, v]) => [k, v].join('=')),
81 cmd,
82 ...args,
83 ].join(' ')
84
85 console.log(grey(cmdline))
86}