Skip to content

Commit

Permalink
chore(toolkit): trim whitespace from IoMessages (#33284)
Browse files Browse the repository at this point in the history
### 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*
  • Loading branch information
mrgrain authored Feb 4, 2025
1 parent 9a0e1ad commit 5e35788
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 34 deletions.
22 changes: 22 additions & 0 deletions packages/@aws-cdk/toolkit/lib/api/io/private/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,28 @@ function stripEmojis(msg: string): string {
return msg.replace(/\p{Emoji_Presentation}/gu, '');
}

/**
* An IoHost wrapper that trims whitespace at the beginning and end of messages.
* This is required, since after removing emojis and ANSI colors,
* we might end up with floating whitespace at either end.
*/
export function withTrimmedWhitespace(ioHost: IIoHost): IIoHost {
return {
notify: async <T>(msg: IoMessage<T>) => {
await ioHost.notify({
...msg,
message: msg.message.trim(),
});
},
requestResponse: async <T, U>(msg: IoRequest<T, U>) => {
return ioHost.requestResponse({
...msg,
message: msg.message.trim(),
});
},
};
}

// @todo these cannot be awaited WTF
export function asSdkLogger(ioHost: IIoHost, action: ToolkitAction): Logger {
return new class implements Logger {
Expand Down
6 changes: 4 additions & 2 deletions packages/@aws-cdk/toolkit/lib/toolkit/toolkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { CachedCloudAssemblySource, IdentityCloudAssemblySource, StackAssembly,
import { ALL_STACKS, CloudAssemblySourceBuilder } from '../api/cloud-assembly/private';
import { ToolkitError } from '../api/errors';
import { IIoHost, IoMessageCode, IoMessageLevel } from '../api/io';
import { asSdkLogger, withAction, Timer, confirm, error, highlight, info, success, warn, ActionAwareIoHost, debug, result, withoutEmojis, withoutColor } from '../api/io/private';
import { asSdkLogger, withAction, Timer, confirm, error, highlight, info, success, warn, ActionAwareIoHost, debug, result, withoutEmojis, withoutColor, withTrimmedWhitespace } from '../api/io/private';

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

public async dispose(): Promise<void> {
Expand Down
86 changes: 54 additions & 32 deletions packages/@aws-cdk/toolkit/test/toolkit/toolkit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,64 @@ import * as chalk from 'chalk';
import { Toolkit } from '../../lib';
import { TestIoHost } from '../_helpers';

test('emojis can be stripped from message', async () => {
const ioHost = new TestIoHost();
const toolkit = new Toolkit({ ioHost, emojis: false });

await toolkit.ioHost.notify({
message: '💯Smile123😀',
action: 'deploy',
level: 'info',
code: 'CDK_TOOLKIT_I0000',
time: new Date(),
describe('message formatting', () => {
test('emojis can be stripped from message', async () => {
const ioHost = new TestIoHost();
const toolkit = new Toolkit({ ioHost, emojis: false });

await toolkit.ioHost.notify({
message: '💯Smile123😀',
action: 'deploy',
level: 'info',
code: 'CDK_TOOLKIT_I0000',
time: new Date(),
});

expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({
action: 'deploy',
level: 'info',
code: 'CDK_TOOLKIT_I0000',
message: 'Smile123',
}));
});

expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({
action: 'deploy',
level: 'info',
code: 'CDK_TOOLKIT_I0000',
message: 'Smile123',
}));
});
test('color can be stripped from message', async () => {
const ioHost = new TestIoHost();
const toolkit = new Toolkit({ ioHost, color: false });

test('color can be stripped from message', async () => {
const ioHost = new TestIoHost();
const toolkit = new Toolkit({ ioHost, color: false });
await toolkit.ioHost.notify({
message: chalk.red('RED') + chalk.bold('BOLD') + chalk.blue('BLUE'),
action: 'deploy',
level: 'info',
code: 'CDK_TOOLKIT_I0000',
time: new Date(),
});

await toolkit.ioHost.notify({
message: chalk.red('RED') + chalk.bold('BOLD') + chalk.blue('BLUE'),
action: 'deploy',
level: 'info',
code: 'CDK_TOOLKIT_I0000',
time: new Date(),
expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({
action: 'deploy',
level: 'info',
code: 'CDK_TOOLKIT_I0000',
message: 'REDBOLDBLUE',
}));
});

expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({
action: 'deploy',
level: 'info',
code: 'CDK_TOOLKIT_I0000',
message: 'REDBOLDBLUE',
}));
test('whitespace is always trimmed from a message', async () => {
const ioHost = new TestIoHost();
const toolkit = new Toolkit({ ioHost, color: false });

await toolkit.ioHost.notify({
message: ' test message\n\n',
action: 'deploy',
level: 'info',
code: 'CDK_TOOLKIT_I0000',
time: new Date(),
});

expect(ioHost.notifySpy).toHaveBeenCalledWith(expect.objectContaining({
action: 'deploy',
level: 'info',
code: 'CDK_TOOLKIT_I0000',
message: 'test message',
}));
});
});

0 comments on commit 5e35788

Please sign in to comment.