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'));