From 478e86fc63c438280da51ad200d8d969994346ba Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Fri, 28 May 2021 11:11:30 +0200 Subject: [PATCH] fix(@schematics/angular): make version 12 workspace config migration idempotent With this change we ensure that `update-angular-config-v12` migration is idempotent Closes #20979 --- .../update-12/update-angular-config.ts | 9 +++++++++ .../update-12/update-angular-config_spec.ts | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/packages/schematics/angular/migrations/update-12/update-angular-config.ts b/packages/schematics/angular/migrations/update-12/update-angular-config.ts index 9589eb248490..ec32330418f3 100644 --- a/packages/schematics/angular/migrations/update-12/update-angular-config.ts +++ b/packages/schematics/angular/migrations/update-12/update-angular-config.ts @@ -59,6 +59,15 @@ function updateOptions( target: workspaces.TargetDefinition, optionsToUpdate: typeof ServerBuilderOptions | typeof BrowserBuilderOptions, ): void { + // This is a hacky way to make this migration idempotent. + // `defaultConfiguration` was only introduced in v12 projects and hence v11 projects do not have this property. + // Setting it as an empty string will not cause any side-effect. + if (typeof target.defaultConfiguration === 'string') { + return; + } + + target.defaultConfiguration = ''; + if (!target.options) { target.options = {}; } diff --git a/packages/schematics/angular/migrations/update-12/update-angular-config_spec.ts b/packages/schematics/angular/migrations/update-12/update-angular-config_spec.ts index 7f80e45ae5a8..0cabc91fa6b4 100644 --- a/packages/schematics/angular/migrations/update-12/update-angular-config_spec.ts +++ b/packages/schematics/angular/migrations/update-12/update-angular-config_spec.ts @@ -120,4 +120,21 @@ describe(`Migration to update 'angular.json'. ${schematicName}`, () => { expect(options.namedChunks).toBeTrue(); expect(options.buildOptimizer).toBeFalse(); }); + + it('migration should be idempotent', async () => { + const { options } = getBuildTarget(tree); + expect(options.aot).toBeTrue(); + + // First run + const newTree1 = await schematicRunner.runSchematicAsync(schematicName, {}, tree).toPromise(); + const { options: options1 } = getBuildTarget(newTree1); + expect(options1.aot).toBeUndefined(); + + // Second run + const newTree2 = await schematicRunner + .runSchematicAsync(schematicName, {}, newTree1) + .toPromise(); + const { options: options2 } = getBuildTarget(newTree2); + expect(options2.aot).toBeUndefined(); + }); });