Skip to content

Commit

Permalink
fix(@angular/cli): check Node, Angular and RxJs minimum versions for …
Browse files Browse the repository at this point in the history
…CLI v6
  • Loading branch information
filipesilva committed Mar 26, 2018
1 parent 6cf7181 commit 5380b72
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 120 deletions.
68 changes: 8 additions & 60 deletions packages/@angular/cli/bin/ng
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const resolve = require('resolve');
const stripIndents = require('common-tags').stripIndents;
const yellow = require('chalk').yellow;
const SemVer = require('semver').SemVer;
const semver = require('semver');
const events = require('events');


Expand Down Expand Up @@ -65,68 +66,18 @@ if (process.env['NG_CLI_PROFILING']) {
}


// Show the warnings due to package and version deprecation.
// Show the warnings/errors due to package and version deprecation.
const version = new SemVer(process.version);
if (version.compare(new SemVer('6.9.0')) < 0
&& CliConfig.fromGlobal().get('warnings.nodeDeprecation')) {
if (version.compare(new SemVer('8.9.0')) < 0
&& CliConfig.fromGlobal().get('warnings.nodeDeprecation')) {
process.stderr.write(yellow(stripIndents`
You are running version ${version.version} of Node, which will not be supported in future
versions of the CLI. The official Node version that will be supported is 6.9 and greater.
You are running version ${version.version} of Node, which is not supported by Angular CLI v6.
The official Node version that is supported is 8.9 and greater.
To disable this warning use "ng set --global warnings.nodeDeprecation=false".
Please visit https://nodejs.org/en/ to find instructions on how to update Node.
`));
}


if (require('../package.json')['name'] == 'angular-cli'
&& CliConfig.fromGlobal().get('warnings.packageDeprecation')) {
process.stderr.write(yellow(stripIndents`
As a forewarning, we are moving the CLI npm package to "@angular/cli" with the next release,
which will only support Node 6.9 and greater. This package will be officially deprecated
shortly after.
To disable this warning use "ng set --global warnings.packageDeprecation=false".
`));
}

const packageJsonProjectPath = findUp('package.json', process.cwd(), true);
if (packageJsonProjectPath && fs.existsSync(packageJsonProjectPath)) {
const packageJsonProject = require(packageJsonProjectPath);
const deps = packageJsonProject['dependencies'] || {};
const devDeps = packageJsonProject['devDependencies'] || {};
const hasOldDep = !!deps['angular-cli'];
const hasDep = !!deps['@angular/cli'];
const hasOldDevDep = !!devDeps['angular-cli'];
const hasDevDep = !!devDeps['@angular/cli'];

if (hasOldDep || hasOldDevDep || !(hasDevDep || hasDep)) {
const warnings = [
'Unable to find "@angular/cli" in devDependencies.',
''
];

if (hasOldDep || hasOldDevDep) {
warnings.push(
'The package "angular-cli" has been deprecated and renamed to "@angular/cli".',
'');
}

warnings.push('Please take the following steps to avoid issues:');

if (hasOldDep) {
warnings.push('"npm uninstall --save angular-cli"');
}
if (hasOldDevDep) {
warnings.push('"npm uninstall --save-dev angular-cli"');
}
if (hasDep) {
warnings.push('"npm uninstall --save @angular/cli"')
}
if (!hasDevDep) {
warnings.push('"npm install --save-dev @angular/cli@latest"');
}
process.stderr.write(yellow(warnings.join('\n'), '\n\n'));
}
process.exit(3);
}

resolve('@angular/cli', { basedir: process.cwd() },
Expand All @@ -139,9 +90,6 @@ resolve('@angular/cli', { basedir: process.cwd() },
// npm package). Most common cause for hitting this is `ng new`
cli = require('../lib/cli');
} else {
// Verify that package's version.
Version.assertPostWebpackVersion();

// This was run from a global, check local version.
const globalVersion = new SemVer(packageJson['version']);
let localVersion;
Expand Down
3 changes: 2 additions & 1 deletion packages/@angular/cli/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export default class BuildCommand extends ArchitectCommand {
];

public validate(options: Options) {
Version.assertAngularVersionIs2_3_1OrHigher(this.project.root);
// Check Angular and TypeScript versions.
Version.assertCompatibleAngularVersion(this.project.root);
Version.assertTypescriptVersion(this.project.root);
return super.validate(options);
}
Expand Down
5 changes: 1 addition & 4 deletions packages/@angular/cli/commands/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import { CommandScope, Option } from '../models/command';
import { Version } from '../upgrade/version';
import { ArchitectCommand } from '../models/architect-command';

// Expose options unrelated to live-reload to other commands that need to run serve
export const baseServeCommandOptions: any = [];

export interface Options {
project?: string;
configuration?: string;
Expand All @@ -24,7 +21,7 @@ export default class ServeCommand extends ArchitectCommand {

public validate(_options: Options) {
// Check Angular and TypeScript versions.
Version.assertAngularVersionIs2_3_1OrHigher(this.project.root);
Version.assertCompatibleAngularVersion(this.project.root);
Version.assertTypescriptVersion(this.project.root);
return true;
}
Expand Down
113 changes: 58 additions & 55 deletions packages/@angular/cli/upgrade/version.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {SemVer, satisfies} from 'semver';
import { SemVer, satisfies } from 'semver';
import chalk from 'chalk';
import {stripIndents, stripIndent} from 'common-tags';
import {readFileSync, existsSync} from 'fs';
import { stripIndents, stripIndent } from 'common-tags';
import { readFileSync, existsSync } from 'fs';
import * as path from 'path';

import {CliConfig} from '../models/config';
import {findUp} from '../utilities/find-up';
import {requireProjectModule} from '../utilities/require-project-module';
import { CliConfig } from '../models/config';
import { findUp } from '../utilities/find-up';
import { requireProjectModule } from '../utilities/require-project-module';

const resolve = require('resolve');

Expand All @@ -15,11 +15,11 @@ const { bold, red, yellow } = chalk;

function _hasOldCliBuildFile() {
return existsSync(findUp('angular-cli-build.js', process.cwd()))
|| existsSync(findUp('angular-cli-build.ts', process.cwd()))
|| existsSync(findUp('ember-cli-build.js', process.cwd()))
|| existsSync(findUp('angular-cli-build.js', __dirname))
|| existsSync(findUp('angular-cli-build.ts', __dirname))
|| existsSync(findUp('ember-cli-build.js', __dirname));
|| existsSync(findUp('angular-cli-build.ts', process.cwd()))
|| existsSync(findUp('ember-cli-build.js', process.cwd()))
|| existsSync(findUp('angular-cli-build.js', __dirname))
|| existsSync(findUp('angular-cli-build.ts', __dirname))
|| existsSync(findUp('ember-cli-build.js', __dirname));
}


Expand Down Expand Up @@ -85,63 +85,66 @@ export class Version {
}
}

static assertAngularVersionIs2_3_1OrHigher(projectRoot: string) {
let pkgJson;
static assertCompatibleAngularVersion(projectRoot: string) {
let angularPkgJson;
let rxjsPkgJson;
try {
pkgJson = requireProjectModule(projectRoot, '@angular/core/package.json');
angularPkgJson = requireProjectModule(projectRoot, '@angular/core/package.json');
rxjsPkgJson = requireProjectModule(projectRoot, 'rxjs/package.json');
} catch (_) {
console.error(bold(red(stripIndents`
You seem to not be depending on "@angular/core". This is an error.
You seem to not be depending on "@angular/core" and/or "rxjs". This is an error.
`)));
process.exit(2);
}

// Just check @angular/core.
if (pkgJson && pkgJson['version']) {
const v = new Version(pkgJson['version']);
if (v.isLocal()) {
console.warn(yellow('Using a local version of angular. Proceeding with care...'));
} else {
// Check if major is not 0, so that we stay compatible with local compiled versions
// of angular.
if (!v.isGreaterThanOrEqualTo(new SemVer('2.3.1')) && v.major != 0) {
console.error(bold(red(stripIndents`
This version of CLI is only compatible with angular version 2.3.1 or better. Please
upgrade your angular version, e.g. by running:
npm install @angular/core@latest
` + '\n')));
process.exit(3);
}
}
} else {
if (!(angularPkgJson && angularPkgJson['version'] && rxjsPkgJson && rxjsPkgJson['version'])) {
console.error(bold(red(stripIndents`
You seem to not be depending on "@angular/core". This is an error.
Cannot determine versions of "@angular/core" and/or "rxjs".
This likely means your local installation is broken. Please reinstall your packages.
`)));
process.exit(2);
}
}

static assertPostWebpackVersion() {
if (this.isPreWebpack()) {
console.error(bold(red('\n' + stripIndents`
It seems like you're using a project generated using an old version of the Angular CLI.
The latest CLI now uses webpack and has a lot of improvements including a simpler
workflow, a faster build, and smaller bundles.
let angularVersion = new Version(angularPkgJson['version']);
let rxjsVersion = new Version(rxjsPkgJson['version']);

To get more info, including a step-by-step guide to upgrade the CLI, follow this link:
https://github.com/angular/angular-cli/wiki/Upgrading-from-Beta.10-to-Beta.14
` + '\n')));
process.exit(1);
} else {
// Verify that there's no build file.
if (_hasOldCliBuildFile()) {
console.error(bold(yellow('\n' + stripIndents`
It seems like you're using the newest version of the Angular CLI that uses webpack.
This version does not require an angular-cli-build file, but your project has one.
It will be ignored.
if (angularVersion.isLocal()) {
console.warn(yellow('Using a local version of angular. Proceeding with care...'));
return;
}

if (!angularVersion.isGreaterThanOrEqualTo(new SemVer('5.0.0'))) {
console.error(bold(red(stripIndents`
This version of CLI is only compatible with Angular version 5.0.0 or higher.
Please visit the link below to find instructions on how to update Angular.
https://angular-update-guide.firebaseapp.com/
` + '\n')));
process.exit(3);
} else if (
angularVersion.isGreaterThanOrEqualTo(new SemVer('6.0.0-rc.0'))
&& !rxjsVersion.isGreaterThanOrEqualTo(new SemVer('5.6.0-forward-compat.0'))
&& !rxjsVersion.isGreaterThanOrEqualTo(new SemVer('6.0.0-beta.0'))
) {
console.error(bold(red(stripIndents`
This project uses version ${rxjsVersion} of RxJs, which is not supported by Angular v6.
The official RxJs version that is supported is 5.6.0-forward-compat.0 and greater.
Please visit the link below to find instructions on how to update RxJs.
https://docs.google.com/document/d/12nlLt71VLKb-z3YaSGzUfx6mJbc34nsMXtByPUN35cg/edit#
` + '\n')));
process.exit(3);
} else if (
angularVersion.isGreaterThanOrEqualTo(new SemVer('6.0.0-rc.0'))
&& !rxjsVersion.isGreaterThanOrEqualTo(new SemVer('6.0.0-beta.0'))
) {
console.warn(bold(red(stripIndents`
This project uses a temporary compatibility version of RxJs (${rxjsVersion}.
Please visit the link below to find instructions on how to update RxJs.
https://docs.google.com/document/d/12nlLt71VLKb-z3YaSGzUfx6mJbc34nsMXtByPUN35cg/edit#
` + '\n')));
}
}
}

Expand Down Expand Up @@ -181,7 +184,7 @@ export class Version {
// First line of warning looks weird being split in two, disable tslint for it.
console.log((yellow('\n' + stripIndent`
@angular/compiler-cli@${compilerVersion} requires typescript@'${
currentCombo.typescript}' but ${tsVersion} was found instead.
currentCombo.typescript}' but ${tsVersion} was found instead.
Using this version can result in undefined behaviour and difficult to debug problems.
Please run the following command to install a compatible version of TypeScript.
Expand Down

0 comments on commit 5380b72

Please sign in to comment.