diff --git a/src/cdk/schematics/migration.json b/src/cdk/schematics/migration.json index 46fdd3891b22..fa89b77b8876 100644 --- a/src/cdk/schematics/migration.json +++ b/src/cdk/schematics/migration.json @@ -16,6 +16,11 @@ "description": "Updates the Angular CDK to v8", "factory": "./ng-update/index#updateToV8" }, + "migration-v9": { + "version": "9", + "description": "Updates the Angular CDK to v9", + "factory": "./ng-update/index#updateToV9" + }, "ng-post-update": { "description": "Prints out results after ng-update.", "factory": "./ng-update/index#postUpdate", diff --git a/src/cdk/schematics/ng-update/index.ts b/src/cdk/schematics/ng-update/index.ts index 9b0f7c8c5410..b10a2b1acf94 100644 --- a/src/cdk/schematics/ng-update/index.ts +++ b/src/cdk/schematics/ng-update/index.ts @@ -12,21 +12,26 @@ import {TargetVersion} from '../update-tool/target-version'; import {cdkUpgradeData} from './upgrade-data'; import {createUpgradeRule} from './upgrade-rules'; -/** Entry point for the migration schematics with target of Angular Material 6.0.0 */ +/** Entry point for the migration schematics with target of Angular CDK 6.0.0 */ export function updateToV6(): Rule { return createUpgradeRule(TargetVersion.V6, [], cdkUpgradeData, onMigrationComplete); } -/** Entry point for the migration schematics with target of Angular Material 7.0.0 */ +/** Entry point for the migration schematics with target of Angular CDK 7.0.0 */ export function updateToV7(): Rule { return createUpgradeRule(TargetVersion.V7, [], cdkUpgradeData, onMigrationComplete); } -/** Entry point for the migration schematics with target of Angular Material 8.0.0 */ +/** Entry point for the migration schematics with target of Angular CDK 8.0.0 */ export function updateToV8(): Rule { return createUpgradeRule(TargetVersion.V8, [], cdkUpgradeData, onMigrationComplete); } +/** Entry point for the migration schematics with target of Angular CDK 9.0.0 */ +export function updateToV9(): Rule { + return createUpgradeRule(TargetVersion.V9, [], cdkUpgradeData, onMigrationComplete); +} + /** Function that will be called when the migration completed. */ function onMigrationComplete(targetVersion: TargetVersion, hasFailures: boolean) { console.log(); diff --git a/src/cdk/schematics/ng-update/update-schematic.md b/src/cdk/schematics/ng-update/update-schematic.md index 5eacf7bd403f..7faf9cde435b 100644 --- a/src/cdk/schematics/ng-update/update-schematic.md +++ b/src/cdk/schematics/ng-update/update-schematic.md @@ -1,43 +1,44 @@ -# ng-update schematic +# ng-update schematic **Note** The CDK ng-update schematic is the foundation for the Angular Material update schematic. This is achieved by making the ng-update code for the CDK as reusable as possible. - + This means that this document also applies for the Angular Material `ng-update`. --- - + The `ng-update` schematic consists of multiple migration entry-points where every entry-point -targets a specific Angular CDK or Angular Material version. +targets a specific Angular CDK or Angular Material version. As of right now, we have multiple migration entry-points that handle the breaking changes for a -given target version: - +given target version: + | Target Version | Description | |----------------|------------------------| -| V6 | Upgrade from any version to v6.0.0 | -| V7 | Upgrade from any version to v7.0.0 | -| V8 | Upgrade from any version to v8.0.0 | - +| V6 | Upgrade from any version to v6.0.0 | +| V7 | Upgrade from any version to v7.0.0 | +| V8 | Upgrade from any version to v8.0.0 | +| V9 | Upgrade from any version to v9.0.0 | + Note that the migrations run _in order_ if multiple versions are implicitly targeted. For example, consider an application which uses Angular Material v5.0.0. In case the developer runs `ng update`, the Angular CLI **only** installs V7 and runs the V6 and V7 migrations _in order_. - + This shows that we technically need to keep all migrations in the code base because the CLI usually only installs the latest version and expects all migrations for past major versions to be present. - -## Update concept - + +## Update concept + The goal of the update schematic is to automatically migrate code that is affected by breaking changes of the target version. Most of the time we can apply such automatic migrations, but there are also a few breaking changes that cannot be migrated automatically. - + In that case, our goal should be to notify the developer about the breaking change that needs attention. - -## Transforming TypeScript files - + +## Transforming TypeScript files + In order to automatically migrate TypeScript source files, we take advantage of the TypeScript Compiler API which allows us to parse and work with the AST of project source files. We built a small framework for analyzing and updating project source files that is called `update-tool`. @@ -53,8 +54,8 @@ leveraged `tslint` caused various problems: * TSLint is not guaranteed to be installed in CLI projects. See: https://github.com/angular/angular-cli/issues/14555 * TSLint replacements lead to memory leaks due to the retained TypeScript nodes * No way to have a *global analysis* phase since lint rules are only able to visit source files. -* No flexibility. i.e. - * No way to ensure source files are only analyzed a single time +* No flexibility. i.e. + * No way to ensure source files are only analyzed a single time * No way to implement a progress bar * No easy way to add support for HTML templates or stylesheets @@ -74,49 +75,49 @@ All of these problems that `tslint` had, have been solved when we built the There also other various concepts for transforming TypeScript source files, but most of them don't provide a simple API for replacements and reporting. Read more about the possible approaches below: - -|Description | Evaluation | -|------------|------------| -| Regular Expressions | Too brittle. No type checking possible. Regular Expression _can_ be used in combination with some real AST walking | -| TypeScript transforms (no emit) | This would be a good solution but there is no API to serialize the transformed AST into source code without using the `ts.Printer`. The printer can be used to serialize the AST but it breaks formatting, code style and more. This is not acceptable for a migration. | + +|Description | Evaluation | +|------------|------------| +| Regular Expressions | Too brittle. No type checking possible. Regular Expression _can_ be used in combination with some real AST walking | +| TypeScript transforms (no emit) | This would be a good solution but there is no API to serialize the transformed AST into source code without using the `ts.Printer`. The printer can be used to serialize the AST but it breaks formatting, code style and more. This is not acceptable for a migration. | ### Upgrade data for target versions - + The upgrade data for migrations is separated based on the target version. This is necessary in -order to allow migrations run sequentially. For example: - +order to allow migrations run sequentially. For example: + * In V6: `onChange` has been renamed to `changed` * In V7: `changed` has been renamed to `onValueChange` - + If we would not run the migrations in order, or don't separate the upgrade data, we would not be able to properly handle the migrations for each target version. e.g. someone is on 5.0.0 and *only* wants to upgrade to 6.0.0. In that case he would end up with `onValueChange` -because the non-separated upgrade data would just include: _`onChange` => `onValueChange`_ - +because the non-separated upgrade data would just include: _`onChange` => `onValueChange`_ + Also besides separating the upgrade data based on the target version, we split the upgrade data -based on the type of code that is affected by these migrations: - -* See here: [src/material/schematics/update/material/data](https://github.com/angular/components/tree/master/src/material/schematics/update/material/data) - +based on the type of code that is affected by these migrations: + +* See here: [src/material/schematics/update/material/data](https://github.com/angular/components/tree/master/src/material/schematics/update/material/data) + ### Adding upgrade data - + Adding upgrade data is now a **mandatory** step before breaking changes should be merged into `upstream`. For simple and common breaking changes, there should be already an upgrade -data file that just needs the new change inserted. - +data file that just needs the new change inserted. + In case there is no upgrade data for a breaking change, we need to evaluate if there should be a single `misc` migration rule that is tied to that specific breaking change, or if we should -create a new migration rule in a more generic way. +create a new migration rule in a more generic way. --- -**Example**: Adding upgrade data for a property rename +**Example**: Adding upgrade data for a property rename **Scenario**: In Angular Material V7.0.0, we rename `MatRipple#color` to `MatRipple#newColor`. - + First, look for an existing upgrade data file that covers similar breaking changes. In that case an existing upgrade data file for `property-names` already exists. Insert the new breaking change -within the proper `VersionTarget`. - +within the proper `VersionTarget`. + _src/material/schematics/ng-update/material/data/property-names.ts_ ```ts export const propertyNames: VersionChanges = { @@ -138,21 +139,21 @@ export const propertyNames: VersionChanges = { }; ``` Once the data is inserted into the upgrade data file, the update schematic will properly migrate -`MatRipple#color` to `MatRipple#newColor` if someone upgrades to Angular Material V7.0.0. - +`MatRipple#color` to `MatRipple#newColor` if someone upgrades to Angular Material V7.0.0. + But that's not all. It's encouraged to add a test-case for the new migration data. In this case, a test case already exists for the type of migration and we just need to add our breaking change -to it. Read more about adding a test case in the next section. - +to it. Read more about adding a test case in the next section. + ### Adding a breaking change to a test case - + Considering we added a breaking change to the update schematic, it's encouraged to add a proper -test case for the new change that has been added. - +test case for the new change that has been added. + In the scenario where a property from `MatRipple` has been renamed in V7, we don't need to create a new test-case file because there is already a test case for the `property-names` upgrade data. -In that case, we just need to add the breaking change to the existing test case. - +In that case, we just need to add the breaking change to the existing test case. + _src/material/schematics/ng-update/test-cases/v7/property-names_input.ts_ ```ts ... @@ -176,7 +177,7 @@ class A implements OnInit { } ``` -_src/material/schematics/ng-update/test-cases/v7/property-names_expected_output.ts_ +_src/material/schematics/ng-update/test-cases/v7/property-names_expected_output.ts_ ```ts ... @@ -188,7 +189,7 @@ class MatRipple { } /* - * Actual test cases using the previously defined definitions. + * Actual test cases using the previously defined definitions. */ class A implements OnInit { constructor(private a: MatRipple) {} diff --git a/src/cdk/schematics/update-tool/target-version.ts b/src/cdk/schematics/update-tool/target-version.ts index 35d27c5a63e3..0ef26504aaec 100644 --- a/src/cdk/schematics/update-tool/target-version.ts +++ b/src/cdk/schematics/update-tool/target-version.ts @@ -11,6 +11,7 @@ export enum TargetVersion { V6 = 'version 6', V7 = 'version 7', V8 = 'version 8', + V9 = 'version 9', } /** diff --git a/src/material/schematics/migration.json b/src/material/schematics/migration.json index 5ed2b19be392..c81ec911fb65 100644 --- a/src/material/schematics/migration.json +++ b/src/material/schematics/migration.json @@ -16,6 +16,11 @@ "description": "Updates Angular Material to v8", "factory": "./ng-update/index#updateToV8" }, + "migration-v9": { + "version": "9", + "description": "Updates Angular Material to v9", + "factory": "./ng-update/index#updateToV9" + }, "ng-post-update": { "description": "Prints out results after ng-update.", "factory": "./ng-update/index#postUpdate", diff --git a/src/material/schematics/ng-update/index.ts b/src/material/schematics/ng-update/index.ts index a679f0d3f840..168c41fb122b 100644 --- a/src/material/schematics/ng-update/index.ts +++ b/src/material/schematics/ng-update/index.ts @@ -49,6 +49,12 @@ export function updateToV8(): Rule { TargetVersion.V8, materialMigrationRules, materialUpgradeData, onMigrationComplete); } +/** Entry point for the migration schematics with target of Angular Material v9 */ +export function updateToV9(): Rule { + return createUpgradeRule( + TargetVersion.V9, materialMigrationRules, materialUpgradeData, onMigrationComplete); +} + /** Function that will be called when the migration completed. */ function onMigrationComplete(targetVersion: TargetVersion, hasFailures: boolean) { console.log();