Skip to content

Commit 52aaa8c

Browse files
committed
fix(@angular/cli): update NPM 7 guidance
Update NPM 7 behavior based on #19957 (comment)
1 parent 088891b commit 52aaa8c

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

packages/angular/cli/commands/new-impl.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ export class NewCommand extends SchematicCommand<NewCommandSchema> {
2222
}
2323

2424
public async run(options: NewCommandSchema & Arguments) {
25-
await ensureCompatibleNpm(this.context.root);
26-
2725
// Register the version of the CLI in the registry.
2826
const packageJson = require('../package.json');
2927
const version = packageJson.version;

packages/angular/cli/models/schematic-command.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import * as systemPath from 'path';
3030
import { colors } from '../utilities/color';
3131
import { getProjectByCwd, getSchematicDefaults, getWorkspace } from '../utilities/config';
3232
import { parseJsonSchemaToOptions } from '../utilities/json-schema';
33-
import { getPackageManager } from '../utilities/package-manager';
33+
import { ensureCompatibleNpm, getPackageManager } from '../utilities/package-manager';
3434
import { isTTY } from '../utilities/tty';
3535
import { isPackageNameSafeForAnalytics } from './analytics';
3636
import { BaseCommandOptions, Command } from './command';
@@ -503,6 +503,16 @@ export abstract class SchematicCommand<
503503
}
504504
});
505505

506+
// Temporary compatibility check for NPM 7
507+
if (collectionName === '@schematics/angular' && schematicName === 'ng-new') {
508+
if (
509+
!input.skipInstall &&
510+
(input.packageManager === undefined || input.packageManager === 'npm')
511+
) {
512+
await ensureCompatibleNpm(this.context.root);
513+
}
514+
}
515+
506516
return new Promise<number | void>(resolve => {
507517
workflow
508518
.execute({

packages/angular/cli/utilities/package-manager.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,18 @@ export async function ensureCompatibleNpm(root: string): Promise<void> {
6666
try {
6767
const version = execSync('npm --version', {encoding: 'utf8', stdio: 'pipe'}).trim();
6868
const major = Number(version.match(/^(\d+)\./)?.[1]);
69-
if (major === 6) {
69+
if (major <= 6) {
7070
return;
7171
}
7272

7373
// tslint:disable-next-line: no-console
7474
console.error(
75-
`npm version ${version} detected.\n` +
76-
'The Angular CLI currently requires npm version 6.\n\n' +
77-
'Please install a compatible version to proceed (`npm install --global npm@6`).\n',
75+
`npm version ${version} detected. The Angular CLI temporarily requires npm version 6 while upstream issues are addressed.\n\n` +
76+
'Please install a compatible version to proceed (`npm install --global npm@6`).\n' +
77+
'For additional information and alternative workarounds, please see ' +
78+
'https://github.com/angular/angular-cli/issues/19957#issuecomment-775407654',
7879
);
80+
7981
process.exit(3);
8082
} catch {
8183
// npm is not installed

tests/legacy-cli/e2e/tests/misc/npm-7.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import { rimraf } from '../../utils/fs';
12
import { getActivePackageManager } from '../../utils/packages';
23
import { ng, npm } from '../../utils/process';
34
import { expectToFail } from '../../utils/utils';
45

5-
const errorText = 'The Angular CLI currently requires npm version 6.';
6+
const errorText = 'The Angular CLI temporarily requires npm version 6';
67

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

36+
// Ensure `ng build` executes successfully
37+
const { stderr: stderrBuild } = await ng('build');
38+
if (stderrBuild.includes(errorText)) {
39+
throw new Error('ng build expected to not show npm version error.');
40+
}
41+
3542
// Ensure `ng new` exits and shows npm error
3643
// Must be outside the project for `ng new`
3744
process.chdir('..');
3845
const { message: stderrNew } = await expectToFail(() => ng('new'));
3946
if (!stderrNew.includes(errorText)) {
4047
throw new Error('ng new expected to show npm version error.');
4148
}
49+
50+
// Ensure `ng new --package-manager=npm` exits and shows npm error
51+
const { message: stderrNewNpm } = await expectToFail(() => ng('new', '--package-manager=npm'));
52+
if (!stderrNewNpm.includes(errorText)) {
53+
throw new Error('ng new expected to show npm version error.');
54+
}
55+
56+
// Ensure `ng new --skip-install` executes successfully
57+
const { stderr: stderrNewSkipInstall } = await ng('new', 'npm-seven-skip', '--skip-install');
58+
if (stderrNewSkipInstall.includes(errorText)) {
59+
throw new Error('ng new --skip-install expected to not show npm version error.');
60+
}
61+
62+
// Ensure `ng new --package-manager=yarn` executes successfully
63+
const { stderr: stderrNewYarn } = await ng('new', 'npm-seven-yarn', '--package-manager=yarn');
64+
if (stderrNewYarn.includes(errorText)) {
65+
throw new Error('ng new --package-manager=yarn expected to not show npm version error.');
66+
}
4267
} finally {
68+
// Cleanup extra test projects
69+
await rimraf('npm-seven-skip');
70+
await rimraf('npm-seven-yarn');
71+
4372
// Change directory back
4473
process.chdir(currentDirectory);
4574

0 commit comments

Comments
 (0)