@@ -41,7 +41,7 @@ interface DriftFormatterOutput {
4141 readonly unchanged ?: string ;
4242
4343 /**
44- * Resources that were not checked for drift
44+ * Resources that were not checked for drift or have an UNKNOWN drift status
4545 */
4646 readonly unchecked ?: string ;
4747
@@ -98,12 +98,10 @@ export class DriftFormatter {
9898 public formatStackDrift ( ) : DriftFormatterOutput {
9999 const formatterOutput = this . formatStackDriftChanges ( this . buildLogicalToPathMap ( ) ) ;
100100
101- // we are only interested in actual drifts and always ignore the metadata resource
101+ // we are only interested in actual drifts ( and ignore the metadata resource)
102102 const actualDrifts = this . resourceDriftResults . filter ( d =>
103- d . StackResourceDriftStatus === 'MODIFIED' ||
104- d . StackResourceDriftStatus === 'DELETED' ||
105- d . ResourceType === 'AWS::CDK::Metadata' ,
106- ) ;
103+ ( d . StackResourceDriftStatus === 'MODIFIED' || d . StackResourceDriftStatus === 'DELETED' )
104+ && d . ResourceType !== 'AWS::CDK::Metadata' ) ;
107105
108106 // must output the stack name if there are drifts
109107 const stackHeader = format ( `Stack ${ chalk . bold ( this . stackName ) } \n` ) ;
@@ -114,6 +112,7 @@ export class DriftFormatter {
114112 numResourcesWithDrift : 0 ,
115113 numResourcesUnchecked : this . allStackResources . size - this . resourceDriftResults . length ,
116114 stackHeader,
115+ unchecked : formatterOutput . unchecked ,
117116 summary : finalResult ,
118117 } ;
119118 }
@@ -140,11 +139,8 @@ export class DriftFormatter {
140139 }
141140
142141 /**
143- * Renders stack drift information to the given stream
142+ * Renders stack drift information
144143 *
145- * @param driftResults - The stack resource drifts from CloudFormation
146- * @param allStackResources - A map of all stack resources
147- * @param verbose - Whether to output more verbose text (include undrifted resources)
148144 * @param logicalToPathMap - A map from logical ID to construct path
149145 */
150146 private formatStackDriftChanges (
@@ -167,35 +163,35 @@ export class DriftFormatter {
167163
168164 for ( const drift of unchangedResources ) {
169165 if ( ! drift . LogicalResourceId || ! drift . ResourceType ) continue ;
170- unchanged += `${ CONTEXT } ${ this . formatValue ( drift . ResourceType , chalk . cyan ) } ${ this . formatLogicalId ( logicalToPathMap , drift . LogicalResourceId ) } \n` ;
166+ unchanged += `${ CONTEXT } ${ chalk . cyan ( drift . ResourceType ) } ${ this . formatLogicalId ( logicalToPathMap , drift . LogicalResourceId ) } \n` ;
171167 }
172168 unchanged += this . printSectionFooter ( ) ;
173169 }
174170
175- // Process all unchecked resources
176- if ( this . allStackResources ) {
177- const uncheckedResources = Array . from ( this . allStackResources . keys ( ) ) . filter ( ( logicalId ) => {
178- return ! drifts . find ( ( drift ) => drift . LogicalResourceId === logicalId ) ;
179- } ) ;
180- if ( uncheckedResources . length > 0 ) {
181- unchecked = this . printSectionHeader ( 'Unchecked Resources' ) ;
182- for ( const logicalId of uncheckedResources ) {
183- const resourceType = this . allStackResources . get ( logicalId ) ;
184- unchecked += `${ CONTEXT } ${ this . formatValue ( resourceType , chalk . cyan ) } ${ this . formatLogicalId ( logicalToPathMap , logicalId ) } \n` ;
185- }
186- unchecked += this . printSectionFooter ( ) ;
171+ // Process all unchecked and unknown resources
172+ const uncheckedResources = Array . from ( this . allStackResources . keys ( ) ) . filter ( ( logicalId ) => {
173+ const drift = drifts . find ( ( d ) => d . LogicalResourceId === logicalId ) ;
174+ return ! drift || drift . StackResourceDriftStatus === StackResourceDriftStatus . UNKNOWN ;
175+ } ) ;
176+ if ( uncheckedResources . length > 0 ) {
177+ unchecked = this . printSectionHeader ( 'Unchecked Resources' ) ;
178+ for ( const logicalId of uncheckedResources ) {
179+ const resourceType = this . allStackResources . get ( logicalId ) ;
180+ unchecked += `${ CONTEXT } ${ chalk . cyan ( resourceType ) } ${ this . formatLogicalId ( logicalToPathMap , logicalId ) } \n` ;
187181 }
182+ unchecked += this . printSectionFooter ( ) ;
188183 }
189184
190- // Process modified resources
191- const modifiedResources = drifts . filter ( d => d . StackResourceDriftStatus === StackResourceDriftStatus . MODIFIED ) ;
185+ // Process modified resources (exclude AWS::CDK::Metadata)
186+ const modifiedResources = drifts . filter ( d =>
187+ d . StackResourceDriftStatus === StackResourceDriftStatus . MODIFIED
188+ && d . ResourceType !== 'AWS::CDK::Metadata' ) ;
192189 if ( modifiedResources . length > 0 ) {
193190 modified = this . printSectionHeader ( 'Modified Resources' ) ;
194191
195192 for ( const drift of modifiedResources ) {
196193 if ( ! drift . LogicalResourceId || ! drift . ResourceType ) continue ;
197- if ( modified === undefined ) modified = '' ;
198- modified += `${ UPDATE } ${ this . formatValue ( drift . ResourceType , chalk . cyan ) } ${ this . formatLogicalId ( logicalToPathMap , drift . LogicalResourceId ) } \n` ;
194+ modified += `${ UPDATE } ${ chalk . cyan ( drift . ResourceType ) } ${ this . formatLogicalId ( logicalToPathMap , drift . LogicalResourceId ) } \n` ;
199195 if ( drift . PropertyDifferences ) {
200196 const propDiffs = drift . PropertyDifferences ;
201197 for ( let i = 0 ; i < propDiffs . length ; i ++ ) {
@@ -209,13 +205,15 @@ export class DriftFormatter {
209205 modified += this . printSectionFooter ( ) ;
210206 }
211207
212- // Process deleted resources
213- const deletedResources = drifts . filter ( d => d . StackResourceDriftStatus === StackResourceDriftStatus . DELETED ) ;
208+ // Process deleted resources (exclude AWS::CDK::Metadata)
209+ const deletedResources = drifts . filter ( d =>
210+ d . StackResourceDriftStatus === StackResourceDriftStatus . DELETED
211+ && d . ResourceType !== 'AWS::CDK::Metadata' ) ;
214212 if ( deletedResources . length > 0 ) {
215213 deleted = this . printSectionHeader ( 'Deleted Resources' ) ;
216214 for ( const drift of deletedResources ) {
217215 if ( ! drift . LogicalResourceId || ! drift . ResourceType ) continue ;
218- deleted += `${ REMOVAL } ${ this . formatValue ( drift . ResourceType , chalk . cyan ) } ${ this . formatLogicalId ( logicalToPathMap , drift . LogicalResourceId ) } \n` ;
216+ deleted += `${ REMOVAL } ${ chalk . cyan ( drift . ResourceType ) } ${ this . formatLogicalId ( logicalToPathMap , drift . LogicalResourceId ) } \n` ;
219217 }
220218 deleted += this . printSectionFooter ( ) ;
221219 }
@@ -250,16 +248,6 @@ export class DriftFormatter {
250248 return `${ normalizedPath } ${ chalk . gray ( logicalId ) } ` ;
251249 }
252250
253- private formatValue ( value : any , colorFn : ( str : string ) => string ) : string {
254- if ( value == null ) {
255- return '' ;
256- }
257- if ( typeof value === 'string' ) {
258- return colorFn ( value ) ;
259- }
260- return colorFn ( JSON . stringify ( value ) ) ;
261- }
262-
263251 private printSectionHeader ( title : string ) : string {
264252 return `${ chalk . underline ( chalk . bold ( title ) ) } \n` ;
265253 }
@@ -268,16 +256,16 @@ export class DriftFormatter {
268256 return '\n' ;
269257 }
270258
271- private formatTreeDiff ( propertyPath : string , difference : Difference < any > , isLast : boolean ) : string {
259+ private formatTreeDiff ( propertyPath : string , difference : Difference < string > , isLast : boolean ) : string {
272260 let result = format ( ' %s─ %s %s\n' , isLast ? '└' : '├' ,
273261 difference . isAddition ? ADDITION :
274262 difference . isRemoval ? REMOVAL :
275263 UPDATE ,
276264 propertyPath ,
277265 ) ;
278266 if ( difference . isUpdate ) {
279- result += format ( ' ├─ %s %s\n' , REMOVAL , this . formatValue ( difference . oldValue , chalk . red ) ) ;
280- result += format ( ' └─ %s %s\n' , ADDITION , this . formatValue ( difference . newValue , chalk . green ) ) ;
267+ result += format ( ' ├─ %s %s\n' , REMOVAL , chalk . red ( difference . oldValue ) ) ;
268+ result += format ( ' └─ %s %s\n' , ADDITION , chalk . green ( difference . newValue ) ) ;
281269 }
282270 return result ;
283271 }
0 commit comments