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;`, + ]); + }); });