diff --git a/.yarn/versions/db5a0b98.yml b/.yarn/versions/db5a0b98.yml new file mode 100644 index 000000000000..fa0f6cc83354 --- /dev/null +++ b/.yarn/versions/db5a0b98.yml @@ -0,0 +1,34 @@ +releases: + "@yarnpkg/cli": major + "@yarnpkg/core": major + "@yarnpkg/plugin-essentials": major + +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/.yarnrc.yml b/.yarnrc.yml index f2bb15d1f523..85dba7c26c25 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -71,8 +71,6 @@ packageExtensions: pnpEnableEsmLoader: true -preferInteractive: true - supportedArchitectures: cpu: - x64 diff --git a/CHANGELOG.md b/CHANGELOG.md index 1399d23b2b04..b5cc7ef68569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,10 @@ Yarn now accepts sponsorships! Please give a look at our [OpenCollective](https: - Plugins cannot access the internal copy of Yup anymore (use [Typanion](https://github.com/arcanis/typanion) instead) - Yarn will no longer remove the old Yarn 2.x `.pnp.js` file when migrating. - The `--assume-fresh-project` flag of `yarn init` has been removed. +- Yarn is now interactive by default whenever possible: + - The `--interactive` flag is no longer needed for `yarn add` and `yarn up`. + - Yarn will never be interactive in CI environments or outside of a TTY. + - You can always set `preferInteractive: false` to prevent Yarn from being implicitly interactive. ### **API Changes** diff --git a/packages/plugin-essentials/sources/commands/add.ts b/packages/plugin-essentials/sources/commands/add.ts index 9aaf74678e09..db670c35eb65 100644 --- a/packages/plugin-essentials/sources/commands/add.ts +++ b/packages/plugin-essentials/sources/commands/add.ts @@ -132,7 +132,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 f457fdcc9fe4..c6790d4d7d2d 100644 --- a/packages/plugin-essentials/sources/commands/up.ts +++ b/packages/plugin-essentials/sources/commands/up.ts @@ -161,7 +161,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 83e69928d052..7df05ff49eeb 100644 --- a/packages/yarnpkg-core/sources/Configuration.ts +++ b/packages/yarnpkg-core/sources/Configuration.ts @@ -6,6 +6,7 @@ import {UsageError} import {parse as parseDotEnv} from 'dotenv'; import pLimit, {Limit} from 'p-limit'; import {PassThrough, Writable} from 'stream'; +import {WriteStream} from 'tty'; import {CorePlugin} from './CorePlugin'; import {Manifest, PeerDependencyMeta} from './Manifest'; @@ -299,7 +300,8 @@ export const coreDefinitions: {[coreSettingName: string]: SettingsDefinition} = preferInteractive: { description: `If true, the CLI will automatically use the interactive mode when called from a TTY`, type: SettingsType.BOOLEAN, - default: false, + default: !isCI, + defaultText: ``, }, preferTruncatedLines: { description: `If true, the CLI will truncate lines that would go beyond the size of the terminal`, @@ -613,6 +615,9 @@ export interface ConfigurationValueMap { enableMotd: boolean; enableProgressBars: boolean; enableTimers: boolean; + /** + * @internal Prefer using `Configuration#isInteractive`. + */ preferInteractive: boolean; preferTruncatedLines: boolean; progressBarStyle: string | undefined; @@ -1719,6 +1724,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`); + } + async refreshPackageExtensions() { this.packageExtensions = new Map(); const packageExtensions = this.packageExtensions;