From 87a3b76c76f5e2cb00f1f75f8743170e0db6fa0e Mon Sep 17 00:00:00 2001 From: Jeremy Elbourn Date: Fri, 21 May 2021 15:27:50 -0700 Subject: [PATCH] fix(material/schematics): don't insert duplicate `@use` statements in themingApi In the case where a file has mixed legacy and new theming API usage, the script would add an extra duplicate `@use` statement. --- .../migrations/theming-api-v12/migration.ts | 6 ++++++ .../test-cases/v12/misc/theming-api-v12.spec.ts | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) 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 e662e1ec504b..c72ce8a7ce5b 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 @@ -207,6 +207,12 @@ function renameSymbols(content: string, /** Inserts an `@use` statement in a string. */ function insertUseStatement(content: string, importPath: string, importsToIgnore: string[], namespace: string): string { + // If the content already has the `@use` import, we don't need to add anything. + const alreadyImportedPattern = new RegExp(`@use +['"]${importPath}['"]`, 'g'); + if (alreadyImportedPattern.test(content)) { + return content; + } + // We want to find the first import that isn't in the list of ignored imports or find nothing, // because the imports being replaced might be the only ones in the file and they can be further // down. An easy way to do this is to replace the imports with a random character and run 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 c8446b701671..32cfc9abc820 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 @@ -737,4 +737,21 @@ describe('v12 theming API migration', () => { `@include mat.core();`, ]); }); + + it('should not add duplicate @use statements', async () => { + writeLines(THEME_PATH, [ + `@use '~@angular/material' as mat;`, + `@import '~@angular/material/theming';`, + `$something: mat.$red-palette;`, + `$another: $mat-pink;`, + ]); + + await runMigration(); + + expect(splitFile(THEME_PATH)).toEqual([ + `@use '~@angular/material' as mat;`, + `$something: mat.$red-palette;`, + `$another: mat.$pink-palette;`, + ]); + }); });