Skip to content

Commit 0d7bcca

Browse files
authored
refactor(cli): use modern messaging infrastructure (#266)
Updates code in `lib/api` to use the latest version of the modern messaging infrastructure instead of legacy helpers. --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
1 parent a15e73e commit 0d7bcca

File tree

18 files changed

+123
-138
lines changed

18 files changed

+123
-138
lines changed

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,10 @@ export const IO = {
7474
}),
7575

7676
// 3: Import & Migrate
77-
CDK_TOOLKIT_E3900: make.error({
77+
CDK_TOOLKIT_E3900: make.error<ErrorPayload>({
7878
code: 'CDK_TOOLKIT_E3900',
7979
description: 'Resource import failed',
80+
interface: 'ErrorPayload',
8081
}),
8182

8283
// 4: Diff (4xxx)
@@ -92,9 +93,10 @@ export const IO = {
9293
description: 'Provides total time in deploy action, including synth and rollback',
9394
interface: 'Duration',
9495
}),
95-
CDK_TOOLKIT_I5002: make.info({
96+
CDK_TOOLKIT_I5002: make.info<Duration>({
9697
code: 'CDK_TOOLKIT_I5002',
9798
description: 'Provides time for resource migration',
99+
interface: 'Duration',
98100
}),
99101
CDK_TOOLKIT_W5021: make.warn({
100102
code: 'CDK_TOOLKIT_W5021',

packages/@aws-cdk/toolkit-lib/docs/message-registry.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ group: Documents
1616
| `CDK_TOOLKIT_I1901` | Provides stack data | `result` | {@link StackAndAssemblyData} |
1717
| `CDK_TOOLKIT_I1902` | Successfully deployed stacks | `result` | {@link AssemblyData} |
1818
| `CDK_TOOLKIT_I2901` | Provides details on the selected stacks and their dependencies | `result` | {@link StackDetailsPayload} |
19-
| `CDK_TOOLKIT_E3900` | Resource import failed | `error` | n/a |
19+
| `CDK_TOOLKIT_E3900` | Resource import failed | `error` | {@link ErrorPayload} |
2020
| `CDK_TOOLKIT_I5000` | Provides deployment times | `info` | {@link Duration} |
2121
| `CDK_TOOLKIT_I5001` | Provides total time in deploy action, including synth and rollback | `info` | {@link Duration} |
22-
| `CDK_TOOLKIT_I5002` | Provides time for resource migration | `info` | n/a |
22+
| `CDK_TOOLKIT_I5002` | Provides time for resource migration | `info` | {@link Duration} |
2323
| `CDK_TOOLKIT_W5021` | Empty non-existent stack, deployment is skipped | `warn` | n/a |
2424
| `CDK_TOOLKIT_W5022` | Empty existing stack, stack will be destroyed | `warn` | n/a |
2525
| `CDK_TOOLKIT_I5031` | Informs about any log groups that are traced as part of the deployment | `info` | n/a |

packages/aws-cdk/lib/api/bootstrap/bootstrap-environment.ts

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { info } from 'console';
21
import * as path from 'path';
32
import type * as cxapi from '@aws-cdk/cx-api';
43
import type { BootstrapEnvironmentOptions, BootstrappingParameters } from './bootstrap-props';
54
import { BootstrapStack, bootstrapVersionFromTemplate } from './deploy-bootstrap';
65
import { legacyBootstrapTemplate } from './legacy-template';
76
import { ToolkitError } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api';
8-
import type { IoHelper } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private';
9-
import { warn } from '../../cli/messages';
7+
import { IO, type IoHelper } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private';
108
import { bundledPackageRootDir, loadStructuredFile, serializeStructure } from '../../util';
119
import type { SDK, SdkProvider } from '../aws-auth';
1210
import type { SuccessfulDeployStackResult } from '../deployments';
@@ -125,14 +123,16 @@ export class Bootstrapper {
125123
accounts.filter(acc => !params.untrustedAccounts?.map(String).includes(String(acc)));
126124

127125
const trustedAccounts = removeUntrusted(params.trustedAccounts ?? splitCfnArray(current.parameters.TrustedAccounts));
128-
info(`Trusted accounts for deployment: ${trustedAccounts.length > 0 ? trustedAccounts.join(', ') : '(none)'}`);
126+
await this.ioHelper.notify(IO.DEFAULT_TOOLKIT_INFO.msg(
127+
`Trusted accounts for deployment: ${trustedAccounts.length > 0 ? trustedAccounts.join(', ') : '(none)'}`,
128+
));
129129

130130
const trustedAccountsForLookup = removeUntrusted(
131131
params.trustedAccountsForLookup ?? splitCfnArray(current.parameters.TrustedAccountsForLookup),
132132
);
133-
info(
133+
await this.ioHelper.notify(IO.DEFAULT_TOOLKIT_INFO.msg(
134134
`Trusted accounts for lookup: ${trustedAccountsForLookup.length > 0 ? trustedAccountsForLookup.join(', ') : '(none)'}`,
135-
);
135+
));
136136

137137
const cloudFormationExecutionPolicies =
138138
params.cloudFormationExecutionPolicies ?? splitCfnArray(current.parameters.CloudFormationExecutionPolicies);
@@ -151,7 +151,7 @@ export class Bootstrapper {
151151
// Would leave AdministratorAccess policies with a trust relationship, without the user explicitly
152152
// approving the trust policy.
153153
const implicitPolicy = `arn:${partition}:iam::aws:policy/AdministratorAccess`;
154-
await this.ioHelper.notify(warn(
154+
await this.ioHelper.notify(IO.DEFAULT_TOOLKIT_WARN.msg(
155155
`Using default execution policy of '${implicitPolicy}'. Pass '--cloudformation-execution-policies' to customize.`,
156156
));
157157
} else if (cloudFormationExecutionPolicies.length === 0) {
@@ -160,7 +160,7 @@ export class Bootstrapper {
160160
);
161161
} else {
162162
// Remind people what the current settings are
163-
info(`Execution policies: ${cloudFormationExecutionPolicies.join(', ')}`);
163+
await this.ioHelper.notify(IO.DEFAULT_TOOLKIT_INFO.msg(`Execution policies: ${cloudFormationExecutionPolicies.join(', ')}`));
164164
}
165165

166166
// * If an ARN is given, that ARN. Otherwise:
@@ -199,15 +199,15 @@ export class Bootstrapper {
199199
}
200200
if (currentPermissionsBoundary !== policyName) {
201201
if (!currentPermissionsBoundary) {
202-
await this.ioHelper.notify(warn(
202+
await this.ioHelper.notify(IO.DEFAULT_TOOLKIT_WARN.msg(
203203
`Adding new permissions boundary ${policyName}`,
204204
));
205205
} else if (!policyName) {
206-
await this.ioHelper.notify(warn(
206+
await this.ioHelper.notify(IO.DEFAULT_TOOLKIT_WARN.msg(
207207
`Removing existing permissions boundary ${currentPermissionsBoundary}`,
208208
));
209209
} else {
210-
await this.ioHelper.notify(warn(
210+
await this.ioHelper.notify(IO.DEFAULT_TOOLKIT_WARN.msg(
211211
`Changing permissions boundary from ${currentPermissionsBoundary} to ${policyName}`,
212212
));
213213
}

packages/aws-cdk/lib/api/bootstrap/deploy-bootstrap.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ import {
1111
BOOTSTRAP_VERSION_RESOURCE,
1212
DEFAULT_BOOTSTRAP_VARIANT,
1313
} from './bootstrap-props';
14-
import type { IoHelper } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private';
15-
import { warn } from '../../cli/messages';
14+
import { IO, type IoHelper } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private';
1615
import type { SDK, SdkProvider } from '../aws-auth';
1716
import type { SuccessfulDeployStackResult } from '../deployments';
1817
import { assertIsSuccessfulDeployStackResult } from '../deployments';
@@ -90,7 +89,7 @@ export class BootstrapStack {
9089
const currentVariant = this.currentToolkitInfo.variant;
9190
const newVariant = bootstrapVariantFromTemplate(template);
9291
if (currentVariant !== newVariant) {
93-
await this.ioHelper.notify(warn(
92+
await this.ioHelper.notify(IO.DEFAULT_TOOLKIT_WARN.msg(
9493
`Bootstrap stack already exists, containing '${currentVariant}'. Not overwriting it with a template containing '${newVariant}' (use --force if you intend to overwrite)`,
9594
));
9695
return abortResponse;
@@ -100,13 +99,13 @@ export class BootstrapStack {
10099
const newVersion = bootstrapVersionFromTemplate(template);
101100
const currentVersion = this.currentToolkitInfo.version;
102101
if (newVersion < currentVersion) {
103-
await this.ioHelper.notify(warn(
102+
await this.ioHelper.notify(IO.DEFAULT_TOOLKIT_WARN.msg(
104103
`Bootstrap stack already at version ${currentVersion}. Not downgrading it to version ${newVersion} (use --force if you intend to downgrade)`,
105104
));
106105
if (newVersion === 0) {
107106
// A downgrade with 0 as target version means we probably have a new-style bootstrap in the account,
108107
// and an old-style bootstrap as current target, which means the user probably forgot to put this flag in.
109-
await this.ioHelper.notify(warn(
108+
await this.ioHelper.notify(IO.DEFAULT_TOOLKIT_WARN.msg(
110109
"(Did you set the '@aws-cdk/core:newStyleStackSynthesis' feature flag in cdk.json?)",
111110
));
112111
}

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

+4-5
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import * as cxapi from '@aws-cdk/cx-api';
55
import * as chalk from 'chalk';
66
import type { AssetManifestBuilder } from './asset-manifest-builder';
77
import { ToolkitError } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api';
8-
import type { IoHelper } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private';
9-
import { debug } from '../../cli/messages';
8+
import { IO, type IoHelper } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private';
109
import type { EnvironmentResources } from '../environment';
1110
import type { ToolkitInfo } from '../toolkit-info';
1211

@@ -44,11 +43,11 @@ export async function addMetadataAssetsToManifest(
4443
const reuseAsset = reuse.indexOf(asset.id) > -1;
4544

4645
if (reuseAsset) {
47-
await ioHelper.notify(debug(`Reusing asset ${asset.id}: ${JSON.stringify(asset)}`));
46+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`Reusing asset ${asset.id}: ${JSON.stringify(asset)}`));
4847
continue;
4948
}
5049

51-
await ioHelper.notify(debug(`Preparing asset ${asset.id}: ${JSON.stringify(asset)}`));
50+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`Preparing asset ${asset.id}: ${JSON.stringify(asset)}`));
5251
if (!stack.assembly) {
5352
throw new ToolkitError('Unexpected: stack assembly is required in order to find assets in assembly directory');
5453
}
@@ -98,7 +97,7 @@ async function prepareFileAsset(
9897
const key = `${s3Prefix}${baseName}`;
9998
const s3url = `s3://${toolkitInfo.bucketName}/${key}`;
10099

101-
await ioHelper.notify(debug(`Storing asset ${asset.path} at ${s3url}`));
100+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`Storing asset ${asset.path} at ${s3url}`));
102101

103102
assetManifest.addFileAsset(asset.sourceHash, {
104103
path: asset.path,

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

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { ToolkitError } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api';
2-
import type { IoHelper } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private';
3-
import { debug } from '../../cli/messages';
2+
import { IO, type IoHelper } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private';
43
import type { SDK } from '../aws-auth';
54

65
export async function determineAllowCrossAccountAssetPublishing(
@@ -34,8 +33,8 @@ export async function determineAllowCrossAccountAssetPublishing(
3433
// of creating bootstrap resources. If they do, there's nothing for us to validate,
3534
// but we can't use that as a reason to disallow cross-account publishing. We'll just
3635
// have to trust they did their due diligence. So we fail open.
37-
await ioHelper.notify(debug(`Error determining cross account asset publishing: ${e}`));
38-
await ioHelper.notify(debug('Defaulting to allowing cross account asset publishing'));
36+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`Error determining cross account asset publishing: ${e}`));
37+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg('Defaulting to allowing cross account asset publishing'));
3938
return true;
4039
}
4140
}

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

+12-13
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ import { AssetManifest } from 'cdk-assets';
1515
import { AssetManifestBuilder } from './asset-manifest-builder';
1616
import type { Deployments } from './deployments';
1717
import { ToolkitError } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api';
18-
import type { IoHelper } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private';
19-
import { debug } from '../../cli/messages';
18+
import { IO, type IoHelper } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/io/private';
2019
import { formatErrorMessage, deserializeStructure } from '../../util';
2120
import type { ICloudFormationClient, SdkProvider } from '../aws-auth';
2221
import { StackStatus } from '../stack-events';
@@ -295,15 +294,15 @@ export async function waitForChangeSet(
295294
changeSetName: string,
296295
{ fetchAll }: { fetchAll: boolean },
297296
): Promise<DescribeChangeSetCommandOutput> {
298-
await ioHelper.notify(debug(format('Waiting for changeset %s on stack %s to finish creating...', changeSetName, stackName)));
297+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(format('Waiting for changeset %s on stack %s to finish creating...', changeSetName, stackName)));
299298
const ret = await waitFor(async () => {
300299
const description = await describeChangeSet(cfn, stackName, changeSetName, {
301300
fetchAll,
302301
});
303302
// The following doesn't use a switch because tsc will not allow fall-through, UNLESS it is allows
304303
// EVERYWHERE that uses this library directly or indirectly, which is undesirable.
305304
if (description.Status === 'CREATE_PENDING' || description.Status === 'CREATE_IN_PROGRESS') {
306-
await ioHelper.notify(debug(format('Changeset %s on stack %s is still creating', changeSetName, stackName)));
305+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(format('Changeset %s on stack %s is still creating', changeSetName, stackName)));
307306
return undefined;
308307
}
309308

@@ -360,7 +359,7 @@ export async function createDiffChangeSet(
360359
// This causes CreateChangeSet to fail with `Template Error: Fn::Equals cannot be partially collapsed`.
361360
for (const resource of Object.values(options.stack.template.Resources ?? {})) {
362361
if ((resource as any).Type === 'AWS::CloudFormation::Stack') {
363-
await ioHelper.notify(debug('This stack contains one or more nested stacks, falling back to template-only diff...'));
362+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg('This stack contains one or more nested stacks, falling back to template-only diff...'));
364363

365364
return undefined;
366365
}
@@ -430,7 +429,7 @@ async function uploadBodyParameterAndCreateChangeSet(
430429
role: executionRoleArn,
431430
});
432431
} catch (e: any) {
433-
await ioHelper.notify(debug(e));
432+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(e));
434433
options.stream.write(
435434
'Could not create a change set, will base the diff on template differences (run again with -v to see the reason)\n',
436435
);
@@ -472,7 +471,7 @@ export async function createChangeSet(
472471
): Promise<DescribeChangeSetCommandOutput> {
473472
await cleanupOldChangeset(options.cfn, ioHelper, options.changeSetName, options.stack.stackName);
474473

475-
await ioHelper.notify(debug(`Attempting to create ChangeSet with name ${options.changeSetName} for stack ${options.stack.stackName}`));
474+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`Attempting to create ChangeSet with name ${options.changeSetName} for stack ${options.stack.stackName}`));
476475

477476
const templateParams = TemplateParameters.fromTemplate(options.stack.template);
478477
const stackParams = templateParams.supplyAll(options.parameters);
@@ -492,7 +491,7 @@ export async function createChangeSet(
492491
Capabilities: ['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND'],
493492
});
494493

495-
await ioHelper.notify(debug(format('Initiated creation of changeset: %s; waiting for it to finish creating...', changeSet.Id)));
494+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(format('Initiated creation of changeset: %s; waiting for it to finish creating...', changeSet.Id)));
496495
// Fetching all pages if we'll execute, so we can have the correct change count when monitoring.
497496
const createdChangeSet = await waitForChangeSet(options.cfn, ioHelper, options.stack.stackName, options.changeSetName, {
498497
fetchAll: options.willExecute,
@@ -517,7 +516,7 @@ async function cleanupOldChangeset(
517516
) {
518517
// Delete any existing change sets generated by CDK since change set names must be unique.
519518
// The delete request is successful as long as the stack exists (even if the change set does not exist).
520-
await ioHelper.notify(debug(`Removing existing change set with name ${changeSetName} if it exists`));
519+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`Removing existing change set with name ${changeSetName} if it exists`));
521520
await cfn.deleteChangeSet({
522521
StackName: stackName,
523522
ChangeSetName: changeSetName,
@@ -619,16 +618,16 @@ export async function stabilizeStack(
619618
ioHelper: IoHelper,
620619
stackName: string,
621620
) {
622-
await ioHelper.notify(debug(format('Waiting for stack %s to finish creating or updating...', stackName)));
621+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(format('Waiting for stack %s to finish creating or updating...', stackName)));
623622
return waitFor(async () => {
624623
const stack = await CloudFormationStack.lookup(cfn, stackName);
625624
if (!stack.exists) {
626-
await ioHelper.notify(debug(format('Stack %s does not exist', stackName)));
625+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(format('Stack %s does not exist', stackName)));
627626
return null;
628627
}
629628
const status = stack.stackStatus;
630629
if (status.isInProgress) {
631-
await ioHelper.notify(debug(format('Stack %s has an ongoing operation in progress and is not stable (%s)', stackName, status)));
630+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(format('Stack %s has an ongoing operation in progress and is not stable (%s)', stackName, status)));
632631
return undefined;
633632
} else if (status.isReviewInProgress) {
634633
// This may happen if a stack creation operation is interrupted before the ChangeSet execution starts. Recovering
@@ -637,7 +636,7 @@ export async function stabilizeStack(
637636
// "forever" we proceed as if the stack was existing and stable. If there is a concurrent operation that just
638637
// hasn't finished proceeding just yet, either this operation or the concurrent one may fail due to the other one
639638
// having made progress. Which is fine. I guess.
640-
await ioHelper.notify(debug(format('Stack %s is in REVIEW_IN_PROGRESS state. Considering this is a stable status (%s)', stackName, status)));
639+
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(format('Stack %s is in REVIEW_IN_PROGRESS state. Considering this is a stable status (%s)', stackName, status)));
641640
}
642641

643642
return stack;

0 commit comments

Comments
 (0)