Skip to content

Commit 5e35788

Browse files
authored
chore(toolkit): trim whitespace from IoMessages (#33284)
### Reason for this change After removing emojis and ANSI colors, an IoMessage might end up with floating whitespace at either end. We want to trim this whitespace. ### Description of changes Always trim whitespace from IoMessages. ### Describe any new or updated permissions being added n/a ### Description of how you validated changes unit tests ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 9a0e1ad commit 5e35788

File tree

3 files changed

+80
-34
lines changed

3 files changed

+80
-34
lines changed

packages/@aws-cdk/toolkit/lib/api/io/private/logger.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,28 @@ function stripEmojis(msg: string): string {
7979
return msg.replace(/\p{Emoji_Presentation}/gu, '');
8080
}
8181

82+
/**
83+
* An IoHost wrapper that trims whitespace at the beginning and end of messages.
84+
* This is required, since after removing emojis and ANSI colors,
85+
* we might end up with floating whitespace at either end.
86+
*/
87+
export function withTrimmedWhitespace(ioHost: IIoHost): IIoHost {
88+
return {
89+
notify: async <T>(msg: IoMessage<T>) => {
90+
await ioHost.notify({
91+
...msg,
92+
message: msg.message.trim(),
93+
});
94+
},
95+
requestResponse: async <T, U>(msg: IoRequest<T, U>) => {
96+
return ioHost.requestResponse({
97+
...msg,
98+
message: msg.message.trim(),
99+
});
100+
},
101+
};
102+
}
103+
82104
// @todo these cannot be awaited WTF
83105
export function asSdkLogger(ioHost: IIoHost, action: ToolkitAction): Logger {
84106
return new class implements Logger {

packages/@aws-cdk/toolkit/lib/toolkit/toolkit.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { CachedCloudAssemblySource, IdentityCloudAssemblySource, StackAssembly,
1919
import { ALL_STACKS, CloudAssemblySourceBuilder } from '../api/cloud-assembly/private';
2020
import { ToolkitError } from '../api/errors';
2121
import { IIoHost, IoMessageCode, IoMessageLevel } from '../api/io';
22-
import { asSdkLogger, withAction, Timer, confirm, error, highlight, info, success, warn, ActionAwareIoHost, debug, result, withoutEmojis, withoutColor } from '../api/io/private';
22+
import { asSdkLogger, withAction, Timer, confirm, error, highlight, info, success, warn, ActionAwareIoHost, debug, result, withoutEmojis, withoutColor, withTrimmedWhitespace } from '../api/io/private';
2323

2424
/**
2525
* The current action being performed by the CLI. 'none' represents the absence of an action.
@@ -115,7 +115,9 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
115115
if (props.color === false) {
116116
ioHost = withoutColor(ioHost);
117117
}
118-
this.ioHost = ioHost;
118+
// After removing emojis and color, we might end up with floating whitespace at either end of the message
119+
// This also removes newlines that we currently emit for CLI backwards compatibility.
120+
this.ioHost = withTrimmedWhitespace(ioHost);
119121
}
120122

121123
public async dispose(): Promise<void> {

packages/@aws-cdk/toolkit/test/toolkit/toolkit.test.ts

Lines changed: 54 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,42 +9,64 @@ import * as chalk from 'chalk';
99
import { Toolkit } from '../../lib';
1010
import { TestIoHost } from '../_helpers';
1111

12-
test('emojis can be stripped from message', async () => {
13-
const ioHost = new TestIoHost();
14-
const toolkit = new Toolkit({ ioHost, emojis: false });
15-
16-
await toolkit.ioHost.notify({
17-
message: '💯Smile123😀',
18-
action: 'deploy',
19-
level: 'info',
20-
code: 'CDK_TOOLKIT_I0000',
21-
time: new Date(),
12+
describe('message formatting', () => {
13+
test('emojis can be stripped from message', async () => {
14+
const ioHost = new TestIoHost();
15+
const toolkit = new Toolkit({ ioHost, emojis: false });
16+
17+
await toolkit.ioHost.notify({
18+
message: '💯Smile123😀',
19+
action: 'deploy',
20+
level: 'info',
21+
code: 'CDK_TOOLKIT_I0000',
22+
time: new Date(),
23+
});
24+
25+
expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({
26+
action: 'deploy',
27+
level: 'info',
28+
code: 'CDK_TOOLKIT_I0000',
29+
message: 'Smile123',
30+
}));
2231
});
2332

24-
expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({
25-
action: 'deploy',
26-
level: 'info',
27-
code: 'CDK_TOOLKIT_I0000',
28-
message: 'Smile123',
29-
}));
30-
});
33+
test('color can be stripped from message', async () => {
34+
const ioHost = new TestIoHost();
35+
const toolkit = new Toolkit({ ioHost, color: false });
3136

32-
test('color can be stripped from message', async () => {
33-
const ioHost = new TestIoHost();
34-
const toolkit = new Toolkit({ ioHost, color: false });
37+
await toolkit.ioHost.notify({
38+
message: chalk.red('RED') + chalk.bold('BOLD') + chalk.blue('BLUE'),
39+
action: 'deploy',
40+
level: 'info',
41+
code: 'CDK_TOOLKIT_I0000',
42+
time: new Date(),
43+
});
3544

36-
await toolkit.ioHost.notify({
37-
message: chalk.red('RED') + chalk.bold('BOLD') + chalk.blue('BLUE'),
38-
action: 'deploy',
39-
level: 'info',
40-
code: 'CDK_TOOLKIT_I0000',
41-
time: new Date(),
45+
expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({
46+
action: 'deploy',
47+
level: 'info',
48+
code: 'CDK_TOOLKIT_I0000',
49+
message: 'REDBOLDBLUE',
50+
}));
4251
});
4352

44-
expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({
45-
action: 'deploy',
46-
level: 'info',
47-
code: 'CDK_TOOLKIT_I0000',
48-
message: 'REDBOLDBLUE',
49-
}));
53+
test('whitespace is always trimmed from a message', async () => {
54+
const ioHost = new TestIoHost();
55+
const toolkit = new Toolkit({ ioHost, color: false });
56+
57+
await toolkit.ioHost.notify({
58+
message: ' test message\n\n',
59+
action: 'deploy',
60+
level: 'info',
61+
code: 'CDK_TOOLKIT_I0000',
62+
time: new Date(),
63+
});
64+
65+
expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({
66+
action: 'deploy',
67+
level: 'info',
68+
code: 'CDK_TOOLKIT_I0000',
69+
message: 'test message',
70+
}));
71+
});
5072
});

0 commit comments

Comments
 (0)