From 6c77c9b965ede3e0bc65263708730c77f6e605f8 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Thu, 2 Jan 2025 18:17:01 -0500 Subject: [PATCH 1/5] chore(cli): model positional arguments in CliArguments --- packages/aws-cdk/lib/cli-arguments.ts | 72 +++++++++++++++++-- packages/aws-cdk/lib/convert-to-cli-args.ts | 22 ++++-- .../lib/parse-command-line-arguments.ts | 1 - packages/aws-cdk/test/cli-arguments.test.ts | 31 +++++++- .../cli-args-gen/lib/cli-args-function-gen.ts | 10 ++- .../@aws-cdk/cli-args-gen/lib/cli-args-gen.ts | 15 +++- 6 files changed, 139 insertions(+), 12 deletions(-) diff --git a/packages/aws-cdk/lib/cli-arguments.ts b/packages/aws-cdk/lib/cli-arguments.ts index ea957cd036765..f02928614238f 100644 --- a/packages/aws-cdk/lib/cli-arguments.ts +++ b/packages/aws-cdk/lib/cli-arguments.ts @@ -2,7 +2,6 @@ // GENERATED FROM packages/aws-cdk/lib/config.ts. // Do not edit by hand; all changes will be overwritten at build time from the config file. // ------------------------------------------------------------------------------------------- -// istanbul ignore file /* eslint-disable @stylistic/max-len */ import { Command } from './settings'; @@ -15,7 +14,7 @@ export interface CliArguments { /** * The CLI command name followed by any properties of the command */ - readonly _: [Command, ...string[]]; + readonly _: Command; /** * Global options available to all CLI commands @@ -328,6 +327,11 @@ export interface ListOptions { * @default - false */ readonly showDependencies?: boolean; + + /** + * Positional argument for list + */ + readonly STACKS?: Array; } /** @@ -362,6 +366,11 @@ export interface SynthesizeOptions { * @default - false */ readonly quiet?: boolean; + + /** + * Positional argument for synthesize + */ + readonly STACKS?: Array; } /** @@ -505,6 +514,11 @@ export interface BootstrapOptions { * @default - true */ readonly previousParameters?: boolean; + + /** + * Positional argument for bootstrap + */ + readonly ENVIRONMENTS?: Array; } /** @@ -554,6 +568,11 @@ export interface GcOptions { * @default - undefined */ readonly bootstrapStackName?: string; + + /** + * Positional argument for gc + */ + readonly ENVIRONMENTS?: Array; } /** @@ -749,6 +768,11 @@ export interface DeployOptions { * @default - false */ readonly ignoreNoStacks?: boolean; + + /** + * Positional argument for deploy + */ + readonly STACKS?: Array; } /** @@ -793,6 +817,11 @@ export interface RollbackOptions { * @default - [] */ readonly orphan?: Array; + + /** + * Positional argument for rollback + */ + readonly STACKS?: Array; } /** @@ -855,6 +884,11 @@ export interface ImportOptions { * @default - undefined */ readonly resourceMapping?: string; + + /** + * Positional argument for import + */ + readonly STACK?: string; } /** @@ -945,6 +979,11 @@ export interface WatchOptions { * @default - 1 */ readonly concurrency?: number; + + /** + * Positional argument for watch + */ + readonly STACKS?: Array; } /** @@ -977,6 +1016,11 @@ export interface DestroyOptions { * @default - undefined */ readonly force?: boolean; + + /** + * Positional argument for destroy + */ + readonly STACKS?: Array; } /** @@ -1053,6 +1097,11 @@ export interface DiffOptions { * @default - true */ readonly changeSet?: boolean; + + /** + * Positional argument for diff + */ + readonly STACKS?: Array; } /** @@ -1060,7 +1109,12 @@ export interface DiffOptions { * * @struct */ -export interface MetadataOptions {} +export interface MetadataOptions { + /** + * Positional argument for metadata + */ + readonly STACK?: string; +} /** * Acknowledge a notice so that it does not show up anymore @@ -1069,7 +1123,12 @@ export interface MetadataOptions {} * * @struct */ -export interface AcknowledgeOptions {} +export interface AcknowledgeOptions { + /** + * Positional argument for acknowledge + */ + readonly ID?: string; +} /** * Returns a list of relevant notices @@ -1115,6 +1174,11 @@ export interface InitOptions { * @default - false */ readonly generateOnly?: boolean; + + /** + * Positional argument for init + */ + readonly TEMPLATE?: string; } /** diff --git a/packages/aws-cdk/lib/convert-to-cli-args.ts b/packages/aws-cdk/lib/convert-to-cli-args.ts index a55fa39092195..3fc1b9a2bc541 100644 --- a/packages/aws-cdk/lib/convert-to-cli-args.ts +++ b/packages/aws-cdk/lib/convert-to-cli-args.ts @@ -2,7 +2,6 @@ // GENERATED FROM packages/aws-cdk/lib/config.ts. // Do not edit by hand; all changes will be overwritten at build time from the config file. // ------------------------------------------------------------------------------------------- -// istanbul ignore file /* eslint-disable @stylistic/max-len */ import { CliArguments, GlobalOptions } from './cli-arguments'; import { Command } from './settings'; @@ -42,6 +41,7 @@ export function convertToCliArgs(args: any): CliArguments { commandOptions = { long: args.long, showDependencies: args.showDependencies, + STACKS: args.STACKS, }; break; @@ -50,6 +50,7 @@ export function convertToCliArgs(args: any): CliArguments { exclusively: args.exclusively, validation: args.validation, quiet: args.quiet, + STACKS: args.STACKS, }; break; @@ -73,6 +74,7 @@ export function convertToCliArgs(args: any): CliArguments { toolkitStackName: args.toolkitStackName, template: args.template, previousParameters: args.previousParameters, + ENVIRONMENTS: args.ENVIRONMENTS, }; break; @@ -84,6 +86,7 @@ export function convertToCliArgs(args: any): CliArguments { createdBufferDays: args.createdBufferDays, confirm: args.confirm, bootstrapStackName: args.bootstrapStackName, + ENVIRONMENTS: args.ENVIRONMENTS, }; break; @@ -114,6 +117,7 @@ export function convertToCliArgs(args: any): CliArguments { assetParallelism: args.assetParallelism, assetPrebuild: args.assetPrebuild, ignoreNoStacks: args.ignoreNoStacks, + STACKS: args.STACKS, }; break; @@ -124,6 +128,7 @@ export function convertToCliArgs(args: any): CliArguments { force: args.force, validateBootstrapVersion: args.validateBootstrapVersion, orphan: args.orphan, + STACKS: args.STACKS, }; break; @@ -136,6 +141,7 @@ export function convertToCliArgs(args: any): CliArguments { force: args.force, recordResourceMapping: args.recordResourceMapping, resourceMapping: args.resourceMapping, + STACK: args.STACK, }; break; @@ -152,6 +158,7 @@ export function convertToCliArgs(args: any): CliArguments { hotswapFallback: args.hotswapFallback, logs: args.logs, concurrency: args.concurrency, + STACKS: args.STACKS, }; break; @@ -160,6 +167,7 @@ export function convertToCliArgs(args: any): CliArguments { all: args.all, exclusively: args.exclusively, force: args.force, + STACKS: args.STACKS, }; break; @@ -174,15 +182,20 @@ export function convertToCliArgs(args: any): CliArguments { processed: args.processed, quiet: args.quiet, changeSet: args.changeSet, + STACKS: args.STACKS, }; break; case 'metadata': - commandOptions = {}; + commandOptions = { + STACK: args.STACK, + }; break; case 'acknowledge': - commandOptions = {}; + commandOptions = { + ID: args.ID, + }; break; case 'notices': @@ -196,6 +209,7 @@ export function convertToCliArgs(args: any): CliArguments { language: args.language, list: args.list, generateOnly: args.generateOnly, + TEMPLATE: args.TEMPLATE, }; break; @@ -233,7 +247,7 @@ export function convertToCliArgs(args: any): CliArguments { break; } const cliArguments: CliArguments = { - _: args._, + _: args._[0], globalOptions, [args._[0]]: commandOptions, }; diff --git a/packages/aws-cdk/lib/parse-command-line-arguments.ts b/packages/aws-cdk/lib/parse-command-line-arguments.ts index 88c379a035dea..b0d4f3060024e 100644 --- a/packages/aws-cdk/lib/parse-command-line-arguments.ts +++ b/packages/aws-cdk/lib/parse-command-line-arguments.ts @@ -2,7 +2,6 @@ // GENERATED FROM packages/aws-cdk/lib/config.ts. // Do not edit by hand; all changes will be overwritten at build time from the config file. // ------------------------------------------------------------------------------------------- -// istanbul ignore file /* eslint-disable @stylistic/max-len */ import { Argv } from 'yargs'; import * as helpers from './util/yargs-helpers'; diff --git a/packages/aws-cdk/test/cli-arguments.test.ts b/packages/aws-cdk/test/cli-arguments.test.ts index d749efb2785bd..33b2b54342cc1 100644 --- a/packages/aws-cdk/test/cli-arguments.test.ts +++ b/packages/aws-cdk/test/cli-arguments.test.ts @@ -7,7 +7,7 @@ test('yargs object can be converted to cli arguments', async () => { const result = convertToCliArgs(input); expect(result).toEqual({ - _: ['deploy'], + _: 'deploy', globalOptions: { app: undefined, assetMetadata: undefined, @@ -36,6 +36,7 @@ test('yargs object can be converted to cli arguments', async () => { output: undefined, }, deploy: { + STACKS: undefined, all: false, assetParallelism: undefined, assetPrebuild: true, @@ -64,3 +65,31 @@ test('yargs object can be converted to cli arguments', async () => { }, }); }); + +test('positional argument is correctly passed through -- variadic', async () => { + const input = await parseCommandLineArguments(['deploy', 'stack1', 'stack2', '-R', '-v', '--ci']); + + const result = convertToCliArgs(input); + + expect(result).toEqual({ + _: 'deploy', + deploy: expect.objectContaining({ + STACKS: ['stack1', 'stack2'], + }), + globalOptions: expect.anything(), + }); +}); + +test('positional argument is correctly passed through -- single', async () => { + const input = await parseCommandLineArguments(['acknowledge', 'id1', '-R', '-v', '--ci']); + + const result = convertToCliArgs(input); + + expect(result).toEqual({ + _: 'acknowledge', + acknowledge: expect.objectContaining({ + ID: 'id1', + }), + globalOptions: expect.anything(), + }); +}); diff --git a/tools/@aws-cdk/cli-args-gen/lib/cli-args-function-gen.ts b/tools/@aws-cdk/cli-args-gen/lib/cli-args-function-gen.ts index 67aa076528238..cb7e6a6dd22d4 100644 --- a/tools/@aws-cdk/cli-args-gen/lib/cli-args-function-gen.ts +++ b/tools/@aws-cdk/cli-args-gen/lib/cli-args-function-gen.ts @@ -67,6 +67,7 @@ function buildCommandSwitch(config: CliConfig): string { `case '${commandName}':`, 'commandOptions = {', ...buildCommandOptions(config.commands[commandName]), + ...(config.commands[commandName].arg ? [buildPositionalArguments(config.commands[commandName].arg)] : []), '};', `break; `); @@ -84,10 +85,17 @@ function buildCommandOptions(options: CliAction): string[] { return commandOptions; } +function buildPositionalArguments(arg: { name: string; variadic: boolean }): string { + if (arg.variadic) { + return `${arg.name}: args.${arg.name}`; + } + return `${arg.name}: args.${arg.name}`; +} + function buildCliArgs(): string { return [ 'const cliArguments: CliArguments = {', - '_: args._,', + '_: args._[0],', 'globalOptions,', '[args._[0]]: commandOptions', '}', diff --git a/tools/@aws-cdk/cli-args-gen/lib/cli-args-gen.ts b/tools/@aws-cdk/cli-args-gen/lib/cli-args-gen.ts index 139e4dd7a6c9d..3e2484e8b4cd5 100644 --- a/tools/@aws-cdk/cli-args-gen/lib/cli-args-gen.ts +++ b/tools/@aws-cdk/cli-args-gen/lib/cli-args-gen.ts @@ -26,7 +26,7 @@ export async function renderCliArgsType(config: CliConfig): Promise { cliArgType.addProperty({ name: '_', - type: Type.ambient(`[${commandEnum}, ...string[]]`), + type: commandEnum, docs: { summary: 'The CLI command name followed by any properties of the command', }, @@ -73,6 +73,7 @@ export async function renderCliArgsType(config: CliConfig): Promise { }, }); + // add command level options for (const [optionName, option] of Object.entries(command.options ?? {})) { commandType.addProperty({ name: kebabToCamelCase(optionName), @@ -88,6 +89,18 @@ export async function renderCliArgsType(config: CliConfig): Promise { }); } + // add positional argument associated with the command + if (command.arg) { + commandType.addProperty({ + name: command.arg.name, + type: command.arg.variadic ? Type.arrayOf(Type.STRING) : Type.STRING, + docs: { + summary: `Positional argument for ${commandName}`, + }, + optional: true, + }); + } + cliArgType.addProperty({ name: kebabToCamelCase(commandName), type: Type.fromName(scope, commandType.name), From 37429b86f062ae3a6eddb49168b6e04eb98360c5 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Thu, 2 Jan 2025 18:21:40 -0500 Subject: [PATCH 2/5] test positional args --- .../@aws-cdk/cli-args-gen/lib/cli-args-gen.ts | 2 +- .../test/cli-args-function-gen.test.ts | 2 +- .../cli-args-gen/test/cli-args-gen.test.ts | 98 ++++++++++++++++++- 3 files changed, 96 insertions(+), 6 deletions(-) diff --git a/tools/@aws-cdk/cli-args-gen/lib/cli-args-gen.ts b/tools/@aws-cdk/cli-args-gen/lib/cli-args-gen.ts index 3e2484e8b4cd5..859319d028661 100644 --- a/tools/@aws-cdk/cli-args-gen/lib/cli-args-gen.ts +++ b/tools/@aws-cdk/cli-args-gen/lib/cli-args-gen.ts @@ -28,7 +28,7 @@ export async function renderCliArgsType(config: CliConfig): Promise { name: '_', type: commandEnum, docs: { - summary: 'The CLI command name followed by any properties of the command', + summary: 'The CLI command name', }, }); diff --git a/tools/@aws-cdk/cli-args-gen/test/cli-args-function-gen.test.ts b/tools/@aws-cdk/cli-args-gen/test/cli-args-function-gen.test.ts index 2f5f1a96e57ed..15d9034c200cb 100644 --- a/tools/@aws-cdk/cli-args-gen/test/cli-args-function-gen.test.ts +++ b/tools/@aws-cdk/cli-args-gen/test/cli-args-function-gen.test.ts @@ -64,7 +64,7 @@ describe('render', () => { break; } const cliArguments: CliArguments = { - _: args._, + _: args._[0], globalOptions, [args._[0]]: commandOptions, }; diff --git a/tools/@aws-cdk/cli-args-gen/test/cli-args-gen.test.ts b/tools/@aws-cdk/cli-args-gen/test/cli-args-gen.test.ts index cdae7d1a6d967..a323974bee1e8 100644 --- a/tools/@aws-cdk/cli-args-gen/test/cli-args-gen.test.ts +++ b/tools/@aws-cdk/cli-args-gen/test/cli-args-gen.test.ts @@ -53,9 +53,9 @@ describe('render', () => { */ export interface CliArguments { /** - * The CLI command name followed by any properties of the command + * The CLI command name */ - readonly _: [Command, ...string[]]; + readonly _: Command; /** * Global options available to all CLI commands @@ -155,9 +155,9 @@ describe('render', () => { */ export interface CliArguments { /** - * The CLI command name followed by any properties of the command + * The CLI command name */ - readonly _: [Command, ...string[]]; + readonly _: Command; /** * Global options available to all CLI commands @@ -200,4 +200,94 @@ describe('render', () => { " `); }); + + test('positional arguments', async () => { + const config: CliConfig = { + commands: { + deploy: { + arg: { + name: 'STACKS', + variadic: true, + }, + description: 'deploy', + }, + acknowledge: { + arg: { + name: 'ID', + variadic: false, + }, + description: 'acknowledge', + }, + }, + globalOptions: {}, + }; + + expect(await renderCliArgsType(config)).toMatchInlineSnapshot(` + "// ------------------------------------------------------------------------------------------- + // GENERATED FROM packages/aws-cdk/lib/config.ts. + // Do not edit by hand; all changes will be overwritten at build time from the config file. + // ------------------------------------------------------------------------------------------- + /* eslint-disable @stylistic/max-len */ + import { Command } from './settings'; + + /** + * The structure of the CLI configuration, generated from packages/aws-cdk/lib/config.ts + * + * @struct + */ + export interface CliArguments { + /** + * The CLI command name + */ + readonly _: Command; + + /** + * Global options available to all CLI commands + */ + readonly globalOptions?: GlobalOptions; + + /** + * deploy + */ + readonly deploy?: DeployOptions; + + /** + * acknowledge + */ + readonly acknowledge?: AcknowledgeOptions; + } + + /** + * Global options available to all CLI commands + * + * @struct + */ + export interface GlobalOptions {} + + /** + * deploy + * + * @struct + */ + export interface DeployOptions { + /** + * Positional argument for deploy + */ + readonly STACKS?: Array; + } + + /** + * acknowledge + * + * @struct + */ + export interface AcknowledgeOptions { + /** + * Positional argument for acknowledge + */ + readonly ID?: string; + } + " + `); + }); }); From 80b91cd0f7af74f5c942a859c9d673e319694636 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Thu, 2 Jan 2025 18:22:42 -0500 Subject: [PATCH 3/5] more test --- .../@aws-cdk/cli-args-gen/test/cli-args-function-gen.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/@aws-cdk/cli-args-gen/test/cli-args-function-gen.test.ts b/tools/@aws-cdk/cli-args-gen/test/cli-args-function-gen.test.ts index 15d9034c200cb..24b92c7fe291e 100644 --- a/tools/@aws-cdk/cli-args-gen/test/cli-args-function-gen.test.ts +++ b/tools/@aws-cdk/cli-args-gen/test/cli-args-function-gen.test.ts @@ -26,6 +26,10 @@ describe('render', () => { }, commands: { deploy: { + arg: { + name: 'STACKS', + variadic: true, + }, description: 'Deploy a stack', options: { all: { @@ -60,6 +64,7 @@ describe('render', () => { case 'deploy': commandOptions = { all: args.all, + STACKS: args.STACKS, }; break; } From b2811ee715a1153be417e4cbc22985eefe2c86b4 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy <36202692+kaizencc@users.noreply.github.com> Date: Thu, 2 Jan 2025 18:28:42 -0500 Subject: [PATCH 4/5] Update packages/aws-cdk/test/cli-arguments.test.ts --- packages/aws-cdk/test/cli-arguments.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk/test/cli-arguments.test.ts b/packages/aws-cdk/test/cli-arguments.test.ts index 33b2b54342cc1..3024bfaae524a 100644 --- a/packages/aws-cdk/test/cli-arguments.test.ts +++ b/packages/aws-cdk/test/cli-arguments.test.ts @@ -81,7 +81,7 @@ test('positional argument is correctly passed through -- variadic', async () => }); test('positional argument is correctly passed through -- single', async () => { - const input = await parseCommandLineArguments(['acknowledge', 'id1', '-R', '-v', '--ci']); + const input = await parseCommandLineArguments(['acknowledge', 'id1', '-v', '--ci']); const result = convertToCliArgs(input); From 057153065f2eaf706d9421566b6a094077b3c33d Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Fri, 3 Jan 2025 10:19:56 -0500 Subject: [PATCH 5/5] sync --- packages/aws-cdk/lib/cli-arguments.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk/lib/cli-arguments.ts b/packages/aws-cdk/lib/cli-arguments.ts index f02928614238f..8dc3afcc24c09 100644 --- a/packages/aws-cdk/lib/cli-arguments.ts +++ b/packages/aws-cdk/lib/cli-arguments.ts @@ -12,7 +12,7 @@ import { Command } from './settings'; */ export interface CliArguments { /** - * The CLI command name followed by any properties of the command + * The CLI command name */ readonly _: Command;