Skip to content

Commit 21003b1

Browse files
authored
chore: Adding a check for old version of the CLI (#2116)
1 parent 4c4e31d commit 21003b1

File tree

4 files changed

+148
-5
lines changed

4 files changed

+148
-5
lines changed

packages/angular-cli/bin/ng

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const resolve = require('resolve');
88
const exit = require('exit');
99
const packageJson = require('../package.json');
1010
const Leek = require('leek');
11+
const Version = require('../upgrade/version').Version;
1112

1213

1314
resolve('angular-cli', { basedir: process.cwd() },
@@ -20,6 +21,9 @@ resolve('angular-cli', { basedir: process.cwd() },
2021
// npm package). Most common cause for hitting this is `ng new`
2122
cli = require('../lib/cli');
2223
} else {
24+
// Verify that package's version.
25+
Version.assertPostWebpackVersion();
26+
2327
// No error implies a projectLocalCli, which will load whatever
2428
// version of ng-cli you have installed in a local package.json
2529
cli = require(projectLocalCli);

packages/angular-cli/models/config.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function getUserHome() {
2929

3030

3131
export class CliConfig extends CliConfigBase<ConfigInterface> {
32-
private static _configFilePath(projectPath?: string): string {
32+
static configFilePath(projectPath?: string): string {
3333
// Find the configuration, either where specified, in the angular-cli project
3434
// (if it's in node_modules) or from the current process.
3535
return (projectPath && _findUp(CLI_CONFIG_FILE_NAME, projectPath))
@@ -39,15 +39,15 @@ export class CliConfig extends CliConfigBase<ConfigInterface> {
3939

4040

4141
static fromProject(): CliConfig {
42-
const configPath = this._configFilePath();
42+
const configPath = this.configFilePath();
4343
const globalConfigPath = path.join(getUserHome(), CLI_CONFIG_FILE_NAME);
4444

4545
if (!configPath) {
4646
return CliConfigBase.fromJson<ConfigInterface>({});
4747
}
4848

4949
const cliConfig = CliConfigBase.fromConfigPath<ConfigInterface>(
50-
CliConfig._configFilePath(), [globalConfigPath]);
50+
CliConfig.configFilePath(), [globalConfigPath]);
5151

5252
const aliases = [
5353
cliConfig.alias('apps.0.root', 'defaults.sourceDir'),
+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import {CliConfig} from '../models/config';
2+
import {readFileSync, existsSync} from 'fs';
3+
import {stripIndents} from 'common-tags';
4+
import {bold, red, yellow} from 'chalk';
5+
import * as path from 'path';
6+
const resolve = require('resolve');
7+
8+
9+
function _findUp(name: string, from: string) {
10+
let currentDir = from;
11+
while (currentDir && currentDir !== path.parse(currentDir).root) {
12+
const p = path.join(currentDir, name);
13+
if (existsSync(p)) {
14+
return p;
15+
}
16+
17+
currentDir = path.dirname(currentDir);
18+
}
19+
20+
return null;
21+
}
22+
23+
24+
function _hasOldCliBuildFile() {
25+
return existsSync(_findUp('angular-cli-build.js', process.cwd()))
26+
|| existsSync(_findUp('angular-cli-build.ts', process.cwd()))
27+
|| existsSync(_findUp('ember-cli-build.js', process.cwd()))
28+
|| existsSync(_findUp('angular-cli-build.js', __dirname))
29+
|| existsSync(_findUp('angular-cli-build.ts', __dirname))
30+
|| existsSync(_findUp('ember-cli-build.js', __dirname));
31+
}
32+
33+
34+
export class Version {
35+
constructor(private _version: string) {}
36+
37+
private _parse() {
38+
return this.isKnown()
39+
? this._version.match(/^(\d+)\.(\d+)(?:\.(\d+))?(?:-(alpha|beta|rc)\.(.*))?$/).slice(1)
40+
: [];
41+
}
42+
43+
isAlpha() { return this.qualifier == 'alpha'; }
44+
isBeta() { return this.qualifier == 'beta'; }
45+
isReleaseCandidate() { return this.qualifier == 'rc'; }
46+
isKnown() { return this._version !== null; }
47+
48+
get major() { return this._parse()[0] || 0; }
49+
get minor() { return this._parse()[1] || 0; }
50+
get patch() { return this._parse()[2] || 0; }
51+
get qualifier() { return this._parse()[3] || ''; }
52+
get extra() { return this._parse()[4] || ''; }
53+
54+
toString() { return this._version; }
55+
56+
static fromProject(): Version {
57+
let packageJson: any = null;
58+
59+
try {
60+
const angularCliPath = resolve.sync('angular-cli', {
61+
basedir: process.cwd(),
62+
packageFilter: (pkg: any, pkgFile: string) => {
63+
packageJson = pkg;
64+
}
65+
});
66+
if (angularCliPath && packageJson) {
67+
try {
68+
return new Version(packageJson.version);
69+
} catch (e) {
70+
return new Version(null);
71+
}
72+
}
73+
} catch (e) {
74+
// Fallback to reading config.
75+
}
76+
77+
78+
const configPath = CliConfig.configFilePath();
79+
const configJson = readFileSync(configPath, 'utf8');
80+
81+
try {
82+
const json = JSON.parse(configJson);
83+
return new Version(json.project && json.project.version);
84+
} catch (e) {
85+
return new Version(null);
86+
}
87+
}
88+
89+
static assertPostWebpackVersion() {
90+
if (this.isPreWebpack()) {
91+
console.error(bold(red('\n' + stripIndents`
92+
It seems like you're using a project generated using an old version of the Angular CLI.
93+
The latest CLI now uses webpack and includes a lot of improvements, include a simpler
94+
workflow, a faster build and smaller bundles.
95+
96+
To get more info, including a step-by-step guide to upgrade the CLI, follow this link:
97+
https://github.com/angular/angular-cli/wiki/Upgrading-from-Beta.10-to-Beta.12
98+
` + '\n')));
99+
process.exit(1);
100+
} else {
101+
// Verify that there's no build file.
102+
if (_hasOldCliBuildFile()) {
103+
console.error(bold(yellow('\n' + stripIndents`
104+
It seems like you're using the newest version of the Angular CLI that uses webpack.
105+
This version does not require an angular-cli-build file, but your project has one.
106+
It will be ignored.
107+
` + '\n')));
108+
}
109+
}
110+
}
111+
112+
static isPreWebpack(): boolean {
113+
// CliConfig is a bit stricter with the schema, so we need to be a little looser with it.
114+
const version = Version.fromProject();
115+
116+
if (version && version.isKnown()) {
117+
if (version.major == 0) {
118+
return true;
119+
} else if (version.minor != 0) {
120+
return false;
121+
} else if (version.isBeta() && !version.toString().match(/webpack/)) {
122+
const betaVersion = version.extra;
123+
124+
if (parseInt(betaVersion) < 12) {
125+
return true;
126+
}
127+
}
128+
} else {
129+
return _hasOldCliBuildFile();
130+
}
131+
132+
return false;
133+
}
134+
}

scripts/publish/build.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
'use strict';
33

44
/*eslint-disable no-console */
5+
const chalk = require('chalk');
56
const denodeify = require('denodeify');
67
const fs = require('fs');
78
const glob = denodeify(require('glob'));
@@ -45,7 +46,11 @@ Promise.resolve()
4546

4647
return promise.then(() => {
4748
console.log(` ${name}`);
48-
return npmRun.execSync(`tsc -p ${path.relative(process.cwd(), pkg.root)}`);
49+
try {
50+
return npmRun.execSync(`tsc -p ${path.relative(process.cwd(), pkg.root)}`);
51+
} catch (err) {
52+
throw new Error(`Compilation error.\n${err.stdout}`);
53+
}
4954
});
5055
}, Promise.resolve());
5156
})
@@ -116,6 +121,6 @@ Promise.resolve()
116121
}));
117122
})
118123
.then(() => process.exit(0), (err) => {
119-
console.error(err);
124+
console.error(chalk.red(err.message));
120125
process.exit(1);
121126
});

0 commit comments

Comments
 (0)