Skip to content

Commit 0ed8de1

Browse files
clydinmgechev
authored andcommitted
refactor(@angular-devkit/build-angular): cleanup compatible Angular version check
1 parent 3bb67d8 commit 0ed8de1

File tree

6 files changed

+99
-132
lines changed

6 files changed

+99
-132
lines changed

packages/angular_devkit/build_angular/src/browser/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import {
5858
} from '../angular-cli-files/utilities/stats';
5959
import { ExecutionTransformer } from '../transforms';
6060
import { BuildBrowserFeatures, deleteOutputDir } from '../utils';
61-
import { Version } from '../utils/version';
61+
import { assertCompatibleAngularVersion } from '../utils/version';
6262
import { generateBrowserWebpackConfigFromContext } from '../utils/webpack-browser-config';
6363
import { Schema as BrowserBuilderSchema } from './schema';
6464

@@ -180,7 +180,7 @@ export function buildWebpackBrowser(
180180
const root = normalize(context.workspaceRoot);
181181

182182
// Check Angular version.
183-
Version.assertCompatibleAngularVersion(context.workspaceRoot);
183+
assertCompatibleAngularVersion(context.workspaceRoot, context.logger);
184184

185185
const loggingFn = transforms.logging
186186
|| createBrowserLoggingCallback(!!options.verbose, context.logger);

packages/angular_devkit/build_angular/src/dev-server/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
import { Schema as BrowserBuilderSchema } from '../browser/schema';
3737
import { ExecutionTransformer } from '../transforms';
3838
import { normalizeOptimization } from '../utils';
39-
import { Version } from '../utils/version';
39+
import { assertCompatibleAngularVersion } from '../utils/version';
4040
import { Schema } from './schema';
4141
const open = require('open');
4242

@@ -80,7 +80,7 @@ export function serveWebpackBrowser(
8080
} = {},
8181
): Observable<DevServerBuilderOutput> {
8282
// Check Angular version.
83-
Version.assertCompatibleAngularVersion(context.workspaceRoot);
83+
assertCompatibleAngularVersion(context.workspaceRoot, context.logger);
8484

8585
const browserTarget = targetFromTargetString(options.browserTarget);
8686
const root = context.workspaceRoot;

packages/angular_devkit/build_angular/src/extract-i18n/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
import { readTsconfig } from '../angular-cli-files/utilities/read-tsconfig';
2424
import { statsErrorsToString, statsWarningsToString } from '../angular-cli-files/utilities/stats';
2525
import { Schema as BrowserBuilderOptions } from '../browser/schema';
26-
import { Version } from '../utils/version';
26+
import { assertCompatibleAngularVersion } from '../utils/version';
2727
import { generateBrowserWebpackConfigFromContext } from '../utils/webpack-browser-config';
2828
import { Schema as ExtractI18nBuilderOptions } from './schema';
2929

@@ -51,7 +51,7 @@ class InMemoryOutputPlugin {
5151

5252
async function execute(options: ExtractI18nBuilderOptions, context: BuilderContext) {
5353
// Check Angular version.
54-
Version.assertCompatibleAngularVersion(context.workspaceRoot);
54+
assertCompatibleAngularVersion(context.workspaceRoot, context.logger);
5555

5656
const browserTarget = targetFromTargetString(options.browserTarget);
5757
const browserOptions = await context.validateOptions<JsonObject & BrowserBuilderOptions>(

packages/angular_devkit/build_angular/src/karma/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
} from '../angular-cli-files/models/webpack-configs';
2020
import { Schema as BrowserBuilderOptions } from '../browser/schema';
2121
import { ExecutionTransformer } from '../transforms';
22-
import { Version } from '../utils/version';
22+
import { assertCompatibleAngularVersion } from '../utils/version';
2323
import { generateBrowserWebpackConfigFromContext } from '../utils/webpack-browser-config';
2424
import { Schema as KarmaBuilderOptions } from './schema';
2525

@@ -69,7 +69,7 @@ export function execute(
6969
} = {},
7070
): Observable<BuilderOutput> {
7171
// Check Angular version.
72-
Version.assertCompatibleAngularVersion(context.workspaceRoot);
72+
assertCompatibleAngularVersion(context.workspaceRoot, context.logger);
7373

7474
return from(initialize(options, context, transforms.webpackConfiguration)).pipe(
7575
switchMap(([karma, webpackConfig]) => new Observable<BuilderOutput>(subscriber => {

packages/angular_devkit/build_angular/src/server/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
} from '../angular-cli-files/models/webpack-configs';
2525
import { ExecutionTransformer } from '../transforms';
2626
import { NormalizedBrowserBuilderSchema, deleteOutputDir } from '../utils';
27-
import { Version } from '../utils/version';
27+
import { assertCompatibleAngularVersion } from '../utils/version';
2828
import { generateBrowserWebpackConfigFromContext } from '../utils/webpack-browser-config';
2929
import { Schema as ServerBuilderOptions } from './schema';
3030

@@ -46,7 +46,7 @@ export function execute(
4646
const root = context.workspaceRoot;
4747

4848
// Check Angular version.
49-
Version.assertCompatibleAngularVersion(context.workspaceRoot);
49+
assertCompatibleAngularVersion(context.workspaceRoot, context.logger);
5050

5151
return from(buildServerWebpackConfig(options, context)).pipe(
5252
concatMap(async v => transforms.webpackConfiguration ? transforms.webpackConfiguration(v) : v),

packages/angular_devkit/build_angular/src/utils/version.ts

+89-122
Original file line numberDiff line numberDiff line change
@@ -5,136 +5,103 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
9-
import { tags, terminal } from '@angular-devkit/core';
10-
import * as path from 'path';
11-
import { SemVer, satisfies } from 'semver';
12-
13-
14-
export class Version {
15-
private _semver: SemVer | null = null;
16-
constructor(private _version: string | null = null) {
17-
this._semver = _version ? new SemVer(_version) : null;
8+
import { logging, tags } from '@angular-devkit/core';
9+
import { SemVer, gte, satisfies } from 'semver';
10+
11+
export function assertCompatibleAngularVersion(projectRoot: string, logger: logging.LoggerApi) {
12+
let angularCliPkgJson;
13+
let angularPkgJson;
14+
let rxjsPkgJson;
15+
const resolveOptions = { paths: [projectRoot] };
16+
17+
try {
18+
const angularPackagePath = require.resolve('@angular/core/package.json', resolveOptions);
19+
const rxjsPackagePath = require.resolve('rxjs/package.json', resolveOptions);
20+
21+
angularPkgJson = require(angularPackagePath);
22+
rxjsPkgJson = require(rxjsPackagePath);
23+
} catch {
24+
logger.error(tags.stripIndents`
25+
You seem to not be depending on "@angular/core" and/or "rxjs". This is an error.
26+
`);
27+
28+
process.exit(2);
1829
}
1930

20-
isAlpha() { return this.qualifier == 'alpha'; }
21-
isBeta() { return this.qualifier == 'beta'; }
22-
isReleaseCandidate() { return this.qualifier == 'rc'; }
23-
isKnown() { return this._version !== null; }
31+
if (!(angularPkgJson && angularPkgJson['version'] && rxjsPkgJson && rxjsPkgJson['version'])) {
32+
logger.error(tags.stripIndents`
33+
Cannot determine versions of "@angular/core" and/or "rxjs".
34+
This likely means your local installation is broken. Please reinstall your packages.
35+
`);
2436

25-
isLocal() { return this.isKnown() && this._version && path.isAbsolute(this._version); }
26-
isGreaterThanOrEqualTo(other: SemVer) {
27-
return this._semver !== null && this._semver.compare(other) >= 0;
28-
}
29-
satisfies(other: string) {
30-
// This comparison includes pre-releases (like betas and rcs), and considers them to be
31-
// before the release proper.
32-
// e.g. '9.0.0-beta.1' will satisfy '>=7.0.0 <9.0.0', but '9.0.0' will not.
33-
return this._semver !== null && satisfies(this._semver, other, { includePrerelease: true });
37+
process.exit(2);
3438
}
3539

36-
get major() { return this._semver ? this._semver.major : 0; }
37-
get minor() { return this._semver ? this._semver.minor : 0; }
38-
get patch() { return this._semver ? this._semver.patch : 0; }
39-
get qualifier() { return this._semver ? this._semver.prerelease[0] : ''; }
40-
get extra() { return this._semver ? this._semver.prerelease[1] : ''; }
41-
42-
toString() { return this._version; }
43-
44-
static assertCompatibleAngularVersion(projectRoot: string) {
45-
let angularCliPkgJson;
46-
let angularPkgJson;
47-
let rxjsPkgJson;
48-
const resolveOptions = { paths: [projectRoot] };
49-
50-
try {
51-
const angularPackagePath = require.resolve('@angular/core/package.json', resolveOptions);
52-
const rxjsPackagePath = require.resolve('rxjs/package.json', resolveOptions);
53-
54-
angularPkgJson = require(angularPackagePath);
55-
rxjsPkgJson = require(rxjsPackagePath);
56-
} catch {
57-
console.error(terminal.bold(terminal.red(tags.stripIndents`
58-
You seem to not be depending on "@angular/core" and/or "rxjs". This is an error.
59-
`)));
60-
process.exit(2);
40+
try {
41+
const angularCliPkgPath = require.resolve('@angular/cli/package.json', resolveOptions);
42+
angularCliPkgJson = require(angularCliPkgPath);
43+
if (!(angularCliPkgJson && angularCliPkgJson['version'])) {
44+
throw new Error();
6145
}
46+
} catch {
47+
logger.error(tags.stripIndents`
48+
Cannot determine versions of "@angular/cli".
49+
This likely means your local installation is broken. Please reinstall your packages.
50+
`);
6251

63-
if (!(angularPkgJson && angularPkgJson['version'] && rxjsPkgJson && rxjsPkgJson['version'])) {
64-
console.error(terminal.bold(terminal.red(tags.stripIndents`
65-
Cannot determine versions of "@angular/core" and/or "rxjs".
66-
This likely means your local installation is broken. Please reinstall your packages.
67-
`)));
68-
process.exit(2);
69-
}
70-
71-
try {
72-
const angularCliPkgPath = require.resolve('@angular/cli/package.json', resolveOptions);
73-
angularCliPkgJson = require(angularCliPkgPath);
74-
if (!(angularCliPkgJson && angularCliPkgJson['version'])) {
75-
throw new Error();
76-
}
77-
} catch (error) {
78-
console.error(terminal.bold(terminal.red(tags.stripIndents`
79-
Cannot determine versions of "@angular/cli".
80-
This likely means your local installation is broken. Please reinstall your packages.
81-
`)));
82-
process.exit(2);
83-
}
84-
85-
if (angularCliPkgJson['version'] === '0.0.0') {
86-
// Internal testing version
87-
return;
88-
}
89-
90-
const cliMajor = new Version(angularCliPkgJson['version']).major;
91-
// e.g. CLI 8.0 supports '>=8.0.0 <9.0.0', including pre-releases (betas, rcs, snapshots)
92-
// of both 8 and 9.
93-
const supportedAngularSemver = `^${cliMajor}.0.0-beta || ` +
94-
`>=${cliMajor}.0.0 <${cliMajor + 1}.0.0`;
95-
96-
const angularVersion = new Version(angularPkgJson['version']);
97-
const rxjsVersion = new Version(rxjsPkgJson['version']);
98-
99-
if (angularVersion.isLocal()) {
100-
console.error(terminal.yellow('Using a local version of angular. Proceeding with care...'));
101-
102-
return;
103-
}
52+
process.exit(2);
53+
}
10454

105-
if (!angularVersion.satisfies(supportedAngularSemver)) {
106-
console.error(terminal.bold(terminal.red(tags.stripIndents`
107-
This version of CLI is only compatible with Angular versions ${supportedAngularSemver},
108-
but Angular version ${angularVersion} was found instead.
109-
110-
Please visit the link below to find instructions on how to update Angular.
111-
https://angular-update-guide.firebaseapp.com/
112-
` + '\n')));
113-
process.exit(3);
114-
} else if (
115-
angularVersion.isGreaterThanOrEqualTo(new SemVer('6.0.0-rc.0'))
116-
&& !rxjsVersion.isGreaterThanOrEqualTo(new SemVer('5.6.0-forward-compat.0'))
117-
&& !rxjsVersion.isGreaterThanOrEqualTo(new SemVer('6.0.0-beta.0'))
118-
) {
119-
console.error(terminal.bold(terminal.red(tags.stripIndents`
120-
This project uses version ${rxjsVersion} of RxJs, which is not supported by Angular v6+.
121-
The official RxJs version that is supported is 5.6.0-forward-compat.0 and greater.
122-
123-
Please visit the link below to find instructions on how to update RxJs.
124-
https://docs.google.com/document/d/12nlLt71VLKb-z3YaSGzUfx6mJbc34nsMXtByPUN35cg/edit#
125-
` + '\n')));
126-
process.exit(3);
127-
} else if (
128-
angularVersion.isGreaterThanOrEqualTo(new SemVer('6.0.0-rc.0'))
129-
&& !rxjsVersion.isGreaterThanOrEqualTo(new SemVer('6.0.0-beta.0'))
130-
) {
131-
console.warn(terminal.bold(terminal.red(tags.stripIndents`
132-
This project uses a temporary compatibility version of RxJs (${rxjsVersion}).
133-
134-
Please visit the link below to find instructions on how to update RxJs.
135-
https://docs.google.com/document/d/12nlLt71VLKb-z3YaSGzUfx6mJbc34nsMXtByPUN35cg/edit#
136-
` + '\n')));
137-
}
55+
if (angularCliPkgJson['version'] === '0.0.0') {
56+
// Internal testing version
57+
return;
13858
}
13959

60+
const cliMajor = new SemVer(angularCliPkgJson['version']).major;
61+
// e.g. CLI 8.0 supports '>=8.0.0 <9.0.0', including pre-releases (betas, rcs, snapshots)
62+
// of both 8 and 9.
63+
const supportedAngularSemver =
64+
`^${cliMajor}.0.0-beta || ` + `>=${cliMajor}.0.0 <${cliMajor + 1}.0.0`;
65+
66+
const angularVersion = new SemVer(angularPkgJson['version']);
67+
const rxjsVersion = new SemVer(rxjsPkgJson['version']);
68+
69+
if (!satisfies(angularVersion, supportedAngularSemver, { includePrerelease: true })) {
70+
logger.error(
71+
tags.stripIndents`
72+
This version of CLI is only compatible with Angular versions ${supportedAngularSemver},
73+
but Angular version ${angularVersion} was found instead.
74+
75+
Please visit the link below to find instructions on how to update Angular.
76+
https://angular-update-guide.firebaseapp.com/
77+
` + '\n',
78+
);
79+
80+
process.exit(3);
81+
} else if (
82+
gte(angularVersion, '6.0.0-rc.0') &&
83+
!gte(rxjsVersion, '5.6.0-forward-compat.0') &&
84+
!gte(rxjsVersion, '6.0.0-beta.0')
85+
) {
86+
logger.error(
87+
tags.stripIndents`
88+
This project uses version ${rxjsVersion} of RxJs, which is not supported by Angular v6+.
89+
The official RxJs version that is supported is 5.6.0-forward-compat.0 and greater.
90+
91+
Please visit the link below to find instructions on how to update RxJs.
92+
https://docs.google.com/document/d/12nlLt71VLKb-z3YaSGzUfx6mJbc34nsMXtByPUN35cg/edit#
93+
` + '\n',
94+
);
95+
96+
process.exit(3);
97+
} else if (gte(angularVersion, '6.0.0-rc.0') && !gte(rxjsVersion, '6.0.0-beta.0')) {
98+
logger.warn(
99+
tags.stripIndents`
100+
This project uses a temporary compatibility version of RxJs (${rxjsVersion}).
101+
102+
Please visit the link below to find instructions on how to update RxJs.
103+
https://docs.google.com/document/d/12nlLt71VLKb-z3YaSGzUfx6mJbc34nsMXtByPUN35cg/edit#
104+
` + '\n',
105+
);
106+
}
140107
}

0 commit comments

Comments
 (0)