Skip to content

Commit

Permalink
feat(project): add commands for CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
RWOverdijk committed Sep 30, 2018
1 parent 36526f4 commit eb555ae
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/Library/Command/AbstractCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export abstract class AbstractCommand {

}
15 changes: 15 additions & 0 deletions src/Library/Command/CommandManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { CommandManagerConfigType } from './CommandManagerConfigType';
import { ServiceManager } from '../ServiceManager';
import { AbstractFileBasedPluginManager } from '../ServiceManager/AbstractFileBasedPluginManager';
import { Instantiable } from '../Core';
import { AbstractCommand } from './AbstractCommand';

export class CommandManager extends AbstractFileBasedPluginManager {
constructor (creationContext: ServiceManager, config: CommandManagerConfigType) {
super(creationContext, config.locations, config.commands);
}

public getCommand (Command: AbstractCommand): Object {
return this.getPlugin(Command as Instantiable<Object>);
}
}
7 changes: 7 additions & 0 deletions src/Library/Command/CommandManagerConfigType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ServiceManagerConfigType } from '../ServiceManager';

export type CommandManagerConfigType = Partial<{
locations: string[];
commands: ServiceManagerConfigType;
}>;

8 changes: 8 additions & 0 deletions src/Library/Command/CommandManagerFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { FactoryInterface, ServiceManager } from '../ServiceManager';
import { CommandManager } from './CommandManager';
import { CommandManagerConfigType } from './CommandManagerConfigType';
import { Config } from '../Config';

export const CommandManagerFactory: FactoryInterface = (sm: ServiceManager) => {
return new CommandManager(sm, sm.get(Config).of<CommandManagerConfigType>('command'));
};
3 changes: 3 additions & 0 deletions src/Library/Command/CommandTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type CommandConfigType = {

};
96 changes: 96 additions & 0 deletions src/Library/Command/HelpCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import chalk from 'chalk';
import commandLineUsage from 'command-line-usage';
import { AbstractCommand } from './AbstractCommand';
import { CliCommandOptionsType, CliCommandType, CliService, ProcessedProgramType } from '../Cli';
import { inject } from '../ServiceManager/decorators';
import { Output } from '../Output';

export class HelpCommand extends AbstractCommand {
@inject(CliService)
private cliService: CliService;

output ({ params, options }: any, output: Output) {
const config = this.cliService.getConfig();
const programs = this.cliService.getPrograms();

if (params.command) {
const command = this.cliService.getCommand(params.command);

if (!command) {
return output.error(`Unknown command "${params.command}".`);
}

return output.addData(commandLineUsage(this.renderUsage(command)));
}

const sections: { [ key: string ]: any } = [
{ header: config.title, content: `{italic ${config.subtitle}}` },
{
header: chalk.yellow('Available commands:'),
},
];

const collectedExamples: string[] = [];

Object.values(programs).forEach(({ program, commands, examples }: ProcessedProgramType) => {
sections.push({ content: chalk.yellow(program), raw: true });
sections.push({ content: Object.keys(commands).map((command: string) => this.renderCommand(commands[ command ])) });

if (Array.isArray(examples)) {
collectedExamples.push(...examples);
}
});

if (collectedExamples) {
sections.push(this.renderExamples(collectedExamples));
}

output.addData(commandLineUsage(sections));
}

private renderUsage (command: CliCommandType): { [ key: string ]: any } {

const sections: { [ key: string ]: any } = [
{ header: chalk.yellow('Usage'), content: [ this.renderCommand(command) ] },
];

if (command.config) {
if (command.config.options) {
sections.push(this.renderOptions(command.config.options));
}

if (command.config.examples) {
sections.push(this.renderExamples(command.config.examples));
}
}

return sections;
}

private renderOptions (options: CliCommandOptionsType) {
return {
header: chalk.yellow('Options:'),
optionList: Object.keys(options).map(optionName => {
const { alias, description, value } = options[optionName];

return {
description,
alias: chalk.green(alias),
name: chalk.green(optionName),
typeLabel: value && `{underline ${value}}`,
};
}),
};
}

private renderExamples (examples: string[]) {
return {
header: chalk.yellow('Examples:'),
content: examples.map(description => ({ description })),
};
}

private renderCommand ({ commandLine, config }: CliCommandType) {
return { name: chalk.green(commandLine), description: (config && config.description) || '{italic No description found}' };
}
}
3 changes: 3 additions & 0 deletions src/Library/Command/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './CommandManagerConfigType';
export * from './CommandManager';
export * from './CommandManagerFactory';

0 comments on commit eb555ae

Please sign in to comment.