From 7da316caca0892ed6a0a5bc254584a33f7cd5203 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 27 May 2022 09:43:47 -0400 Subject: [PATCH 1/2] fix(@angular/cli): support silent package installs with Yarn 2+ Yarn 2 and higher no longer support the `--silent` flag. The Angular CLI will now spawn package managers with the stdout ignored when silent mode is needed and only show stderr when the process exits unsuccessfully. This provides the necessary functionality for the CLI without relying on package manager options. --- .../cli/src/utilities/package-manager.ts | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/angular/cli/src/utilities/package-manager.ts b/packages/angular/cli/src/utilities/package-manager.ts index fddcfb2f8601..ef111588bd15 100644 --- a/packages/angular/cli/src/utilities/package-manager.ts +++ b/packages/angular/cli/src/utilities/package-manager.ts @@ -18,7 +18,6 @@ import { memoize } from './memoize'; import { Spinner } from './spinner'; interface PackageManagerOptions { - silent: string; saveDev: string; install: string; installAll?: string; @@ -79,28 +78,24 @@ export class PackageManagerUtils { cwd?: string, ): Promise { const packageManagerArgs = this.getArguments(); - const installArgs: string[] = [ - packageManagerArgs.install, - packageName, - packageManagerArgs.silent, - ]; + const installArgs: string[] = [packageManagerArgs.install, packageName]; if (save === 'devDependencies') { installArgs.push(packageManagerArgs.saveDev); } - return this.run([...installArgs, ...extraArgs], cwd); + return this.run([...installArgs, ...extraArgs], { cwd, silent: true }); } /** Install all packages. */ async installAll(extraArgs: string[] = [], cwd?: string): Promise { const packageManagerArgs = this.getArguments(); - const installArgs: string[] = [packageManagerArgs.silent]; + const installArgs: string[] = []; if (packageManagerArgs.installAll) { installArgs.push(packageManagerArgs.installAll); } - return this.run([...installArgs, ...extraArgs], cwd); + return this.run([...installArgs, ...extraArgs], { cwd, silent: true }); } /** Install a single package temporary. */ @@ -160,7 +155,6 @@ export class PackageManagerUtils { switch (this.name) { case PackageManager.Yarn: return { - silent: '--silent', saveDev: '--dev', install: 'add', prefix: '--modules-folder', @@ -168,7 +162,6 @@ export class PackageManagerUtils { }; case PackageManager.Pnpm: return { - silent: '--silent', saveDev: '--save-dev', install: 'add', installAll: 'install', @@ -177,7 +170,6 @@ export class PackageManagerUtils { }; default: return { - silent: '--quiet', saveDev: '--save-dev', install: 'install', installAll: 'install', @@ -187,7 +179,12 @@ export class PackageManagerUtils { } } - private async run(args: string[], cwd = process.cwd()): Promise { + private async run( + args: string[], + options: { cwd?: string; silent?: boolean } = {}, + ): Promise { + const { cwd = process.cwd(), silent = false } = options; + const spinner = new Spinner(); spinner.start('Installing packages...'); @@ -195,7 +192,8 @@ export class PackageManagerUtils { const bufferedOutput: { stream: NodeJS.WriteStream; data: Buffer }[] = []; const childProcess = spawn(this.name, args, { - stdio: 'pipe', + // Always pipe stderr to allow for failures to be reported + stdio: silent ? ['ignore', 'ignore', 'pipe'] : 'pipe', shell: true, cwd, }).on('close', (code: number) => { From ca9388df24b6595a86f0d627d5b63d1113358134 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 27 May 2022 10:32:54 -0400 Subject: [PATCH 2/2] fix(@angular-devkit/schematics): support quiet package installs with Yarn 2+ Yarn 2 and higher no longer support the `--silent` flag. The `NodePackageInstallTask` will now spawn package managers with the stdout ignored when quiet mode is needed and only show stderr when the process exits unsuccessfully. This provides the necessary functionality for the task without relying on package manager options. --- .../schematics/tasks/package-manager/executor.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts index 45047ba3b1d8..cb16ef2dc7cb 100644 --- a/packages/angular_devkit/schematics/tasks/package-manager/executor.ts +++ b/packages/angular_devkit/schematics/tasks/package-manager/executor.ts @@ -15,7 +15,6 @@ import { TaskExecutor, UnsuccessfulWorkflowExecution } from '../../src'; import { NodePackageTaskFactoryOptions, NodePackageTaskOptions } from './options'; interface PackageManagerProfile { - quietArgument?: string; commands: { installAll?: string; installPackage: string; @@ -24,7 +23,6 @@ interface PackageManagerProfile { const packageManagers: { [name: string]: PackageManagerProfile } = { 'npm': { - quietArgument: '--quiet', commands: { installAll: 'install', installPackage: 'install', @@ -37,13 +35,11 @@ const packageManagers: { [name: string]: PackageManagerProfile } = { }, }, 'yarn': { - quietArgument: '--silent', commands: { installPackage: 'add', }, }, 'pnpm': { - quietArgument: '--silent', commands: { installAll: 'install', installPackage: 'install', @@ -81,10 +77,15 @@ export default function ( const bufferedOutput: { stream: NodeJS.WriteStream; data: Buffer }[] = []; const spawnOptions: SpawnOptions = { - stdio: options.hideOutput ? 'pipe' : 'inherit', shell: true, cwd: path.join(rootDirectory, options.workingDirectory || ''), }; + if (options.hideOutput) { + spawnOptions.stdio = options.quiet ? ['ignore', 'ignore', 'pipe'] : 'pipe'; + } else { + spawnOptions.stdio = options.quiet ? ['ignore', 'ignore', 'inherit'] : 'inherit'; + } + const args: string[] = []; if (options.packageName) { @@ -96,10 +97,6 @@ export default function ( args.push(taskPackageManagerProfile.commands.installAll); } - if (options.quiet && taskPackageManagerProfile.quietArgument) { - args.push(taskPackageManagerProfile.quietArgument); - } - if (!options.allowScripts) { args.push('--ignore-scripts'); }