Skip to content

Commit 523e0f0

Browse files
authored
fix(cli): init templates still assume the same versions (#33449)
The init templates still have a single `%cdk-version%` placeholder for both the library and the CLI. Introduce a new `%cdk-cli-version%` placeholder and fill it with the "current" version of the CLI used to create the template. Turning `DISPLAY_VERSION` into a lazy function, because we added a dependency `init.ts -> version.ts`, and since `init.ts` is included in a pre-build script, we now include `version.ts` in that pre-build script which tries to read a file at load time that still needs to be generated. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent e5e4f9b commit 523e0f0

File tree

10 files changed

+72
-49
lines changed

10 files changed

+72
-49
lines changed

packages/aws-cdk/lib/cli/cli.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export async function exec(args: string[], synthesizer?: Synthesizer): Promise<n
7878
debug(`Error while checking for platform warnings: ${e}`);
7979
}
8080

81-
debug('CDK toolkit version:', version.DISPLAY_VERSION);
81+
debug('CDK toolkit version:', version.displayVersion());
8282
debug('Command line arguments:', argv);
8383

8484
const configuration = new Configuration({
@@ -494,7 +494,7 @@ export async function exec(args: string[], synthesizer?: Synthesizer): Promise<n
494494
});
495495
case 'version':
496496
ioHost.currentAction = 'version';
497-
return result(version.DISPLAY_VERSION);
497+
return result(version.displayVersion());
498498

499499
default:
500500
throw new ToolkitError('Unknown command: ' + command);

packages/aws-cdk/lib/cli/util/yargs-helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function yargsNegativeAlias<T extends { [x in S | L]: boolean | undefined
2929
* @returns the current version of the CLI
3030
*/
3131
export function cliVersion(): string {
32-
return version.DISPLAY_VERSION;
32+
return version.displayVersion();
3333
}
3434

3535
/**

packages/aws-cdk/lib/cli/version.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ const UPGRADE_DOCUMENTATION_LINKS: Record<number, string> = {
1515
1: 'https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html',
1616
};
1717

18-
export const DISPLAY_VERSION = `${versionNumber()} (build ${commit()})`;
18+
export function displayVersion() {
19+
return `${versionNumber()} (build ${commit()})`;
20+
}
1921

2022
export function isDeveloperBuild(): boolean {
2123
return versionNumber() === '0.0.0';

packages/aws-cdk/lib/commands/doctor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const verifications: Array<() => boolean | Promise<boolean>> = [
2424
// ### Verifications ###
2525

2626
function displayVersionInformation() {
27-
info(`ℹ️ CDK Version: ${chalk.green(version.DISPLAY_VERSION)}`);
27+
info(`ℹ️ CDK Version: ${chalk.green(version.displayVersion())}`);
2828
return true;
2929
}
3030

packages/aws-cdk/lib/init-templates/app/javascript/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"test": "jest"
1111
},
1212
"devDependencies": {
13-
"aws-cdk": "%cdk-version%",
13+
"aws-cdk": "%cdk-cli-version%",
1414
"jest": "^29.7.0"
1515
},
1616
"dependencies": {

packages/aws-cdk/lib/init-templates/app/typescript/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"@types/node": "22.7.9",
1616
"jest": "^29.7.0",
1717
"ts-jest": "^29.2.5",
18-
"aws-cdk": "%cdk-version%",
18+
"aws-cdk": "%cdk-cli-version%",
1919
"ts-node": "^10.9.2",
2020
"typescript": "~5.6.3"
2121
},

packages/aws-cdk/lib/init-templates/sample-app/javascript/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"test": "jest"
1111
},
1212
"devDependencies": {
13-
"aws-cdk": "%cdk-version%",
13+
"aws-cdk": "%cdk-cli-version%",
1414
"jest": "^29.7.0"
1515
},
1616
"dependencies": {

packages/aws-cdk/lib/init-templates/sample-app/typescript/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"@types/node": "22.7.9",
1616
"jest": "^29.7.0",
1717
"ts-jest": "^29.2.5",
18-
"aws-cdk": "%cdk-version%",
18+
"aws-cdk": "%cdk-cli-version%",
1919
"ts-node": "^10.9.2",
2020
"typescript": "~5.6.3"
2121
},

packages/aws-cdk/lib/init.ts

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as childProcess from 'child_process';
22
import * as path from 'path';
33
import * as chalk from 'chalk';
44
import * as fs from 'fs-extra';
5+
import { versionNumber } from './cli/version';
56
import { invokeBuiltinHooks } from './init-hooks';
67
import { error, info, warning } from './logging';
78
import { ToolkitError } from './toolkit/error';
@@ -141,18 +142,18 @@ export class InitTemplate {
141142
for (const fileName of fileNames) {
142143
const fullPath = path.join(targetDirectory, fileName);
143144
const template = await fs.readFile(fullPath, { encoding: 'utf-8' });
144-
await fs.writeFile(fullPath, this.expand(template, language, projectInfo));
145+
await fs.writeFile(fullPath, expandPlaceholders(template, language, projectInfo));
145146
}
146147
},
147-
placeholder: (ph: string) => this.expand(`%${ph}%`, language, projectInfo),
148+
placeholder: (ph: string) => expandPlaceholders(`%${ph}%`, language, projectInfo),
148149
},
149150
);
150151
}
151152

152153
private async installFiles(sourceDirectory: string, targetDirectory: string, language: string, project: ProjectInfo) {
153154
for (const file of await fs.readdir(sourceDirectory)) {
154155
const fromFile = path.join(sourceDirectory, file);
155-
const toFile = path.join(targetDirectory, this.expand(file, language, project));
156+
const toFile = path.join(targetDirectory, expandPlaceholders(file, language, project));
156157
if ((await fs.stat(fromFile)).isDirectory()) {
157158
await fs.mkdir(toFile);
158159
await this.installFiles(fromFile, toFile, language, project);
@@ -171,42 +172,7 @@ export class InitTemplate {
171172

172173
private async installProcessed(templatePath: string, toFile: string, language: string, project: ProjectInfo) {
173174
const template = await fs.readFile(templatePath, { encoding: 'utf-8' });
174-
await fs.writeFile(toFile, this.expand(template, language, project));
175-
}
176-
177-
private expand(template: string, language: string, project: ProjectInfo) {
178-
const cdkVersion = project.versions['aws-cdk-lib'];
179-
let constructsVersion = project.versions.constructs;
180-
181-
switch (language) {
182-
case 'java':
183-
case 'csharp':
184-
case 'fsharp':
185-
constructsVersion = rangeFromSemver(constructsVersion, 'bracket');
186-
break;
187-
case 'python':
188-
constructsVersion = rangeFromSemver(constructsVersion, 'pep');
189-
break;
190-
}
191-
return template
192-
.replace(/%name%/g, project.name)
193-
.replace(/%stackname%/, project.stackName ?? '%name.PascalCased%Stack')
194-
.replace(
195-
/%PascalNameSpace%/,
196-
project.stackName ? camelCase(project.stackName + 'Stack', { pascalCase: true }) : '%name.PascalCased%',
197-
)
198-
.replace(
199-
/%PascalStackProps%/,
200-
project.stackName ? camelCase(project.stackName, { pascalCase: true }) + 'StackProps' : 'StackProps',
201-
)
202-
.replace(/%name\.camelCased%/g, camelCase(project.name))
203-
.replace(/%name\.PascalCased%/g, camelCase(project.name, { pascalCase: true }))
204-
.replace(/%cdk-version%/g, cdkVersion)
205-
.replace(/%constructs-version%/g, constructsVersion)
206-
.replace(/%cdk-home%/g, cdkHomeDir())
207-
.replace(/%name\.PythonModule%/g, project.name.replace(/-/g, '_'))
208-
.replace(/%python-executable%/g, pythonExecutable())
209-
.replace(/%name\.StackName%/g, project.name.replace(/[^A-Za-z0-9-]/g, '-'));
175+
await fs.writeFile(toFile, expandPlaceholders(template, language, project));
210176
}
211177

212178
/**
@@ -244,6 +210,43 @@ export class InitTemplate {
244210
}
245211
}
246212

213+
export function expandPlaceholders(template: string, language: string, project: ProjectInfo) {
214+
const cdkVersion = project.versions['aws-cdk-lib'];
215+
const cdkCliVersion = project.versions['aws-cdk'];
216+
let constructsVersion = project.versions.constructs;
217+
218+
switch (language) {
219+
case 'java':
220+
case 'csharp':
221+
case 'fsharp':
222+
constructsVersion = rangeFromSemver(constructsVersion, 'bracket');
223+
break;
224+
case 'python':
225+
constructsVersion = rangeFromSemver(constructsVersion, 'pep');
226+
break;
227+
}
228+
return template
229+
.replace(/%name%/g, project.name)
230+
.replace(/%stackname%/, project.stackName ?? '%name.PascalCased%Stack')
231+
.replace(
232+
/%PascalNameSpace%/,
233+
project.stackName ? camelCase(project.stackName + 'Stack', { pascalCase: true }) : '%name.PascalCased%',
234+
)
235+
.replace(
236+
/%PascalStackProps%/,
237+
project.stackName ? camelCase(project.stackName, { pascalCase: true }) + 'StackProps' : 'StackProps',
238+
)
239+
.replace(/%name\.camelCased%/g, camelCase(project.name))
240+
.replace(/%name\.PascalCased%/g, camelCase(project.name, { pascalCase: true }))
241+
.replace(/%cdk-version%/g, cdkVersion)
242+
.replace(/%cdk-cli-version%/g, cdkCliVersion)
243+
.replace(/%constructs-version%/g, constructsVersion)
244+
.replace(/%cdk-home%/g, cdkHomeDir())
245+
.replace(/%name\.PythonModule%/g, project.name.replace(/-/g, '_'))
246+
.replace(/%python-executable%/g, pythonExecutable())
247+
.replace(/%name\.StackName%/g, project.name.replace(/[^A-Za-z0-9-]/g, '-'));
248+
}
249+
247250
interface ProjectInfo {
248251
/** The value used for %name% */
249252
readonly name: string;
@@ -267,6 +270,7 @@ export async function availableInitTemplates(): Promise<InitTemplate[]> {
267270
}
268271
});
269272
}
273+
270274
export async function availableInitLanguages(): Promise<string[]> {
271275
return new Promise(async (resolve) => {
272276
const templates = await availableInitTemplates();
@@ -475,6 +479,7 @@ async function execute(cmd: string, args: string[], { cwd }: { cwd: string }) {
475479
}
476480

477481
interface Versions {
482+
['aws-cdk']: string;
478483
['aws-cdk-lib']: string;
479484
constructs: string;
480485
}
@@ -491,6 +496,7 @@ async function loadInitVersions(): Promise<Versions> {
491496
const ret = {
492497
'aws-cdk-lib': contents['aws-cdk-lib'],
493498
'constructs': contents.constructs,
499+
'aws-cdk': versionNumber(),
494500
};
495501
for (const [key, value] of Object.entries(ret)) {
496502
/* istanbul ignore next */

packages/aws-cdk/test/init.test.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as os from 'os';
22
import * as path from 'path';
33
import * as cxapi from '@aws-cdk/cx-api';
44
import * as fs from 'fs-extra';
5-
import { availableInitLanguages, availableInitTemplates, cliInit, currentlyRecommendedAwsCdkLibFlags, printAvailableTemplates } from '../lib/init';
5+
import { availableInitLanguages, availableInitTemplates, cliInit, currentlyRecommendedAwsCdkLibFlags, expandPlaceholders, printAvailableTemplates } from '../lib/init';
66

77
describe('constructs version', () => {
88
cliTest('create a TypeScript library project', async (workDir) => {
@@ -291,6 +291,21 @@ test('exercise printing available templates', async () => {
291291
await printAvailableTemplates();
292292
});
293293

294+
describe('expandPlaceholders', () => {
295+
test('distinguish library and CLI version', () => {
296+
const translated = expandPlaceholders('%cdk-version% and %cdk-cli-version%', 'javascript', {
297+
name: 'test',
298+
versions: {
299+
'aws-cdk': '1',
300+
'aws-cdk-lib': '2',
301+
'constructs': '3',
302+
},
303+
});
304+
305+
expect(translated).toEqual('2 and 1');
306+
});
307+
});
308+
294309
function cliTest(name: string, handler: (dir: string) => void | Promise<any>): void {
295310
test(name, () => withTempDir(handler));
296311
}

0 commit comments

Comments
 (0)