From 78ada79e3a97c1994d85716bfd76de3d6ad2da27 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Sun, 23 Feb 2025 03:06:50 +0900 Subject: [PATCH 1/6] fix(toolkit-lib): message including tokens from annotations cannot output correctly --- .../toolkit-lib/lib/toolkit/toolkit.ts | 24 +++++-- .../toolkit-lib/test/toolkit/toolkit.test.ts | 68 ++++++++++++++++++- 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts b/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts index 3007f92a2..c1e66277d 100644 --- a/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts +++ b/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts @@ -757,13 +757,23 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab default: return 'CDK_ASSEMBLY_I9999'; } }; - await stacks.validateMetadata(this.props.assemblyFailureAt, async (level, msg) => ioHost.notify({ - time: new Date(), - level, - code: code(level), - message: `[${level} at ${msg.id}] ${msg.entry.data}`, - data: msg, - })); + + await stacks.validateMetadata(this.props.assemblyFailureAt, async (level, msg) => { + // Data comes from Annotations and the data can be of object type containing 'Fn::Join' or 'Ref' when tokens are included in Annotations. + // Therefore, we use JSON.stringify to convert it to a string when the data is of object type. + // see: https://github.com/aws/aws-cdk/issues/33527 + const data = typeof msg.entry.data === 'object' && msg.entry.data !== null + ? JSON.stringify(msg.entry.data) + : msg.entry.data; + + ioHost.notify({ + time: new Date(), + level, + code: code(level), + message: `[${level} at ${msg.id}] ${data}`, + data: msg, + }); + }); } /** diff --git a/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts b/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts index 156b428b8..217adb619 100644 --- a/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts +++ b/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts @@ -7,7 +7,7 @@ import * as chalk from 'chalk'; import { Toolkit } from '../../lib'; -import { TestIoHost } from '../_helpers'; +import { TestCloudAssemblySource, TestIoHost } from '../_helpers'; describe('message formatting', () => { test('emojis can be stripped from message', async () => { @@ -70,3 +70,69 @@ describe('message formatting', () => { })); }); }); + +describe('metadata message formatting', () => { + test('converts object data to string for log message types', async () => { + const ioHost = new TestIoHost(); + const toolkit = new Toolkit({ ioHost }); + + const source = new TestCloudAssemblySource({ + stacks: [{ + stackName: 'test-stack', + metadata: { + 'test-stack': [{ + type: 'aws:cdk:warning', + data: { 'Fn::Join': ['','test'], 'Ref': 'someRef' } as any + }] + } + }] + }); + + await toolkit.synth(source); + + expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({ + level: 'warn', + message: expect.stringContaining('{"Fn::Join":["","test"],"Ref":"someRef"}'), + data: { + entry: { + type: 'aws:cdk:warning', + data: { 'Fn::Join': ['','test'], 'Ref': 'someRef' } + }, + id: 'test-stack', + level: 'warning' + } + })); + }); + + test('keeps non-object data as-is for log message types', async () => { + const ioHost = new TestIoHost(); + const toolkit = new Toolkit({ ioHost }); + + const source = new TestCloudAssemblySource({ + stacks: [{ + stackName: 'test-stack', + metadata: { + 'test-stack': [{ + type: 'aws:cdk:info', + data: 'simple string message' + }] + } + }] + }); + + await toolkit.synth(source); + + expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({ + level: 'info', + message: expect.stringContaining('simple string message'), + data: { + entry: { + type: 'aws:cdk:info', + data: 'simple string message' + }, + id: 'test-stack', + level: 'info' + } + })); + }); +}); From 42570c4be7465ca82e7a7556ef7436d355ba55b2 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Sun, 23 Feb 2025 03:34:55 +0900 Subject: [PATCH 2/6] change test names --- packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts b/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts index 217adb619..f673ff438 100644 --- a/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts +++ b/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts @@ -72,7 +72,7 @@ describe('message formatting', () => { }); describe('metadata message formatting', () => { - test('converts object data to string for log message types', async () => { + test('converts object data for log message to string', async () => { const ioHost = new TestIoHost(); const toolkit = new Toolkit({ ioHost }); @@ -104,7 +104,7 @@ describe('metadata message formatting', () => { })); }); - test('keeps non-object data as-is for log message types', async () => { + test('keeps non-object data for log message as-is', async () => { const ioHost = new TestIoHost(); const toolkit = new Toolkit({ ioHost }); From 05d3b92aeeae062e441ea9e5d17e250882725ea0 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Sun, 23 Feb 2025 03:57:11 +0900 Subject: [PATCH 3/6] nit --- packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts b/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts index c1e66277d..7af3bce5b 100644 --- a/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts +++ b/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts @@ -762,7 +762,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab // Data comes from Annotations and the data can be of object type containing 'Fn::Join' or 'Ref' when tokens are included in Annotations. // Therefore, we use JSON.stringify to convert it to a string when the data is of object type. // see: https://github.com/aws/aws-cdk/issues/33527 - const data = typeof msg.entry.data === 'object' && msg.entry.data !== null + const data = msg.entry.data !== null && typeof msg.entry.data === 'object' ? JSON.stringify(msg.entry.data) : msg.entry.data; From 89815b27e691dba81ba177b14f1226a54ca7802b Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Sun, 23 Feb 2025 04:37:11 +0900 Subject: [PATCH 4/6] tests --- .../toolkit-lib/test/toolkit/toolkit.test.ts | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts b/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts index f673ff438..0cd92ff97 100644 --- a/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts +++ b/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts @@ -82,21 +82,31 @@ describe('metadata message formatting', () => { metadata: { 'test-stack': [{ type: 'aws:cdk:warning', - data: { 'Fn::Join': ['','test'], 'Ref': 'someRef' } as any - }] - } - }] + data: { + 'Fn::Join': [ + '', + [ + 'stackId: ', + { + 'Ref': "AWS::StackId" + } + ] + ], + } as any, + }], + }, + }], }); await toolkit.synth(source); expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({ level: 'warn', - message: expect.stringContaining('{"Fn::Join":["","test"],"Ref":"someRef"}'), + message: expect.stringContaining('{"Fn::Join":["",["stackId: ",{"Ref":"AWS::StackId"}]]}'), data: { entry: { type: 'aws:cdk:warning', - data: { 'Fn::Join': ['','test'], 'Ref': 'someRef' } + data: { 'Fn::Join': ['', ['stackId: ', { 'Ref': 'AWS::StackId' }]] } }, id: 'test-stack', level: 'warning' From 4811e4d6a1f6767647263ef6dbda7b50715f90b5 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Sun, 23 Feb 2025 04:48:47 +0900 Subject: [PATCH 5/6] style --- .../toolkit-lib/test/toolkit/toolkit.test.ts | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts b/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts index 0cd92ff97..42154487a 100644 --- a/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts +++ b/packages/@aws-cdk/toolkit-lib/test/toolkit/toolkit.test.ts @@ -88,9 +88,9 @@ describe('metadata message formatting', () => { [ 'stackId: ', { - 'Ref': "AWS::StackId" - } - ] + Ref: 'AWS::StackId', + }, + ], ], } as any, }], @@ -106,11 +106,11 @@ describe('metadata message formatting', () => { data: { entry: { type: 'aws:cdk:warning', - data: { 'Fn::Join': ['', ['stackId: ', { 'Ref': 'AWS::StackId' }]] } + data: { 'Fn::Join': ['', ['stackId: ', { Ref: 'AWS::StackId' }]] }, }, id: 'test-stack', - level: 'warning' - } + level: 'warning', + }, })); }); @@ -124,10 +124,10 @@ describe('metadata message formatting', () => { metadata: { 'test-stack': [{ type: 'aws:cdk:info', - data: 'simple string message' - }] - } - }] + data: 'simple string message', + }], + }, + }], }); await toolkit.synth(source); @@ -138,11 +138,11 @@ describe('metadata message formatting', () => { data: { entry: { type: 'aws:cdk:info', - data: 'simple string message' + data: 'simple string message', }, id: 'test-stack', - level: 'info' - } + level: 'info', + }, })); }); }); From 83a2d48563f627489a256b4cb5d645a439a86557 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Sun, 23 Feb 2025 04:48:56 +0900 Subject: [PATCH 6/6] missed await --- packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts b/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts index 7af3bce5b..5ea9cf232 100644 --- a/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts +++ b/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts @@ -766,7 +766,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab ? JSON.stringify(msg.entry.data) : msg.entry.data; - ioHost.notify({ + await ioHost.notify({ time: new Date(), level, code: code(level),