From 9c14b1423aa016b44a5cf17da4672430a92c3f9a Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 14 May 2021 13:02:46 +0200 Subject: [PATCH] fix(material/schematics): don't drop prebuilt imports in theming API migration Currently the theming API migration drops any imports starting with `~@angular/material/`, assuming that they're Sass APIs. This can result in prebuilt style imports being removed by mistake. These changes add a regex based on which we'll exclude some imports from the migration. Fixes #22697. --- .../migrations/theming-api-v12/migration.ts | 16 ++++++++++++---- .../theming-api-v12/theming-api-migration.ts | 3 ++- .../v12/misc/theming-api-v12.spec.ts | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/material/schematics/ng-update/migrations/theming-api-v12/migration.ts b/src/material/schematics/ng-update/migrations/theming-api-v12/migration.ts index dff9b77db95f..0c4e95ba284b 100644 --- a/src/material/schematics/ng-update/migrations/theming-api-v12/migration.ts +++ b/src/material/schematics/ng-update/migrations/theming-api-v12/migration.ts @@ -41,15 +41,17 @@ interface ExtraSymbols { * matched, the prefix would be `~@angular/cdk/`. * @param newMaterialImportPath New import to the Material theming API (e.g. `~@angular/material`). * @param newCdkImportPath New import to the CDK Sass APIs (e.g. `~@angular/cdk`). + * @param excludedImports Pattern that can be used to exclude imports from being processed. */ export function migrateFileContent(content: string, oldMaterialPrefix: string, oldCdkPrefix: string, newMaterialImportPath: string, newCdkImportPath: string, - extraMaterialSymbols: ExtraSymbols = {}): string { - const materialResults = detectImports(content, oldMaterialPrefix); - const cdkResults = detectImports(content, oldCdkPrefix); + extraMaterialSymbols: ExtraSymbols = {}, + excludedImports?: RegExp): string { + const materialResults = detectImports(content, oldMaterialPrefix, excludedImports); + const cdkResults = detectImports(content, oldCdkPrefix, excludedImports); // Try to migrate the symbols even if there are no imports. This is used // to cover the case where the Components symbols were used transitively. @@ -77,8 +79,10 @@ export function migrateFileContent(content: string, * Counts the number of imports with a specific prefix and extracts their namespaces. * @param content File content in which to look for imports. * @param prefix Prefix that the imports should start with. + * @param excludedImports Pattern that can be used to exclude imports from being processed. */ -function detectImports(content: string, prefix: string): DetectImportResult { +function detectImports(content: string, prefix: string, + excludedImports?: RegExp): DetectImportResult { if (prefix[prefix.length - 1] !== '/') { // Some of the logic further down makes assumptions about the import depth. throw Error(`Prefix "${prefix}" has to end in a slash.`); @@ -95,6 +99,10 @@ function detectImports(content: string, prefix: string): DetectImportResult { while (match = pattern.exec(content)) { const [fullImport, type] = match; + if (excludedImports?.test(fullImport)) { + continue; + } + if (type === 'use') { const namespace = extractNamespaceFromUseStatement(fullImport); diff --git a/src/material/schematics/ng-update/migrations/theming-api-v12/theming-api-migration.ts b/src/material/schematics/ng-update/migrations/theming-api-v12/theming-api-migration.ts index ec98653c2ec0..f14c4e605a73 100644 --- a/src/material/schematics/ng-update/migrations/theming-api-v12/theming-api-migration.ts +++ b/src/material/schematics/ng-update/migrations/theming-api-v12/theming-api-migration.ts @@ -22,7 +22,8 @@ export class ThemingApiMigration extends DevkitMigration { if (extname(stylesheet.filePath) === '.scss') { const content = stylesheet.content; const migratedContent = content ? migrateFileContent(content, - '~@angular/material/', '~@angular/cdk/', '~@angular/material', '~@angular/cdk') : content; + '~@angular/material/', '~@angular/cdk/', '~@angular/material', '~@angular/cdk', + undefined, /material\/prebuilt-themes|cdk\/.*-prebuilt/) : content; if (migratedContent && migratedContent !== content) { this.fileSystem.edit(stylesheet.filePath) diff --git a/src/material/schematics/ng-update/test-cases/v12/misc/theming-api-v12.spec.ts b/src/material/schematics/ng-update/test-cases/v12/misc/theming-api-v12.spec.ts index 7ab129d6070c..4a49efc55112 100644 --- a/src/material/schematics/ng-update/test-cases/v12/misc/theming-api-v12.spec.ts +++ b/src/material/schematics/ng-update/test-cases/v12/misc/theming-api-v12.spec.ts @@ -716,4 +716,22 @@ describe('v12 theming API migration', () => { `@include mat.mdc-button-theme();`, ].join('\n')); }); + + it('should not drop imports of prebuilt styles', async () => { + writeLines(THEME_PATH, [ + `@import '~@angular/material/prebuilt-themes/indigo-pink.css';`, + `@import '~@angular/material/theming';`, + `@import '~@angular/cdk/overlay-prebuilt.css';`, + `@include mat-core();`, + ]); + + await runMigration(); + + expect(splitFile(THEME_PATH)).toEqual([ + `@use '~@angular/material' as mat;`, + `@import '~@angular/material/prebuilt-themes/indigo-pink.css';`, + `@import '~@angular/cdk/overlay-prebuilt.css';`, + `@include mat.core();`, + ]); + }); });