Skip to content

Conversation

@ren-yamanashi
Copy link
Contributor

@ren-yamanashi ren-yamanashi commented Nov 26, 2025

Fixes #940

Adds --package-manager option to cdk init for choosing npm, yarn, or pnpm when initializing TypeScript/JavaScript projects.

Usage

cdk init app -l ts --package-manager npm
cdk init app -l ts --package-manager yarn
cdk init app -l ts --package-manager pnpm
cdk init app -l ts --package-manager bun

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@codecov-commenter
Copy link

codecov-commenter commented Nov 26, 2025

Codecov Report

❌ Patch coverage is 94.11765% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.40%. Comparing base (2a6f8d3) to head (e251095).

Files with missing lines Patch % Lines
packages/aws-cdk/lib/cli/cli.ts 0.00% 1 Missing ⚠️
packages/aws-cdk/lib/commands/init/init.ts 96.42% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #961      +/-   ##
==========================================
+ Coverage   87.38%   87.40%   +0.02%     
==========================================
  Files          71       72       +1     
  Lines       10010    10036      +26     
  Branches     1311     1314       +3     
==========================================
+ Hits         8747     8772      +25     
  Misses       1240     1240              
- Partials       23       24       +1     
Flag Coverage Δ
suite.unit 87.40% <94.11%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ren-yamanashi ren-yamanashi changed the title feat(init): add package manager option to cdk init feat(cli): add package manager option to cdk init Nov 26, 2025
…nto feat(init)/support-package-manager-option
@ren-yamanashi ren-yamanashi marked this pull request as ready for review November 26, 2025 16:07
Copy link
Contributor

@mrgrain mrgrain left a comment

Choose a reason for hiding this comment

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

Thanks, few notes.

/**
* The package manager to use to install dependencies. Only applicable for TypeScript and JavaScript projects.
*
* @default - undefined
Copy link
Contributor

Choose a reason for hiding this comment

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

instead of undefined describe what it does

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This JSDoc is auto generated during the build process, and as mentioned in #961 (comment) comments, I think difficult to change this @default comment because package-manager option can't set default value.

Copy link
Contributor Author

@ren-yamanashi ren-yamanashi left a comment

Choose a reason for hiding this comment

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

@mrgrain

Thanks review! I fixed.

/**
* The package manager to use to install dependencies. Only applicable for TypeScript and JavaScript projects.
*
* @default - undefined
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@mrgrain mrgrain left a comment

Choose a reason for hiding this comment

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

almost there!

'from-path': { type: 'string', desc: 'Path to a local custom template directory or multi-template repository', requiresArg: true, conflicts: ['lib-version'] },
'template-path': { type: 'string', desc: 'Path to a specific template within a multi-template repository', requiresArg: true },
'package-manager': { type: 'string', desc: 'The package manager to use to install dependencies. Only applicable for TypeScript and JavaScript projects.', choices: JS_PACKAGE_MANAGERS },
'package-manager': { type: 'string', desc: 'The package manager to use to install dependencies. Only applicable for TypeScript and JavaScript projects.', default: JS_PACKAGE_MANAGER.NPM, choices: Object.values(JS_PACKAGE_MANAGER) },
Copy link
Contributor

Choose a reason for hiding this comment

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

we can't add a default here, this will now always cause a warning for other languages

Copy link
Contributor Author

Choose a reason for hiding this comment

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

await withTempDir(async (workDir) => {
const warnSpy = jest.spyOn(ioHelper.defaults, 'warn');

await cliInit({
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm aware there's no infrastructure yet for this in this test file, but can we make this an end-to-end test of the CLI please, instead of testing just cliInit. Same for the other one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I fixed some test cases. deedd00


I'm aware there's no infrastructure yet for this in this test file

I referred to test that was already implemented as an E2E test.

cliTest('conflict between lib-version and from-path is enforced', async (workDir) => {
const { exec } = await import('child_process');
const { promisify } = await import('util');
const execAsync = promisify(exec);
const templateDir = await createSingleLanguageTemplate(workDir, 'conflict-test', 'typescript');
const cdkBin = path.join(__dirname, '..', '..', 'bin', 'cdk');
// Test that using both flags together causes an error
await expect(execAsync(`node ${cdkBin} init app --language typescript --lib-version 2.0.0 --from-path ${templateDir} --generate-only`, {
cwd: workDir,
env: { ...process.env, CDK_DISABLE_VERSION_CHECK: '1' },
})).rejects.toThrow();
});


Same for the other one.

Would you suggesting that test cases within describe('package-manager option' should also be made into e2e tests? Or suggesting that all test cases within describe('validate CLI init options' should be made into e2e tests?

I suspect it's latter, so I've implemented it that way (please comment if I'm mistaken).

Copy link
Contributor Author

@ren-yamanashi ren-yamanashi left a comment

Choose a reason for hiding this comment

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

@mrgrain

I fixed! Please confirm.

'from-path': { type: 'string', desc: 'Path to a local custom template directory or multi-template repository', requiresArg: true, conflicts: ['lib-version'] },
'template-path': { type: 'string', desc: 'Path to a specific template within a multi-template repository', requiresArg: true },
'package-manager': { type: 'string', desc: 'The package manager to use to install dependencies. Only applicable for TypeScript and JavaScript projects.', choices: JS_PACKAGE_MANAGERS },
'package-manager': { type: 'string', desc: 'The package manager to use to install dependencies. Only applicable for TypeScript and JavaScript projects.', default: JS_PACKAGE_MANAGER.NPM, choices: Object.values(JS_PACKAGE_MANAGER) },
Copy link
Contributor Author

Choose a reason for hiding this comment

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

/**
* The package manager to use to install dependencies. Only applicable for TypeScript and JavaScript projects.
*
* @default - undefined
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This JSDoc is auto generated during the build process, and as mentioned in #961 (comment) comments, I think difficult to change this @default comment because package-manager option can't set default value.

await withTempDir(async (workDir) => {
const warnSpy = jest.spyOn(ioHelper.defaults, 'warn');

await cliInit({
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I fixed some test cases. deedd00


I'm aware there's no infrastructure yet for this in this test file

I referred to test that was already implemented as an E2E test.

cliTest('conflict between lib-version and from-path is enforced', async (workDir) => {
const { exec } = await import('child_process');
const { promisify } = await import('util');
const execAsync = promisify(exec);
const templateDir = await createSingleLanguageTemplate(workDir, 'conflict-test', 'typescript');
const cdkBin = path.join(__dirname, '..', '..', 'bin', 'cdk');
// Test that using both flags together causes an error
await expect(execAsync(`node ${cdkBin} init app --language typescript --lib-version 2.0.0 --from-path ${templateDir} --generate-only`, {
cwd: workDir,
env: { ...process.env, CDK_DISABLE_VERSION_CHECK: '1' },
})).rejects.toThrow();
});


Same for the other one.

Would you suggesting that test cases within describe('package-manager option' should also be made into e2e tests? Or suggesting that all test cases within describe('validate CLI init options' should be made into e2e tests?

I suspect it's latter, so I've implemented it that way (please comment if I'm mistaken).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(init): provide an option to pass package manager of choice in cdk init

3 participants