Repository: sindresorhus/execa (js)

Issue:
Default `preferLocal` to `true` when using `$`
The default value for [`preferLocal`](https://github.com/sindresorhus/execa#preferlocal) used to be `true`. We changed it to `false` in #314 because it conflicted with some uncommon setups (#196, #153). IMHO `preferLocal` is still a very helpful option for most users, and it's too bad we cannot enable it by default due to the above.

Now, I am wondering whether the default value should be `true` with the new `$` methods we just introduced? The reasons for this is:
  - It is easier for users with the uncommon setups mentioned above to change the default value thanks to the options binding method: `const $$ = $({ preferLocal: false })`
  - `$()` is more likely than `execa()` to be used in a script with many commands to execute. This increases the chance of at least one of them to be a local binary.

What do you think @sindresorhus and @aaronccasanova?

Pull request:
Make `preferLocal` default to `true` with `$`
Fixes #522.

This makes the `preferLocal` option default to `true` when using `$` or `$.sync`.

cc @aaronccasanova for code review too.

Patch:
diff --git a/index.d.ts b/index.d.ts
index dc97323..7aa4a67 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -27,7 +27,7 @@ export type CommonOptions<EncodingType> = {
 
 	If you `$ npm install foo`, you can then `execa('foo')`.
 
-	@default false
+	@default `true` with `$`/`$.sync`, `false` otherwise
 	*/
 	readonly preferLocal?: boolean;
 
diff --git a/index.js b/index.js
index e9f3582..bd49574 100644
--- a/index.js
+++ b/index.js
@@ -242,7 +242,7 @@ function create$(options) {
 	return $;
 }
 
-export const $ = create$();
+export const $ = create$({preferLocal: true});
 
 export function execaCommand(command, options) {
 	const [file, ...args] = parseCommand(command);
diff --git a/readme.md b/readme.md
index 0b9a5a2..89625df 100644
--- a/readme.md
+++ b/readme.md
@@ -312,7 +312,7 @@ This is not escaped and should not be executed directly as a process, including
 
 Type: `string`
 
-Same as [`command`](#command) but escaped.
+Same as [`command`](#command-1) but escaped.
 
 This is meant to be copy and pasted into a shell, for debugging purposes.
 Since the escaping is fairly basic, this should not be executed directly as a process, including using [`execa()`](#execafile-arguments-options) or [`execaCommand()`](#execacommandcommand-options).
@@ -425,7 +425,7 @@ Kill the spawned process when the parent process exits unless either:
 #### preferLocal
 
 Type: `boolean`\
-Default: `false`
+Default: `true` with [`$`](#command)/[`$.sync`](#synccommand), `false` otherwise
 
 Prefer locally installed binaries when looking for a binary to execute.\
 If you `$ npm install foo`, you can then `execa('foo')`.


Test patch:
diff --git a/test/test.js b/test/test.js
index 47192fb..14bcabe 100644
--- a/test/test.js
+++ b/test/test.js
@@ -4,7 +4,7 @@ import {fileURLToPath, pathToFileURL} from 'node:url';
 import test from 'ava';
 import isRunning from 'is-running';
 import getNode from 'get-node';
-import {execa, execaSync} from '../index.js';
+import {execa, execaSync, $} from '../index.js';
 import {setFixtureDir, PATH_KEY} from './helpers/fixtures-dir.js';
 
 setFixtureDir();
@@ -96,6 +96,10 @@ test('preferLocal: undefined', async t => {
 	await t.throwsAsync(execa('ava', ['--version'], {env: getPathWithoutLocalDir()}), {message: ENOENT_REGEXP});
 });
 
+test('preferLocal: undefined with $', async t => {
+	await t.notThrowsAsync($({env: getPathWithoutLocalDir()})`ava --version`);
+});
+
 test('localDir option', async t => {
 	const command = process.platform === 'win32' ? 'echo %PATH%' : 'echo $PATH';
 	const {stdout} = await execa(command, {shell: true, preferLocal: true, localDir: '/test'});