diff --git a/index.d.ts b/index.d.ts index f0c431b49a..f787fe7566 100644 --- a/index.d.ts +++ b/index.d.ts @@ -38,6 +38,19 @@ declare namespace execa { */ readonly localDir?: string; + /** + Path to the Node.js executable to use in child processes. + + This can be either an absolute path or a path relative to the `cwd` option. + + Requires `preferLocal` to be `true`. + + For example, this can be used together with [`get-node`](https://github.com/ehmicky/get-node) to run a specific Node.js version in a child process. + + @default process.execPath + */ + readonly execPath?: string; + /** Buffer the output from the spawned process. When set to `false`, you must read the output of `stdout` and `stderr` (or `all` if the `all` option is `true`). Otherwise the returned promise will not be resolved/rejected. diff --git a/index.js b/index.js index f60593f0d7..4e691ef9dd 100644 --- a/index.js +++ b/index.js @@ -14,11 +14,11 @@ const {joinCommand, parseCommand} = require('./lib/command.js'); const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; -const getEnv = ({env: envOption, extendEnv, preferLocal, localDir}) => { +const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { const env = extendEnv ? {...process.env, ...envOption} : envOption; if (preferLocal) { - return npmRunPath.env({env, cwd: localDir}); + return npmRunPath.env({env, cwd: localDir, execPath}); } return env; @@ -37,6 +37,7 @@ const handleArgs = (file, args, options = {}) => { extendEnv: true, preferLocal: false, localDir: options.cwd || process.cwd(), + execPath: process.execPath, encoding: 'utf8', reject: true, cleanup: true, diff --git a/index.test-d.ts b/index.test-d.ts index 938067f7a0..5729538879 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -72,6 +72,7 @@ try { execa('unicorns', {cleanup: false}); execa('unicorns', {preferLocal: false}); execa('unicorns', {localDir: '.'}); +execa('unicorns', {execPath: '/path'}); execa('unicorns', {buffer: false}); execa('unicorns', {input: ''}); execa('unicorns', {input: Buffer.from('')}); diff --git a/package.json b/package.json index be5b7a2c24..499864b459 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@types/node": "^12.0.7", "ava": "^2.1.0", "coveralls": "^3.0.4", + "get-node": "^5.0.0", "is-running": "^2.1.0", "nyc": "^14.1.1", "p-event": "^4.1.0", diff --git a/readme.md b/readme.md index 3e494e7381..69cb1fcf53 100644 --- a/readme.md +++ b/readme.md @@ -308,6 +308,19 @@ Default: `process.cwd()` Preferred path to find locally installed binaries in (use with `preferLocal`). +#### execPath + +Type: `string`
+Default: `process.execPath` (current Node.js executable) + +Path to the Node.js executable to use in child processes. + +This can be either an absolute path or a path relative to the [`cwd` option](#cwd). + +Requires [`preferLocal`](#preferlocal) to be `true`. + +For example, this can be used together with [`get-node`](https://github.com/ehmicky/get-node) to run a specific Node.js version in a child process. + #### buffer Type: `boolean`
diff --git a/test/test.js b/test/test.js index 8105a22a30..4c9459f2c2 100644 --- a/test/test.js +++ b/test/test.js @@ -1,6 +1,7 @@ import path from 'path'; import test from 'ava'; import isRunning from 'is-running'; +import getNode from 'get-node'; import execa from '..'; process.env.PATH = path.join(__dirname, 'fixtures') + path.delimiter + process.env.PATH; @@ -92,6 +93,12 @@ test('localDir option', async t => { t.true(envPaths.some(envPath => envPath.endsWith('.bin'))); }); +test('execPath option', async t => { + const {path: execPath} = await getNode('6.0.0'); + const {stdout} = await execa('node', ['-p', 'process.env.Path || process.env.PATH'], {preferLocal: true, execPath}); + t.true(stdout.includes('6.0.0')); +}); + test('stdin errors are handled', async t => { const child = execa('noop'); child.stdin.emit('error', new Error('test'));