Skip to content

Commit 0feb05a

Browse files
authored
chore(cli): convert dynamic commands to static (#18913)
We had a few commands defined dynamically through `yargs` [commandsDir](https://www.tabnine.com/code/javascript/functions/yargs/Argv/commandDir) option. This dynamic loading prevents bundling tools from detecting these imports and thus fails to run on a bundled package. Explicitly define those commands just like all our other commands. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 7eff0f2 commit 0feb05a

File tree

6 files changed

+43
-67
lines changed

6 files changed

+43
-67
lines changed

packages/aws-cdk/bin/cdk.ts

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import { execProgram } from '../lib/api/cxapp/exec';
1414
import { ToolkitInfo } from '../lib/api/toolkit-info';
1515
import { StackActivityProgress } from '../lib/api/util/cloudformation/stack-activity-monitor';
1616
import { CdkToolkit } from '../lib/cdk-toolkit';
17+
import { realHandler as context } from '../lib/commands/context';
18+
import { realHandler as docs } from '../lib/commands/docs';
19+
import { realHandler as doctor } from '../lib/commands/doctor';
1720
import { RequireApproval } from '../lib/diff';
1821
import { availableInitLanguages, cliInit, printAvailableTemplates } from '../lib/init';
1922
import { data, debug, error, print, setLogLevel } from '../lib/logging';
@@ -39,6 +42,11 @@ async function parseCommandLineArguments() {
3942
//
4043
// ./prog --arg one --arg two position => will parse to { arg: ['one', 'two'], _: ['positional'] }.
4144

45+
const defaultBrowserCommand: { [key in NodeJS.Platform]?: string } = {
46+
darwin: 'open %u',
47+
win32: 'start %u',
48+
};
49+
4250
const initTemplateLanguages = await availableInitLanguages();
4351
return yargs
4452
.env('CDK')
@@ -189,7 +197,17 @@ async function parseCommandLineArguments() {
189197
.option('list', { type: 'boolean', desc: 'List the available templates' })
190198
.option('generate-only', { type: 'boolean', default: false, desc: 'If true, only generates project files, without executing additional operations such as setting up a git repo, installing dependencies or compiling the project' }),
191199
)
192-
.commandDir('../lib/commands', { exclude: /^_.*/ })
200+
.command('context', 'Manage cached context values', yargs => yargs
201+
.option('reset', { alias: 'e', desc: 'The context key (or its index) to reset', type: 'string', requiresArg: true })
202+
.option('clear', { desc: 'Clear all context', type: 'boolean' }))
203+
.command(['docs', 'doc'], 'Opens the reference documentation in a browser', yargs => yargs
204+
.option('browser', {
205+
alias: 'b',
206+
desc: 'the command to use to open the browser, using %u as a placeholder for the path of the file to open',
207+
type: 'string',
208+
default: process.platform in defaultBrowserCommand ? defaultBrowserCommand[process.platform] : 'xdg-open %u',
209+
}))
210+
.command('doctor', 'Check your set-up for potential problems')
193211
.version(version.DISPLAY_VERSION)
194212
.demandCommand(1, '') // just print help
195213
.recommendCommands()
@@ -276,9 +294,25 @@ async function initCommandLine() {
276294
const commandOptions = { args: argv, configuration, aws: sdkProvider };
277295

278296
try {
279-
const returnValue = argv.commandHandler
280-
? await (argv.commandHandler as (opts: typeof commandOptions) => any)(commandOptions)
281-
: await main(cmd, argv);
297+
298+
let returnValue = undefined;
299+
300+
switch (cmd) {
301+
case 'context':
302+
returnValue = await context(commandOptions);
303+
break;
304+
case 'docs':
305+
returnValue = await docs(commandOptions);
306+
break;
307+
case 'doctor':
308+
returnValue = await doctor(commandOptions);
309+
break;
310+
}
311+
312+
if (!returnValue) {
313+
returnValue = await main(cmd, argv);
314+
}
315+
282316
if (typeof returnValue === 'object') {
283317
return toJsonOrYaml(returnValue);
284318
} else if (typeof returnValue === 'string') {

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

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,10 @@
11
import * as chalk from 'chalk';
2-
import * as yargs from 'yargs';
32
import * as version from '../../lib/version';
43
import { CommandOptions } from '../command-api';
54
import { print } from '../logging';
65
import { Context, PROJECT_CONFIG } from '../settings';
76
import { renderTable } from '../util';
87

9-
export const command = 'context';
10-
export const describe = 'Manage cached context values';
11-
export const builder = {
12-
reset: {
13-
alias: 'e',
14-
desc: 'The context key (or its index) to reset',
15-
type: 'string',
16-
requiresArg: true,
17-
},
18-
clear: {
19-
desc: 'Clear all context',
20-
type: 'boolean',
21-
},
22-
};
23-
24-
export function handler(args: yargs.Arguments) {
25-
args.commandHandler = realHandler;
26-
}
27-
288
export async function realHandler(options: CommandOptions): Promise<number> {
299
const { configuration, args } = options;
3010

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

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,12 @@
11
import * as childProcess from 'child_process';
2-
import * as process from 'process';
32
import * as chalk from 'chalk';
4-
import * as yargs from 'yargs';
53
import { debug, print, warning } from '../../lib/logging';
64
import { CommandOptions } from '../command-api';
75

86
export const command = 'docs';
97
export const describe = 'Opens the reference documentation in a browser';
108
export const aliases = ['doc'];
119

12-
const defaultBrowserCommand: { [key in NodeJS.Platform]?: string } = {
13-
darwin: 'open %u',
14-
win32: 'start %u',
15-
};
16-
17-
export const builder = {
18-
browser: {
19-
alias: 'b',
20-
desc: 'the command to use to open the browser, using %u as a placeholder for the path of the file to open',
21-
type: 'string',
22-
default: process.platform in defaultBrowserCommand ? defaultBrowserCommand[process.platform] : 'xdg-open %u',
23-
},
24-
};
25-
26-
export interface Arguments extends yargs.Arguments {
27-
browser: string
28-
}
29-
30-
export function handler(args: yargs.Arguments) {
31-
args.commandHandler = realHandler;
32-
}
33-
3410
export async function realHandler(options: CommandOptions): Promise<number> {
3511
const url = 'https://docs.aws.amazon.com/cdk/api/v2/';
3612
print(chalk.green(url));

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as process from 'process';
22
import * as cxapi from '@aws-cdk/cx-api';
33
import * as chalk from 'chalk';
4-
import * as yargs from 'yargs';
54
import { print } from '../../lib/logging';
65
import * as version from '../../lib/version';
76
import { CommandOptions } from '../command-api';
87

9-
export const command = 'doctor';
10-
export const describe = 'Check your set-up for potential problems';
11-
export const builder = {};
12-
13-
export function handler(args: yargs.Arguments) {
14-
args.commandHandler = realHandler;
15-
}
16-
178
export async function realHandler(_options: CommandOptions): Promise<number> {
189
let exitStatus: number = 0;
1910
for (const verification of verifications) {

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as mockery from 'mockery';
22
import { CommandHandler } from '../lib/command-api';
3+
import { realHandler } from '../lib/commands/docs';
34

45
const argv = {
56
browser: 'echo %u',
@@ -25,9 +26,7 @@ describe('`cdk docs`', () => {
2526
});
2627

2728
test('exits with 0 when everything is OK', async () => {
28-
// eslint-disable-next-line @typescript-eslint/no-require-imports
29-
require('../lib/commands/docs').handler(argv);
30-
const result = await argv.commandHandler!({ args: argv } as any);
29+
const result = await realHandler({ args: argv } as any);
3130
expect(result).toBe(0);
3231
});
3332

@@ -37,9 +36,7 @@ describe('`cdk docs`', () => {
3736
cb(new Error('TEST'));
3837
},
3938
});
40-
// eslint-disable-next-line @typescript-eslint/no-require-imports
41-
require('../lib/commands/docs').handler(argv);
42-
const result = await argv.commandHandler!({ args: argv } as any);
39+
const result = await realHandler({ args: argv } as any);
4340
expect(result).toBe(0);
4441
});
4542
});

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as mockery from 'mockery';
2-
import { CommandHandler } from '../lib/command-api';
2+
import { realHandler } from '../lib/commands/doctor';
33

44
describe('`cdk doctor`', () => {
55
beforeEach(done => {
@@ -18,9 +18,7 @@ describe('`cdk doctor`', () => {
1818

1919
test('exits with 0 when everything is OK', async () => {
2020
const argv: any = {};
21-
// eslint-disable-next-line @typescript-eslint/no-require-imports
22-
require('../lib/commands/doctor').handler(argv);
23-
const result = await (argv.commandHandler as CommandHandler)({ args: argv } as any);
21+
const result = await realHandler({ args: argv } as any);
2422
expect(result).toBe(0);
2523
});
2624
});

0 commit comments

Comments
 (0)