@@ -65,9 +65,14 @@ export class StackActivityMonitor {
6565 */
6666 private readPromise ?: Promise < AWS . CloudFormation . StackEvent [ ] > ;
6767
68+ /**
69+ * The with of the "resource type" column.
70+ */
71+ private readonly resourceTypeColumnWidth : number ;
72+
6873 constructor ( private readonly cfn : aws . CloudFormation ,
6974 private readonly stackName : string ,
70- private readonly metadata ? : cxapi . StackMetadata ,
75+ private readonly stack : cxapi . SynthesizedStack ,
7176 private readonly resourcesTotal ?: number ) {
7277
7378 if ( this . resourcesTotal != null ) {
@@ -78,6 +83,8 @@ export class StackActivityMonitor {
7883 // How many digits does this number take to represent?
7984 this . resourceDigits = Math . ceil ( Math . log10 ( this . resourcesTotal ) ) ;
8085 }
86+
87+ this . resourceTypeColumnWidth = calcMaxResourceTypeLength ( this . stack . template ) ;
8188 }
8289
8390 public start ( ) {
@@ -164,20 +171,33 @@ export class StackActivityMonitor {
164171 const e = activity . event ;
165172 const color = this . colorFromStatus ( e . ResourceStatus ) ;
166173 const md = this . findMetadataFor ( e . LogicalResourceId ) ;
174+ let reasonColor = colors . cyan ;
167175
168- let suffix = '' ;
176+ let stackTrace = '' ;
169177 if ( md && e . ResourceStatus && e . ResourceStatus . indexOf ( 'FAILED' ) !== - 1 ) {
170- suffix = `\n${ md . entry . data } was created at: ${ md . path } \n\t${ md . entry . trace . join ( '\n\t\\_ ' ) } ` ;
178+ stackTrace = `\n\t${ md . entry . trace . join ( '\n\t\\_ ' ) } ` ;
179+ reasonColor = colors . red ;
180+ }
181+
182+ let resourceName = md ? md . path . replace ( / \/ R e s o u r c e $ / , '' ) : ( e . LogicalResourceId || '' ) ;
183+ resourceName = resourceName . replace ( / ^ \/ / , '' ) ; // remove "/" prefix
184+
185+ // remove "<stack-name>/" prefix
186+ if ( resourceName . startsWith ( this . stackName + '/' ) ) {
187+ resourceName = resourceName . substr ( this . stackName . length + 1 ) ;
171188 }
172189
173- process . stderr . write ( util . format ( color ( `%s %s %s [%s] %s %s%s\n` ) ,
190+ const logicalId = resourceName !== e . LogicalResourceId ? `(${ e . LogicalResourceId } ) ` : '' ;
191+
192+ process . stderr . write ( util . format ( ` %s | %s | %s | %s | %s %s%s%s\n` ,
174193 this . progress ( ) ,
175- e . Timestamp ,
176- padRight ( 18 , "" + e . ResourceStatus ) ,
177- e . ResourceType ,
178- e . LogicalResourceId ,
179- e . ResourceStatusReason ? e . ResourceStatusReason : '' ,
180- suffix ) ) ;
194+ new Date ( e . Timestamp ) . toLocaleTimeString ( ) ,
195+ color ( padRight ( 20 , ( e . ResourceStatus || '' ) . substr ( 0 , 20 ) ) ) , // pad left and trim
196+ padRight ( this . resourceTypeColumnWidth , e . ResourceType || '' ) ,
197+ color ( colors . bold ( resourceName ) ) ,
198+ logicalId ,
199+ reasonColor ( colors . bold ( e . ResourceStatusReason ? e . ResourceStatusReason : '' ) ) ,
200+ reasonColor ( stackTrace ) ) ) ;
181201
182202 this . lastPrintTime = Date . now ( ) ;
183203 }
@@ -188,10 +208,10 @@ export class StackActivityMonitor {
188208 private progress ( ) : string {
189209 if ( this . resourcesTotal == null ) {
190210 // Don't have total, show simple count and hope the human knows
191- return util . format ( '[%s] ' , this . resourcesDone ) ;
211+ return padLeft ( 3 , util . format ( '%s ' , this . resourcesDone ) ) ; // max 200 resources
192212 }
193213
194- return util . format ( '[ %s/%s] ' ,
214+ return util . format ( '%s/%s' ,
195215 padLeft ( this . resourceDigits , this . resourcesDone . toString ( ) ) ,
196216 padLeft ( this . resourceDigits , this . resourcesTotal != null ? this . resourcesTotal . toString ( ) : '?' ) ) ;
197217 }
@@ -204,9 +224,11 @@ export class StackActivityMonitor {
204224 return ;
205225 }
206226
207- process . stderr . write ( util . format ( colors . blue ( '%s Currently in progress: %s\n' ) ,
208- this . progress ( ) ,
209- Array . from ( this . resourcesInProgress ) . join ( ', ' ) ) ) ;
227+ if ( this . resourcesInProgress . size > 0 ) {
228+ process . stderr . write ( util . format ( '%s Currently in progress: %s\n' ,
229+ this . progress ( ) ,
230+ colors . bold ( Array . from ( this . resourcesInProgress ) . join ( ', ' ) ) ) ) ;
231+ }
210232
211233 // We cheat a bit here. To prevent printInProgress() from repeatedly triggering,
212234 // we set the timestamp into the future. It will be reset whenever a regular print
@@ -215,9 +237,10 @@ export class StackActivityMonitor {
215237 }
216238
217239 private findMetadataFor ( logicalId : string | undefined ) : { entry : cxapi . MetadataEntry , path : string } | undefined {
218- if ( ! logicalId || ! this . metadata ) { return undefined ; }
219- for ( const path of Object . keys ( this . metadata ) ) {
220- const entry = this . metadata [ path ] . filter ( e => e . type === 'aws:cdk:logicalId' )
240+ const metadata = this . stack . metadata ;
241+ if ( ! logicalId || ! metadata ) { return undefined ; }
242+ for ( const path of Object . keys ( metadata ) ) {
243+ const entry = metadata [ path ] . filter ( e => e . type === 'aws:cdk:logicalId' )
221244 . find ( e => e . data === logicalId ) ;
222245 if ( entry ) { return { entry, path } ; }
223246 }
@@ -284,3 +307,15 @@ function padRight(n: number, x: string): string {
284307function padLeft ( n : number , x : string ) : string {
285308 return ' ' . repeat ( Math . max ( 0 , n - x . length ) ) + x ;
286309}
310+
311+ function calcMaxResourceTypeLength ( template : any ) {
312+ const resources = ( template && template . Resources ) || { } ;
313+ let maxWidth = 0 ;
314+ for ( const id of Object . keys ( resources ) ) {
315+ const type = resources [ id ] . Type || '' ;
316+ if ( type . length > maxWidth ) {
317+ maxWidth = type . length ;
318+ }
319+ }
320+ return maxWidth ;
321+ }
0 commit comments