77 */
88
99import { Rule , SchematicContext , Tree } from '@angular-devkit/schematics' ;
10+ import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks' ;
1011
1112import { Constructor , runMigrationRules } from '../../update-tool' ;
1213import { MigrationRule } from '../../update-tool/migration-rule' ;
@@ -51,7 +52,7 @@ type NullableMigrationRule = Constructor<MigrationRule<RuleUpgradeData|null>>;
5152export function createUpgradeRule (
5253 targetVersion : TargetVersion , extraRules : NullableMigrationRule [ ] , upgradeData : RuleUpgradeData ,
5354 onMigrationCompleteFn ?: ( targetVersion : TargetVersion , hasFailures : boolean ) => void ) : Rule {
54- return ( tree : Tree , context : SchematicContext ) => {
55+ return async ( tree : Tree , context : SchematicContext ) => {
5556 const logger = context . logger ;
5657 const { buildPaths, testPaths} = getProjectTsConfigPaths ( tree ) ;
5758
@@ -67,13 +68,30 @@ export function createUpgradeRule(
6768 // we don't want to check these again, as this would result in duplicated failure messages.
6869 const analyzedFiles = new Set < string > ( ) ;
6970 let hasRuleFailures = false ;
71+ let needsPackageManagerRun = false ;
7072
71- for ( const tsconfigPath of [ ...buildPaths , ...testPaths ] ) {
72- hasRuleFailures = hasRuleFailures || runMigrationRules (
73- tree , context . logger , tsconfigPath , targetVersion , [ ...cdkMigrationRules , ...extraRules ] ,
74- upgradeData , analyzedFiles ) ;
73+ const runMigration = ( tsconfigPath : string , isTestTarget : boolean ) => {
74+ const result = runMigrationRules (
75+ tree , context . logger , tsconfigPath , isTestTarget , targetVersion ,
76+ [ ...cdkMigrationRules , ...extraRules ] , upgradeData , analyzedFiles ) ;
77+
78+ hasRuleFailures = hasRuleFailures || result . hasFailures ;
79+ needsPackageManagerRun = needsPackageManagerRun || result . needsPackageManagerRun ;
80+ } ;
81+
82+ buildPaths . forEach ( p => runMigration ( p , false ) ) ;
83+ testPaths . forEach ( p => runMigration ( p , true ) ) ;
84+
85+ // Migrations can be require the package manager to run upon completion.
86+ // e.g. to update the lock file when a dependency has been removed.
87+ if ( needsPackageManagerRun ) {
88+ context . addTask ( new NodePackageInstallTask ( { quiet : true } ) ) ;
7589 }
7690
91+ // Execute all asynchronous tasks and await them here. We want to run
92+ // the "onMigrationCompleteFn" after all work is done.
93+ await context . engine . executePostTasks ( ) . toPromise ( ) ;
94+
7795 if ( onMigrationCompleteFn ) {
7896 onMigrationCompleteFn ( targetVersion , hasRuleFailures ) ;
7997 }
0 commit comments