diff --git a/src/cli.ts b/src/cli.ts index 786076e9de..a726ee1aef 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -248,12 +248,14 @@ export class GardenCli { } addCommand(command: Command, program): void { - if (this.commands[command.name]) { + const fullName = command.getFullName() + + if (this.commands[fullName]) { // For now we don't allow multiple definitions of the same command. We may want to revisit this later. - throw new PluginError(`Multiple definitions of command "${command.name}"`, {}) + throw new PluginError(`Multiple definitions of command "${fullName}"`, {}) } - this.commands[command.name] = command + this.commands[fullName] = command const args = command.arguments as Parameter const options = command.options as Parameter @@ -294,7 +296,7 @@ export class GardenCli { // Command specific positional args and options are set inside the builder function const setup = parser => { - subCommands.forEach(subCommand => this.addCommand(subCommand, parser)) + subCommands.forEach(subCommandCls => this.addCommand(new subCommandCls(command), parser)) argKeys.forEach(key => parser.positional(makeArgSynopsis(key, args[key]), makeArgConfig(args[key]))) optKeys.forEach(key => parser.option(makeOptSynopsis(key, options[key]), makeOptConfig(options[key]))) } diff --git a/src/commands/base.ts b/src/commands/base.ts index dfd257629f..b6265b6645 100644 --- a/src/commands/base.ts +++ b/src/commands/base.ts @@ -116,6 +116,10 @@ export class EnvironmentOption extends StringParameter { export type Parameters = { [key: string]: Parameter } export type ParameterValues = { [P in keyof T]: T["_valueType"] } +export interface CommandConstructor { + new(parent?: Command): Command +} + export abstract class Command { abstract name: string abstract help: string @@ -124,9 +128,14 @@ export abstract class Command { it("should contain a set of subcommands", () => { const cmd = new RunCommand() - const subcommandNames = new Set(cmd.subCommands.map(s => s.name)) - expect(subcommandNames).to.eql(new Set(["module", "service", "test"])) + const subcommandNames = cmd.subCommands.map(s => new s().name) + expect(subcommandNames).to.eql(["module", "service", "test"]) }) })