Skip to content

Commit

Permalink
refactor(cli): fix various minor codegen issues (#32024)
Browse files Browse the repository at this point in the history
### Reason for this change

Fixes some small issues that got missed before #31850 was unintentionally merged too early.

### Description of changes

* re-add support for `CDK_` env variables
* remove square bracktes when commands don't have an alias
* remove extra space in command args
* fixed `demandCommand` call

### Description of how you validated changes

Run via tests, compared manually with cli options before we started to generate them.

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
mrgrain authored Nov 5, 2024
1 parent 4f8ecae commit b3de7e6
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 57 deletions.
104 changes: 54 additions & 50 deletions packages/aws-cdk/lib/parse-command-line-arguments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export function parseCommandLineArguments(
yargsNegativeAlias: any
): any {
return yargs
.env('CDK')
.usage('Usage: cdk -a <cdk-app> COMMAND')
.option('app', {
type: 'string',
Expand Down Expand Up @@ -148,7 +149,7 @@ export function parseCommandLineArguments(
desc: 'Opt in to unstable features. The flag indicates that the scope and API of a feature might still change. Otherwise the feature is generally production ready and fully supported. Can be specified multiple times.',
default: [],
})
.command(['list [STACKS..]', 'ls [STACKS..]'], 'Lists all stacks in the app', (yargs: Argv) =>
.command(['list [STACKS..]', 'ls [STACKS..]'], 'Lists all stacks in the app', (yargs: Argv) =>
yargs
.option('long', {
type: 'boolean',
Expand All @@ -163,7 +164,7 @@ export function parseCommandLineArguments(
desc: 'Display stack dependency information for each stack',
})
)
.command(['synthesize [STACKS..]', 'synth [STACKS..]'], 'Synthesizes and prints the CloudFormation template for this stack', (yargs: Argv) =>
.command(['synthesize [STACKS..]', 'synth [STACKS..]'], 'Synthesizes and prints the CloudFormation template for this stack', (yargs: Argv) =>
yargs
.option('exclusively', {
type: 'boolean',
Expand All @@ -182,7 +183,7 @@ export function parseCommandLineArguments(
default: false,
})
)
.command(['bootstrap [ENVIRONMENTS..]'], 'Deploys the CDK toolkit stack into an AWS environment', (yargs: Argv) =>
.command('bootstrap [ENVIRONMENTS..]', 'Deploys the CDK toolkit stack into an AWS environment', (yargs: Argv) =>
yargs
.option('bootstrap-bucket-name', {
type: 'string',
Expand Down Expand Up @@ -292,40 +293,43 @@ export function parseCommandLineArguments(
desc: 'Use previous values for existing parameters (you must specify all parameters on every deployment if this is disabled)',
})
)
.command(['gc [ENVIRONMENTS..]'], 'Garbage collect assets', (yargs: Argv) =>
yargs
.option('action', {
type: 'string',
desc: 'The action (or sub-action) you want to perform. Valid entires are "print", "tag", "delete-tagged", "full".',
default: 'full',
})
.option('type', {
type: 'string',
desc: 'Specify either ecr, s3, or all',
default: 'all',
})
.option('rollback-buffer-days', {
type: 'number',
desc: 'Delete assets that have been marked as isolated for this many days',
default: 0,
})
.option('created-buffer-days', {
type: 'number',
desc: 'Never delete assets younger than this (in days)',
default: 1,
})
.option('confirm', {
type: 'boolean',
desc: 'Confirm via manual prompt before deletion',
default: true,
})
.option('bootstrap-stack-name', {
type: 'string',
desc: 'The name of the CDK toolkit stack, if different from the default "CDKToolkit"',
requiresArg: true,
})
.command(
'gc [ENVIRONMENTS..]',
'Garbage collect assets. Options detailed here: https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk/README.md#cdk-gc',
(yargs: Argv) =>
yargs
.option('action', {
type: 'string',
desc: 'The action (or sub-action) you want to perform. Valid entires are "print", "tag", "delete-tagged", "full".',
default: 'full',
})
.option('type', {
type: 'string',
desc: 'Specify either ecr, s3, or all',
default: 'all',
})
.option('rollback-buffer-days', {
type: 'number',
desc: 'Delete assets that have been marked as isolated for this many days',
default: 0,
})
.option('created-buffer-days', {
type: 'number',
desc: 'Never delete assets younger than this (in days)',
default: 1,
})
.option('confirm', {
type: 'boolean',
desc: 'Confirm via manual prompt before deletion',
default: true,
})
.option('bootstrap-stack-name', {
type: 'string',
desc: 'The name of the CDK toolkit stack, if different from the default "CDKToolkit"',
requiresArg: true,
})
)
.command(['deploy [STACKS..]'], 'Deploys the stack(s) named STACKS into your AWS account', (yargs: Argv) =>
.command('deploy [STACKS..]', 'Deploys the stack(s) named STACKS into your AWS account', (yargs: Argv) =>
yargs
.option('all', {
type: 'boolean',
Expand Down Expand Up @@ -459,7 +463,7 @@ export function parseCommandLineArguments(
default: false,
})
)
.command(['rollback [STACKS..]'], 'Rolls back the stack(s) named STACKS to their last stable state', (yargs: Argv) =>
.command('rollback [STACKS..]', 'Rolls back the stack(s) named STACKS to their last stable state', (yargs: Argv) =>
yargs
.option('all', {
type: 'boolean',
Expand Down Expand Up @@ -488,7 +492,7 @@ export function parseCommandLineArguments(
default: [],
})
)
.command(['import [STACK]'], 'Import existing resource(s) into the given STACK', (yargs: Argv) =>
.command('import [STACK]', 'Import existing resource(s) into the given STACK', (yargs: Argv) =>
yargs
.option('execute', {
type: 'boolean',
Expand Down Expand Up @@ -526,7 +530,7 @@ export function parseCommandLineArguments(
desc: 'If specified, CDK will use the given file to map physical resources to CDK resources for import, instead of interactively asking the user. Can be run from scripts',
})
)
.command(['watch [STACKS..]'], "Shortcut for 'deploy --watch'", (yargs: Argv) =>
.command('watch [STACKS..]', "Shortcut for 'deploy --watch'", (yargs: Argv) =>
yargs
.option('build-exclude', {
type: 'array',
Expand Down Expand Up @@ -589,7 +593,7 @@ export function parseCommandLineArguments(
requiresArg: true,
})
)
.command(['destroy [STACKS..]'], 'Destroy the stack(s) named STACKS', (yargs: Argv) =>
.command('destroy [STACKS..]', 'Destroy the stack(s) named STACKS', (yargs: Argv) =>
yargs
.option('all', {
type: 'boolean',
Expand All @@ -608,7 +612,7 @@ export function parseCommandLineArguments(
})
)
.command(
['diff [STACKS..]'],
'diff [STACKS..]',
'Compares the specified stack with the deployed stack or a local template file, and returns with status 1 if any difference is found',
(yargs: Argv) =>
yargs
Expand Down Expand Up @@ -660,17 +664,17 @@ export function parseCommandLineArguments(
default: true,
})
)
.command(['metadata [STACK]'], 'Returns all metadata associated with this stack')
.command(['acknowledge [ID]', 'ack [ID]'], 'Acknowledge a notice so that it does not show up anymore')
.command(['notices'], 'Returns a list of relevant notices', (yargs: Argv) =>
.command('metadata [STACK]', 'Returns all metadata associated with this stack')
.command(['acknowledge [ID]', 'ack [ID]'], 'Acknowledge a notice so that it does not show up anymore')
.command('notices', 'Returns a list of relevant notices', (yargs: Argv) =>
yargs.option('unacknowledged', {
type: 'boolean',
alias: 'u',
default: false,
desc: 'Returns a list of unacknowledged notices',
})
)
.command(['init [TEMPLATE]'], 'Create a new, empty CDK project from a template.', (yargs: Argv) =>
.command('init [TEMPLATE]', 'Create a new, empty CDK project from a template.', (yargs: Argv) =>
yargs
.option('language', {
type: 'string',
Expand All @@ -688,7 +692,7 @@ export function parseCommandLineArguments(
desc: 'If true, only generates project files, without executing additional operations such as setting up a git repo, installing dependencies or compiling the project',
})
)
.command(['migrate'], false, (yargs: Argv) =>
.command('migrate', false, (yargs: Argv) =>
yargs
.option('stack-name', {
type: 'string',
Expand Down Expand Up @@ -736,7 +740,7 @@ export function parseCommandLineArguments(
desc: 'Use this flag to zip the generated CDK app',
})
)
.command(['context'], 'Manage cached context values', (yargs: Argv) =>
.command('context', 'Manage cached context values', (yargs: Argv) =>
yargs
.option('reset', {
alias: 'e',
Expand All @@ -755,17 +759,17 @@ export function parseCommandLineArguments(
type: 'boolean',
})
)
.command(['docs', 'doc '], 'Opens the reference documentation in a browser', (yargs: Argv) =>
.command(['docs', 'doc'], 'Opens the reference documentation in a browser', (yargs: Argv) =>
yargs.option('browser', {
alias: 'b',
desc: 'the command to use to open the browser, using %u as a placeholder for the path of the file to open',
type: 'string',
default: browserDefault,
})
)
.command(['doctor'], 'Check your set-up for potential problems')
.command('doctor', 'Check your set-up for potential problems')
.version(version)
.demandCommand(1, "''")
.demandCommand(1, '')
.recommendCommands()
.help()
.alias('h', 'help')
Expand Down
24 changes: 18 additions & 6 deletions tools/@aws-cdk/yargs-gen/lib/yargs-gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ export async function renderYargs(config: CliConfig): Promise<string> {
// ./prog --arg one --arg two position => will parse to { arg: ['one', 'two'], _: ['positional'] }.
function makeYargs(config: CliConfig): Statement {
let yargsExpr: Expression = code.expr.ident('yargs');
yargsExpr = yargsExpr.callMethod('usage', lit('Usage: cdk -a <cdk-app> COMMAND'));
yargsExpr = yargsExpr
.callMethod('env', lit('CDK'))
.callMethod('usage', lit('Usage: cdk -a <cdk-app> COMMAND'));

// we must compute global options first, as they are not part of an argument to a command call
yargsExpr = makeOptions(yargsExpr, config.globalOptions);
Expand All @@ -75,16 +77,26 @@ function makeYargs(config: CliConfig): Statement {
? ` [${commandFacts.arg?.name}${commandFacts.arg?.variadic ? '..' : ''}]`
: '';
const aliases = commandFacts.aliases
? commandFacts.aliases.map((alias) => `, '${alias} ${commandArg}'`)
? commandFacts.aliases.map((alias) => `, '${alias}${commandArg}'`)
: '';

// must compute options before we compute the full command, because in yargs, the options are an argument to the command call.
let optionsExpr: Expression = code.expr.directCode('(yargs: Argv) => yargs');
optionsExpr = makeOptions(optionsExpr, commandFacts.options ?? {});

yargsExpr = commandFacts.options
? yargsExpr.callMethod('command', code.expr.directCode(`['${command}${commandArg}'${aliases}]`), lit(commandFacts.description), optionsExpr)
: yargsExpr.callMethod('command', code.expr.directCode(`['${command}${commandArg}'${aliases}]`), lit(commandFacts.description));
const commandCallArgs: Array<Expression> = [];
if (aliases) {
commandCallArgs.push(code.expr.directCode(`['${command}${commandArg}'${aliases}]`));
} else {
commandCallArgs.push(code.expr.directCode(`'${command}${commandArg}'`));
}
commandCallArgs.push(lit(commandFacts.description));

if (commandFacts.options) {
commandCallArgs.push(optionsExpr);
}

yargsExpr = yargsExpr.callMethod('command', ...commandCallArgs);
}

return code.stmt.ret(makeEpilogue(yargsExpr));
Expand Down Expand Up @@ -129,7 +141,7 @@ function makeOptions(prefix: Expression, options: { [optionName: string]: YargsO

function makeEpilogue(prefix: Expression) {
let completeDefinition = prefix.callMethod('version', code.expr.ident('version'));
completeDefinition = completeDefinition.callMethod('demandCommand', lit(1), lit("''")); // just print help
completeDefinition = completeDefinition.callMethod('demandCommand', lit(1), lit('')); // just print help
completeDefinition = completeDefinition.callMethod('recommendCommands');
completeDefinition = completeDefinition.callMethod('help');
completeDefinition = completeDefinition.callMethod('alias', lit('h'), lit('help'));
Expand Down
3 changes: 2 additions & 1 deletion tools/@aws-cdk/yargs-gen/test/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe('render', () => {
yargsNegativeAlias: any
): any {
return yargs
.env('CDK')
.usage('Usage: cdk -a <cdk-app> COMMAND')
.option('one', {
type: 'string',
Expand All @@ -59,7 +60,7 @@ describe('render', () => {
requiresArg: true,
})
.version(version)
.demandCommand(1, "''")
.demandCommand(1, '')
.recommendCommands()
.help()
.alias('h', 'help')
Expand Down

0 comments on commit b3de7e6

Please sign in to comment.