@@ -19,6 +19,11 @@ import {
19
19
DestructiveChangesType ,
20
20
VirtualTreeContainer ,
21
21
DeployResult ,
22
+ ScopedPreDeploy ,
23
+ ScopedPostRetrieve ,
24
+ ScopedPreRetrieve ,
25
+ ScopedPostDeploy ,
26
+ RetrieveResult ,
22
27
} from '@salesforce/source-deploy-retrieve' ;
23
28
import { RemoteSourceTrackingService , remoteChangeElementToChangeResult } from './shared/remoteSourceTrackingService' ;
24
29
import { ShadowRepo } from './shared/localShadowRepo' ;
@@ -42,8 +47,8 @@ import { populateTypesAndNames } from './shared/populateTypesAndNames';
42
47
export interface SourceTrackingOptions {
43
48
org : Org ;
44
49
project : SfProject ;
45
- ignoreConflicts ?: boolean ;
46
50
subscribeSDREvents ?: boolean ;
51
+ ignoreConflicts ?: boolean ;
47
52
}
48
53
49
54
/**
@@ -65,17 +70,19 @@ export class SourceTracking extends AsyncCreatable {
65
70
private hasSfdxTrackingFiles : boolean ;
66
71
private ignoreConflicts : boolean ;
67
72
private subscribeSDREvents : boolean ;
73
+ private orgId : string ;
68
74
69
75
public constructor ( options : SourceTrackingOptions ) {
70
76
super ( options ) ;
71
77
this . org = options . org ;
78
+ this . orgId = this . org . getOrgId ( ) ;
72
79
this . projectPath = options . project . getPath ( ) ;
73
80
this . packagesDirs = options . project . getPackageDirectories ( ) ;
74
81
this . logger = Logger . childFromRoot ( 'SourceTracking' ) ;
75
82
this . project = options . project ;
76
83
this . ignoreConflicts = options . ignoreConflicts ?? false ;
77
84
this . subscribeSDREvents = options . subscribeSDREvents ?? false ;
78
- this . hasSfdxTrackingFiles = hasSfdxTrackingFiles ( this . org . getOrgId ( ) , this . projectPath ) ;
85
+ this . hasSfdxTrackingFiles = hasSfdxTrackingFiles ( this . orgId , this . projectPath ) ;
79
86
this . maybeSubscribeLifecycleEvents ( ) ;
80
87
}
81
88
@@ -296,7 +303,7 @@ export class SourceTracking extends AsyncCreatable {
296
303
this . logger . debug ( 'remoteChanges' , remoteChanges ) ;
297
304
const filteredChanges = remoteChanges
298
305
. filter ( remoteFilterByState [ options . state ] )
299
- // skip any remote types not in the registry. Will emit node warnings
306
+ // skip any remote types not in the registry. Will emit warnings
300
307
. filter ( ( rce ) => registrySupportsType ( rce . type ) ) ;
301
308
if ( options . format === 'ChangeResult' ) {
302
309
return filteredChanges . map ( ( change ) => remoteChangeElementToChangeResult ( change ) ) ;
@@ -330,6 +337,20 @@ export class SourceTracking extends AsyncCreatable {
330
337
throw new Error ( `unsupported options: ${ JSON . stringify ( options ) } ` ) ;
331
338
}
332
339
340
+ /**
341
+ *
342
+ * Convenience method to reduce duplicated steps required to do a fka pull
343
+ * It's full of side effects: retrieving remote deletes, deleting those files locall, and then updating tracking files
344
+ * Most bizarrely, it then returns a ComponentSet of the remote nonDeletes.
345
+ *
346
+ * @returns the ComponentSet for what you would retrieve now that the deletes are done
347
+ */
348
+
349
+ public async maybeApplyRemoteDeletesToLocal ( ) : Promise < ComponentSet > {
350
+ const changesToDelete = await this . getChanges ( { origin : 'remote' , state : 'delete' , format : 'SourceComponent' } ) ;
351
+ await this . deleteFilesAndUpdateTracking ( changesToDelete ) ;
352
+ return this . remoteNonDeletesAsComponentSet ( ) ;
353
+ }
333
354
/**
334
355
*
335
356
* returns immediately if there are no changesToDelete
@@ -441,7 +462,7 @@ export class SourceTracking extends AsyncCreatable {
441
462
return ;
442
463
}
443
464
this . localRepo = await ShadowRepo . getInstance ( {
444
- orgId : this . org . getOrgId ( ) ,
465
+ orgId : this . orgId ,
445
466
projectPath : normalize ( this . projectPath ) ,
446
467
packageDirs : this . packagesDirs ,
447
468
hasSfdxTrackingFiles : this . hasSfdxTrackingFiles ,
@@ -501,7 +522,7 @@ export class SourceTracking extends AsyncCreatable {
501
522
* Deletes the remote tracking files
502
523
*/
503
524
public async clearRemoteTracking ( ) : Promise < string > {
504
- return RemoteSourceTrackingService . delete ( this . org . getOrgId ( ) , this . hasSfdxTrackingFiles ) ;
525
+ return RemoteSourceTrackingService . delete ( this . orgId , this . hasSfdxTrackingFiles ) ;
505
526
}
506
527
507
528
/**
@@ -573,8 +594,7 @@ export class SourceTracking extends AsyncCreatable {
573
594
. map ( ( fileResponse ) => fileResponse . filePath as string ) ,
574
595
} ) ,
575
596
this . updateRemoteTracking (
576
- successes . map ( ( { state, fullName, type, filePath } ) => ( { state, fullName, type, filePath } ) ) ,
577
- true // retrieves don't need to poll for SourceMembers
597
+ successes . map ( ( { state, fullName, type, filePath } ) => ( { state, fullName, type, filePath } ) )
578
598
) ,
579
599
] ) ;
580
600
}
@@ -584,15 +604,17 @@ export class SourceTracking extends AsyncCreatable {
584
604
*
585
605
* @param result FileResponse[]
586
606
*/
587
- public async updateTrackingFromRetrieve ( responses : FileResponse [ ] ) : Promise < void > {
588
- const successes = responses . filter ( ( fileResponse ) => fileResponse . state !== ComponentStatus . Failed ) ;
607
+ public async updateTrackingFromRetrieve ( retrieveResult : RetrieveResult ) : Promise < void > {
608
+ const successes = retrieveResult
609
+ . getFileResponses ( )
610
+ . filter ( ( fileResponse ) => fileResponse . state !== ComponentStatus . Failed ) ;
589
611
if ( ! successes . length ) {
590
612
return ;
591
613
}
592
614
593
615
await Promise . all ( [
594
616
this . updateLocalTracking ( {
595
- // assertion allowed because it's filtering out undefined on the next line
617
+ // assertion allowed because it's filtering out undefined
596
618
files : successes . map ( ( fileResponse ) => fileResponse . filePath as string ) . filter ( Boolean ) ,
597
619
} ) ,
598
620
this . updateRemoteTracking (
@@ -615,21 +637,35 @@ export class SourceTracking extends AsyncCreatable {
615
637
private maybeSubscribeLifecycleEvents ( ) : void {
616
638
if ( this . subscribeSDREvents && this . org . tracksSource ) {
617
639
const lifecycle = Lifecycle . getInstance ( ) ;
640
+ // the only thing STL uses pre events for is to check conflicts. So if you don't care about conflicts, don't listen!
618
641
if ( ! this . ignoreConflicts ) {
619
642
this . logger . debug ( 'subscribing to predeploy/retrieve events' ) ;
620
643
// subscribe to SDR `pre` events to handle conflicts before deploy/retrieve
621
- lifecycle . on ( 'predeploy' , async ( components : SourceComponent [ ] ) => {
622
- throwIfConflicts ( findConflictsInComponentSet ( components , await this . getConflicts ( ) ) ) ;
644
+ lifecycle . on ( 'scopedPreDeploy' , async ( e : ScopedPreDeploy ) => {
645
+ if ( e . orgId === this . orgId ) {
646
+ throwIfConflicts ( findConflictsInComponentSet ( e . componentSet , await this . getConflicts ( ) ) ) ;
647
+ }
623
648
} ) ;
624
- lifecycle . on ( 'preretrieve' , async ( components : SourceComponent [ ] ) => {
625
- throwIfConflicts ( findConflictsInComponentSet ( components , await this . getConflicts ( ) ) ) ;
649
+ lifecycle . on ( 'scopedPreRetrieve' , async ( e : ScopedPreRetrieve ) => {
650
+ if ( e . orgId === this . orgId ) {
651
+ throwIfConflicts ( findConflictsInComponentSet ( e . componentSet , await this . getConflicts ( ) ) ) ;
652
+ }
626
653
} ) ;
627
654
}
628
655
// subscribe to SDR post-deploy event
629
656
this . logger . debug ( 'subscribing to postdeploy/retrieve events' ) ;
657
+
630
658
// yes, the post hooks really have different payloads!
631
- lifecycle . on ( 'postdeploy' , async ( result : DeployResult ) => this . updateTrackingFromDeploy ( result ) ) ;
632
- lifecycle . on ( 'postretrieve' , async ( result : FileResponse [ ] ) => this . updateTrackingFromRetrieve ( result ) ) ;
659
+ lifecycle . on ( 'scopedPostDeploy' , async ( e : ScopedPostDeploy ) => {
660
+ if ( e . orgId === this . orgId ) {
661
+ await this . updateTrackingFromDeploy ( e . deployResult ) ;
662
+ }
663
+ } ) ;
664
+ lifecycle . on ( 'scopedPostRetrieve' , async ( e : ScopedPostRetrieve ) => {
665
+ if ( e . orgId === this . orgId ) {
666
+ await this . updateTrackingFromRetrieve ( e . retrieveResult ) ;
667
+ }
668
+ } ) ;
633
669
}
634
670
}
635
671
0 commit comments