Skip to content

Commit b41b4fb

Browse files
authored
fix(cli): always disable interactive mode in non-TTYs (#6419)
## What's the problem this PR addresses? <!-- Describe the rationale of your PR. --> <!-- Link all issues that it closes. (Closes/Resolves #xxxx.) --> When `preferInteractive` is set to `true`, `yarn {add,up}` are interactive even outside TTYs, which is unintended. Can be checked by running `yarn add lodash > foo.txt` in our repository. ## How did you fix it? <!-- A detailed description of your implementation. --> Made it disable interactivity when `stdout` isn't a TTY (and added a new `configuration.isInteractive` helper). ## Checklist <!--- Don't worry if you miss something, chores are automatically tested. --> <!--- This checklist exists to help you remember doing the chores when you submit a PR. --> <!--- Put an `x` in all the boxes that apply. --> - [X] I have read the [Contributing Guide](https://yarnpkg.com/advanced/contributing). <!-- See https://yarnpkg.com/advanced/contributing#preparing-your-pr-to-be-released for more details. --> <!-- Check with `yarn version check` and fix with `yarn version check -i` --> - [X] I have set the packages that need to be released for my changes to be effective. <!-- The "Testing chores" workflow validates that your PR follows our guidelines. --> <!-- If it doesn't pass, click on it to see details as to what your PR might be missing. --> - [X] I will check that all automated PR checks pass before the PR gets reviewed.
1 parent 49db260 commit b41b4fb

File tree

5 files changed

+55
-2
lines changed

5 files changed

+55
-2
lines changed

.yarn/versions/34e33c5b.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
releases:
2+
"@yarnpkg/cli": patch
3+
"@yarnpkg/core": patch
4+
"@yarnpkg/plugin-essentials": patch
5+
6+
declined:
7+
- "@yarnpkg/plugin-compat"
8+
- "@yarnpkg/plugin-constraints"
9+
- "@yarnpkg/plugin-dlx"
10+
- "@yarnpkg/plugin-exec"
11+
- "@yarnpkg/plugin-file"
12+
- "@yarnpkg/plugin-git"
13+
- "@yarnpkg/plugin-github"
14+
- "@yarnpkg/plugin-http"
15+
- "@yarnpkg/plugin-init"
16+
- "@yarnpkg/plugin-interactive-tools"
17+
- "@yarnpkg/plugin-link"
18+
- "@yarnpkg/plugin-nm"
19+
- "@yarnpkg/plugin-npm"
20+
- "@yarnpkg/plugin-npm-cli"
21+
- "@yarnpkg/plugin-pack"
22+
- "@yarnpkg/plugin-patch"
23+
- "@yarnpkg/plugin-pnp"
24+
- "@yarnpkg/plugin-pnpm"
25+
- "@yarnpkg/plugin-stage"
26+
- "@yarnpkg/plugin-typescript"
27+
- "@yarnpkg/plugin-version"
28+
- "@yarnpkg/plugin-workspace-tools"
29+
- "@yarnpkg/builder"
30+
- "@yarnpkg/doctor"
31+
- "@yarnpkg/extensions"
32+
- "@yarnpkg/nm"
33+
- "@yarnpkg/pnpify"
34+
- "@yarnpkg/sdks"

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Yarn now accepts sponsors! Please take a look at our [OpenCollective](https://op
88
Features in `master` can be tried out by running `yarn set version from sources` in your project.
99
:::
1010

11+
- Fixes `preferInteractive` forcing interactive mode in non-TTY environments.
12+
1113
## 4.1.0
1214

1315
- Tweaks `-,--verbose` in `yarn workspaces foreach`; `-v` will now only print the prefixes, `-vv` will be necessary to also print the timings.

packages/plugin-essentials/sources/commands/add.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,10 @@ export default class AddCommand extends BaseCommand {
135135
});
136136

137137
const fixed = this.fixed;
138-
const interactive = this.interactive ?? configuration.get(`preferInteractive`);
138+
const interactive = configuration.isInteractive({
139+
interactive: this.interactive,
140+
stdout: this.context.stdout,
141+
});
139142
const reuse = interactive || configuration.get(`preferReuse`);
140143

141144
const modifier = suggestUtils.getModifier(this, project);

packages/plugin-essentials/sources/commands/up.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ export default class UpCommand extends BaseCommand {
162162
});
163163

164164
const fixed = this.fixed;
165-
const interactive = this.interactive ?? configuration.get(`preferInteractive`);
165+
const interactive = configuration.isInteractive({
166+
interactive: this.interactive,
167+
stdout: this.context.stdout,
168+
});
166169

167170
const modifier = suggestUtils.getModifier(this, project);
168171

packages/yarnpkg-core/sources/Configuration.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {parse as parseDotEnv}
88
import {builtinModules} from 'module';
99
import pLimit, {Limit} from 'p-limit';
1010
import {PassThrough, Writable} from 'stream';
11+
import {WriteStream} from 'tty';
1112

1213
import {CorePlugin} from './CorePlugin';
1314
import {Manifest, PeerDependencyMeta} from './Manifest';
@@ -313,6 +314,9 @@ export const coreDefinitions: {[coreSettingName: string]: SettingsDefinition} =
313314
default: !isCI,
314315
defaultText: `<dynamic>`,
315316
},
317+
/**
318+
* @internal Prefer using `Configuration#isInteractive`.
319+
*/
316320
preferInteractive: {
317321
description: `If true, the CLI will automatically use the interactive mode when called from a TTY`,
318322
type: SettingsType.BOOLEAN,
@@ -1786,6 +1790,13 @@ export class Configuration {
17861790
return {os, cpu, libc};
17871791
}
17881792

1793+
isInteractive({interactive, stdout}: {interactive?: boolean, stdout: Writable}): boolean {
1794+
if (!(stdout as WriteStream).isTTY)
1795+
return false;
1796+
1797+
return interactive ?? this.get(`preferInteractive`);
1798+
}
1799+
17891800
private packageExtensions: PackageExtensions | null = null;
17901801

17911802
/**

0 commit comments

Comments
 (0)