@@ -27,7 +27,12 @@ import {
27
27
fetchPackageManifest ,
28
28
fetchPackageMetadata ,
29
29
} from '../utilities/package-metadata' ;
30
- import { PackageTreeNode , findNodeDependencies , readPackageTree } from '../utilities/package-tree' ;
30
+ import {
31
+ PackageTreeNode ,
32
+ findPackageJson ,
33
+ getTreeFromNodeModules ,
34
+ readPackageJson ,
35
+ } from '../utilities/package-tree' ;
31
36
import { Schema as UpdateCommandSchema } from './update' ;
32
37
33
38
const npa = require ( 'npm-package-arg' ) as ( selector : string ) => PackageIdentifier ;
@@ -40,7 +45,7 @@ const oldConfigFileNames = ['.angular-cli.json', 'angular-cli.json'];
40
45
41
46
const NG_VERSION_9_POST_MSG = colors . cyan (
42
47
'\nYour project has been updated to Angular version 9!\n' +
43
- 'For more info, please see: https://v9.angular.io/guide/updating-to-version-9' ,
48
+ 'For more info, please see: https://v9.angular.io/guide/updating-to-version-9' ,
44
49
) ;
45
50
46
51
/**
@@ -84,7 +89,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
84
89
let logs : string [ ] = [ ] ;
85
90
const files = new Set < string > ( ) ;
86
91
87
- const reporterSubscription = this . workflow . reporter . subscribe ( event => {
92
+ const reporterSubscription = this . workflow . reporter . subscribe ( ( event ) => {
88
93
// Strip leading slash to prevent confusion.
89
94
const eventPath = event . path . startsWith ( '/' ) ? event . path . substr ( 1 ) : event . path ;
90
95
@@ -114,11 +119,11 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
114
119
}
115
120
} ) ;
116
121
117
- const lifecycleSubscription = this . workflow . lifeCycle . subscribe ( event => {
122
+ const lifecycleSubscription = this . workflow . lifeCycle . subscribe ( ( event ) => {
118
123
if ( event . kind == 'end' || event . kind == 'post-tasks-start' ) {
119
124
if ( ! error ) {
120
125
// Output the logging queue, no error happened.
121
- logs . forEach ( log => this . logger . info ( log ) ) ;
126
+ logs . forEach ( ( log ) => this . logger . info ( log ) ) ;
122
127
logs = [ ] ;
123
128
}
124
129
}
@@ -141,12 +146,14 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
141
146
return { success : ! error , files } ;
142
147
} catch ( e ) {
143
148
if ( e instanceof UnsuccessfulWorkflowExecution ) {
144
- this . logger . error ( `${ colors . symbols . cross } Migration failed. See above for further details.\n` ) ;
149
+ this . logger . error (
150
+ `${ colors . symbols . cross } Migration failed. See above for further details.\n` ,
151
+ ) ;
145
152
} else {
146
153
const logPath = writeErrorToLogFile ( e ) ;
147
154
this . logger . fatal (
148
155
`${ colors . symbols . cross } Migration failed: ${ e . message } \n` +
149
- ` See "${ logPath } " for further details.\n` ,
156
+ ` See "${ logPath } " for further details.\n` ,
150
157
) ;
151
158
}
152
159
@@ -164,7 +171,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
164
171
commit ?: boolean ,
165
172
) : Promise < boolean > {
166
173
const collection = this . workflow . engine . createCollection ( collectionPath ) ;
167
- const name = collection . listSchematicNames ( ) . find ( name => name === migrationName ) ;
174
+ const name = collection . listSchematicNames ( ) . find ( ( name ) => name === migrationName ) ;
168
175
if ( ! name ) {
169
176
this . logger . error ( `Cannot find migration '${ migrationName } ' in '${ packageName } '.` ) ;
170
177
@@ -213,20 +220,20 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
213
220
return true ;
214
221
}
215
222
216
- this . logger . info (
217
- colors . cyan ( `** Executing migrations of package '${ packageName } ' **\n` ) ,
218
- ) ;
223
+ this . logger . info ( colors . cyan ( `** Executing migrations of package '${ packageName } ' **\n` ) ) ;
219
224
220
225
return this . executePackageMigrations ( migrations , packageName , commit ) ;
221
226
}
222
227
223
228
private async executePackageMigrations (
224
- migrations : Iterable < { name : string ; description : string ; collection : { name : string } } > ,
229
+ migrations : Iterable < { name : string ; description : string ; collection : { name : string } } > ,
225
230
packageName : string ,
226
231
commit = false ,
227
232
) : Promise < boolean > {
228
233
for ( const migration of migrations ) {
229
- this . logger . info ( `${ colors . symbols . pointer } ${ migration . description . replace ( / \. / g, '.\n ' ) } ` ) ;
234
+ this . logger . info (
235
+ `${ colors . symbols . pointer } ${ migration . description . replace ( / \. / g, '.\n ' ) } ` ,
236
+ ) ;
230
237
231
238
const result = await this . executeSchematic ( migration . collection . name , migration . name ) ;
232
239
if ( ! result . success ) {
@@ -279,10 +286,11 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
279
286
}
280
287
281
288
// Check if the current installed CLI version is older than the latest version.
282
- if ( ! disableVersionCheck && await this . checkCLILatestVersion ( options . verbose , options . next ) ) {
289
+ if ( ! disableVersionCheck && ( await this . checkCLILatestVersion ( options . verbose , options . next ) ) ) {
283
290
this . logger . warn (
284
- `The installed local Angular CLI version is older than the latest ${ options . next ? 'pre-release' : 'stable' } version.\n` +
285
- 'Installing a temporary version to perform the update.' ,
291
+ `The installed local Angular CLI version is older than the latest ${
292
+ options . next ? 'pre-release' : 'stable'
293
+ } version.\n` + 'Installing a temporary version to perform the update.' ,
286
294
) ;
287
295
288
296
return runTempPackageBin (
@@ -305,7 +313,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
305
313
return 1 ;
306
314
}
307
315
308
- if ( packages . some ( v => v . name === packageIdentifier . name ) ) {
316
+ if ( packages . some ( ( v ) => v . name === packageIdentifier . name ) ) {
309
317
this . logger . error ( `Duplicate package '${ packageIdentifier . name } ' specified.` ) ;
310
318
311
319
return 1 ;
@@ -377,15 +385,14 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
377
385
378
386
this . logger . info ( 'Collecting installed dependencies...' ) ;
379
387
380
- const packageTree = await readPackageTree ( this . workspace . root ) ;
381
- const rootDependencies = findNodeDependencies ( packageTree ) ;
388
+ const rootDependencies = await getTreeFromNodeModules ( this . workspace . root ) ;
382
389
383
- this . logger . info ( `Found ${ Object . keys ( rootDependencies ) . length } dependencies.` ) ;
390
+ this . logger . info ( `Found ${ rootDependencies . size } dependencies.` ) ;
384
391
385
392
if ( options . all ) {
386
393
// 'all' option and a zero length packages have already been checked.
387
394
// Add all direct dependencies to be updated
388
- for ( const dep of Object . keys ( rootDependencies ) ) {
395
+ for ( const dep of rootDependencies . keys ( ) ) {
389
396
const packageIdentifier = npa ( dep ) ;
390
397
if ( options . next ) {
391
398
packageIdentifier . fetchSpec = 'next' ;
@@ -400,15 +407,17 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
400
407
next : options . next || false ,
401
408
verbose : options . verbose || false ,
402
409
packageManager : this . packageManager ,
403
- packages : options . all ? Object . keys ( rootDependencies ) : [ ] ,
410
+ packages : options . all ? rootDependencies . keys ( ) : [ ] ,
404
411
} ) ;
405
412
406
413
return success ? 0 : 1 ;
407
414
}
408
415
409
416
if ( options . migrateOnly ) {
410
417
if ( ! options . from && typeof options . migrateOnly !== 'string' ) {
411
- this . logger . error ( '"from" option is required when using the "migrate-only" option without a migration name.' ) ;
418
+ this . logger . error (
419
+ '"from" option is required when using the "migrate-only" option without a migration name.' ,
420
+ ) ;
412
421
413
422
return 1 ;
414
423
} else if ( packages . length !== 1 ) {
@@ -424,8 +433,9 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
424
433
}
425
434
426
435
const packageName = packages [ 0 ] . name ;
427
- const packageDependency = rootDependencies [ packageName ] ;
428
- let packageNode = packageDependency && packageDependency . node ;
436
+ const packageDependency = rootDependencies . get ( packageName ) ;
437
+ let packagePath = packageDependency ?. path ;
438
+ let packageNode = packageDependency ?. package ;
429
439
if ( packageDependency && ! packageNode ) {
430
440
this . logger . error ( 'Package found in package.json but is not installed.' ) ;
431
441
@@ -434,19 +444,17 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
434
444
// Allow running migrations on transitively installed dependencies
435
445
// There can technically be nested multiple versions
436
446
// TODO: If multiple, this should find all versions and ask which one to use
437
- const child = packageTree . children . find ( c => c . name === packageName ) ;
438
- if ( child ) {
439
- packageNode = child ;
440
- }
447
+ packagePath = path . dirname ( findPackageJson ( this . workspace . root , packageName ) ) ;
448
+ packageNode = await readPackageJson ( packagePath ) ;
441
449
}
442
450
443
- if ( ! packageNode ) {
451
+ if ( ! packageNode || ! packagePath ) {
444
452
this . logger . error ( 'Package is not installed.' ) ;
445
453
446
454
return 1 ;
447
455
}
448
456
449
- const updateMetadata = packageNode . package [ 'ng-update' ] ;
457
+ const updateMetadata = packageNode [ 'ng-update' ] ;
450
458
let migrations = updateMetadata && updateMetadata . migrations ;
451
459
if ( migrations === undefined ) {
452
460
this . logger . error ( 'Package does not provide migrations.' ) ;
@@ -477,14 +485,14 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
477
485
}
478
486
479
487
// Check if it is a package-local location
480
- const localMigrations = path . join ( packageNode . path , migrations ) ;
488
+ const localMigrations = path . join ( packagePath , migrations ) ;
481
489
if ( fs . existsSync ( localMigrations ) ) {
482
490
migrations = localMigrations ;
483
491
} else {
484
492
// Try to resolve from package location.
485
493
// This avoids issues with package hoisting.
486
494
try {
487
- migrations = require . resolve ( migrations , { paths : [ packageNode . path ] } ) ;
495
+ migrations = require . resolve ( migrations , { paths : [ packagePath ] } ) ;
488
496
} catch ( e ) {
489
497
if ( e . code === 'MODULE_NOT_FOUND' ) {
490
498
this . logger . error ( 'Migrations for package were not found.' ) ;
@@ -513,7 +521,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
513
521
}
514
522
515
523
const migrationRange = new semver . Range (
516
- '>' + from + ' <=' + ( options . to || packageNode . package . version ) ,
524
+ '>' + from + ' <=' + ( options . to || packageNode . version ) ,
517
525
) ;
518
526
519
527
success = await this . executeMigrations (
@@ -526,10 +534,10 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
526
534
527
535
if ( success ) {
528
536
if (
529
- packageName === '@angular/core'
530
- && options . from
531
- && + options . from . split ( '.' ) [ 0 ] < 9
532
- && ( options . to || packageNode . package . version ) . split ( '.' ) [ 0 ] === '9'
537
+ packageName === '@angular/core' &&
538
+ options . from &&
539
+ + options . from . split ( '.' ) [ 0 ] < 9 &&
540
+ ( options . to || packageNode . version ) . split ( '.' ) [ 0 ] === '9'
533
541
) {
534
542
this . logger . info ( NG_VERSION_9_POST_MSG ) ;
535
543
}
@@ -547,8 +555,8 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
547
555
548
556
// Validate packages actually are part of the workspace
549
557
for ( const pkg of packages ) {
550
- const node = rootDependencies [ pkg . name ] && rootDependencies [ pkg . name ] . node ;
551
- if ( ! node ) {
558
+ const node = rootDependencies . get ( pkg . name ) ;
559
+ if ( ! node ?. package ) {
552
560
this . logger . error ( `Package '${ pkg . name } ' is not a dependency.` ) ;
553
561
554
562
return 1 ;
@@ -627,7 +635,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
627
635
return 1 ;
628
636
}
629
637
630
- if ( manifest . version === node . package . version ) {
638
+ if ( manifest . version === node . package ? .version ) {
631
639
this . logger . info ( `Package '${ packageName } ' is already up to date.` ) ;
632
640
continue ;
633
641
}
@@ -650,7 +658,8 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
650
658
651
659
if ( success && options . createCommits ) {
652
660
const committed = this . commit (
653
- `Angular CLI update for packages - ${ packagesToUpdate . join ( ', ' ) } ` ) ;
661
+ `Angular CLI update for packages - ${ packagesToUpdate . join ( ', ' ) } ` ,
662
+ ) ;
654
663
if ( ! committed ) {
655
664
return 1 ;
656
665
}
@@ -681,7 +690,14 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
681
690
}
682
691
}
683
692
684
- if ( migrations . some ( m => m . package === '@angular/core' && m . to . split ( '.' ) [ 0 ] === '9' && + m . from . split ( '.' ) [ 0 ] < 9 ) ) {
693
+ if (
694
+ migrations . some (
695
+ ( m ) =>
696
+ m . package === '@angular/core' &&
697
+ m . to . split ( '.' ) [ 0 ] === '9' &&
698
+ + m . from . split ( '.' ) [ 0 ] < 9 ,
699
+ )
700
+ ) {
685
701
this . logger . info ( NG_VERSION_9_POST_MSG ) ;
686
702
}
687
703
}
@@ -713,8 +729,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
713
729
try {
714
730
createCommit ( message ) ;
715
731
} catch ( err ) {
716
- this . logger . error (
717
- `Failed to commit update (${ message } ):\n${ err . stderr } ` ) ;
732
+ this . logger . error ( `Failed to commit update (${ message } ):\n${ err . stderr } ` ) ;
718
733
719
734
return false ;
720
735
}
@@ -723,8 +738,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
723
738
const hash = findCurrentGitSha ( ) ;
724
739
const shortMessage = message . split ( '\n' ) [ 0 ] ;
725
740
if ( hash ) {
726
- this . logger . info ( ` Committed migration step (${ getShortHash ( hash ) } ): ${
727
- shortMessage } .`) ;
741
+ this . logger . info ( ` Committed migration step (${ getShortHash ( hash ) } ): ${ shortMessage } .` ) ;
728
742
} else {
729
743
// Commit was successful, but reading the hash was not. Something weird happened,
730
744
// but nothing that would stop the update. Just log the weirdness and continue.
@@ -737,7 +751,10 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
737
751
738
752
private checkCleanGit ( ) : boolean {
739
753
try {
740
- const topLevel = execSync ( 'git rev-parse --show-toplevel' , { encoding : 'utf8' , stdio : 'pipe' } ) ;
754
+ const topLevel = execSync ( 'git rev-parse --show-toplevel' , {
755
+ encoding : 'utf8' ,
756
+ stdio : 'pipe' ,
757
+ } ) ;
741
758
const result = execSync ( 'git status --porcelain' , { encoding : 'utf8' , stdio : 'pipe' } ) ;
742
759
if ( result . trim ( ) . length === 0 ) {
743
760
return true ;
@@ -762,7 +779,7 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
762
779
/**
763
780
* Checks if the current installed CLI version is older than the latest version.
764
781
* @returns `true` when the installed version is older.
765
- */
782
+ */
766
783
private async checkCLILatestVersion ( verbose = false , next = false ) : Promise < boolean > {
767
784
const { version : installedCLIVersion } = require ( '../package.json' ) ;
768
785
@@ -808,7 +825,7 @@ function createCommit(message: string) {
808
825
*/
809
826
function findCurrentGitSha ( ) : string | null {
810
827
try {
811
- const hash = execSync ( 'git rev-parse HEAD' , { encoding : 'utf8' , stdio : 'pipe' } ) ;
828
+ const hash = execSync ( 'git rev-parse HEAD' , { encoding : 'utf8' , stdio : 'pipe' } ) ;
812
829
813
830
return hash . trim ( ) ;
814
831
} catch {
0 commit comments