Skip to content

Commit

Permalink
fix(@angular/cli): update NPM 7 guidance
Browse files Browse the repository at this point in the history
Update NPM 7 behavior based on #19957 (comment)
  • Loading branch information
clydin committed Feb 9, 2021
1 parent 088891b commit 52aaa8c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 8 deletions.
2 changes: 0 additions & 2 deletions packages/angular/cli/commands/new-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ export class NewCommand extends SchematicCommand<NewCommandSchema> {
}

public async run(options: NewCommandSchema & Arguments) {
await ensureCompatibleNpm(this.context.root);

// Register the version of the CLI in the registry.
const packageJson = require('../package.json');
const version = packageJson.version;
Expand Down
12 changes: 11 additions & 1 deletion packages/angular/cli/models/schematic-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import * as systemPath from 'path';
import { colors } from '../utilities/color';
import { getProjectByCwd, getSchematicDefaults, getWorkspace } from '../utilities/config';
import { parseJsonSchemaToOptions } from '../utilities/json-schema';
import { getPackageManager } from '../utilities/package-manager';
import { ensureCompatibleNpm, getPackageManager } from '../utilities/package-manager';
import { isTTY } from '../utilities/tty';
import { isPackageNameSafeForAnalytics } from './analytics';
import { BaseCommandOptions, Command } from './command';
Expand Down Expand Up @@ -503,6 +503,16 @@ export abstract class SchematicCommand<
}
});

// Temporary compatibility check for NPM 7
if (collectionName === '@schematics/angular' && schematicName === 'ng-new') {
if (
!input.skipInstall &&
(input.packageManager === undefined || input.packageManager === 'npm')
) {
await ensureCompatibleNpm(this.context.root);
}
}

return new Promise<number | void>(resolve => {
workflow
.execute({
Expand Down
10 changes: 6 additions & 4 deletions packages/angular/cli/utilities/package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,18 @@ export async function ensureCompatibleNpm(root: string): Promise<void> {
try {
const version = execSync('npm --version', {encoding: 'utf8', stdio: 'pipe'}).trim();
const major = Number(version.match(/^(\d+)\./)?.[1]);
if (major === 6) {
if (major <= 6) {
return;
}

// tslint:disable-next-line: no-console
console.error(
`npm version ${version} detected.\n` +
'The Angular CLI currently requires npm version 6.\n\n' +
'Please install a compatible version to proceed (`npm install --global npm@6`).\n',
`npm version ${version} detected. The Angular CLI temporarily requires npm version 6 while upstream issues are addressed.\n\n` +
'Please install a compatible version to proceed (`npm install --global npm@6`).\n' +
'For additional information and alternative workarounds, please see ' +
'https://github.com/angular/angular-cli/issues/19957#issuecomment-775407654',
);

process.exit(3);
} catch {
// npm is not installed
Expand Down
31 changes: 30 additions & 1 deletion tests/legacy-cli/e2e/tests/misc/npm-7.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { rimraf } from '../../utils/fs';
import { getActivePackageManager } from '../../utils/packages';
import { ng, npm } from '../../utils/process';
import { expectToFail } from '../../utils/utils';

const errorText = 'The Angular CLI currently requires npm version 6.';
const errorText = 'The Angular CLI temporarily requires npm version 6';

export default async function() {
// Only relevant with npm as a package manager
Expand Down Expand Up @@ -32,14 +33,42 @@ export default async function() {
throw new Error('ng update expected to show npm version error.');
}

// Ensure `ng build` executes successfully
const { stderr: stderrBuild } = await ng('build');
if (stderrBuild.includes(errorText)) {
throw new Error('ng build expected to not show npm version error.');
}

// Ensure `ng new` exits and shows npm error
// Must be outside the project for `ng new`
process.chdir('..');
const { message: stderrNew } = await expectToFail(() => ng('new'));
if (!stderrNew.includes(errorText)) {
throw new Error('ng new expected to show npm version error.');
}

// Ensure `ng new --package-manager=npm` exits and shows npm error
const { message: stderrNewNpm } = await expectToFail(() => ng('new', '--package-manager=npm'));
if (!stderrNewNpm.includes(errorText)) {
throw new Error('ng new expected to show npm version error.');
}

// Ensure `ng new --skip-install` executes successfully
const { stderr: stderrNewSkipInstall } = await ng('new', 'npm-seven-skip', '--skip-install');
if (stderrNewSkipInstall.includes(errorText)) {
throw new Error('ng new --skip-install expected to not show npm version error.');
}

// Ensure `ng new --package-manager=yarn` executes successfully
const { stderr: stderrNewYarn } = await ng('new', 'npm-seven-yarn', '--package-manager=yarn');
if (stderrNewYarn.includes(errorText)) {
throw new Error('ng new --package-manager=yarn expected to not show npm version error.');
}
} finally {
// Cleanup extra test projects
await rimraf('npm-seven-skip');
await rimraf('npm-seven-yarn');

// Change directory back
process.chdir(currentDirectory);

Expand Down

0 comments on commit 52aaa8c

Please sign in to comment.