Skip to content

Commit

Permalink
fix(cli): duplicate command checks now accounts for subcommands
Browse files Browse the repository at this point in the history
  • Loading branch information
edvald committed May 14, 2018
1 parent 3aca6ac commit b9e22f5
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 16 deletions.
10 changes: 6 additions & 4 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<any>
const options = command.options as Parameter<any>
Expand Down Expand Up @@ -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])))
}
Expand Down
13 changes: 11 additions & 2 deletions src/commands/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ export class EnvironmentOption extends StringParameter {
export type Parameters = { [key: string]: Parameter<any> }
export type ParameterValues<T extends Parameters> = { [P in keyof T]: T["_valueType"] }

export interface CommandConstructor {
new(parent?: Command): Command
}

export abstract class Command<T extends Parameters = {}, U extends Parameters = {}> {
abstract name: string
abstract help: string
Expand All @@ -124,9 +128,14 @@ export abstract class Command<T extends Parameters = {}, U extends Parameters =

arguments: T
options: U
subCommands?: Command[]

constructor() { }
subCommands?: CommandConstructor[]

constructor(private parent?: Command) { }

getFullName() {
return !!this.parent ? `${this.parent.getFullName()} ${this.name}` : this.name
}

// Note: Due to a current TS limitation (apparently covered by https://github.com/Microsoft/TypeScript/issues/7011),
// subclass implementations need to explicitly set the types in the implemented function signature. So for now we
Expand Down
6 changes: 3 additions & 3 deletions src/commands/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export class ConfigCommand extends Command {
help = "Manage configuration variables in your environment"

subCommands = [
new ConfigGetCommand(),
new ConfigSetCommand(),
new ConfigDeleteCommand(),
ConfigGetCommand,
ConfigSetCommand,
ConfigDeleteCommand,
]

async action() { }
Expand Down
4 changes: 2 additions & 2 deletions src/commands/environment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export class EnvironmentCommand extends Command {
help = "Manage your runtime environment(s)"

subCommands = [
new EnvironmentConfigureCommand(),
new EnvironmentDestroyCommand(),
EnvironmentConfigureCommand,
EnvironmentDestroyCommand,
]

async action() { }
Expand Down
6 changes: 3 additions & 3 deletions src/commands/run/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ export class RunCommand extends Command {
help = "Run ad-hoc instances of your modules, services and tests"

subCommands = [
new RunModuleCommand(),
new RunServiceCommand(),
new RunTestCommand(),
RunModuleCommand,
RunServiceCommand,
RunTestCommand,
]

async action() { }
Expand Down
4 changes: 2 additions & 2 deletions test/src/commands/run/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe("RunCommand", () => {

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"])
})
})

0 comments on commit b9e22f5

Please sign in to comment.