Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/@aws-cdk/tmp-toolkit-helpers/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './io';
export * from './toolkit-error';
3 changes: 3 additions & 0 deletions packages/@aws-cdk/tmp-toolkit-helpers/src/api/io/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './io-host';
export * from './io-message';
export * from './toolkit-action';
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ToolkitAction } from '../../toolkit';
import { ToolkitAction } from './toolkit-action';

/**
* The reporting level of the message.
Expand All @@ -7,7 +7,7 @@ import { ToolkitAction } from '../../toolkit';
export type IoMessageLevel = 'error'| 'result' | 'warn' | 'info' | 'debug' | 'trace';

/**
* A valid message code. See https://github.com/aws/aws-cdk-cli/blob/main/packages/%40aws-cdk/toolkit-lib/CODE_REGISTRY.md
* A valid message code.
*/
export type IoMessageCode = `CDK_${string}_${'E' | 'W' | 'I'}${number}${number}${number}${number}`;

Expand All @@ -21,7 +21,10 @@ export interface IoMessage<T> {
readonly time: Date;

/**
* The log level of the message.
* The recommended log level of the message.
*
* This is an indicative level and should not be used to explicitly match messages, instead match the `code`.
* The level of a message may change without notice.
*/
readonly level: IoMessageLevel;

Expand All @@ -45,6 +48,8 @@ export interface IoMessage<T> {
* 'CDK_TOOLKIT_E0002' // valid: specific toolkit error message
* 'CDK_SDK_W0023' // valid: specific sdk warning message
* ```
*
* @see https://github.com/aws/aws-cdk-cli/blob/main/packages/%40aws-cdk/toolkit-lib/CODE_REGISTRY.md
*/
readonly code: IoMessageCode;

Expand All @@ -60,6 +65,9 @@ export interface IoMessage<T> {
readonly data?: T;
}

/**
* An IO request emitted.
*/
export interface IoRequest<T, U> extends IoMessage<T> {
/**
* The default response that will be used if no data is returned.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
import { IIoHost } from '../io-host';
import { IoMessage, IoRequest } from '../io-message';

/**
* Valid reporting categories for messages.
*/
export type IoMessageCodeCategory = 'TOOLKIT' | 'SDK' | 'ASSETS' | 'ASSEMBLY';

/**
* Code level matching the reporting level.
*/
export type IoCodeLevel = 'E' | 'W' | 'I';

/**
* A message code at a specific level
*/
export type IoMessageSpecificCode<L extends IoCodeLevel> = `CDK_${IoMessageCodeCategory}_${L}${number}${number}${number}${number}`;
import { ToolkitAction } from '../toolkit-action';

export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
export type SimplifiedMessage<T> = Pick<IoMessage<T>, 'level' | 'code' | 'message' | 'data'>;
Expand All @@ -28,3 +14,24 @@ export interface ActionAwareIoHost extends IIoHost {
notify<T>(msg: ActionLessMessage<T>): Promise<void>;
requestResponse<T, U>(msg: ActionLessRequest<T, U>): Promise<U>;
}

/**
* An IoHost wrapper that adds the given action to an actionless message before
* sending the message to the given IoHost
*/
export function withAction(ioHost: IIoHost, action: ToolkitAction): ActionAwareIoHost {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we already have this function here:

export function withAction(ioHost: IIoHost, action: ToolkitAction) {

Can we reuse?

return {
notify: async <T>(msg: Omit<IoMessage<T>, 'action'>) => {
await ioHost.notify({
...msg,
action,
});
},
requestResponse: async <T, U>(msg: Omit<IoRequest<T, U>, 'action'>) => {
return ioHost.requestResponse({
...msg,
action,
});
},
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './action-aware';
export * from './message-maker';
export * from './types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { IoMessageCode, IoMessageLevel } from '../io-message';
import { ActionLessMessage } from './action-aware';

/**
* Information for each IO Message Code.
*/
interface CodeInfo {
/**
* The message code.
*/
code: IoMessageCode;

/**
* A brief description of the meaning of this IO Message.
*/
description: string;

/**
* The name of the payload interface, if applicable.
* Some Io Messages include a payload, with a specific interface. The name of
* the interface is specified here so that it can be linked with the message
* when documentation is generated.
*
* The interface _must_ be exposed directly from toolkit-lib, so that it will
* have a documentation page generated (that can be linked to).
*/
interface?: string;
}

/**
* Information for each IO Message
*/
interface MessageInfo extends CodeInfo {
/**
* The message level
*/
level: IoMessageLevel;
}

/**
* An interface that can produce messages for a specific code.
*/
export interface IoMessageMaker<T> extends MessageInfo {
/**
* Create a message for this code, with or without payload.
*/
msg: [T] extends [never] ? (message: string) => ActionLessMessage<never> : (message: string, data: T) => ActionLessMessage<T>;
}

/**
* Produce an IoMessageMaker for the provided level and code info.
*/
function generic<T = never>(level: IoMessageLevel, details: CodeInfo): IoMessageMaker<T> {
const msg = (message: string, data: T) => ({
time: new Date(),
level,
code: details.code,
message: message,
data: data,
} as ActionLessMessage<T>);

return {
...details,
level,
msg: msg as any,
};
}

// Create `IoMessageMaker`s for a given level and type check that calls with payload are using the correct interface
type CodeInfoMaybeInterface<T> = [T] extends [never] ? Omit<CodeInfo, 'interface'> : Required<CodeInfo>;

export const trace = <T = never>(details: CodeInfoMaybeInterface<T>) => generic<T>('trace', details);
export const debug = <T = never>(details: CodeInfoMaybeInterface<T>) => generic<T>('debug', details);
export const info = <T = never>(details: CodeInfoMaybeInterface<T>) => generic<T>('info', details);
export const warn = <T = never>(details: CodeInfoMaybeInterface<T>) => generic<T>('warn', details);
export const error = <T = never>(details: CodeInfoMaybeInterface<T>) => generic<T>('error', details);
export const result = <T extends object>(details: Required<CodeInfo>) => generic<T extends object ? T : never>('result', details);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* Valid reporting categories for messages.
*/
export type IoMessageCodeCategory = 'TOOLKIT' | 'SDK' | 'ASSETS' | 'ASSEMBLY';
19 changes: 19 additions & 0 deletions packages/@aws-cdk/tmp-toolkit-helpers/src/api/io/toolkit-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* The current action being performed by the CLI. 'none' represents the absence of an action.
*/
export type ToolkitAction =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this PR but it just caught my so putting it out here. This list is slightly different than then one in the CLI. Intentional?

export type ToolkitAction =
| 'assembly'
| 'bootstrap'
| 'synth'
| 'list'
| 'diff'
| 'deploy'
| 'rollback'
| 'watch'
| 'destroy'
| 'context'
| 'docs'
| 'doctor'
| 'gc'
| 'import'
| 'metadata'
| 'notices'
| 'init'
| 'migrate'
| 'version';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the CLI has more. To be unified soon.

| 'assembly'
| 'bootstrap'
| 'synth'
| 'list'
| 'diff'
| 'deploy'
| 'rollback'
| 'watch'
| 'destroy'
| 'doctor'
| 'gc'
| 'import'
| 'metadata'
| 'init'
| 'migrate';
20 changes: 10 additions & 10 deletions packages/@aws-cdk/toolkit-lib/CODE_REGISTRY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

| Code | Description | Level | Data Interface |
|------|-------------|-------|----------------|
| CDK_TOOLKIT_I1000 | Provides synthesis times. | info | n/a |
| CDK_TOOLKIT_I1901 | Provides stack data | result | [StackData](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/StackData.html) |
| CDK_TOOLKIT_I1000 | Provides synthesis times. | info | [Duration](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/Duration.html) |
| CDK_TOOLKIT_I1901 | Provides stack data | result | [StackAndAssemblyData](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/StackAndAssemblyData.html) |
| CDK_TOOLKIT_I1902 | Successfully deployed stacks | result | [AssemblyData](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/AssemblyData.html) |
| CDK_TOOLKIT_I2901 | Provides details on the selected stacks and their dependencies | result | n/a |
| CDK_TOOLKIT_I2901 | Provides details on the selected stacks and their dependencies | result | [StackDetailsPayload](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/StackDetailsPayload.html) |
| CDK_TOOLKIT_E3900 | Resource import failed | error | n/a |
| CDK_TOOLKIT_I5000 | Provides deployment times | info | n/a |
| CDK_TOOLKIT_I5000 | Provides deployment times | info | [Duration](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/Duration.html) |
| CDK_TOOLKIT_I5001 | Provides total time in deploy action, including synth and rollback | info | [Duration](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/Duration.html) |
| CDK_TOOLKIT_I5002 | Provides time for resource migration | info | n/a |
| CDK_TOOLKIT_I5031 | Informs about any log groups that are traced as part of the deployment | info | n/a |
Expand All @@ -19,20 +19,20 @@
| CDK_TOOLKIT_I5900 | Deployment results on success | result | [SuccessfulDeployStackResult](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/SuccessfulDeployStackResult.html) |
| CDK_TOOLKIT_E5001 | No stacks found | error | n/a |
| CDK_TOOLKIT_E5500 | Stack Monitoring error | error | [ErrorPayload](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/ErrorPayload.html) |
| CDK_TOOLKIT_I6000 | Provides rollback times | info | n/a |
| CDK_TOOLKIT_I6000 | Provides rollback times | info | [Duration](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/Duration.html) |
| CDK_TOOLKIT_E6001 | No stacks found | error | n/a |
| CDK_TOOLKIT_E6900 | Rollback failed | error | n/a |
| CDK_TOOLKIT_I7000 | Provides destroy times | info | n/a |
| CDK_TOOLKIT_I7000 | Provides destroy times | info | [Duration](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/Duration.html) |
| CDK_TOOLKIT_I7010 | Confirm destroy stacks | info | n/a |
| CDK_TOOLKIT_E7010 | Action was aborted due to negative confirmation of request | error | n/a |
| CDK_TOOLKIT_E7900 | Stack deletion failed | error | n/a |
| CDK_TOOLKIT_I9000 | Provides bootstrap times | info | n/a |
| CDK_TOOLKIT_I9000 | Provides bootstrap times | info | [Duration](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/Duration.html) |
| CDK_TOOLKIT_I9900 | Bootstrap results on success | info | n/a |
| CDK_TOOLKIT_E9900 | Bootstrap failed | error | n/a |
| CDK_ASSEMBLY_I0042 | Writing updated context | debug | n/a |
| CDK_ASSEMBLY_I0241 | Fetching missing context | debug | n/a |
| CDK_ASSEMBLY_I0042 | Writing updated context | debug | [UpdatedContext](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/UpdatedContext.html) |
| CDK_ASSEMBLY_I0241 | Fetching missing context | debug | [MissingContext](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/MissingContext.html) |
| CDK_ASSEMBLY_I1000 | Cloud assembly output starts | debug | n/a |
| CDK_ASSEMBLY_I1001 | Output lines emitted by the cloud assembly to stdout | info | n/a |
| CDK_ASSEMBLY_E1002 | Output lines emitted by the cloud assembly to stderr | error | n/a |
| CDK_ASSEMBLY_I1003 | Cloud assembly output finished | info | n/a |
| CDK_ASSEMBLY_E1111 | Incompatible CDK CLI version. Upgrade needed. | error | n/a |
| CDK_ASSEMBLY_E1111 | Incompatible CDK CLI version. Upgrade needed. | error | [ErrorPayload](https://docs.aws.amazon.com/cdk/api/toolkit-lib/interfaces/ErrorPayload.html) |
3 changes: 2 additions & 1 deletion packages/@aws-cdk/toolkit-lib/build-tools/bundle.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ await esbuild.build({
outdir: 'lib',
entryPoints: [
'lib/api/aws-cdk.ts',
'lib/api/shared-public.ts',
'lib/api/shared-public.ts',
'lib/api/shared-private.ts',
'lib/private/util.ts',
],
target: 'node18',
Expand Down
5 changes: 5 additions & 0 deletions packages/@aws-cdk/toolkit-lib/lib/actions/list/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { StackDetails } from '../../api/aws-cdk';
import type { StackSelector } from '../../api/cloud-assembly';

export interface ListOptions {
Expand All @@ -6,3 +7,7 @@ export interface ListOptions {
*/
readonly stacks?: StackSelector;
}

export interface StackDetailsPayload {
stacks: StackDetails[];
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/toolkit-lib/lib/api/aws-cdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export { ResourceMigrator } from '../../../../aws-cdk/lib/api/resource-import';
export { CloudWatchLogEventMonitor, findCloudWatchLogGroups } from '../../../../aws-cdk/lib/api/logs';
export { type WorkGraph, WorkGraphBuilder, AssetBuildNode, AssetPublishNode, StackNode, Concurrency } from '../../../../aws-cdk/lib/api/work-graph';
export { Bootstrapper } from '../../../../aws-cdk/lib/api/bootstrap';
export type { StackActivity, StackMonitoringControlEvent } from '../../../../aws-cdk/lib/api/stack-events';

// Context Providers
export * as contextproviders from '../../../../aws-cdk/lib/context-providers';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface MissingContext {
missingKeys: string[];
}

export interface UpdatedContext {
contextFile: string;
context: { [key: string]: any };
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import type { MissingContext } from '@aws-cdk/cloud-assembly-schema';
import * as cxapi from '@aws-cdk/cx-api';
import { ToolkitServices } from '../../../toolkit/private';
import { type Context, contextproviders, PROJECT_CONTEXT } from '../../aws-cdk';
import { ActionAwareIoHost, CODES, debug } from '../../io/private';
import { CODES, debug } from '../../io/private';
import { ActionAwareIoHost } from '../../shared-private';
import { ToolkitError } from '../../shared-public';
import { ICloudAssemblySource } from '../types';

Expand Down Expand Up @@ -82,7 +83,7 @@ export class ContextAwareCloudAssembly implements ICloudAssemblySource {
previouslyMissingKeys = missingKeys;

if (tryLookup) {
await this.ioHost.notify(debug('Some context information is missing. Fetching...', CODES.CDK_ASSEMBLY_I0241, {
await this.ioHost.notify(CODES.CDK_ASSEMBLY_I0241.msg('Some context information is missing. Fetching...', {
missingKeys: Array.from(missingKeys),
}));
await contextproviders.provideContextValues(
Expand All @@ -92,7 +93,7 @@ export class ContextAwareCloudAssembly implements ICloudAssemblySource {
);

// Cache the new context to disk
await this.ioHost.notify(debug(`Writing updated context to ${this.contextFile}...`, CODES.CDK_ASSEMBLY_I0042, {
await this.ioHost.notify(CODES.CDK_ASSEMBLY_I0042.msg(`Writing updated context to ${this.contextFile}...`, {
contextFile: this.contextFile,
context: this.context.all,
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { lte } from 'semver';
import { prepareDefaultEnvironment as oldPrepare, prepareContext, spaceAvailableForContext, Settings, loadTree, some, versionNumber } from '../../../api/aws-cdk';
import { splitBySize } from '../../../private/util';
import { ToolkitServices } from '../../../toolkit/private';
import { ActionAwareIoHost, asLogger, CODES, error } from '../../io/private';
import { asLogger, CODES } from '../../io/private';
import { ActionAwareIoHost } from '../../shared-private';
import { ToolkitError } from '../../shared-public';
import type { AppSynthOptions } from '../source-builder';

Expand Down Expand Up @@ -161,7 +162,7 @@ export async function assemblyFromDirectory(assemblyDir: string, ioHost: ActionA
// this means the CLI version is too old.
// we instruct the user to upgrade.
const message = 'This AWS CDK Toolkit is not compatible with the AWS CDK library used by your application. Please upgrade to the latest version.';
await ioHost.notify(error(message, CODES.CDK_ASSEMBLY_E1111, { error: err.message }));
await ioHost.notify(CODES.CDK_ASSEMBLY_E1111.msg(message, { error: err }));
throw new ToolkitError(`${message}\n(${err.message}`);
}
throw err;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { execInChildProcess } from './exec';
import { assemblyFromDirectory, changeDir, determineOutputDirectory, guessExecutable, prepareDefaultEnvironment, withContext, withEnv } from './prepare-source';
import { ToolkitServices } from '../../../toolkit/private';
import { Context, ILock, RWLock, Settings } from '../../aws-cdk';
import { CODES, debug, error, info } from '../../io/private';
import { CODES, debug } from '../../io/private';
import { ToolkitError } from '../../shared-public';
import { AssemblyBuilder } from '../source-builder';

Expand Down Expand Up @@ -126,10 +126,10 @@ export abstract class CloudAssemblySourceBuilder {
eventPublisher: async (type, line) => {
switch (type) {
case 'data_stdout':
await services.ioHost.notify(info(line, CODES.CDK_ASSEMBLY_I1001));
await services.ioHost.notify(CODES.CDK_ASSEMBLY_I1001.msg(line));
break;
case 'data_stderr':
await services.ioHost.notify(error(line, CODES.CDK_ASSEMBLY_E1002));
await services.ioHost.notify(CODES.CDK_ASSEMBLY_E1002.msg(line));
break;
}
},
Expand Down
3 changes: 1 addition & 2 deletions packages/@aws-cdk/toolkit-lib/lib/api/io/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './io-host';
export * from './io-message';
export type { IoMessageLevel, IoMessageCode, IIoHost, IoMessage, IoRequest } from '../shared-public';
Loading