diff --git a/packages/angular-cli/bin/ng b/packages/angular-cli/bin/ng index b1eb5c355735..9e987f93c9f0 100755 --- a/packages/angular-cli/bin/ng +++ b/packages/angular-cli/bin/ng @@ -8,6 +8,7 @@ const resolve = require('resolve'); const exit = require('exit'); const packageJson = require('../package.json'); const Leek = require('leek'); +const Version = require('../upgrade/version').Version; resolve('angular-cli', { basedir: process.cwd() }, @@ -20,6 +21,9 @@ 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(); + // No error implies a projectLocalCli, which will load whatever // version of ng-cli you have installed in a local package.json cli = require(projectLocalCli); diff --git a/packages/angular-cli/models/config.ts b/packages/angular-cli/models/config.ts index 9cadd6dd2c63..f98e113f070a 100644 --- a/packages/angular-cli/models/config.ts +++ b/packages/angular-cli/models/config.ts @@ -29,7 +29,7 @@ function getUserHome() { export class CliConfig extends CliConfigBase { - private static _configFilePath(projectPath?: string): string { + static configFilePath(projectPath?: string): string { // Find the configuration, either where specified, in the angular-cli project // (if it's in node_modules) or from the current process. return (projectPath && _findUp(CLI_CONFIG_FILE_NAME, projectPath)) @@ -39,7 +39,7 @@ export class CliConfig extends CliConfigBase { static fromProject(): CliConfig { - const configPath = this._configFilePath(); + const configPath = this.configFilePath(); const globalConfigPath = path.join(getUserHome(), CLI_CONFIG_FILE_NAME); if (!configPath) { @@ -47,7 +47,7 @@ export class CliConfig extends CliConfigBase { } const cliConfig = CliConfigBase.fromConfigPath( - CliConfig._configFilePath(), [globalConfigPath]); + CliConfig.configFilePath(), [globalConfigPath]); const aliases = [ cliConfig.alias('apps.0.root', 'defaults.sourceDir'), diff --git a/packages/angular-cli/upgrade/version.ts b/packages/angular-cli/upgrade/version.ts new file mode 100644 index 000000000000..ca591ef62f63 --- /dev/null +++ b/packages/angular-cli/upgrade/version.ts @@ -0,0 +1,134 @@ +import {CliConfig} from '../models/config'; +import {readFileSync, existsSync} from 'fs'; +import {stripIndents} from 'common-tags'; +import {bold, red, yellow} from 'chalk'; +import * as path from 'path'; +const resolve = require('resolve'); + + +function _findUp(name: string, from: string) { + let currentDir = from; + while (currentDir && currentDir !== path.parse(currentDir).root) { + const p = path.join(currentDir, name); + if (existsSync(p)) { + return p; + } + + currentDir = path.dirname(currentDir); + } + + return null; +} + + +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)); +} + + +export class Version { + constructor(private _version: string) {} + + private _parse() { + return this.isKnown() + ? this._version.match(/^(\d+)\.(\d+)(?:\.(\d+))?(?:-(alpha|beta|rc)\.(.*))?$/).slice(1) + : []; + } + + isAlpha() { return this.qualifier == 'alpha'; } + isBeta() { return this.qualifier == 'beta'; } + isReleaseCandidate() { return this.qualifier == 'rc'; } + isKnown() { return this._version !== null; } + + get major() { return this._parse()[0] || 0; } + get minor() { return this._parse()[1] || 0; } + get patch() { return this._parse()[2] || 0; } + get qualifier() { return this._parse()[3] || ''; } + get extra() { return this._parse()[4] || ''; } + + toString() { return this._version; } + + static fromProject(): Version { + let packageJson: any = null; + + try { + const angularCliPath = resolve.sync('angular-cli', { + basedir: process.cwd(), + packageFilter: (pkg: any, pkgFile: string) => { + packageJson = pkg; + } + }); + if (angularCliPath && packageJson) { + try { + return new Version(packageJson.version); + } catch (e) { + return new Version(null); + } + } + } catch (e) { + // Fallback to reading config. + } + + + const configPath = CliConfig.configFilePath(); + const configJson = readFileSync(configPath, 'utf8'); + + try { + const json = JSON.parse(configJson); + return new Version(json.project && json.project.version); + } catch (e) { + return new Version(null); + } + } + + 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 includes a lot of improvements, include a simpler + workflow, a faster build and smaller bundles. + + 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.12 + ` + '\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. + ` + '\n'))); + } + } + } + + static isPreWebpack(): boolean { + // CliConfig is a bit stricter with the schema, so we need to be a little looser with it. + const version = Version.fromProject(); + + if (version && version.isKnown()) { + if (version.major == 0) { + return true; + } else if (version.minor != 0) { + return false; + } else if (version.isBeta() && !version.toString().match(/webpack/)) { + const betaVersion = version.extra; + + if (parseInt(betaVersion) < 12) { + return true; + } + } + } else { + return _hasOldCliBuildFile(); + } + + return false; + } +} diff --git a/scripts/publish/build.js b/scripts/publish/build.js index 5370311bacdb..01a79a91f804 100755 --- a/scripts/publish/build.js +++ b/scripts/publish/build.js @@ -2,6 +2,7 @@ 'use strict'; /*eslint-disable no-console */ +const chalk = require('chalk'); const denodeify = require('denodeify'); const fs = require('fs'); const glob = denodeify(require('glob')); @@ -45,7 +46,11 @@ Promise.resolve() return promise.then(() => { console.log(` ${name}`); - return npmRun.execSync(`tsc -p ${path.relative(process.cwd(), pkg.root)}`); + try { + return npmRun.execSync(`tsc -p ${path.relative(process.cwd(), pkg.root)}`); + } catch (err) { + throw new Error(`Compilation error.\n${err.stdout}`); + } }); }, Promise.resolve()); }) @@ -116,6 +121,6 @@ Promise.resolve() })); }) .then(() => process.exit(0), (err) => { - console.error(err); + console.error(chalk.red(err.message)); process.exit(1); });