diff --git a/package-lock.json b/package-lock.json index db1c8da..70473ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1709,6 +1709,15 @@ "integrity": "sha512-9IdED8wU93ty8gP06ninox+42SBSJHp2IAamsSYMUY76mshRTeUsid/gtbl8ovnOwy8im41ib4cxTiIYMXGKew==", "dev": true }, + "@types/lodash.clone": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.clone/-/lodash.clone-4.5.6.tgz", + "integrity": "sha512-cmwjyhyjvdWfTcuCmyjHzqxNv4yYGnlnpN24crxq8JwIKLtMI+ro0ScUcLSYo6wy8ToLczi6Sln0tqZntLganA==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/marked": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.4.2.tgz", @@ -6766,6 +6775,11 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, + "lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" + }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -9085,8 +9099,7 @@ "spawn-command": { "version": "0.0.2-1", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", - "dev": true + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=" }, "spawn-command-with-kill": { "version": "1.0.2", diff --git a/package.json b/package.json index 3a94e70..717870a 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "@pika/pack": "^0.3.6", "@types/find-up": "^2.1.1", "@types/jest": "^24.0.9", + "@types/lodash.clone": "^4.5.6", "@types/pify": "^3.0.2", "@typescript-eslint/eslint-plugin": "^1.6.0", "@typescript-eslint/parser": "^1.6.0", @@ -100,7 +101,9 @@ }, "dependencies": { "find-up": "^3.0.0", - "pify": "^4.0.1" + "lodash.clone": "^4.5.0", + "pify": "^4.0.1", + "spawn-command": "0.0.2-1" }, "husky": { "hooks": { diff --git a/src/@types/spawn-command.ts b/src/@types/spawn-command.ts new file mode 100644 index 0000000..98c7712 --- /dev/null +++ b/src/@types/spawn-command.ts @@ -0,0 +1,8 @@ +declare module 'spawn-command' { + import { ChildProcess, SpawnOptions } from 'child_process'; + + export default function sc( + command: string, + options?: SpawnOptions + ): ChildProcess; +} diff --git a/src/constants.ts b/src/constants.ts index 2b2d609..9e2a8f7 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,2 +1,4 @@ // Default configuration file name export const FILE_NAME = 'kpo.scripts'; +// Default stdio for spawned commands +export const DEFAULT_STDIO = 'inherit'; diff --git a/src/utils/exec.ts b/src/utils/exec.ts new file mode 100644 index 0000000..3ab615d --- /dev/null +++ b/src/utils/exec.ts @@ -0,0 +1,30 @@ +import sc from 'spawn-command'; +import ensure from './ensure'; +import clone from 'lodash.clone'; +import { ChildProcess, SpawnOptions } from 'child_process'; +import { DEFAULT_STDIO } from '~/constants'; + +export interface IExec { + ps: ChildProcess; + promise: Promise; +} + +export default function exec(command: string, options: SpawnOptions): IExec { + const opts: SpawnOptions = options ? Object.assign({}, options) : {}; + + if (!opts.stdio) opts.stdio = DEFAULT_STDIO; + if (!opts.env) opts.env = clone(process.env); + + const ps = sc(command, opts); + return { + ps, + promise: new Promise((resolve, reject) => { + ps.on('close', (code: number) => { + return code ? reject(Error(`Failed: ${command}`)) : resolve(); + }); + ps.on('error', (err: any) => { + return reject(ensure.error(err)); + }); + }) + }; +}