Skip to content

Commit db6aa96

Browse files
authored
refactor(cli): make the cli use more shared code (#207)
Removes duplicated interfaces. I know this is messy. Please bear with me 🙈 --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
1 parent 2dca898 commit db6aa96

File tree

24 files changed

+101
-190
lines changed

24 files changed

+101
-190
lines changed

.projenrc.ts

+2
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,8 @@ tmpToolkitHelpers.eslint?.addRules({
733733
'@typescript-eslint/consistent-type-imports': 'error',
734734
});
735735

736+
tmpToolkitHelpers.gitignore.addPatterns('test/**/*.map');
737+
736738
//////////////////////////////////////////////////////////////////////
737739

738740
let CLI_SDK_VERSION: '2' | '3' = ('3' as any);

packages/@aws-cdk/tmp-toolkit-helpers/.gitignore

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
export * from './action-aware';
1+
export * from './io-helper';
2+
export * from './level-priority';
23
export * from './message-maker';
34
export * from './types';

packages/@aws-cdk/tmp-toolkit-helpers/src/api/io/private/action-aware.ts renamed to packages/@aws-cdk/tmp-toolkit-helpers/src/api/io/private/io-helper.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,22 @@ export type ActionLessMessage<T> = Omit<IoMessage<T>, 'action'>;
88
export type ActionLessRequest<T, U> = Omit<IoRequest<T, U>, 'action'>;
99

1010
/**
11-
* Helper type for IoHosts that are action aware
11+
* Helper for IO messaging.
12+
*
13+
* Wraps a client provided IoHost and provides additional features & services to toolkit internal classes.
1214
*/
13-
export interface ActionAwareIoHost extends IIoHost {
15+
export interface IoHelper extends IIoHost {
16+
action: ToolkitAction;
1417
notify<T>(msg: ActionLessMessage<T>): Promise<void>;
1518
requestResponse<T, U>(msg: ActionLessRequest<T, U>): Promise<U>;
1619
}
1720

1821
/**
19-
* An IoHost wrapper that adds the given action to an actionless message before
20-
* sending the message to the given IoHost
22+
* Wraps an IoHost and creates an IoHelper from it
2123
*/
22-
export function withAction(ioHost: IIoHost, action: ToolkitAction): ActionAwareIoHost {
24+
export function asIoHelper(ioHost: IIoHost, action: ToolkitAction): IoHelper {
2325
return {
26+
action,
2427
notify: async <T>(msg: Omit<IoMessage<T>, 'action'>) => {
2528
await ioHost.notify({
2629
...msg,

packages/@aws-cdk/tmp-toolkit-helpers/src/api/io/private/message-maker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { IoMessageCode, IoMessageLevel } from '../io-message';
2-
import type { ActionLessMessage, ActionLessRequest } from './action-aware';
2+
import type { ActionLessMessage, ActionLessRequest } from './io-helper';
33

44
/**
55
* Information for each IO Message Code.

packages/@aws-cdk/toolkit-lib/test/api/io/io-message.test.ts renamed to packages/@aws-cdk/tmp-toolkit-helpers/test/api/io/io-message.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isMessageRelevantForLevel } from '../../../lib/api/io/private/level-priority';
1+
import { isMessageRelevantForLevel } from '../../../src/api/io/private/level-priority';
22

33
describe('IoMessageLevel', () => {
44
test.each`

packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/context-aware-source.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type * as cxapi from '@aws-cdk/cx-api';
33
import type { ToolkitServices } from '../../../toolkit/private';
44
import { type Context, contextproviders, PROJECT_CONTEXT } from '../../aws-cdk';
55
import { IO } from '../../io/private';
6-
import type { ActionAwareIoHost } from '../../shared-private';
6+
import type { IoHelper } from '../../shared-private';
77
import { ToolkitError } from '../../shared-public';
88
import type { ICloudAssemblySource } from '../types';
99

@@ -43,7 +43,7 @@ export class ContextAwareCloudAssembly implements ICloudAssemblySource {
4343
private canLookup: boolean;
4444
private context: Context;
4545
private contextFile: string;
46-
private ioHost: ActionAwareIoHost;
46+
private ioHost: IoHelper;
4747

4848
constructor(private readonly source: ICloudAssemblySource, private readonly props: ContextAwareCloudAssemblyProps) {
4949
this.canLookup = props.lookups ?? true;

packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/prepare-source.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { prepareDefaultEnvironment as oldPrepare, prepareContext, spaceAvailable
99
import { splitBySize } from '../../../private/util';
1010
import type { ToolkitServices } from '../../../toolkit/private';
1111
import { IO } from '../../io/private';
12-
import type { ActionAwareIoHost } from '../../shared-private';
12+
import type { IoHelper } from '../../shared-private';
1313
import { ToolkitError } from '../../shared-public';
1414
import type { AppSynthOptions, LoadAssemblyOptions } from '../source-builder';
1515

@@ -130,7 +130,7 @@ export async function withContext<T>(
130130
*
131131
* @param assembly the assembly to check
132132
*/
133-
export async function checkContextOverflowSupport(assembly: cxapi.CloudAssembly, ioHost: ActionAwareIoHost): Promise<void> {
133+
export async function checkContextOverflowSupport(assembly: cxapi.CloudAssembly, ioHost: IoHelper): Promise<void> {
134134
const tree = loadTree(assembly);
135135
const frameworkDoesNotSupportContextOverflow = some(tree, node => {
136136
const fqn = node.constructInfo?.fqn;
@@ -149,7 +149,7 @@ export async function checkContextOverflowSupport(assembly: cxapi.CloudAssembly,
149149
/**
150150
* Safely create an assembly from a cloud assembly directory
151151
*/
152-
export async function assemblyFromDirectory(assemblyDir: string, ioHost: ActionAwareIoHost, loadOptions: LoadAssemblyOptions = {}) {
152+
export async function assemblyFromDirectory(assemblyDir: string, ioHost: IoHelper, loadOptions: LoadAssemblyOptions = {}) {
153153
try {
154154
const assembly = new cxapi.CloudAssembly(assemblyDir, {
155155
skipVersionCheck: !(loadOptions.checkVersion ?? true),
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export * from './messages';
22
export * from './io-host-wrappers';
3-
export * from './level-priority';
43
export * from './timer';
54
export * from './sdk-logger';

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { inspect } from 'util';
33
import type { Logger } from '@smithy/types';
44
import { IO } from './messages';
55
import { replacerBufferWithInfo } from '../../../private/util';
6-
import type { ActionAwareIoHost } from '../../shared-private';
6+
import type { IoHelper } from '../../shared-private';
77

88
/**
99
* An SDK logging trace.
@@ -27,7 +27,7 @@ export interface SdkTrace {
2727
readonly content: any;
2828
}
2929

30-
export function asSdkLogger(ioHost: ActionAwareIoHost): Logger {
30+
export function asSdkLogger(ioHost: IoHelper): Logger {
3131
return new class implements Logger {
3232
// This is too much detail for our logs
3333
public trace(..._content: any[]) {

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { format } from 'util';
22
import { IO } from './messages';
33
import { formatTime } from '../../../private/util';
4-
import type { ActionAwareIoHost } from '../../shared-private';
4+
import type { IoHelper } from '../../shared-private';
55

66
/**
77
* Helper class to measure the time of code.
@@ -37,7 +37,7 @@ export class Timer {
3737
* Ends the current timer as a specified timing and notifies the IoHost.
3838
* @returns the elapsed time
3939
*/
40-
public async endAs(ioHost: ActionAwareIoHost, type: 'synth' | 'deploy' | 'rollback' | 'destroy' | 'bootstrap') {
40+
public async endAs(ioHost: IoHelper, type: 'synth' | 'deploy' | 'rollback' | 'destroy' | 'bootstrap') {
4141
const duration = this.end();
4242
await ioHost.notify(timerMessage(type, duration));
4343
return duration;

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
import type { SdkProvider } from '../../api/aws-cdk';
33
import type { ICloudAssemblySource } from '../../api/cloud-assembly';
44
import { CachedCloudAssemblySource, StackAssembly } from '../../api/cloud-assembly/private';
5-
import type { ActionAwareIoHost } from '../../api/shared-private';
5+
import type { IoHelper } from '../../api/shared-private';
66

77
/**
88
* Helper struct to pass internal services around.
99
*/
1010
export interface ToolkitServices {
1111
sdkProvider: SdkProvider;
12-
ioHost: ActionAwareIoHost;
12+
ioHost: IoHelper;
1313
}
1414

1515
/**

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import type { StackAssembly } from '../api/cloud-assembly/private';
2626
import { ALL_STACKS, CloudAssemblySourceBuilder, IdentityCloudAssemblySource } from '../api/cloud-assembly/private';
2727
import type { IIoHost, IoMessageLevel } from '../api/io';
2828
import { Timer, IO, asSdkLogger, withoutColor, withoutEmojis, withTrimmedWhitespace } from '../api/io/private';
29-
import type { ActionAwareIoHost } from '../api/shared-private';
30-
import { withAction } from '../api/shared-private';
29+
import type { IoHelper } from '../api/shared-private';
30+
import { asIoHelper } from '../api/shared-private';
3131
import type { ToolkitAction } from '../api/shared-public';
3232
import { ToolkitError } from '../api/shared-public';
3333
import { obscureTemplate, serializeStructure, validateSnsTopicArn, formatTime, formatErrorMessage } from '../private/util';
@@ -130,7 +130,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
130130
if (!this._sdkProvider) {
131131
this._sdkProvider = await SdkProvider.withAwsCliCompatibleDefaults({
132132
...this.props.sdkConfig,
133-
logger: asSdkLogger(withAction(this.ioHost, action)),
133+
logger: asSdkLogger(asIoHelper(this.ioHost, action)),
134134
});
135135
}
136136

@@ -142,7 +142,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
142142
*/
143143
protected override async sourceBuilderServices(): Promise<ToolkitServices> {
144144
return {
145-
ioHost: withAction(this.ioHost, 'assembly'),
145+
ioHost: asIoHelper(this.ioHost, 'assembly'),
146146
sdkProvider: await this.sdkProvider('assembly'),
147147
};
148148
}
@@ -151,7 +151,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
151151
* Bootstrap Action
152152
*/
153153
public async bootstrap(environments: BootstrapEnvironments, options: BootstrapOptions): Promise<void> {
154-
const ioHost = withAction(this.ioHost, 'bootstrap');
154+
const ioHost = asIoHelper(this.ioHost, 'bootstrap');
155155
const bootstrapEnvironments = await environments.getEnvironments();
156156
const source = options.source ?? BootstrapSource.default();
157157
const parameters = options.parameters;
@@ -197,7 +197,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
197197
* Synth Action
198198
*/
199199
public async synth(cx: ICloudAssemblySource, options: SynthOptions = {}): Promise<ICloudAssemblySource> {
200-
const ioHost = withAction(this.ioHost, 'synth');
200+
const ioHost = asIoHelper(this.ioHost, 'synth');
201201
const synthTimer = Timer.start();
202202
const assembly = await assemblyFromSource(cx);
203203
const stacks = assembly.selectStacksV2(options.stacks ?? ALL_STACKS);
@@ -242,7 +242,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
242242
* List selected stacks and their dependencies
243243
*/
244244
public async list(cx: ICloudAssemblySource, options: ListOptions = {}): Promise<StackDetails[]> {
245-
const ioHost = withAction(this.ioHost, 'list');
245+
const ioHost = asIoHelper(this.ioHost, 'list');
246246
const synthTimer = Timer.start();
247247
const assembly = await assemblyFromSource(cx);
248248
const stackCollection = await assembly.selectStacksV2(options.stacks ?? ALL_STACKS);
@@ -269,7 +269,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
269269
* Helper to allow deploy being called as part of the watch action.
270270
*/
271271
private async _deploy(assembly: StackAssembly, action: 'deploy' | 'watch', options: ExtendedDeployOptions = {}) {
272-
const ioHost = withAction(this.ioHost, action);
272+
const ioHost = asIoHelper(this.ioHost, action);
273273
const synthTimer = Timer.start();
274274
const stackCollection = assembly.selectStacksV2(options.stacks ?? ALL_STACKS);
275275
await this.validateStacksMetadata(stackCollection, ioHost);
@@ -571,7 +571,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
571571
*/
572572
public async watch(cx: ICloudAssemblySource, options: WatchOptions): Promise<void> {
573573
const assembly = await assemblyFromSource(cx, false);
574-
const ioHost = withAction(this.ioHost, 'watch');
574+
const ioHost = asIoHelper(this.ioHost, 'watch');
575575
const rootDir = options.watchDir ?? process.cwd();
576576

577577
if (options.include === undefined && options.exclude === undefined) {
@@ -694,7 +694,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
694694
* Helper to allow rollback being called as part of the deploy or watch action.
695695
*/
696696
private async _rollback(assembly: StackAssembly, action: 'rollback' | 'deploy' | 'watch', options: RollbackOptions): Promise<void> {
697-
const ioHost = withAction(this.ioHost, action);
697+
const ioHost = asIoHelper(this.ioHost, action);
698698
const synthTimer = Timer.start();
699699
const stacks = assembly.selectStacksV2(options.stacks);
700700
await this.validateStacksMetadata(stacks, ioHost);
@@ -752,7 +752,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
752752
* Helper to allow destroy being called as part of the deploy action.
753753
*/
754754
private async _destroy(assembly: StackAssembly, action: 'deploy' | 'destroy', options: DestroyOptions): Promise<void> {
755-
const ioHost = withAction(this.ioHost, action);
755+
const ioHost = asIoHelper(this.ioHost, action);
756756
const synthTimer = Timer.start();
757757
// The stacks will have been ordered for deployment, so reverse them for deletion.
758758
const stacks = await assembly.selectStacksV2(options.stacks).reversed();
@@ -794,7 +794,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
794794
/**
795795
* Validate the stacks for errors and warnings according to the CLI's current settings
796796
*/
797-
private async validateStacksMetadata(stacks: StackCollection, ioHost: ActionAwareIoHost) {
797+
private async validateStacksMetadata(stacks: StackCollection, ioHost: IoHelper) {
798798
const builder = (level: IoMessageLevel) => {
799799
switch (level) {
800800
case 'error': return IO.CDK_ASSEMBLY_E9999;

packages/@aws-cdk/toolkit-lib/test/_helpers/test-io-host.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { IIoHost, IoMessage, IoMessageLevel, IoRequest } from '../../lib';
22
import { RequireApproval } from '../../lib';
3-
import { isMessageRelevantForLevel } from '../../lib/api/io/private/level-priority';
3+
import { isMessageRelevantForLevel } from '../../lib/api/shared-private';
44

55
/**
66
* A test implementation of IIoHost that does nothing but can by spied on.

packages/aws-cdk/lib/api/deployments/asset-publishing.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
} from 'cdk-assets';
1515
import type { SDK } from '..';
1616
import { formatMessage } from '../../cli/messages';
17-
import { IIoHost, IoMessageLevel, IoMessaging, ToolkitAction } from '../../toolkit/cli-io-host';
17+
import { IIoHost, IoMessageLevel, IoMessaging } from '../../toolkit/cli-io-host';
1818
import { ToolkitError } from '../../toolkit/error';
1919
import type { SdkProvider } from '../aws-auth';
2020
import { Mode } from '../plugin';
@@ -184,7 +184,7 @@ export const EVENT_TO_LEVEL: Record<EventType, IoMessageLevel | false> = {
184184

185185
export abstract class BasePublishProgressListener implements IPublishProgressListener {
186186
protected readonly ioHost: IIoHost;
187-
protected readonly action: ToolkitAction;
187+
protected readonly action: IoMessaging['action'];
188188

189189
constructor({ ioHost, action }: IoMessaging) {
190190
this.ioHost = ioHost;

packages/aws-cdk/lib/api/deployments/deploy-stack.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { ChangeSetDeploymentMethod, DeploymentMethod } from './deployment-method
2929
import { DeployStackResult, SuccessfulDeployStackResult } from './deployment-result';
3030
import { tryHotswapDeployment } from './hotswap-deployments';
3131
import { debug, info, warn } from '../../cli/messages';
32-
import { IIoHost, IoMessaging, ToolkitAction } from '../../toolkit/cli-io-host';
32+
import { IIoHost, IoMessaging } from '../../toolkit/cli-io-host';
3333
import { ToolkitError } from '../../toolkit/error';
3434
import { formatErrorMessage } from '../../util';
3535
import type { SDK, SdkProvider, ICloudFormationClient } from '../aws-auth';
@@ -368,7 +368,7 @@ class FullCloudFormationDeployment {
368368
private readonly stackParams: ParameterValues,
369369
private readonly bodyParameter: TemplateBodyParameter,
370370
private readonly ioHost: IIoHost,
371-
private readonly action: ToolkitAction,
371+
private readonly action: IoMessaging['action'],
372372
) {
373373
this.cfn = options.sdk.cloudFormation();
374374
this.stackName = options.deployName ?? stackArtifact.stackName;

packages/aws-cdk/lib/api/deployments/deployments.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
type RootTemplateWithNestedStacks,
2626
} from './nested-stack-helpers';
2727
import { debug, warn } from '../../cli/messages';
28-
import { IIoHost, IoMessaging, ToolkitAction } from '../../toolkit/cli-io-host';
28+
import { IIoHost, IoMessaging } from '../../toolkit/cli-io-host';
2929
import { ToolkitError } from '../../toolkit/error';
3030
import { formatErrorMessage } from '../../util';
3131
import type { SdkProvider } from '../aws-auth/sdk-provider';
@@ -290,7 +290,7 @@ export interface DeploymentsProps {
290290
readonly sdkProvider: SdkProvider;
291291
readonly toolkitStackName?: string;
292292
readonly ioHost: IIoHost;
293-
readonly action: ToolkitAction;
293+
readonly action: IoMessaging['action'];
294294
}
295295

296296
/**
@@ -326,7 +326,7 @@ export class Deployments {
326326
private _allowCrossAccountAssetPublishing: boolean | undefined;
327327

328328
private readonly ioHost: IIoHost;
329-
private readonly action: ToolkitAction;
329+
private readonly action: IoMessaging['action'];
330330

331331
constructor(private readonly props: DeploymentsProps) {
332332
this.assetSdkProvider = props.sdkProvider;

0 commit comments

Comments
 (0)