diff --git a/.travis.yml b/.travis.yml
index 8a9876e669c6..72305cb70144 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,11 @@
dist: trusty
sudo: required
env:
- - NODE_VERSION=5 SCRIPT=lint
- - NODE_VERSION=5 SCRIPT=test
+ global:
+ - DBUS_SESSION_BUS_ADDRESS=/dev/null
+ matrix:
+ - NODE_VERSION=5 SCRIPT=lint
+ - NODE_VERSION=5 SCRIPT=test
os:
- linux
- osx
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9abc840911a6..4abf0e151d50 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,35 +1,145 @@
-## Always follow the [upgrade guide](https://github.com/angular/angular-cli/blob/master/CHANGELOG.md#updating-angular-cli) when upgrading to a new version. The changelog does not list breaking changes that are fixed via the update procedure.
+**Always follow the [update guide](https://github.com/angular/angular-cli/blob/master/README.md#updating-angular-cli) when updating to a new version. The changelog does not list breaking changes that are fixed via the update procedure.**
-
-# 1.0.0-beta.6 (2016-06-13)
+---
+
+
+# 1.0.0-beta.7 (2016-06-23)
+
+
+### Bug Fixes
+
+* **deps:** update router (#1121) ([b90a110](https://github.com/angular/angular-cli/commit/b90a110))
+* **e2e:** prevent chrome race condition (#1141) ([9df0ffe](https://github.com/angular/angular-cli/commit/9df0ffe))
+* **init:** don't replace live reload script on diffs (#1128) ([e97fd9f](https://github.com/angular/angular-cli/commit/e97fd9f)), closes [#1122](https://github.com/angular/angular-cli/issues/1122)
+* **lint:** add missing rulesDirectory (#1108) ([1690a82](https://github.com/angular/angular-cli/commit/1690a82)), closes [#1094](https://github.com/angular/angular-cli/issues/1094)
+* **mobile:** partially fix dep problem (#1151) ([4b638c8](https://github.com/angular/angular-cli/commit/4b638c8)), closes [(#1151](https://github.com/(/issues/1151)
### Features
-- Admin elevation no longer required on Windows (https://github.com/angular/angular-cli/pull/905).
-- Automatically add SASS/Stylus if project is initialized with `--style={sass|scss|styl}` (https://github.com/angular/angular-cli/pull/998).
-- Allow any number of env files (https://github.com/angular/angular-cli/pull/913).
+
+* add file system utilities for 'upgrade' process ([327f649](https://github.com/angular/angular-cli/commit/327f649))
+
+
+
+
+# 1.0.0-beta.6 (2016-06-15)
+
### Bug Fixes
-- Fix adding 3rd party libs without package format (https://github.com/angular/angular-cli/pull/1028/commits/065e98f40384f8b28dcaf84028c411043697ff11).
-- Fix github deploy deep links (https://github.com/angular/angular-cli/pull/1020).
-- Fix `ng e2e` exit code (https://github.com/angular/angular-cli/pull/1025).
-- Fix missing vendor file (https://github.com/angular/angular-cli/pull/972).
-- Fix github user pages base href (https://github.com/angular/angular-cli/pull/965).
+
+* **admin:** added support for non Administrator CLI user ([0bc3d94](https://github.com/angular/angular-cli/commit/0bc3d94)), closes [#905](https://github.com/angular/angular-cli/issues/905) [#886](https://github.com/angular/angular-cli/issues/886) [#370](https://github.com/angular/angular-cli/issues/370)
+* **barrel:** alphabetized barrel exports ([67b577d](https://github.com/angular/angular-cli/commit/67b577d)), closes [#582](https://github.com/angular/angular-cli/issues/582)
+* **deploy:** Fix base href for user pages (#965) ([424cff2](https://github.com/angular/angular-cli/commit/424cff2)), closes [(#965](https://github.com/(/issues/965)
+* **e2e:** return exit codes on failure of e2e tests ([d0c07ac](https://github.com/angular/angular-cli/commit/d0c07ac)), closes [#1017](https://github.com/angular/angular-cli/issues/1017) [#1025](https://github.com/angular/angular-cli/issues/1025) [#1044](https://github.com/angular/angular-cli/issues/1044)
+* **generator:** --dry-run no longer modifies files ([6efc8ee](https://github.com/angular/angular-cli/commit/6efc8ee))
+* Persist style extension config at project creation. ([85c9aec](https://github.com/angular/angular-cli/commit/85c9aec)), closes [#780](https://github.com/angular/angular-cli/issues/780)
+* skips git-init if working folder is inside a git repo ([52c0cfb](https://github.com/angular/angular-cli/commit/52c0cfb)), closes [#802](https://github.com/angular/angular-cli/issues/802)
+* **gh-deploy:** fix deep links (#1020) ([f8f8179](https://github.com/angular/angular-cli/commit/f8f8179)), closes [(#1020](https://github.com/(/issues/1020) [#995](https://github.com/angular/angular-cli/issues/995)
+* **mobile:** add missing vendor file to build (#972) ([9a7bfe0](https://github.com/angular/angular-cli/commit/9a7bfe0)), closes [#847](https://github.com/angular/angular-cli/issues/847)
+* **mobile:** lock dependency (#961) ([740805b](https://github.com/angular/angular-cli/commit/740805b)), closes [#958](https://github.com/angular/angular-cli/issues/958)
+* **sourcemaps:** try to improve the source maps by fixing the path (#1028) ([5f909aa](https://github.com/angular/angular-cli/commit/5f909aa))
+* **template:** Update pipe template to include Pipe in name ([c92f330](https://github.com/angular/angular-cli/commit/c92f330)), closes [#869](https://github.com/angular/angular-cli/issues/869)
+
+### Features
+
+* allow lazy route prefix to be configurable ([c3fd9c7](https://github.com/angular/angular-cli/commit/c3fd9c7)), closes [#842](https://github.com/angular/angular-cli/issues/842)
+* **router:** upgrade the router version ([eb9b80e](https://github.com/angular/angular-cli/commit/eb9b80e))
+* **style:** automatically add dependencies if style is set on new projects ([01e31ab](https://github.com/angular/angular-cli/commit/01e31ab)), closes [#986](https://github.com/angular/angular-cli/issues/986)
+* **test:** run e2e of generated project (#490) ([d0dbd70](https://github.com/angular/angular-cli/commit/d0dbd70))
+
### BREAKING CHANGES
-- `AppComponent` is now simply `AppComponent`, and it's selector is now `app-root` (https://github.com/angular/angular-cli/pull/1042).
-- Route generation is temporarily disabled while we move to the [recently announce router](http://angularjs.blogspot.ie/2016/06/improvements-coming-for-routing-in.html)(https://github.com/angular/angular-cli/pull/992). It is recommended that users manually move to this router in all new projects.
+* The router has been updated to the newest version, usage of the deprecated router and the original release candidate routers are no longer supported
+
+* `AppComponent` is now simply `AppComponent`, and it's selector is now `app-root` (https://github.com/angular/angular-cli/pull/1042).
+
+* Route generation is temporarily disabled while we move to the [recently announce router](http://angularjs.blogspot.ie/2016/06/improvements-coming-for-routing-in.html)(https://github.com/angular/angular-cli/pull/992). It is recommended that users manually move to this router in all new projects.
+
+
# 1.0.0-beta.5 (2016-05-19)
-### Known Issues
-- `ng new -mobile` fails npm install (https://github.com/angular/angular-cli/issues/958).
-- Adding 3rd party libs without SystemJS package format breaks prod mode (https://github.com/angular/angular-cli/issues/951).
-- Deep links do not work on Github pages deploys (https://github.com/angular/angular-cli/issues/995).
-- `ng e2e` doesn't return error exit code on test failures (https://github.com/angular/angular-cli/issues/1017).
-- `ng build -prod` fails on mobile projects due to missing vendor file (https://github.com/angular/angular-cli/issues/847).
-- Github deploy to user pages doesn't use correct base href (https://github.com/angular/angular-cli/pull/965).
-- `ng test` on windows hits the file discriptor limit (https://github.com/angular/angular-cli/issues/977).
-- `ng serve/build/test` need admin elevation on Windows (https://github.com/angular/angular-cli/issues/641).
\ No newline at end of file
+### Bug Fixes
+
+* **build:** fix broken sourcemaps (#839) ([234de2b](https://github.com/angular/angular-cli/commit/234de2b)), closes [(#839](https://github.com/(/issues/839)
+
+### Features
+
+* **blueprint:** add blueprint for generating interfaces (#757) ([482aa74](https://github.com/angular/angular-cli/commit/482aa74)), closes [#729](https://github.com/angular/angular-cli/issues/729)
+* **test:** use link-cli option on e2e (#841) ([85d1400](https://github.com/angular/angular-cli/commit/85d1400))
+
+### Performance Improvements
+
+* **ng new:** command to link to `angular-cli` (#778) ([9b8334f](https://github.com/angular/angular-cli/commit/9b8334f))
+
+
+
+
+# 1.0.0-beta.4 (2016-05-18)
+
+
+### Bug Fixes
+
+* **build:** fix infinite loop on ng serve (#775) ([285db13](https://github.com/angular/angular-cli/commit/285db13)), closes [(#775](https://github.com/(/issues/775)
+* **deploy:** fix file copy, index tag rewrite (#772) ([a34aca8](https://github.com/angular/angular-cli/commit/a34aca8)), closes [(#772](https://github.com/(/issues/772)
+* **index:** fix live reload file path (#774) ([be718cb](https://github.com/angular/angular-cli/commit/be718cb)), closes [(#774](https://github.com/(/issues/774)
+* **mobile:** don't import system-config in system-import.js (#794) ([7ab7d72](https://github.com/angular/angular-cli/commit/7ab7d72))
+* **mobile:** make app-shell compilation synchronous ([9ed28ba](https://github.com/angular/angular-cli/commit/9ed28ba))
+* **mobile:** prevent already-bundled JS from getting cached by Service Worker ([9d18f74](https://github.com/angular/angular-cli/commit/9d18f74))
+
+### Features
+
+* **mobile:** add app shell to mobile blueprint (#809) ([e7d7ed8](https://github.com/angular/angular-cli/commit/e7d7ed8))
+* **SASSPlugin:** Allow regexes to be passed to include/exclude certain file patterns ([6b45099](https://github.com/angular/angular-cli/commit/6b45099)), closes [#558](https://github.com/angular/angular-cli/issues/558)
+
+
+
+
+# 1.0.0-beta.2-mobile.3 (2016-05-13)
+
+
+### Bug Fixes
+
+* **broccoli-typescript:** properly parse compilerOptions (#764) ([bbf1bc8](https://github.com/angular/angular-cli/commit/bbf1bc8))
+* **mobile:** include vendor scripts in bundle ([679d0e6](https://github.com/angular/angular-cli/commit/679d0e6)), closes [#733](https://github.com/angular/angular-cli/issues/733)
+* **mobile:** remove mobile-specific dependencies from root package ([263e23b](https://github.com/angular/angular-cli/commit/263e23b))
+* **mobile:** update path to reflect updated service worker package (#746) ([818fb19](https://github.com/angular/angular-cli/commit/818fb19))
+* **package:** temporarily remove angular2-service-worker ([7f86ab3](https://github.com/angular/angular-cli/commit/7f86ab3))
+
+### Features
+
+* **blueprints:** add enum blueprint. ([eddb354](https://github.com/angular/angular-cli/commit/eddb354)), closes [#707](https://github.com/angular/angular-cli/issues/707)
+
+
+
+
+# 1.0.0-beta.2-mobile (2016-05-12)
+
+
+### Bug Fixes
+
+* package.json use sourceDir for new command ([8dcd996](https://github.com/angular/angular-cli/commit/8dcd996))
+* use options sourceDir, and fix null property access. Also use 1.9 ([7ba388d](https://github.com/angular/angular-cli/commit/7ba388d)), closes [#619](https://github.com/angular/angular-cli/issues/619)
+* **710:** Missing http module dependency ([c0aadae](https://github.com/angular/angular-cli/commit/c0aadae))
+* **commands:** fix outdated string utils import. ([7db40df](https://github.com/angular/angular-cli/commit/7db40df))
+
+### Features
+
+* **mobile:** add blueprint for app manifest and icons ([f717bde](https://github.com/angular/angular-cli/commit/f717bde))
+* **mobile:** add prod build step to concatenate scripts ([51569ce](https://github.com/angular/angular-cli/commit/51569ce))
+* **mobile:** add ServiceWorker generation to build process and index ([04593eb](https://github.com/angular/angular-cli/commit/04593eb))
+* **mobile:** add support for generating App Shell in index.html ([cb1270f](https://github.com/angular/angular-cli/commit/cb1270f))
+* **ng2 blueprint:** add test script entry to package.json ([eabc160](https://github.com/angular/angular-cli/commit/eabc160))
+
+
+
+
+# 1.0.0-beta.1 (2016-05-07)
+
+
+### Bug Fixes
+
+* **generated-project:** cli was not using the correct version of CLI in generated project. (#672) ([02073ae](https://github.com/angular/angular-cli/commit/02073ae))
+
diff --git a/README.md b/README.md
index 7fb9e7f58cb6..2deb864fa7b2 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,9 @@ If you wish to collaborate while the project is still young, check out [our issu
## Prerequisites
-The generated project has dependencies that require **Node 4 or greater**.
+The generated project has dependencies that require
+* **Node 4 or greater**.
+* **Typings v1 or greater**.
## Table of Contents
@@ -29,6 +31,7 @@ The generated project has dependencies that require **Node 4 or greater**.
* [Generating a Route](#generating-a-route)
* [Creating a Build](#creating-a-build)
* [Environments](#environments)
+* [Bundling](#bundling)
* [Running Unit Tests](#running-unit-tests)
* [Running End-to-End Tests](#running-end-to-end-tests)
* [Deploying the App via GitHub Pages](#deploying-the-app-via-github-pages)
@@ -129,16 +132,21 @@ The build artifacts will be stored in the `dist/` directory.
### Environments
-At build time, the `src/client/app/environment.ts` will be replaced by either
+At build time, the `src/app/environment.ts` will be replaced by either
`config/environment.dev.ts` or `config/environment.prod.ts`, depending on the
-current cli environment.
+current cli environment. The resulting file will be `dist/app/environment.ts`.
Environment defaults to `dev`, but you can generate a production build via
the `-prod` flag in either `ng build -prod` or `ng serve -prod`.
-You can also add your own env files other than `dev` and `prod` by creating a
-`src/client/app/environment.{NAME}.ts` and use them by using the `--env=NAME`
-flag on the build/serve commands.
+You can also add your own env files other than `dev` and `prod` by creating a
+`config/environment.{NAME}.ts` and use them by using the `--env=NAME`
+flag on the build/serve commands.
+
+### Bundling
+
+Builds created with the `-prod` flag via `ng build -prod` or `ng serve -prod` bundle
+all dependencies into a single file, and make use of tree-shaking techniques.
### Running unit tests
@@ -206,7 +214,7 @@ You can modify the these scripts in `package.json` to run whatever tool you pref
### Support for offline applications
-The index.html file includes a commented-out code snippet for installing the angular2-service-worker. This support is experimental, please see the angular/mobile-toolkit project for documentation on how to make use of this functionality.
+The index.html file includes a commented-out code snippet for installing the angular2-service-worker. This support is experimental, please see the angular/mobile-toolkit project and https://mobile.angular.io/ for documentation on how to make use of this functionality.
### Commands autocompletion
diff --git a/addon/ng2/blueprints/ng2/files/__path__/system-config.ts b/addon/ng2/blueprints/ng2/files/__path__/system-config.ts
index 36e6f9403836..55e4ac712886 100644
--- a/addon/ng2/blueprints/ng2/files/__path__/system-config.ts
+++ b/addon/ng2/blueprints/ng2/files/__path__/system-config.ts
@@ -22,6 +22,7 @@ const barrels: string[] = [
'@angular/core',
'@angular/common',
'@angular/compiler',
+ '@angular/forms',
'@angular/http',
'@angular/router',
'@angular/platform-browser',
diff --git a/addon/ng2/blueprints/ng2/files/package.json b/addon/ng2/blueprints/ng2/files/package.json
index a0bc9b676b58..723bdbc12380 100644
--- a/addon/ng2/blueprints/ng2/files/package.json
+++ b/addon/ng2/blueprints/ng2/files/package.json
@@ -13,13 +13,14 @@
},
"private": true,
"dependencies": {
- "@angular/common": "2.0.0-rc.1",
- "@angular/compiler": "2.0.0-rc.1",
- "@angular/core": "2.0.0-rc.1",
- "@angular/http": "2.0.0-rc.1",
- "@angular/platform-browser": "2.0.0-rc.1",
- "@angular/platform-browser-dynamic": "2.0.0-rc.1",
- "@angular/router": "3.0.0-alpha.3",
+ "@angular/common": "2.0.0-rc.3",
+ "@angular/compiler": "2.0.0-rc.3",
+ "@angular/core": "2.0.0-rc.3",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.3",
+ "@angular/platform-browser": "2.0.0-rc.3",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.3",
+ "@angular/router": "3.0.0-alpha.8",
"es6-shim": "0.35.1",
"reflect-metadata": "0.1.3",
"rxjs": "5.0.0-beta.6",
@@ -27,12 +28,11 @@
"zone.js": "0.6.12"
},
"devDependencies": {<% if(isMobile) { %>
- "@angular/platform-server": "2.0.0-rc.1",
- "@angular/router-deprecated": "2.0.0-rc.1",
+ "@angular/platform-server": "2.0.0-rc.3",
"@angular/service-worker": "0.2.0",
"@angular/app-shell": "0.0.0",
"angular2-broccoli-prerender": "0.11.0",
- "angular2-universal":"0.101.5",
+ "angular2-universal":"0.100.5",
"angular2-universal-polyfills": "0.4.1",
"preboot": "2.0.10",<% } %>
"angular-cli": "<%= version %>",
diff --git a/addon/ng2/blueprints/ng2/files/tslint.json b/addon/ng2/blueprints/ng2/files/tslint.json
index 490c4bd51da5..7b13bd1790a4 100644
--- a/addon/ng2/blueprints/ng2/files/tslint.json
+++ b/addon/ng2/blueprints/ng2/files/tslint.json
@@ -1,4 +1,7 @@
{
+ "rulesDirectory": [
+ "node_modules/codelyzer"
+ ],
"rules": {
"class-name": true,
"comment-format": [
diff --git a/addon/ng2/commands/init.js b/addon/ng2/commands/init.js
index f77a1c2852b7..7c7fff8aa460 100644
--- a/addon/ng2/commands/init.js
+++ b/addon/ng2/commands/init.js
@@ -7,6 +7,7 @@ var validProjectName = require('ember-cli/lib/utilities/valid-project-name');
var normalizeBlueprint = require('ember-cli/lib/utilities/normalize-blueprint-option');
var GitInit = require('../tasks/git-init');
var LinkCli = require('../tasks/link-cli');
+var NpmInstall = require('../tasks/npm-install');
module.exports = Command.extend({
name: 'init',
@@ -68,7 +69,7 @@ module.exports = Command.extend({
}
if (!commandOptions.skipNpm) {
- var npmInstall = new this.tasks.NpmInstall({
+ var npmInstall = new NpmInstall({
ui: this.ui,
analytics: this.analytics,
project: this.project
diff --git a/addon/ng2/tasks/npm-install.js b/addon/ng2/tasks/npm-install.js
new file mode 100644
index 000000000000..40fa58af9cbe
--- /dev/null
+++ b/addon/ng2/tasks/npm-install.js
@@ -0,0 +1,11 @@
+'use strict';
+
+// Runs `npm install` in cwd
+
+var NpmTask = require('./npm-task');
+
+module.exports = NpmTask.extend({
+ command: 'install',
+ startProgressMessage: 'Installing packages for tooling via npm',
+ completionMessage: 'Installed packages for tooling via npm.'
+});
diff --git a/addon/ng2/tasks/npm-task.js b/addon/ng2/tasks/npm-task.js
new file mode 100644
index 000000000000..4f720da73175
--- /dev/null
+++ b/addon/ng2/tasks/npm-task.js
@@ -0,0 +1,64 @@
+/*eslint-disable no-console */
+'use strict';
+
+// Runs `npm install` in cwd
+
+var chalk = require('chalk');
+var Task = require('ember-cli/lib/models/task');
+var npm = require('../utilities/npm');
+
+module.exports = Task.extend({
+ // The command to run: can be 'install' or 'uninstall'
+ command: '',
+ // Message to send to ui.startProgress
+ startProgressMessage: '',
+ // Message to send to ui.writeLine on completion
+ completionMessage: '',
+
+ init: function() {
+ this.npm = this.npm || require('npm');
+ },
+ // Options: Boolean verbose
+ run: function(options) {
+ this.ui.startProgress(chalk.green(this.startProgressMessage), chalk.green('.'));
+
+ var npmOptions = {
+ loglevel: options.verbose ? 'verbose' : 'error',
+ progress: false,
+ logstream: this.ui.outputStream,
+ color: 'always',
+ // by default, do install peoples optional deps
+ 'optional': 'optional' in options ? options.optional : true,
+ 'save-dev': !!options['save-dev'],
+ 'save-exact': !!options['save-exact']
+ };
+
+ var packages = options.packages || [];
+
+ // npm otherwise is otherwise noisy, already submitted PR for npm to fix
+ // misplaced console.log
+ this.disableLogger();
+
+ return npm(this.command, packages, npmOptions, this.npm).
+ finally(this.finally.bind(this)).
+ then(this.announceCompletion.bind(this));
+ },
+
+ announceCompletion: function() {
+ this.ui.writeLine(chalk.green(this.completionMessage));
+ },
+
+ finally: function() {
+ this.ui.stopProgress();
+ this.restoreLogger();
+ },
+
+ disableLogger: function() {
+ this.oldLog = console.log;
+ console.log = function() {};
+ },
+
+ restoreLogger: function() {
+ console.log = this.oldLog; // Hack, see above
+ }
+});
diff --git a/addon/ng2/utilities/change.ts b/addon/ng2/utilities/change.ts
new file mode 100644
index 000000000000..4e6191952875
--- /dev/null
+++ b/addon/ng2/utilities/change.ts
@@ -0,0 +1,114 @@
+'use strict';
+
+import * as Promise from 'ember-cli/lib/ext/promise';
+import fs = require('fs');
+
+const readFile = Promise.denodeify(fs.readFile);
+const writeFile = Promise.denodeify(fs.writeFile);
+
+export interface Change {
+
+ apply(): Promise;
+
+ // The file this change should be applied to. Some changes might not apply to
+ // a file (maybe the config).
+ path: string | null;
+
+ // The order this change should be applied. Normally the position inside the file.
+ // Changes are applied from the bottom of a file to the top.
+ order: number;
+
+ // The description of this change. This will be outputted in a dry or verbose run.
+ description: string;
+}
+
+/**
+ * Will add text to the source code.
+ */
+export class InsertChange implements Change {
+
+ const order: number;
+ const description: string;
+
+ constructor(
+ public path: string,
+ private pos: number,
+ private toAdd: string,
+ ) {
+ if (pos < 0) {
+ throw new Error('Negative positions are invalid');
+ }
+ this.description = `Inserted ${toAdd} into position ${pos} of ${path}`;
+ this.order = pos;
+ }
+
+ /**
+ * This method does not insert spaces if there is none in the original string.
+ */
+ apply(): Promise {
+ return readFile(this.path, 'utf8').then(content => {
+ let prefix = content.substring(0, this.pos);
+ let suffix = content.substring(this.pos);
+ return writeFile(this.path, `${prefix}${this.toAdd}${suffix}`);
+ });
+ }
+}
+
+/**
+ * Will remove text from the source code.
+ */
+export class RemoveChange implements Change {
+
+ const order: number;
+ const description: string;
+
+ constructor(
+ public path: string,
+ private pos: number,
+ private toRemove: string) {
+ if (pos < 0) {
+ throw new Error('Negative positions are invalid');
+ }
+ this.description = `Removed ${toRemove} into position ${pos} of ${path}`;
+ this.order = pos;
+ }
+
+ apply(): Promise {
+ return readFile(this.path, 'utf8').then(content => {
+ let prefix = content.substring(0, this.pos);
+ let suffix = content.substring(this.pos + this.toRemove.length);
+ // TODO: throw error if toRemove doesn't match removed string.
+ return writeFile(this.path, `${prefix}${suffix}`);
+ });
+ }
+}
+
+/**
+ * Will replace text from the source code.
+ */
+export class ReplaceChange implements Change {
+
+ const order: number;
+ const description: string;
+
+ constructor(
+ public path: string,
+ private pos: number,
+ private oldText: string,
+ private newText: string) {
+ if (pos < 0) {
+ throw new Error('Negative positions are invalid');
+ }
+ this.description = `Replaced ${oldText} into position ${pos} of ${path} with ${newText}`;
+ this.order = pos;
+ }
+
+ apply(): Promise {
+ return readFile(this.path, 'utf8').then(content => {
+ let prefix = content.substring(0, this.pos);
+ let suffix = content.substring(this.pos + this.oldText.length);
+ // TODO: throw error if oldText doesn't match removed string.
+ return writeFile(this.path, `${prefix}${this.newText}${suffix}`);
+ });
+ }
+}
diff --git a/addon/ng2/utilities/npm.js b/addon/ng2/utilities/npm.js
new file mode 100644
index 000000000000..fd88e14538d1
--- /dev/null
+++ b/addon/ng2/utilities/npm.js
@@ -0,0 +1,38 @@
+'use strict';
+
+var Promise = require('ember-cli/lib/ext/promise');
+
+//
+
+/**
+ Runs the npm command `command` with the supplied args and load options.
+
+ Please note that the loaded module appears to retain some state, so do not
+ expect multiple invocations within the same process to work without quirks.
+ This problem is likely fixable.
+
+ @method npm
+ @param {String} command The npm command to run.
+ @param {Array} npmArgs The arguments passed to the npm command.
+ @param {Array} options The options passed when loading npm.
+ @param {Module} [npm] A reference to the npm module.
+*/
+module.exports = function npm(command, npmArgs, options/*, npm*/) {
+ var lib;
+ if (arguments.length === 4) {
+ lib = arguments[3];
+ } else {
+ lib = require('npm');
+ }
+
+ var load = Promise.denodeify(lib.load);
+
+ return load(options)
+ .then(function() {
+ // if install is denodeified outside load.then(),
+ // it throws "Call npm.load(config, cb) before using this command."
+ var operation = Promise.denodeify(lib.commands[command]);
+
+ return operation(npmArgs || []);
+ });
+};
diff --git a/lib/broccoli/angular-broccoli-sass.js b/lib/broccoli/angular-broccoli-sass.js
index 9d0f5e35b82e..aca7d93aac20 100644
--- a/lib/broccoli/angular-broccoli-sass.js
+++ b/lib/broccoli/angular-broccoli-sass.js
@@ -26,10 +26,13 @@ class SASSPlugin extends Plugin {
build() {
this.listFiles().forEach(fileName => {
- // Normalize is necessary for changing `\`s into `/`s on windows.
- this.compile(path.normalize(fileName),
- path.normalize(this.inputPaths[0]),
- path.normalize(this.outputPath));
+ // We skip compiling partials (_*.scss files)
+ if(!/^_+.*.s[ac]ss$/.test(path.basename(fileName))) {
+ // Normalize is necessary for changing `\`s into `/`s on windows.
+ this.compile(path.normalize(fileName),
+ path.normalize(this.inputPaths[0]),
+ path.normalize(this.outputPath));
+ }
});
}
diff --git a/lib/broccoli/angular2-app.js b/lib/broccoli/angular2-app.js
index 06d94fae2e48..1d2879b5296e 100644
--- a/lib/broccoli/angular2-app.js
+++ b/lib/broccoli/angular2-app.js
@@ -53,6 +53,14 @@ class Angular2App extends BroccoliPlugin {
this._tree = this._buildTree();
}
+ /**
+ * For compatibility with Ember addons
+ * @returns {*|{}}
+ */
+ get options(){
+ return this._options;
+ }
+
/**
* For backward compatibility.
* @public
diff --git a/lib/cli/index.js b/lib/cli/index.js
index ec87c3dbec98..bcf0fdd2c3c5 100644
--- a/lib/cli/index.js
+++ b/lib/cli/index.js
@@ -74,6 +74,10 @@ module.exports = function(options) {
if (line.match(/version:|WARNING:/)) {
return;
}
+ if (line.match(/ember-cli-(inject-)?live-reload/)) {
+ // don't replace 'ember-cli-live-reload' on ng init diffs
+ return oldStdoutWrite.apply(process.stdout, arguments);
+ }
line = line.replace(/ember-cli(?!.com)/g, 'angular-cli')
.replace(/ember(?!-cli.com)/g, 'ng');
return oldStdoutWrite.apply(process.stdout, arguments);
diff --git a/package.json b/package.json
index da14efca3de7..3aa0fb95d0da 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "angular-cli",
- "version": "1.0.0-beta.6",
+ "version": "1.0.0-beta.9",
"description": "CLI tool for Angular",
"main": "lib/cli/index.js",
"trackingCode": "UA-8594346-19",
@@ -47,6 +47,7 @@
"handlebars": "^4.0.5",
"leek": "0.0.21",
"lodash": "^4.11.1",
+ "npm": "3.10.2",
"opn": "4.0.1",
"resolve": "^1.1.7",
"shelljs": "^0.7.0",
@@ -63,6 +64,7 @@
},
"devDependencies": {
"chai": "^3.5.0",
+ "conventional-changelog": "^1.1.0",
"eslint": "^2.8.0",
"exists-sync": "0.0.3",
"minimatch": "^3.0.0",
@@ -72,8 +74,8 @@
"rewire": "^2.5.1",
"sinon": "^1.17.3",
"through": "^2.3.8",
- "tslint": "^3.8.1",
"tree-kill": "^1.0.0",
+ "tslint": "^3.8.1",
"walk-sync": "^0.2.6"
}
}
diff --git a/scripts/publish/changelog.js b/scripts/publish/changelog.js
new file mode 100755
index 000000000000..9064ee0ef0a9
--- /dev/null
+++ b/scripts/publish/changelog.js
@@ -0,0 +1,41 @@
+#!/usr/bin/env node
+'use strict';
+
+/**
+ * Just a small command-line wrapper around the conventional-changelog npm module
+ * (https://www.npmjs.com/package/conventional-changelog), which also prepends
+ * changes to CHANGELOG.md.
+ *
+ * Appends CHANGELOG.md with the changes between tag and HEAD.
+ * NOTE: only `fix`, `feat`, `perf` and `revert` commits are used
+ * see: https://github.com/conventional-changelog/conventional-changelog/blob/v0.2.1/presets/angular.js#L24
+ */
+
+var fs = require('fs');
+var cl = require('conventional-changelog');
+const exec = require('child_process').exec;
+
+var changelogStream = fs.createWriteStream('CHANGELOG-delta.md');
+
+if (process.argv.length < 3) {
+ console.log('Usage: ./scripts/publish/changelog.js ');
+ process.exit(-1);
+}
+
+var config = {
+ preset: 'angular',
+ releaseCount: 1,
+};
+
+var prependDelta = function() {
+ exec('cat CHANGELOG-delta.md CHANGELOG.md > CHANGELOG-new.md;' +
+ 'mv CHANGELOG-new.md CHANGELOG.md;' +
+ 'rm CHANGELOG-delta.md');
+}
+
+cl(config, null, { from: process.argv[2] })
+ .on('error', function(err) {
+ console.error('Failed to generate changelog: ' + err);
+ })
+ .pipe(changelogStream)
+ .on('close', prependDelta);
diff --git a/tests/acceptance/change.spec.ts b/tests/acceptance/change.spec.ts
new file mode 100644
index 000000000000..aaed20037394
--- /dev/null
+++ b/tests/acceptance/change.spec.ts
@@ -0,0 +1,120 @@
+'use strict';
+
+// This needs to be first so fs module can be mocked correctly.
+let mockFs = require('mock-fs');
+
+import {expect} from 'chai';
+import {InsertChange, RemoveChange, ReplaceChange} from '../../addon/ng2/utilities/change';
+import fs = require('fs');
+
+let path = require('path');
+let Promise = require('ember-cli/lib/ext/promise');
+
+const readFile = Promise.denodeify(fs.readFile);
+
+describe('Change', () => {
+ let sourcePath = 'src/app/my-component';
+
+ beforeEach(() => {
+ let mockDrive = {
+ 'src/app/my-component': {
+ 'add-file.txt': 'hello',
+ 'remove-replace-file.txt': 'import * as foo from "./bar"',
+ 'replace-file.txt': 'import { FooComponent } from "./baz"'
+ }
+ };
+ mockFs(mockDrive);
+ });
+ afterEach(() => {
+ mockFs.restore();
+ });
+
+ describe('InsertChange', () => {
+ let sourceFile = path.join(sourcePath, 'add-file.txt');
+
+ it('adds text to the source code', () => {
+ let changeInstance = new InsertChange(sourceFile, 6, ' world!');
+ return changeInstance
+ .apply()
+ .then(() => readFile(sourceFile, 'utf8'))
+ .then(contents => {
+ expect(contents).to.equal('hello world!');
+ });
+ });
+ it('fails for negative position', () => {
+ expect(() => new InsertChange(sourceFile, -6, ' world!')).to.throw(Error);
+ });
+ it('adds nothing in the source code if empty string is inserted', () => {
+ let changeInstance = new InsertChange(sourceFile, 6, '');
+ return changeInstance
+ .apply()
+ .then(() => readFile(sourceFile, 'utf8'))
+ .then(contents => {
+ expect(contents).to.equal('hello');
+ });
+ });
+ });
+
+ describe('RemoveChange', () => {
+ let sourceFile = path.join(sourcePath, 'remove-replace-file.txt');
+
+ it('removes given text from the source code', () => {
+ let changeInstance = new RemoveChange(sourceFile, 9, 'as foo');
+ return changeInstance
+ .apply()
+ .then(() => readFile(sourceFile, 'utf8'))
+ .then(contents => {
+ expect(contents).to.equal('import * from "./bar"');
+ });
+ });
+ it('fails for negative position', () => {
+ expect(() => new RemoveChange(sourceFile, -6, ' world!')).to.throw(Error);
+ });
+ it('does not change the file if told to remove empty string', () => {
+ let changeInstance = new RemoveChange(sourceFile, 9, '');
+ return changeInstance
+ .apply()
+ .then(() => readFile(sourceFile, 'utf8'))
+ .then(contents => {
+ expect(contents).to.equal('import * as foo from "./bar"');
+ });
+ });
+ });
+
+ describe('ReplaceChange', () => {
+ it('replaces the given text in the source code', () => {
+ let sourceFile = path.join(sourcePath, 'remove-replace-file.txt');
+ let changeInstance = new ReplaceChange(sourceFile, 7, '* as foo', '{ fooComponent }');
+ return changeInstance
+ .apply()
+ .then(() => readFile(sourceFile, 'utf8'))
+ .then(contents => {
+ expect(contents).to.equal('import { fooComponent } from "./bar"');
+ });
+ });
+ it('fails for negative position', () => {
+ let sourceFile = path.join(sourcePath, 'remove-replace-file.txt');
+ expect(() => new ReplaceChange(sourceFile, -6, 'hello', ' world!')).to.throw(Error);
+ });
+ it('adds string to the position of an empty string', () => {
+ let sourceFile = path.join(sourcePath, 'replace-file.txt');
+ let changeInstance = new ReplaceChange(sourceFile, 9, '', 'BarComponent, ');
+ return changeInstance
+ .apply()
+ .then(() => readFile(sourceFile, 'utf8'))
+ .then(contents => {
+ expect(contents).to.equal('import { BarComponent, FooComponent } from "./baz"');
+ });
+ });
+ it('removes the given string only if an empty string to add is given', () => {
+ let sourceFile = path.join(sourcePath, 'remove-replace-file.txt');
+ let changeInstance = new ReplaceChange(sourceFile, 9, ' as foo', '');
+ return changeInstance
+ .apply()
+ .then(() => readFile(sourceFile, 'utf8'))
+ .then(contents => {
+ expect(contents).to.equal('import * from "./bar"');
+ });
+ });
+ });
+});
diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js
index 3c90073b84fe..ea1ea1d2d920 100644
--- a/tests/e2e/e2e_workflow.spec.js
+++ b/tests/e2e/e2e_workflow.spec.js
@@ -291,12 +291,17 @@ describe('Basic end-to-end Workflow', function () {
let componentPath = path.join(process.cwd(), 'src', 'app', 'test-component');
let cssFile = path.join(componentPath, 'test-component.component.css');
let scssFile = path.join(componentPath, 'test-component.component.scss');
+ let scssPartialFile = path.join(componentPath, '_test-component.component.partial.scss');
+
+ let scssPartialExample = '.partial {\n @extend .outer;\n }';
+ fs.writeFileSync(scssPartialFile, scssPartialExample, 'utf8');
+ expect(existsSync(scssPartialFile)).to.be.equal(true);
expect(existsSync(componentPath)).to.be.equal(true);
sh.mv(cssFile, scssFile);
expect(existsSync(scssFile)).to.be.equal(true);
expect(existsSync(cssFile)).to.be.equal(false);
- let scssExample = '.outer {\n .inner { background: #fff; }\n }';
+ let scssExample = '@import "test-component.component.partial";\n\n.outer {\n .inner { background: #fff; }\n }';
fs.writeFileSync(scssFile, scssExample, 'utf8');
sh.exec(`${ngBin} build`);
@@ -304,6 +309,7 @@ describe('Basic end-to-end Workflow', function () {
expect(existsSync(destCss)).to.be.equal(true);
let contents = fs.readFileSync(destCss, 'utf8');
expect(contents).to.include('.outer .inner');
+ expect(contents).to.include('.partial .inner');
sh.rm('-f', destCss);
process.chdir('src');
@@ -311,6 +317,7 @@ describe('Basic end-to-end Workflow', function () {
expect(existsSync(destCss)).to.be.equal(true);
contents = fs.readFileSync(destCss, 'utf8');
expect(contents).to.include('.outer .inner');
+ expect(contents).to.include('.partial .inner');
process.chdir('..');
sh.exec('npm uninstall node-sass', { silent: true });