diff --git a/tools/@aws-cdk/cdk-integ-tools/bin/cdk-integ-assert.ts b/tools/@aws-cdk/cdk-integ-tools/bin/cdk-integ-assert.ts index cdca064874099..50a50575cf79c 100644 --- a/tools/@aws-cdk/cdk-integ-tools/bin/cdk-integ-assert.ts +++ b/tools/@aws-cdk/cdk-integ-tools/bin/cdk-integ-assert.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node // Verify that all integration tests still match their expected output -import { canonicalizeTemplate } from '@aws-cdk/assert-internal'; import { diffTemplate, formatDifferences } from '@aws-cdk/cloudformation-diff'; +import { canonicalizeTemplate } from '../lib/canonicalize-assets'; import { DEFAULT_SYNTH_OPTIONS, IntegrationTests } from '../lib/integ-helpers'; /* eslint-disable no-console */ diff --git a/tools/@aws-cdk/cdk-integ-tools/lib/canonicalize-assets.ts b/tools/@aws-cdk/cdk-integ-tools/lib/canonicalize-assets.ts new file mode 100644 index 0000000000000..9cee3d4742b3c --- /dev/null +++ b/tools/@aws-cdk/cdk-integ-tools/lib/canonicalize-assets.ts @@ -0,0 +1,71 @@ +/** + * Reduce template to a normal form where asset references have been normalized + * + * This makes it possible to compare templates if all that's different between + * them is the hashes of the asset values. + * + * Currently only handles parameterized assets, but can (and should) + * be adapted to handle convention-mode assets as well when we start using + * more of those. + */ +export function canonicalizeTemplate(template: any): any { + // For the weird case where we have an array of templates... + if (Array.isArray(template)) { + return template.map(canonicalizeTemplate); + } + + // Find assets via parameters + const stringSubstitutions = new Array<[RegExp, string]>(); + const paramRe = /^AssetParameters([a-zA-Z0-9]{64})(S3Bucket|S3VersionKey|ArtifactHash)([a-zA-Z0-9]{8})$/; + + const assetsSeen = new Set(); + for (const paramName of Object.keys(template?.Parameters || {})) { + const m = paramRe.exec(paramName); + if (!m) { continue; } + if (assetsSeen.has(m[1])) { continue; } + + assetsSeen.add(m[1]); + const ix = assetsSeen.size; + + // Full parameter reference + stringSubstitutions.push([ + new RegExp(`AssetParameters${m[1]}(S3Bucket|S3VersionKey|ArtifactHash)([a-zA-Z0-9]{8})`), + `Asset${ix}$1`, + ]); + // Substring asset hash reference + stringSubstitutions.push([ + new RegExp(`${m[1]}`), + `Asset${ix}Hash`, + ]); + } + + // Substitute them out + return substitute(template); + + function substitute(what: any): any { + if (Array.isArray(what)) { + return what.map(substitute); + } + + if (typeof what === 'object' && what !== null) { + const ret: any = {}; + for (const [k, v] of Object.entries(what)) { + ret[stringSub(k)] = substitute(v); + } + return ret; + } + + if (typeof what === 'string') { + return stringSub(what); + } + + return what; + } + + function stringSub(x: string) { + for (const [re, replacement] of stringSubstitutions) { + x = x.replace(re, replacement); + } + return x; + } +} diff --git a/tools/@aws-cdk/cdk-integ-tools/package.json b/tools/@aws-cdk/cdk-integ-tools/package.json index 01e3efa6ec6a1..de5ad2cfed9fd 100644 --- a/tools/@aws-cdk/cdk-integ-tools/package.json +++ b/tools/@aws-cdk/cdk-integ-tools/package.json @@ -39,7 +39,6 @@ "dependencies": { "@aws-cdk/cloudformation-diff": "0.0.0", "@aws-cdk/cx-api": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0", "aws-cdk": "0.0.0", "fs-extra": "^9.1.0", "yargs": "^16.2.0" @@ -52,9 +51,6 @@ "engines": { "node": ">= 10.13.0 <13 || >=13.7.0" }, - "peerDependencies": { - "@aws-cdk/assert-internal": "0.0.0" - }, "ubergen": { "exclude": true }