spawn.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import crossSpawn from 'cross-spawn'
  2. import logger from './logger'
  3. const log = logger('app:spawn')
  4. const warn = logger('app:spawn', 'red')
  5. /*
  6. Returns pid, takes onClose
  7. */
  8. export const spawn = (
  9. cmd: string,
  10. params: string[],
  11. cwd: string,
  12. onClose: (code: number) => void
  13. ): number => {
  14. log(`Running "${cmd} ${params.join(' ')}"`)
  15. log()
  16. // TODO: move to execa?
  17. const runner = crossSpawn(cmd, params, {
  18. stdio: 'inherit',
  19. cwd,
  20. env: process.env
  21. })
  22. runner.on('close', code => {
  23. log()
  24. if (code) {
  25. // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
  26. log(`Command "${cmd}" failed with exit code: ${code}`)
  27. }
  28. onClose?.(code)
  29. })
  30. return runner.pid
  31. }
  32. /*
  33. Returns nothing, takes onFail
  34. */
  35. export const spawnSync = (
  36. cmd: string,
  37. params: string[],
  38. cwd: string,
  39. onFail?: () => void
  40. ): void => {
  41. log(`[sync] Running "${cmd} ${params.join(' ')}"`)
  42. log()
  43. const runner = crossSpawn.sync(cmd, params, {
  44. stdio: 'inherit',
  45. cwd
  46. })
  47. // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
  48. if (runner.status || runner.error) {
  49. warn()
  50. // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
  51. warn(`⚠️ Command "${cmd}" failed with exit code: ${runner.status}`)
  52. if (runner.status === null) {
  53. warn(`⚠️ Please globally install "${cmd}"`)
  54. }
  55. onFail?.()
  56. process.exit(1)
  57. }
  58. }