Skip to content

Commit

Permalink
chore(toolkit): register valid message codes (#33160)
Browse files Browse the repository at this point in the history
Begins a registry of valid codes that are currently in use within the toolkit, and requires that only registered codes are used.

### 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
kaizencc authored Jan 28, 2025
1 parent 0c53765 commit 78bcd09
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 17 deletions.
43 changes: 43 additions & 0 deletions packages/@aws-cdk/toolkit/lib/api/io/private/codes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { IoMessageCode } from '../io-message';

export const CODES = {
// Default codes -- all 0000 codes
CDK_TOOLKIT_I0000: 'Default toolkit info code',
CDK_TOOLKIT_E0000: 'Default toolkit error code',
CDK_TOOLKIT_W0000: 'Default toolkit warning code',
CDK_SDK_I0000: 'Default sdk info code',
CDK_SDK_E0000: 'Default sdk error code',
CDK_SDK_WOOOO: 'Default sdk warning code',
CDK_ASSETS_I0000: 'Default assets info code',
CDK_ASSETS_E0000: 'Default assets error code',
CDK_ASSETS_W0000: 'Default assets warning code',
CDK_ASSEMBLY_I0000: 'Default assembly info code',
CDK_ASSEMBLY_E0000: 'Default assembly error code',
CDK_ASSEMBLY_W0000: 'Default assembly warning code',

// Toolkit Info codes
CDK_TOOLKIT_I0001: 'Display stack data',
CDK_TOOLKIT_I0002: 'Successfully deployed stacks',
CDK_TOOLKIT_I5001: 'Display synthesis times',
CDK_TOOLKIT_I5050: 'Confirm rollback',
CDK_TOOLKIT_I5060: 'Confirm deploy security sensitive changes',
CDK_TOOLKIT_I7010: 'Confirm destroy stacks',

// Toolkit Warning codes

// Toolkit Error codes

// Assembly Info codes
CDK_ASSEMBLY_I0042: 'Writing updated context',
CDK_ASSEMBLY_I0241: 'Fetching missing context',

// Assembly Warning codes

// Assembly Error codes
CDK_ASSEMBLY_E1111: 'Incompatible CDK CLI version. Upgrade needed.',
};

// If we give CODES a type with key: IoMessageCode,
// this dynamically generated type will generalize to allow all IoMessageCodes.
// Instead, we will validate that VALID_CODE must be IoMessageCode with the '&'.
export type VALID_CODE = keyof typeof CODES & IoMessageCode;
1 change: 1 addition & 0 deletions packages/@aws-cdk/toolkit/lib/api/io/private/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './logger';
export * from './messages';
export * from './timer';
export * from './types';
export * from './codes';
4 changes: 2 additions & 2 deletions packages/@aws-cdk/toolkit/lib/api/io/private/logger.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as util from 'node:util';
import type { Logger } from '@smithy/types';
import type { IoMessage, IoMessageCodeCategory, IoMessageLevel, IoRequest } from '../io-message';
import { debug, error, info, messageCode, trace, warn } from './messages';
import { debug, error, info, defaultMessageCode, trace, warn } from './messages';
import type { ActionAwareIoHost } from './types';
import type { ToolkitAction } from '../../../toolkit';
import { formatSdkLoggerContent } from '../../aws-cdk';
Expand Down Expand Up @@ -118,7 +118,7 @@ export function asSdkLogger(ioHost: IIoHost, action: ToolkitAction): Logger {
* Turn an ActionAwareIoHost into a logger that is compatible with older code, but doesn't support data
*/
export function asLogger(ioHost: ActionAwareIoHost, category?: IoMessageCodeCategory) {
const code = (level: IoMessageLevel) => messageCode(level, category);
const code = (level: IoMessageLevel) => defaultMessageCode(level, category);

return {
trace: async (msg: string, ...args: any[]) => {
Expand Down
32 changes: 17 additions & 15 deletions packages/@aws-cdk/toolkit/lib/api/io/private/messages.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as chalk from 'chalk';
import type { IoMessageCode, IoMessageCodeCategory, IoMessageLevel } from '../io-message';
import type { IoMessageCodeCategory, IoMessageLevel } from '../io-message';
import { type VALID_CODE } from './codes';
import type { ActionLessMessage, ActionLessRequest, Optional, SimplifiedMessage } from './types';

/**
Expand All @@ -11,27 +12,28 @@ export function formatMessage<T>(msg: Optional<SimplifiedMessage<T>, 'code'>, ca
return {
time: new Date(),
level: msg.level,
code: msg.code ?? messageCode(msg.level, category),
code: msg.code ?? defaultMessageCode(msg.level, category),
message: msg.message,
data: msg.data,
};
}

/**
* Build a message code from level and category
* Build a message code from level and category. The code must be valid for this function to pass.
* Otherwise it returns a ToolkitError.
*/
export function messageCode(level: IoMessageLevel, category: IoMessageCodeCategory = 'TOOLKIT', number?: `${number}${number}${number}${number}`): IoMessageCode {
export function defaultMessageCode(level: IoMessageLevel, category: IoMessageCodeCategory = 'TOOLKIT'): VALID_CODE {
const levelIndicator = level === 'error' ? 'E' :
level === 'warn' ? 'W' :
'I';
return `CDK_${category}_${levelIndicator}${number ?? '0000'}`;
return `CDK_${category}_${levelIndicator}0000` as VALID_CODE;
}

/**
* Requests a yes/no confirmation from the IoHost.
*/
export const confirm = (
code: IoMessageCode,
code: VALID_CODE,
question: string,
motivation: string,
defaultResponse: boolean,
Expand All @@ -49,7 +51,7 @@ export const confirm = (
/**
* Prompt for a a response from the IoHost.
*/
export const prompt = <T, U>(code: IoMessageCode, message: string, defaultResponse: U, payload?: T): ActionLessRequest<T, U> => {
export const prompt = <T, U>(code: VALID_CODE, message: string, defaultResponse: U, payload?: T): ActionLessRequest<T, U> => {
return {
defaultResponse,
...formatMessage({
Expand All @@ -64,7 +66,7 @@ export const prompt = <T, U>(code: IoMessageCode, message: string, defaultRespon
/**
* Logs an error level message.
*/
export const error = <T>(message: string, code?: IoMessageCode, payload?: T) => {
export const error = <T>(message: string, code?: VALID_CODE, payload?: T) => {
return formatMessage({
level: 'error',
code,
Expand All @@ -76,7 +78,7 @@ export const error = <T>(message: string, code?: IoMessageCode, payload?: T) =>
/**
* Logs an warning level message.
*/
export const warn = <T>(message: string, code?: IoMessageCode, payload?: T) => {
export const warn = <T>(message: string, code?: VALID_CODE, payload?: T) => {
return formatMessage({
level: 'warn',
code,
Expand All @@ -88,7 +90,7 @@ export const warn = <T>(message: string, code?: IoMessageCode, payload?: T) => {
/**
* Logs an info level message.
*/
export const info = <T>(message: string, code?: IoMessageCode, payload?: T) => {
export const info = <T>(message: string, code?: VALID_CODE, payload?: T) => {
return formatMessage({
level: 'info',
code,
Expand All @@ -101,7 +103,7 @@ export const info = <T>(message: string, code?: IoMessageCode, payload?: T) => {
* Logs an info level message to stdout.
* @deprecated
*/
export const data = <T>(message: string, code?: IoMessageCode, payload?: T) => {
export const data = <T>(message: string, code?: VALID_CODE, payload?: T) => {
return formatMessage({
level: 'info',
code,
Expand All @@ -113,7 +115,7 @@ export const data = <T>(message: string, code?: IoMessageCode, payload?: T) => {
/**
* Logs a debug level message.
*/
export const debug = <T>(message: string, code?: IoMessageCode, payload?: T) => {
export const debug = <T>(message: string, code?: VALID_CODE, payload?: T) => {
return formatMessage({
level: 'debug',
code,
Expand All @@ -125,7 +127,7 @@ export const debug = <T>(message: string, code?: IoMessageCode, payload?: T) =>
/**
* Logs a trace level message.
*/
export const trace = <T>(message: string, code?: IoMessageCode, payload?: T) => {
export const trace = <T>(message: string, code?: VALID_CODE, payload?: T) => {
return formatMessage({
level: 'trace',
code,
Expand All @@ -138,7 +140,7 @@ export const trace = <T>(message: string, code?: IoMessageCode, payload?: T) =>
* Logs an info level success message in green text.
* @deprecated
*/
export const success = <T>(message: string, code?: IoMessageCode, payload?: T) => {
export const success = <T>(message: string, code?: VALID_CODE, payload?: T) => {
return formatMessage({
level: 'info',
code,
Expand All @@ -151,7 +153,7 @@ export const success = <T>(message: string, code?: IoMessageCode, payload?: T) =
* Logs an info level message in bold text.
* @deprecated
*/
export const highlight = <T>(message: string, code?: IoMessageCode, payload?: T) => {
export const highlight = <T>(message: string, code?: VALID_CODE, payload?: T) => {
return formatMessage({
level: 'info',
code,
Expand Down

0 comments on commit 78bcd09

Please sign in to comment.