diff --git a/.yarn/versions/34e33c5b.yml b/.yarn/versions/34e33c5b.yml new file mode 100644 index 000000000000..6382dce07ce9 --- /dev/null +++ b/.yarn/versions/34e33c5b.yml @@ -0,0 +1,34 @@ +releases: + "@yarnpkg/cli": patch + "@yarnpkg/core": patch + "@yarnpkg/plugin-essentials": patch + +declined: + - "@yarnpkg/plugin-compat" + - "@yarnpkg/plugin-constraints" + - "@yarnpkg/plugin-dlx" + - "@yarnpkg/plugin-exec" + - "@yarnpkg/plugin-file" + - "@yarnpkg/plugin-git" + - "@yarnpkg/plugin-github" + - "@yarnpkg/plugin-http" + - "@yarnpkg/plugin-init" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-link" + - "@yarnpkg/plugin-nm" + - "@yarnpkg/plugin-npm" + - "@yarnpkg/plugin-npm-cli" + - "@yarnpkg/plugin-pack" + - "@yarnpkg/plugin-patch" + - "@yarnpkg/plugin-pnp" + - "@yarnpkg/plugin-pnpm" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-typescript" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - "@yarnpkg/builder" + - "@yarnpkg/doctor" + - "@yarnpkg/extensions" + - "@yarnpkg/nm" + - "@yarnpkg/pnpify" + - "@yarnpkg/sdks" diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b1b20a90129..982e0371c88a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ Yarn now accepts sponsors! Please take a look at our [OpenCollective](https://op Features in `master` can be tried out by running `yarn set version from sources` in your project. ::: +- Fixes `preferInteractive` forcing interactive mode in non-TTY environments. + ## 4.1.0 - Tweaks `-,--verbose` in `yarn workspaces foreach`; `-v` will now only print the prefixes, `-vv` will be necessary to also print the timings. diff --git a/packages/plugin-essentials/sources/commands/add.ts b/packages/plugin-essentials/sources/commands/add.ts index 2dae8f1e7eda..36f0049268e1 100644 --- a/packages/plugin-essentials/sources/commands/add.ts +++ b/packages/plugin-essentials/sources/commands/add.ts @@ -135,7 +135,10 @@ export default class AddCommand extends BaseCommand { }); const fixed = this.fixed; - const interactive = this.interactive ?? configuration.get(`preferInteractive`); + const interactive = configuration.isInteractive({ + interactive: this.interactive, + stdout: this.context.stdout, + }); const reuse = interactive || configuration.get(`preferReuse`); const modifier = suggestUtils.getModifier(this, project); diff --git a/packages/plugin-essentials/sources/commands/up.ts b/packages/plugin-essentials/sources/commands/up.ts index 28cbc4790e2d..adc95c12406f 100644 --- a/packages/plugin-essentials/sources/commands/up.ts +++ b/packages/plugin-essentials/sources/commands/up.ts @@ -162,7 +162,10 @@ export default class UpCommand extends BaseCommand { }); const fixed = this.fixed; - const interactive = this.interactive ?? configuration.get(`preferInteractive`); + const interactive = configuration.isInteractive({ + interactive: this.interactive, + stdout: this.context.stdout, + }); const modifier = suggestUtils.getModifier(this, project); diff --git a/packages/yarnpkg-core/sources/Configuration.ts b/packages/yarnpkg-core/sources/Configuration.ts index 930b3f8630ca..afdc21da250a 100644 --- a/packages/yarnpkg-core/sources/Configuration.ts +++ b/packages/yarnpkg-core/sources/Configuration.ts @@ -8,6 +8,7 @@ import {parse as parseDotEnv} import {builtinModules} from 'module'; import pLimit, {Limit} from 'p-limit'; import {PassThrough, Writable} from 'stream'; +import {WriteStream} from 'tty'; import {CorePlugin} from './CorePlugin'; import {Manifest, PeerDependencyMeta} from './Manifest'; @@ -313,6 +314,9 @@ export const coreDefinitions: {[coreSettingName: string]: SettingsDefinition} = default: !isCI, defaultText: ``, }, + /** + * @internal Prefer using `Configuration#isInteractive`. + */ preferInteractive: { description: `If true, the CLI will automatically use the interactive mode when called from a TTY`, type: SettingsType.BOOLEAN, @@ -1786,6 +1790,13 @@ export class Configuration { return {os, cpu, libc}; } + isInteractive({interactive, stdout}: {interactive?: boolean, stdout: Writable}): boolean { + if (!(stdout as WriteStream).isTTY) + return false; + + return interactive ?? this.get(`preferInteractive`); + } + private packageExtensions: PackageExtensions | null = null; /**